summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2009-06-08 14:35:29 +0200
committerJan Schmidt <thaytan@noraisin.net>2009-06-20 15:21:46 +0100
commit53a5272f73beaf87d33f99dc4a0d0dd0770934cc (patch)
tree3ff7a78e02e1c1e4e0861b12e81ba16c6f5acde8 /sys
parentaff91bb89acaa2528ad2ed8f696cc93eb254325a (diff)
downloadgst-plugins-bad-53a5272f73beaf87d33f99dc4a0d0dd0770934cc.tar.gz
gst-plugins-bad-53a5272f73beaf87d33f99dc4a0d0dd0770934cc.tar.bz2
gst-plugins-bad-53a5272f73beaf87d33f99dc4a0d0dd0770934cc.zip
vdpaumpegdec: drop all frames before a GOP when we seek
Diffstat (limited to 'sys')
-rw-r--r--sys/vdpau/gstvdpmpegdec.c18
-rw-r--r--sys/vdpau/gstvdpmpegdec.h9
2 files changed, 26 insertions, 1 deletions
diff --git a/sys/vdpau/gstvdpmpegdec.c b/sys/vdpau/gstvdpmpegdec.c
index fbd53ae9..a4c2f687 100644
--- a/sys/vdpau/gstvdpmpegdec.c
+++ b/sys/vdpau/gstvdpmpegdec.c
@@ -499,6 +499,9 @@ gst_vdp_mpeg_dec_parse_sequence (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer)
memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix,
&hdr.non_intra_quantizer_matrix, 64);
+ if (mpeg_dec->state == GST_VDP_MPEG_DEC_NEED_SEQUENCE)
+ mpeg_dec->state = GST_VDP_MPEG_DEC_NEED_DATA;
+
return TRUE;
}
@@ -555,6 +558,9 @@ gst_vdp_mpeg_dec_parse_gop (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer)
gst_util_uint64_scale (time, mpeg_dec->fps_n,
mpeg_dec->fps_d * GST_SECOND) + gop.frame;
+ if (mpeg_dec->state == GST_VDP_MPEG_DEC_NEED_GOP)
+ mpeg_dec->state = GST_VDP_MPEG_DEC_NEED_DATA;
+
return TRUE;
}
@@ -601,6 +607,8 @@ gst_vdp_mpeg_dec_reset (GstVdpMpegDec * mpeg_dec)
g_object_unref (mpeg_dec->device);
mpeg_dec->device = NULL;
+ mpeg_dec->state = GST_VDP_MPEG_DEC_NEED_SEQUENCE;
+
gst_segment_init (&mpeg_dec->segment, GST_FORMAT_TIME);
mpeg_dec->seeking = FALSE;
@@ -688,6 +696,12 @@ gst_vdp_mpeg_dec_chain (GstPad * pad, GstBuffer * buffer)
gst_buffer_unref (buf);
}
+ if (mpeg_dec->state == GST_VDP_MPEG_DEC_NEED_SEQUENCE ||
+ mpeg_dec->state == GST_VDP_MPEG_DEC_NEED_GOP) {
+ gst_adapter_clear (mpeg_dec->adapter);
+ goto done;
+ }
+
if (mpeg_dec->vdp_info.slice_count > 0)
ret = gst_vdp_mpeg_dec_decode (mpeg_dec, GST_BUFFER_TIMESTAMP (buffer),
GST_BUFFER_SIZE (buffer));
@@ -843,8 +857,10 @@ normal_seek (GstVdpMpegDec * mpeg_dec, GstEvent * event)
/* do the seek */
res = gst_pad_push_event (mpeg_dec->sink, peer_event);
- if (res)
+ if (res) {
+ mpeg_dec->state = GST_VDP_MPEG_DEC_NEED_GOP;
mpeg_dec->seeking = TRUE;
+ }
g_mutex_unlock (mpeg_dec->mutex);
diff --git a/sys/vdpau/gstvdpmpegdec.h b/sys/vdpau/gstvdpmpegdec.h
index 9d4c791f..fc36df5b 100644
--- a/sys/vdpau/gstvdpmpegdec.h
+++ b/sys/vdpau/gstvdpmpegdec.h
@@ -35,6 +35,12 @@ G_BEGIN_DECLS
#define GST_IS_VDP_MPEG_DEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_MPEG_DEC))
#define GST_IS_VDP_MPEG_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_MPEG_DEC))
+typedef enum {
+ GST_VDP_MPEG_DEC_NEED_SEQUENCE,
+ GST_VDP_MPEG_DEC_NEED_GOP,
+ GST_VDP_MPEG_DEC_NEED_DATA
+} GstVdpMpegDecState;
+
typedef struct _GstVdpMpegDec GstVdpMpegDec;
typedef struct _GstVdpMpegDecClass GstVdpMpegDecClass;
@@ -56,6 +62,9 @@ struct _GstVdpMpegDec
gboolean interlaced;
gint version;
+ /* decoder state */
+ GstVdpMpegDecState state;
+
/* currently decoded frame info */
GstAdapter *adapter;
VdpPictureInfoMPEG1Or2 vdp_info;