aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c240
1 files changed, 100 insertions, 140 deletions
diff --git a/main.c b/main.c
index 574c81c..5ea236e 100644
--- a/main.c
+++ b/main.c
@@ -33,6 +33,7 @@
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
+#include <stdint.h>
#include "args.h"
#include "common.h"
@@ -56,27 +57,6 @@ static const int event_type[] = {
V4L2_EVENT_SOURCE_CHANGE,
};
-static struct timeval start, end;
-
-static void time_start(void)
-{
- gettimeofday(&start, NULL);
-}
-
-static void print_time_delta(const char *prefix)
-{
- unsigned long delta;
-
- gettimeofday(&end, NULL);
-
- delta = (end.tv_sec * 1000000 + end.tv_usec) -
- (start.tv_sec * 1000000 + start.tv_usec);
-
- delta = delta;
-
- dbg("%s: %ld\n", prefix, delta);
-}
-
static int subscribe_for_events(int fd)
{
int size_event = sizeof(event_type) / sizeof(event_type[0]);
@@ -108,23 +88,14 @@ static int handle_v4l_events(struct video *vid)
}
switch (event.type) {
- case V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT:
- dbg("Port Reconfig recieved insufficient\n");
- break;
- case V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT:
- dbg("Setting changed sufficient\n");
+ case V4L2_EVENT_EOS:
+ dbg("event eos");
break;
- case V4L2_EVENT_MSM_VIDC_FLUSH_DONE:
- dbg("Flush Done Recieved \n");
- break;
- case V4L2_EVENT_MSM_VIDC_CLOSE_DONE:
- dbg("Close Done Recieved \n");
- break;
- case V4L2_EVENT_MSM_VIDC_SYS_ERROR:
- dbg("SYS Error Recieved \n");
+ case V4L2_EVENT_SOURCE_CHANGE:
+ dbg("event source change");
break;
default:
- dbg("unknown event type occurred %x\n", event.type);
+ dbg("unknown event type occurred %x", event.type);
break;
}
@@ -137,106 +108,90 @@ void cleanup(struct instance *i)
video_close(i);
if (i->in.fd)
input_close(i);
+ if (i->out.fd)
+ close(i->out.fd);
}
-int extract_and_process_header(struct instance *i)
-{
- int used, fs;
- int ret;
- int n;
- struct video *vid = &i->video;
-#if 0
- ret = i->parser.func(&i->parser.ctx,
- i->in.p + i->in.offs,
- i->in.size - i->in.offs,
- i->video.out_buf_addr[0],
- i->video.out_buf_size,
- &used, &fs, 1);
-
- if (ret == 0) {
- err("Failed to extract header from stream");
- return -1;
- }
-
- /* For H263 the header is passed with the first frame, so we should
- * pass it again */
- if (i->parser.codec != V4L2_PIX_FMT_H263)
- i->in.offs += used;
- else
- /* To do this we shall reset the stream parser to the initial
- * configuration */
- parse_stream_init(&i->parser.ctx);
-
- dbg("Extracted header of size %d", fs);
-#endif
- ret = video_queue_buf_out(i, 0, fs);
- if (ret)
- return -1;
-
- dbg("queued output buffer %d", 0);
-
- i->video.out_buf_flag[0] = 1;
-#if 1
- for (n = 1; n < vid->out_buf_cnt; n++) {
- ret = video_queue_buf_out(i, n, 1);
- if (ret)
- return -1;
-
- i->video.out_buf_flag[n] = 1;
- }
-#endif
- ret = video_stream(i, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
- VIDIOC_STREAMON);
- if (ret)
- return -1;
-
- return 0;
-}
-
-int save_frame(struct instance *i, const void *buf, unsigned int size)
+int save_encoded(struct instance *i, const void *buf, unsigned int size)
{
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
char filename[64];
- int fd;
int ret;
- static unsigned int frame_num = 0;
+ struct output *out = &i->out;
+ ssize_t written;
- if (!i->save_frames)
+ if (!i->save_encoded)
return 0;
if (!i->save_path)
- ret = sprintf(filename, "/mnt/frame%04d.nv12", frame_num);
+ ret = sprintf(filename, "/mnt/sdcard/encoded.h264");
else
- ret = sprintf(filename, "%s/frame%04d.nv12", i->save_path,
- frame_num);
+ ret = sprintf(filename, "%s/encoded.h264", i->save_path);
if (ret < 0) {
err("sprintf fail (%s)", strerror(errno));
return -1;
}
+ if (out->fd)
+ goto write;
+
dbg("create file %s", filename);
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, mode);
- if (fd < 0) {
+ out->fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, mode);
+ if (out->fd < 0) {
err("cannot open file (%s)", strerror(errno));
return -1;
}
- ret = write(fd, buf, size);
- if (ret < 0) {
+write:
+ written = pwrite(out->fd, buf, size, out->offs);
+ if (written < 0) {
err("cannot write to file (%s)", strerror(errno));
return -1;
}
- close(fd);
+ out->offs += written;
- frame_num++;
+ dbg("written %zd bytes at offset: %zu", written, out->offs);
return 0;
}
-static int input_read(struct instance *i, unsigned int *used, unsigned int *fs)
+static int input_read(struct instance *inst, unsigned int index,
+ unsigned int *used, unsigned int *fs)
{
+ struct video *vid = &inst->video;
+ uint8_t *to = vid->out_buf_addr[index];
+ int ret;
+ char filename[64];
+ static int num = 1;
+
+ *used = vid->out_buf_size;
+ *fs = vid->out_buf_size;
+
+ ret = sprintf(filename, "/mnt/sdcard/frame%04d.nv12", num++);
+ if (ret < 0) {
+ err("sprintf fail (%s)", strerror(errno));
+ return -1;
+ }
+
+ dbg("open %s", filename);
+
+ ret = input_open(inst, filename);
+ if (ret)
+ return ret;
+
+ dbg("input nv12 size:%d, sizeimage:%d", inst->in.size, *fs);
+
+ memcpy(to, inst->in.p, inst->in.size);
+
+ input_close(inst);
+
+ usleep(33 * 1000);
+
+ if (num > 14)
+ num = 1;
+
return 0;
}
@@ -249,8 +204,6 @@ void *input_thread_func(void *args)
unsigned int used, fs, n;
int ret;
- dbg("input thread started");
-
while (!i->error && !i->finish) {
n = 0;
pthread_mutex_lock(&i->lock);
@@ -260,28 +213,27 @@ void *input_thread_func(void *args)
if (n < vid->out_buf_cnt) {
- ret = input_read(i, &used, &fs);
+ ret = input_read(i, n, &used, &fs);
+ if (ret)
+ continue;
- if (ret == 0 && i->in.offs == i->in.size) {
- info("read all frames");
+ if (vid->total_encoded >= i->num_frames_to_save) {
i->finish = 1;
fs = 0;
}
ret = video_queue_buf_out(i, n, fs);
+ if (ret)
+ continue;
pthread_mutex_lock(&i->lock);
vid->out_buf_flag[n] = 1;
pthread_mutex_unlock(&i->lock);
dbg("queued output buffer %d", n);
-
- i->in.offs += used;
}
}
- dbg("input thread finished");
-
return NULL;
}
@@ -293,8 +245,6 @@ void *main_thread_func(void *args)
short revents;
int ret, n, finished;
- dbg("main thread started");
-
pfd.fd = vid->fd;
pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM |
POLLRDBAND | POLLPRI;
@@ -327,21 +277,26 @@ void *main_thread_func(void *args)
if (ret < 0)
goto next_event;
+ pthread_mutex_lock(&i->lock);
vid->cap_buf_flag[n] = 0;
+ pthread_mutex_unlock(&i->lock);
- dbg("encoded frame %ld", vid->total_captured);
+ info("encoded frame %ld", vid->total_encoded);
if (finished)
break;
- vid->total_captured++;
+ vid->total_encoded++;
- save_frame(i, (void *)vid->cap_buf_addr[n][0],
- bytesused);
+ save_encoded(i, (void *)vid->cap_buf_addr[n][0],
+ bytesused);
ret = video_queue_buf_cap(i, n);
- if (!ret)
+ if (!ret) {
+ pthread_mutex_lock(&i->lock);
vid->cap_buf_flag[n] = 1;
+ pthread_mutex_unlock(&i->lock);
+ }
}
next_event:
@@ -367,8 +322,6 @@ next_event:
}
}
- dbg("main thread finished");
-
return NULL;
}
@@ -376,8 +329,7 @@ int main(int argc, char **argv)
{
struct instance inst;
struct video *vid = &inst.video;
- pthread_t input_thread;
- pthread_t main_thread;
+ pthread_t input_thread, main_thread;
int ret, n;
ret = parse_args(&inst, argc, argv);
@@ -390,11 +342,11 @@ int main(int argc, char **argv)
pthread_mutex_init(&inst.lock, 0);
- vid->total_captured = 0;
+ vid->total_encoded = 0;
- ret = input_open(&inst, inst.in.name);
- if (ret)
- goto err;
+// ret = input_open(&inst, inst.in.name);
+// if (ret)
+// goto err;
ret = video_open(&inst, inst.video.name);
if (ret)
@@ -405,13 +357,6 @@ int main(int argc, char **argv)
if (ret)
goto err;
#endif
- ret = video_setup_output(&inst, inst.codec, STREAM_BUUFER_SIZE, 1);
- if (ret)
- goto err;
-
-// ret = video_set_control(&inst);
-// if (ret)
-// goto err;
if (inst.use_dmabuf)
ret = video_setup_capture_dmabuf(&inst, 2, inst.width,
@@ -421,14 +366,13 @@ int main(int argc, char **argv)
if (ret)
goto err;
- ret = extract_and_process_header(&inst);
+ ret = video_setup_output(&inst, inst.codec, STREAM_BUUFER_SIZE, 1);
if (ret)
goto err;
-#if 0
- for (n = 0; n < vid->cap_buf_cnt; n++)
- video_export_buf(&inst, n);
-#endif
+ ret = video_set_control(&inst);
+ if (ret)
+ goto err;
/* queue all capture buffers */
for (n = 0; n < vid->cap_buf_cnt; n++) {
@@ -444,6 +388,22 @@ int main(int argc, char **argv)
if (ret)
goto err;
+ ret = video_stream(&inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ VIDIOC_STREAMON);
+ if (ret)
+ goto err;
+
+ if (0) {
+ struct v4l2_control cntrl;
+
+ cntrl.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER;
+ cntrl.value = 1;
+
+ ret = ioctl(inst.video.fd, VIDIOC_S_CTRL, &cntrl);
+ if (ret)
+ err("request seq header failed (%s)", strerror(errno));
+ }
+
dbg("Launching threads");
if (pthread_create(&input_thread, NULL, input_thread_func, &inst))
@@ -459,7 +419,7 @@ int main(int argc, char **argv)
video_stop(&inst);
- info("Total frames encoded %ld", vid->total_captured);
+ info("Total frames encoded %ld", vid->total_encoded);
cleanup(&inst);