summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Grzeschik <m.grzeschik@pengutronix.de>2011-06-16 13:10:45 +0200
committerMichael Grzeschik <m.grzeschik@pengutronix.de>2011-06-21 11:04:29 +0200
commitd20bbdc07adf7901775afb58ff040d7cbc4d3ce4 (patch)
tree9e007ff9c4ed61cbb6cecd9d88dbe9416eef3366
parentf7ab9003c55a42980b9c83225900f3bfb69cd213 (diff)
downloadgst-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.c39
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;
}