diff options
author | Michael Grzeschik <m.grzeschik@pengutronix.de> | 2011-06-16 13:10:45 +0200 |
---|---|---|
committer | Michael Grzeschik <m.grzeschik@pengutronix.de> | 2011-06-21 11:04:29 +0200 |
commit | d20bbdc07adf7901775afb58ff040d7cbc4d3ce4 (patch) | |
tree | 9e007ff9c4ed61cbb6cecd9d88dbe9416eef3366 | |
parent | f7ab9003c55a42980b9c83225900f3bfb69cd213 (diff) | |
download | gst-plugins-fsl-vpu-d20bbdc07adf7901775afb58ff040d7cbc4d3ce4.tar.gz gst-plugins-fsl-vpu-d20bbdc07adf7901775afb58ff040d7cbc4d3ce4.tar.xz |
mfw_vpu_encoder: fix buffer queue handling
this patch fixes several issues:
- The init function was not queueing any buffers after the query.
- The chain function handling the buffers in the wrong order.
- While handling the bufferqueue the chain function was only doing the
memcpy for the pushbuffer from one buffer, which actually was not
dequeued. it did always dq only buffer[0], while the decoder seems to
make it right by dqueueing into one local buffer.
DQBUF
memcpy
QBUF
-rw-r--r-- | src/mfw_gst_vpu_encoder.c | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/src/mfw_gst_vpu_encoder.c b/src/mfw_gst_vpu_encoder.c index d10e88d..ffea2c1 100644 --- a/src/mfw_gst_vpu_encoder.c +++ b/src/mfw_gst_vpu_encoder.c @@ -82,7 +82,6 @@ typedef struct _GstVPU_Enc struct v4l2_buffer buf_v4l2[NUM_BUFFERS]; unsigned char *buf_data[NUM_BUFFERS]; unsigned int buf_size[NUM_BUFFERS]; - unsigned int queued; char *device; }GstVPU_Enc; @@ -295,6 +294,14 @@ printf("%s\n", __func__); vpu_enc->vpu_fd, vpu_enc->buf_v4l2[i].m.offset); } + for (i = 0; i < NUM_BUFFERS; ++i) { + retval = ioctl(vpu_enc->vpu_fd, VIDIOC_QBUF, &vpu_enc->buf_v4l2[i]); + if (retval) { + GST_ERROR("VIDIOC_QBUF failed: %s\n", strerror(errno)); + return -errno; + } + } + if (vpu_enc->codec == STD_MPEG4) mime = "video/mpeg"; else if (vpu_enc->codec == STD_AVC) @@ -329,9 +336,12 @@ static GstFlowReturn mfw_gst_vpuenc_chain(GstPad * pad, GstBuffer * buffer) GstFlowReturn retval = GST_FLOW_OK; GstCaps *src_caps; GstBuffer *outbuffer; - gint i = 0; int ret; struct pollfd pollfd; + struct v4l2_buffer v4l2_buf = { + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT, + }; + GST_DEBUG("mfw_gst_vpuenc_chain"); @@ -345,35 +355,26 @@ static GstFlowReturn mfw_gst_vpuenc_chain(GstPad * pad, GstBuffer * buffer) printf("VPU ENC initialised\n"); } - for (i = 0; i < NUM_BUFFERS; i++) { - if (!(vpu_enc->queued & (1 << i))) - break; - } - - if (i == NUM_BUFFERS) { - printf("NO BUFFER AVAILABLE\n"); - return GST_FLOW_ERROR; - } if (!buffer) return GST_FLOW_OK; - /* copy the input Frame into the allocated buffer */ - memcpy(vpu_enc->buf_data[i], GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); - gst_buffer_unref(buffer); - pollfd.fd = vpu_enc->vpu_fd; pollfd.events = POLLIN | POLLOUT; - ret = ioctl(vpu_enc->vpu_fd, VIDIOC_QBUF, &vpu_enc->buf_v4l2[0]); + ret = ioctl(vpu_enc->vpu_fd, VIDIOC_DQBUF, &v4l2_buf); if (ret) { - GST_ERROR("VIDIOC_QBUF failed: %s\n", strerror(errno)); + GST_ERROR("VIDIOC_DQBUF failed: %s\n", strerror(errno)); return GST_FLOW_ERROR; } - ret = ioctl(vpu_enc->vpu_fd, VIDIOC_DQBUF, &vpu_enc->buf_v4l2[0]); + /* copy the input Frame into the allocated buffer */ + memcpy(vpu_enc->buf_data[v4l2_buf.index], GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); + gst_buffer_unref(buffer); + + ret = ioctl(vpu_enc->vpu_fd, VIDIOC_QBUF, &v4l2_buf); if (ret) { - GST_ERROR("VIDIOC_DQBUF failed: %s\n", strerror(errno)); + GST_ERROR("VIDIOC_QBUF failed: %s\n", strerror(errno)); return GST_FLOW_ERROR; } |