summaryrefslogtreecommitdiff
path: root/gst/videoparsers/gstmpegvideoparse.c
diff options
context:
space:
mode:
authorMatej Knopp <matej.knopp@gmail.com>2011-11-10 19:42:40 -0300
committerThibault Saunier <thibault.saunier@collabora.com>2011-11-10 19:58:13 -0300
commita08b3bfa235b51ecf156f159001d4b2573196f2c (patch)
tree2988b59cfc9c4ccc374dcd3a84759c11ba91ba6c /gst/videoparsers/gstmpegvideoparse.c
parent609ae9b8125fd0a9b18401ebadc2bce5e0522ae1 (diff)
downloadgstreamer-plugins-bad-a08b3bfa235b51ecf156f159001d4b2573196f2c.tar.gz
mpegvideoparse: add support for progressive frames
https://bugzilla.gnome.org/show_bug.cgi?id=663782
Diffstat (limited to 'gst/videoparsers/gstmpegvideoparse.c')
-rw-r--r--gst/videoparsers/gstmpegvideoparse.c55
1 files changed, 49 insertions, 6 deletions
diff --git a/gst/videoparsers/gstmpegvideoparse.c b/gst/videoparsers/gstmpegvideoparse.c
index 5db0080a1..66a8929f7 100644
--- a/gst/videoparsers/gstmpegvideoparse.c
+++ b/gst/videoparsers/gstmpegvideoparse.c
@@ -183,6 +183,7 @@ gst_mpegv_parse_reset_frame (GstMpegvParse * mpvparse)
mpvparse->last_sc = -1;
mpvparse->seq_offset = G_MAXUINT;
mpvparse->pic_offset = -1;
+ mpvparse->frame_repeat_count = 0;
}
static void
@@ -238,8 +239,13 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf,
memcmp (GST_BUFFER_DATA (mpvparse->config), data, size) == 0)
return TRUE;
- if (!gst_mpeg_video_parse_sequence_header (&mpvparse->sequencehdr, data,
+ if (gst_mpeg_video_parse_sequence_header (&mpvparse->sequencehdr, data,
GST_BUFFER_SIZE (buf) - mpvparse->seq_offset, 0)) {
+ if (mpvparse->fps_num == 0 || mpvparse->fps_den == 0) {
+ mpvparse->fps_num = mpvparse->sequencehdr.fps_n;
+ mpvparse->fps_den = mpvparse->sequencehdr.fps_d;
+ }
+ } else {
GST_DEBUG_OBJECT (mpvparse,
"failed to parse config data (size %d) at offset %d",
size, mpvparse->seq_offset);
@@ -258,8 +264,17 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf,
if (tpoffsz->type == GST_MPEG_VIDEO_PACKET_EXTENSION) {
mpvparse->mpeg_version = 2;
- gst_mpeg_video_parse_sequence_extension (&mpvparse->sequenceext,
- GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf), tpoffsz->offset);
+
+ if (gst_mpeg_video_parse_sequence_extension (&mpvparse->sequenceext,
+ GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf),
+ tpoffsz->offset)) {
+ mpvparse->fps_num =
+ mpvparse->sequencehdr.fps_n * (mpvparse->sequenceext.fps_n_ext +
+ 1) * 2;
+ mpvparse->fps_den =
+ mpvparse->sequencehdr.fps_d * (mpvparse->sequenceext.fps_d_ext +
+ 1);
+ }
}
}
}
@@ -335,6 +350,27 @@ picture_type_name (guint8 pct)
}
#endif /* GST_DISABLE_GST_DEBUG */
+static void
+parse_picture_extension (GstMpegvParse * mpvparse, GstBuffer * buf, guint off)
+{
+ GstMpegVideoPictureExt ext;
+ if (gst_mpeg_video_parse_picture_extension (&ext, GST_BUFFER_DATA (buf),
+ GST_BUFFER_SIZE (buf), off)) {
+ mpvparse->frame_repeat_count = 1;
+
+ if (ext.repeat_first_field) {
+ if (mpvparse->sequenceext.progressive) {
+ if (ext.top_field_first)
+ mpvparse->frame_repeat_count = 5;
+ else
+ mpvparse->frame_repeat_count = 3;
+ } else if (ext.progressive_frame) {
+ mpvparse->frame_repeat_count = 2;
+ }
+ }
+ }
+}
+
/* caller guarantees at least start code in @buf at @off */
/* for off == 0 initial code; returns TRUE if code starts a frame,
* otherwise returns TRUE if code terminates preceding frame */
@@ -374,6 +410,10 @@ gst_mpegv_parse_process_sc (GstMpegvParse * mpvparse,
else
ret = TRUE;
break;
+ case GST_MPEG_VIDEO_PACKET_EXTENSION:
+ GST_LOG_OBJECT (mpvparse, "startcode is VIDEO PACKET EXTENSION");
+ parse_picture_extension (mpvparse, buf, off);
+ packet = FALSE;
default:
packet = FALSE;
break;
@@ -551,9 +591,9 @@ gst_mpegv_parse_update_src_caps (GstMpegvParse * mpvparse)
}
/* perhaps we have a framerate */
- if (mpvparse->sequencehdr.fps_n > 0 && mpvparse->sequencehdr.fps_d > 0) {
- gint fps_num = mpvparse->sequencehdr.fps_n;
- gint fps_den = mpvparse->sequencehdr.fps_d;
+ if (mpvparse->fps_num > 0 && mpvparse->fps_den > 0) {
+ gint fps_num = mpvparse->fps_num;
+ gint fps_den = mpvparse->fps_den;
GstClockTime latency = gst_util_uint64_scale (GST_SECOND, fps_den, fps_num);
gst_caps_set_simple (caps, "framerate",
@@ -658,6 +698,9 @@ gst_mpegv_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
GST_BUFFER_DURATION (buffer) = 0;
}
+ GST_BUFFER_DURATION (buffer) =
+ (1 + mpvparse->frame_repeat_count) * GST_BUFFER_DURATION (buffer);
+
if (G_UNLIKELY (mpvparse->drop && !mpvparse->config)) {
GST_DEBUG_OBJECT (mpvparse, "dropping frame as no config yet");
return GST_BASE_PARSE_FLOW_DROPPED;