summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c50cc91)
raw | patch | inline | side by side (parent: c50cc91)
author | Harinarayan Bhatta <harinarayan@ti.com> | |
Fri, 4 Jul 2014 10:18:35 +0000 (15:48 +0530) | ||
committer | Harinarayan Bhatta <harinarayan@ti.com> | |
Fri, 4 Jul 2014 10:18:35 +0000 (15:48 +0530) |
Adapt the re-order buffer to send out frames in reverse order
when playing with negative rate.
Signed-off-by: Harinarayan Bhatta <harinarayan@ti.com>
when playing with negative rate.
Signed-off-by: Harinarayan Bhatta <harinarayan@ti.com>
src/gstducatividdec.c | patch | blob | history | |
src/gstducatividdec.h | patch | blob | history |
diff --git a/src/gstducatividdec.c b/src/gstducatividdec.c
index 56ba4c3eac9c2cce83b6c37e67f81005763ad4a5..bd485d899288681713390df1cbf3051f2d1985ef 100644 (file)
--- a/src/gstducatividdec.c
+++ b/src/gstducatividdec.c
}
}
+/* Called when playing in reverse */
+static GstFlowReturn
+gst_ducati_viddec_push_latest (GstDucatiVidDec * self)
+{
+ GstBuffer *buf;
+
+ if (self->backlog_nframes == 0)
+ return GST_FLOW_OK;
+
+ /* send it, giving away the ref */
+ buf = self->backlog_frames[--self->backlog_nframes];
+ GST_DEBUG_OBJECT (self, "Actually pushing backlog buffer %" GST_PTR_FORMAT,
+ buf);
+ return gst_pad_push (self->srcpad, buf);
+}
+
static GstFlowReturn
gst_ducati_viddec_push_earliest (GstDucatiVidDec * self)
{
static void
gst_ducati_viddec_on_flush (GstDucatiVidDec * self, gboolean eos)
{
- /* push everything on the backlog, ignoring errors */
- while (self->backlog_nframes > 0) {
- gst_ducati_viddec_push_earliest (self);
+ if (self->segment.format == GST_FORMAT_TIME &&
+ self->segment.rate < (gdouble) 0.0) {
+ /* negative rate */
+ /* push everything on the backlog, ignoring errors */
+ while (self->backlog_nframes > 0) {
+ gst_ducati_viddec_push_latest (self);
+ }
+ } else {
+ /* push everything on the backlog, ignoring errors */
+ while (self->backlog_nframes > 0) {
+ gst_ducati_viddec_push_earliest (self);
+ }
}
}
/* Get dmabuf fd of the buffer to lock it*/
fd = gst_dma_buf_get_fd(gst_buffer_get_dma_buf((GstBuffer *) self->inArgs->inputID));
/* Must lock all the buffer passed to ducati */
+ GST_DEBUG_OBJECT (self, "dce_buf_lock(inputID: %08x", self->inArgs->inputID);
dce_buf_lock(1,&fd);
}
- GST_DEBUG ("Calling VIDDEC3_process");
+ GST_DEBUG_OBJECT (self, "Calling VIDDEC3_process, inputID: %08x", self->inArgs->inputID);
t = gst_util_get_timestamp ();
err = VIDDEC3_process (self->codec,
self->inBufs, self->outBufs, self->inArgs, self->outArgs);
for (i = 0; i < IVIDEO2_MAX_IO_BUFFERS && self->outArgs->outputID[i]; i++) {
gboolean interlaced;
+ GST_DEBUG_OBJECT (self, "VIDDEC3_process outputID[%d]: %08x",
+ i, self->outArgs->outputID[i]);
interlaced =
self->outArgs->displayBufs.bufDesc[0].contentType ==
IVIDEO_PROGRESSIVE ? FALSE : TRUE;
skip_outbuf_processing:
for (i = 0; i < IVIDEO2_MAX_IO_BUFFERS && self->outArgs->freeBufID[i]; i++) {
+ GST_DEBUG_OBJECT (self, "VIDDEC3_process freeBufID[%d]: %08x",
+ i, self->outArgs->freeBufID[i]);
codec_unlock_outbuf (self, self->outArgs->freeBufID[i]);
}
{
GstFlowReturn ret = GST_FLOW_OK;
- /* if no reordering info was set, just send the buffer */
- if (GST_BUFFER_OFFSET_END (buf) == GST_BUFFER_OFFSET_NONE) {
- GST_DEBUG_OBJECT (self, "No reordering info on that buffer, sending now");
- return gst_pad_push (self->srcpad, buf);
- }
+ if (self->segment.format == GST_FORMAT_TIME &&
+ self->segment.rate < (gdouble) 0.0) {
+ /* negative rate: reverse playback */
+
+ if (self->backlog_nframes > 0 &&
+ (GST_BUFFER_TIMESTAMP (self->backlog_frames[0]) >
+ GST_BUFFER_TIMESTAMP (buf))) {
+ /* push out all backlog frames, since we have a buffer that is
+ earlier than any other in the list */
+ while (self->backlog_nframes > 0) {
+ ret = gst_ducati_viddec_push_latest (self);
+ if (ret != GST_FLOW_OK)
+ break;
+ }
+ }
+ /* add the frame to the list, the array will own the ref */
+ GST_DEBUG_OBJECT (self, "Adding buffer %" GST_PTR_FORMAT " to backlog",
+ buf);
+ if (self->backlog_nframes < MAX_BACKLOG_ARRAY_SIZE) {
+ self->backlog_frames[self->backlog_nframes++] = buf;
+ } else {
+ /* No space in the re-order buffer, drop the frame */
+ GST_WARNING_OBJECT (self, "Dropping buffer %" GST_PTR_FORMAT, buf);
+ gst_buffer_unref (buf);
+ }
- /* add the frame to the list, the array will own the ref */
- GST_DEBUG_OBJECT (self, "Adding buffer %" GST_PTR_FORMAT " to backlog", buf);
- self->backlog_frames[self->backlog_nframes++] = buf;
+ } else {
+ /* if no reordering info was set, just send the buffer */
+ if (GST_BUFFER_OFFSET_END (buf) == GST_BUFFER_OFFSET_NONE) {
+ GST_DEBUG_OBJECT (self, "No reordering info on that buffer, sending now");
+ return gst_pad_push (self->srcpad, buf);
+ }
- /* push till we have no more than the max needed, or error */
- while (self->backlog_nframes > self->backlog_maxframes) {
- ret = gst_ducati_viddec_push_earliest (self);
- if (ret != GST_FLOW_OK)
- break;
- }
+ /* add the frame to the list, the array will own the ref */
+ GST_DEBUG_OBJECT (self, "Adding buffer %" GST_PTR_FORMAT " to backlog",
+ buf);
+ self->backlog_frames[self->backlog_nframes++] = buf;
+ /* push till we have no more than the max needed, or error */
+ while (self->backlog_nframes > self->backlog_maxframes) {
+ ret = gst_ducati_viddec_push_earliest (self);
+ if (ret != GST_FLOW_OK)
+ break;
+ }
+ }
return ret;
}
diff --git a/src/gstducatividdec.h b/src/gstducatividdec.h
index 192d17a26c1f64c4405a9797181e13a94bfb11d4..6c7b9a54d798099efe4b384bd195a46e74be6ab9 100644 (file)
--- a/src/gstducatividdec.h
+++ b/src/gstducatividdec.h
typedef struct _GstDucatiVidDec GstDucatiVidDec;
typedef struct _GstDucatiVidDecClass GstDucatiVidDecClass;
+/* For re-ordering in normal playback */
#define MAX_BACKLOG_FRAMES 16
+/* For re-ordering in reverse playback */
+#define MAX_BACKLOG_ARRAY_SIZE 120
struct _GstDucatiVidDec
{
struct omap_device *device;
/* Frames waiting to be reordered */
- GstBuffer *backlog_frames[MAX_BACKLOG_FRAMES + 1];
+ GstBuffer *backlog_frames[MAX_BACKLOG_ARRAY_SIZE + 1];
gint backlog_maxframes;
gint backlog_nframes;
gint backlog_max_maxframes;