diff options
author | Harinarayan Bhatta | 2014-07-04 05:18:35 -0500 |
---|---|---|
committer | Harinarayan Bhatta | 2014-07-04 05:18:35 -0500 |
commit | 3dcadffbb4848afe79f88c143536469fccc2f96d (patch) | |
tree | f3b4f339d7bedbe2f56617cc5c70ba3c6c2b62cf | |
parent | c50cc9132010bde7f4cb9efc04ca3eba536d26f9 (diff) | |
download | gst-plugin-ducati-3dcadffbb4848afe79f88c143536469fccc2f96d.tar.gz gst-plugin-ducati-3dcadffbb4848afe79f88c143536469fccc2f96d.tar.xz gst-plugin-ducati-3dcadffbb4848afe79f88c143536469fccc2f96d.zip |
Changes for reverse playback
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>
-rw-r--r-- | src/gstducatividdec.c | 94 | ||||
-rw-r--r-- | src/gstducatividdec.h | 5 |
2 files changed, 80 insertions, 19 deletions
diff --git a/src/gstducatividdec.c b/src/gstducatividdec.c index 56ba4c3..bd485d8 100644 --- a/src/gstducatividdec.c +++ b/src/gstducatividdec.c | |||
@@ -347,6 +347,22 @@ codec_unlock_outbuf (GstDucatiVidDec * self, XDAS_Int32 id) | |||
347 | } | 347 | } |
348 | } | 348 | } |
349 | 349 | ||
350 | /* Called when playing in reverse */ | ||
351 | static GstFlowReturn | ||
352 | gst_ducati_viddec_push_latest (GstDucatiVidDec * self) | ||
353 | { | ||
354 | GstBuffer *buf; | ||
355 | |||
356 | if (self->backlog_nframes == 0) | ||
357 | return GST_FLOW_OK; | ||
358 | |||
359 | /* send it, giving away the ref */ | ||
360 | buf = self->backlog_frames[--self->backlog_nframes]; | ||
361 | GST_DEBUG_OBJECT (self, "Actually pushing backlog buffer %" GST_PTR_FORMAT, | ||
362 | buf); | ||
363 | return gst_pad_push (self->srcpad, buf); | ||
364 | } | ||
365 | |||
350 | static GstFlowReturn | 366 | static GstFlowReturn |
351 | gst_ducati_viddec_push_earliest (GstDucatiVidDec * self) | 367 | gst_ducati_viddec_push_earliest (GstDucatiVidDec * self) |
352 | { | 368 | { |
@@ -378,9 +394,18 @@ gst_ducati_viddec_push_earliest (GstDucatiVidDec * self) | |||
378 | static void | 394 | static void |
379 | gst_ducati_viddec_on_flush (GstDucatiVidDec * self, gboolean eos) | 395 | gst_ducati_viddec_on_flush (GstDucatiVidDec * self, gboolean eos) |
380 | { | 396 | { |
381 | /* push everything on the backlog, ignoring errors */ | 397 | if (self->segment.format == GST_FORMAT_TIME && |
382 | while (self->backlog_nframes > 0) { | 398 | self->segment.rate < (gdouble) 0.0) { |
383 | gst_ducati_viddec_push_earliest (self); | 399 | /* negative rate */ |
400 | /* push everything on the backlog, ignoring errors */ | ||
401 | while (self->backlog_nframes > 0) { | ||
402 | gst_ducati_viddec_push_latest (self); | ||
403 | } | ||
404 | } else { | ||
405 | /* push everything on the backlog, ignoring errors */ | ||
406 | while (self->backlog_nframes > 0) { | ||
407 | gst_ducati_viddec_push_earliest (self); | ||
408 | } | ||
384 | } | 409 | } |
385 | } | 410 | } |
386 | 411 | ||
@@ -406,10 +431,11 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush, | |||
406 | /* Get dmabuf fd of the buffer to lock it*/ | 431 | /* Get dmabuf fd of the buffer to lock it*/ |
407 | fd = gst_dma_buf_get_fd(gst_buffer_get_dma_buf((GstBuffer *) self->inArgs->inputID)); | 432 | fd = gst_dma_buf_get_fd(gst_buffer_get_dma_buf((GstBuffer *) self->inArgs->inputID)); |
408 | /* Must lock all the buffer passed to ducati */ | 433 | /* Must lock all the buffer passed to ducati */ |
434 | GST_DEBUG_OBJECT (self, "dce_buf_lock(inputID: %08x", self->inArgs->inputID); | ||
409 | dce_buf_lock(1,&fd); | 435 | dce_buf_lock(1,&fd); |
410 | } | 436 | } |
411 | 437 | ||
412 | GST_DEBUG ("Calling VIDDEC3_process"); | 438 | GST_DEBUG_OBJECT (self, "Calling VIDDEC3_process, inputID: %08x", self->inArgs->inputID); |
413 | t = gst_util_get_timestamp (); | 439 | t = gst_util_get_timestamp (); |
414 | err = VIDDEC3_process (self->codec, | 440 | err = VIDDEC3_process (self->codec, |
415 | self->inBufs, self->outBufs, self->inArgs, self->outArgs); | 441 | self->inBufs, self->outBufs, self->inArgs, self->outArgs); |
@@ -449,6 +475,8 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush, | |||
449 | for (i = 0; i < IVIDEO2_MAX_IO_BUFFERS && self->outArgs->outputID[i]; i++) { | 475 | for (i = 0; i < IVIDEO2_MAX_IO_BUFFERS && self->outArgs->outputID[i]; i++) { |
450 | gboolean interlaced; | 476 | gboolean interlaced; |
451 | 477 | ||
478 | GST_DEBUG_OBJECT (self, "VIDDEC3_process outputID[%d]: %08x", | ||
479 | i, self->outArgs->outputID[i]); | ||
452 | interlaced = | 480 | interlaced = |
453 | self->outArgs->displayBufs.bufDesc[0].contentType == | 481 | self->outArgs->displayBufs.bufDesc[0].contentType == |
454 | IVIDEO_PROGRESSIVE ? FALSE : TRUE; | 482 | IVIDEO_PROGRESSIVE ? FALSE : TRUE; |
@@ -605,6 +633,8 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush, | |||
605 | 633 | ||
606 | skip_outbuf_processing: | 634 | skip_outbuf_processing: |
607 | for (i = 0; i < IVIDEO2_MAX_IO_BUFFERS && self->outArgs->freeBufID[i]; i++) { | 635 | for (i = 0; i < IVIDEO2_MAX_IO_BUFFERS && self->outArgs->freeBufID[i]; i++) { |
636 | GST_DEBUG_OBJECT (self, "VIDDEC3_process freeBufID[%d]: %08x", | ||
637 | i, self->outArgs->freeBufID[i]); | ||
608 | codec_unlock_outbuf (self, self->outArgs->freeBufID[i]); | 638 | codec_unlock_outbuf (self, self->outArgs->freeBufID[i]); |
609 | } | 639 | } |
610 | 640 | ||
@@ -822,23 +852,51 @@ gst_ducati_viddec_push_output (GstDucatiVidDec * self, GstBuffer * buf) | |||
822 | { | 852 | { |
823 | GstFlowReturn ret = GST_FLOW_OK; | 853 | GstFlowReturn ret = GST_FLOW_OK; |
824 | 854 | ||
825 | /* if no reordering info was set, just send the buffer */ | 855 | if (self->segment.format == GST_FORMAT_TIME && |
826 | if (GST_BUFFER_OFFSET_END (buf) == GST_BUFFER_OFFSET_NONE) { | 856 | self->segment.rate < (gdouble) 0.0) { |
827 | GST_DEBUG_OBJECT (self, "No reordering info on that buffer, sending now"); | 857 | /* negative rate: reverse playback */ |
828 | return gst_pad_push (self->srcpad, buf); | 858 | |
829 | } | 859 | if (self->backlog_nframes > 0 && |
860 | (GST_BUFFER_TIMESTAMP (self->backlog_frames[0]) > | ||
861 | GST_BUFFER_TIMESTAMP (buf))) { | ||
862 | /* push out all backlog frames, since we have a buffer that is | ||
863 | earlier than any other in the list */ | ||
864 | while (self->backlog_nframes > 0) { | ||
865 | ret = gst_ducati_viddec_push_latest (self); | ||
866 | if (ret != GST_FLOW_OK) | ||
867 | break; | ||
868 | } | ||
869 | } | ||
870 | /* add the frame to the list, the array will own the ref */ | ||
871 | GST_DEBUG_OBJECT (self, "Adding buffer %" GST_PTR_FORMAT " to backlog", | ||
872 | buf); | ||
873 | if (self->backlog_nframes < MAX_BACKLOG_ARRAY_SIZE) { | ||
874 | self->backlog_frames[self->backlog_nframes++] = buf; | ||
875 | } else { | ||
876 | /* No space in the re-order buffer, drop the frame */ | ||
877 | GST_WARNING_OBJECT (self, "Dropping buffer %" GST_PTR_FORMAT, buf); | ||
878 | gst_buffer_unref (buf); | ||
879 | } | ||
830 | 880 | ||
831 | /* add the frame to the list, the array will own the ref */ | 881 | } else { |
832 | GST_DEBUG_OBJECT (self, "Adding buffer %" GST_PTR_FORMAT " to backlog", buf); | 882 | /* if no reordering info was set, just send the buffer */ |
833 | self->backlog_frames[self->backlog_nframes++] = buf; | 883 | if (GST_BUFFER_OFFSET_END (buf) == GST_BUFFER_OFFSET_NONE) { |
884 | GST_DEBUG_OBJECT (self, "No reordering info on that buffer, sending now"); | ||
885 | return gst_pad_push (self->srcpad, buf); | ||
886 | } | ||
834 | 887 | ||
835 | /* push till we have no more than the max needed, or error */ | 888 | /* add the frame to the list, the array will own the ref */ |
836 | while (self->backlog_nframes > self->backlog_maxframes) { | 889 | GST_DEBUG_OBJECT (self, "Adding buffer %" GST_PTR_FORMAT " to backlog", |
837 | ret = gst_ducati_viddec_push_earliest (self); | 890 | buf); |
838 | if (ret != GST_FLOW_OK) | 891 | self->backlog_frames[self->backlog_nframes++] = buf; |
839 | break; | ||
840 | } | ||
841 | 892 | ||
893 | /* push till we have no more than the max needed, or error */ | ||
894 | while (self->backlog_nframes > self->backlog_maxframes) { | ||
895 | ret = gst_ducati_viddec_push_earliest (self); | ||
896 | if (ret != GST_FLOW_OK) | ||
897 | break; | ||
898 | } | ||
899 | } | ||
842 | return ret; | 900 | return ret; |
843 | } | 901 | } |
844 | 902 | ||
diff --git a/src/gstducatividdec.h b/src/gstducatividdec.h index 192d17a..6c7b9a5 100644 --- a/src/gstducatividdec.h +++ b/src/gstducatividdec.h | |||
@@ -44,7 +44,10 @@ G_BEGIN_DECLS | |||
44 | typedef struct _GstDucatiVidDec GstDucatiVidDec; | 44 | typedef struct _GstDucatiVidDec GstDucatiVidDec; |
45 | typedef struct _GstDucatiVidDecClass GstDucatiVidDecClass; | 45 | typedef struct _GstDucatiVidDecClass GstDucatiVidDecClass; |
46 | 46 | ||
47 | /* For re-ordering in normal playback */ | ||
47 | #define MAX_BACKLOG_FRAMES 16 | 48 | #define MAX_BACKLOG_FRAMES 16 |
49 | /* For re-ordering in reverse playback */ | ||
50 | #define MAX_BACKLOG_ARRAY_SIZE 120 | ||
48 | 51 | ||
49 | struct _GstDucatiVidDec | 52 | struct _GstDucatiVidDec |
50 | { | 53 | { |
@@ -139,7 +142,7 @@ struct _GstDucatiVidDec | |||
139 | struct omap_device *device; | 142 | struct omap_device *device; |
140 | 143 | ||
141 | /* Frames waiting to be reordered */ | 144 | /* Frames waiting to be reordered */ |
142 | GstBuffer *backlog_frames[MAX_BACKLOG_FRAMES + 1]; | 145 | GstBuffer *backlog_frames[MAX_BACKLOG_ARRAY_SIZE + 1]; |
143 | gint backlog_maxframes; | 146 | gint backlog_maxframes; |
144 | gint backlog_nframes; | 147 | gint backlog_nframes; |
145 | gint backlog_max_maxframes; | 148 | gint backlog_max_maxframes; |