diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/input/input_v4l2.c | 55 |
1 files changed, 39 insertions, 16 deletions
diff --git a/src/input/input_v4l2.c b/src/input/input_v4l2.c index 43b28b8d5..69d0a3b75 100644 --- a/src/input/input_v4l2.c +++ b/src/input/input_v4l2.c @@ -68,6 +68,8 @@ typedef struct { buffer_data *buffers; int bufcount; resolution_t resolution; + struct v4l2_buffer inbuf; + off_t index; int headerSent; } v4l2_video_t; @@ -90,7 +92,7 @@ typedef struct { } v4l2_input_plugin_t; static void v4l2_input_enqueue_video_buffer(v4l2_input_plugin_t *this, int idx); -static void v4l2_input_dequeue_video_buffer(v4l2_input_plugin_t *this, buf_element_t *input); +static int v4l2_input_dequeue_video_buffer(v4l2_input_plugin_t *this, buf_element_t *input); static int v4l2_input_setup_video_streaming(v4l2_input_plugin_t *this); @@ -208,10 +210,11 @@ static buf_element_t* v4l2_input_read_block(input_plugin_t *this_gen, fifo_buffe lprintf("Reading block\n"); v4l2_input_plugin_t *this = (v4l2_input_plugin_t*)this_gen; buf_element_t *buf = fifo->buffer_pool_alloc(fifo); - struct timeval tv; - xine_monotonic_clock(&tv, NULL); - buf->pts = (int64_t) tv.tv_sec * 90000 + (int64_t) tv.tv_usec * 9 / 100; if (!this->video->headerSent) { + struct timeval tv; + xine_monotonic_clock(&tv, NULL); + buf->pts = (int64_t) tv.tv_sec * 90000 + (int64_t) tv.tv_usec * 9 / 100; + lprintf("Sending video header\n"); xine_bmiheader bih; bih.biSize = sizeof(xine_bmiheader); @@ -223,12 +226,12 @@ static buf_element_t* v4l2_input_read_block(input_plugin_t *this_gen, fifo_buffe buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_START; memcpy(buf->content, &bih, sizeof(xine_bmiheader)); this->video->headerSent = 1; + this->video->index = 0; buf->type = BUF_VIDEO_YUY2; } else { - lprintf("Sending video frame\n"); + lprintf("Sending video frame (sent %d of %d)\n", this->video->index, this->video->buffers[this->video->inbuf.index].length); /* TODO: Add audio support */ - v4l2_input_dequeue_video_buffer(this, buf); - this->video->headerSent = 0; + this->video->headerSent = v4l2_input_dequeue_video_buffer(this, buf); } return buf; } @@ -246,17 +249,37 @@ static uint32_t v4l2_input_blocksize(input_plugin_t *this_gen) { } } -static void v4l2_input_dequeue_video_buffer(v4l2_input_plugin_t *this, buf_element_t *output) { - struct v4l2_buffer buf; - memset(&buf, 0, sizeof(buf)); - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.memory = V4L2_MEMORY_MMAP; +static int v4l2_input_dequeue_video_buffer(v4l2_input_plugin_t *this, buf_element_t *output) +{ + if (!this->video->index) + { + memset (&this->video->inbuf, 0, sizeof (this->video->inbuf)); + this->video->inbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + this->video->inbuf.memory = V4L2_MEMORY_MMAP; + v4l2_ioctl(this->fd, VIDIOC_DQBUF, &this->video->inbuf); + output->decoder_flags = BUF_FLAG_FRAME_START; + } + else + output->decoder_flags = 0; + output->content = output->mem; - v4l2_ioctl(this->fd, VIDIOC_DQBUF, &buf); - output->decoder_flags = BUF_FLAG_FRAME_START|BUF_FLAG_FRAME_END; - xine_fast_memcpy(output->content, this->video->buffers[buf.index].start, this->video->buffers[buf.index].length); output->type = BUF_VIDEO_YUY2; - v4l2_input_enqueue_video_buffer(this, buf.index); + + output->size = this->video->buffers[this->video->inbuf.index].length - this->video->index; + if (output->size > output->max_size) + output->size = output->max_size; + + xine_fast_memcpy (output->content, this->video->buffers[this->video->inbuf.index].start + this->video->index, output->size); + + this->video->index += output->size; + if (this->video->index == this->video->buffers[this->video->inbuf.index].length) + { + output->decoder_flags |= BUF_FLAG_FRAME_END; + v4l2_input_enqueue_video_buffer(this, this->video->inbuf.index); + return 0; + } + + return 1; } static void v4l2_input_enqueue_video_buffer(v4l2_input_plugin_t *this, int idx) { |