mpeg4videoparse: use previously parsed visual object when parsing VOL

https://bugzilla.gnome.org/show_bug.cgi?id=683254
This commit is contained in:
Arnaud Vrac 2012-09-02 20:17:14 +02:00 committed by Edward Hervey
parent 0331fb6203
commit 744bd3d3f2
2 changed files with 25 additions and 8 deletions

View file

@ -192,6 +192,7 @@ gst_mpeg4vparse_reset_frame (GstMpeg4VParse * mp4vparse)
mp4vparse->vop_offset = -1; mp4vparse->vop_offset = -1;
mp4vparse->vo_found = FALSE; mp4vparse->vo_found = FALSE;
mp4vparse->vol_offset = -1; mp4vparse->vol_offset = -1;
mp4vparse->vo_offset = -1;
} }
static void static void
@ -238,6 +239,8 @@ static gboolean
gst_mpeg4vparse_process_config (GstMpeg4VParse * mp4vparse, gst_mpeg4vparse_process_config (GstMpeg4VParse * mp4vparse,
const guint8 * data, guint offset, gsize size) const guint8 * data, guint offset, gsize size)
{ {
GstMpeg4VisualObject *vo;
/* only do stuff if something new */ /* only do stuff if something new */
if (mp4vparse->config if (mp4vparse->config
&& !gst_buffer_memcmp (mp4vparse->config, offset, data, size)) && !gst_buffer_memcmp (mp4vparse->config, offset, data, size))
@ -249,10 +252,12 @@ gst_mpeg4vparse_process_config (GstMpeg4VParse * mp4vparse,
return FALSE; return FALSE;
} }
vo = mp4vparse->vo_found ? &mp4vparse->vo : NULL;
/* If the parsing fail, we accept the config only if we don't have /* If the parsing fail, we accept the config only if we don't have
* any config yet. */ * any config yet. */
if (gst_mpeg4_parse_video_object_layer (&mp4vparse->vol, if (gst_mpeg4_parse_video_object_layer (&mp4vparse->vol,
NULL, data + mp4vparse->vol_offset, vo, data + mp4vparse->vol_offset,
size - mp4vparse->vol_offset) != GST_MPEG4_PARSER_OK && size - mp4vparse->vol_offset) != GST_MPEG4_PARSER_OK &&
mp4vparse->config) mp4vparse->config)
return FALSE; return FALSE;
@ -344,6 +349,14 @@ gst_mpeg4vparse_process_sc (GstMpeg4VParse * mp4vparse, GstMpeg4Packet * packet,
return TRUE; return TRUE;
} }
if (mp4vparse->vo_offset >= 0) {
gst_mpeg4_parse_visual_object (&mp4vparse->vo, NULL,
packet->data + mp4vparse->vo_offset,
packet->offset - 3 - mp4vparse->vo_offset);
mp4vparse->vo_offset = -1;
mp4vparse->vo_found = TRUE;
}
switch (packet->type) { switch (packet->type) {
case GST_MPEG4_VIDEO_OBJ_PLANE: case GST_MPEG4_VIDEO_OBJ_PLANE:
case GST_MPEG4_GROUP_OF_VOP: case GST_MPEG4_GROUP_OF_VOP:
@ -358,22 +371,17 @@ gst_mpeg4vparse_process_sc (GstMpeg4VParse * mp4vparse, GstMpeg4Packet * packet,
GST_LOG_OBJECT (mp4vparse, "startcode is User Data"); GST_LOG_OBJECT (mp4vparse, "startcode is User Data");
} }
/* parse config data ending here if proper startcodes found earlier; /* parse config data ending here if proper startcodes found earlier;
* preferably start at VOS (visual object sequence), * we should have received a visual object before. */
* otherwise at VO (video object) */
if (mp4vparse->vo_found) { if (mp4vparse->vo_found) {
/*Do not take care startcode into account */ /*Do not take care startcode into account */
gst_mpeg4vparse_process_config (mp4vparse, gst_mpeg4vparse_process_config (mp4vparse,
packet->data, packet->offset, packet->offset - 3); packet->data, packet->offset, packet->offset - 3);
/* avoid accepting again for a VOP sc following a GOP sc */
mp4vparse->vo_found = FALSE; mp4vparse->vo_found = FALSE;
} }
break; break;
} }
case GST_MPEG4_VISUAL_OBJ_SEQ_START: case GST_MPEG4_VISUAL_OBJ_SEQ_START:
GST_LOG_OBJECT (mp4vparse, "Visual Sequence Start"); GST_LOG_OBJECT (mp4vparse, "Visual Sequence Start");
mp4vparse->vo_found = TRUE;
mp4vparse->profile = gst_codec_utils_mpeg4video_get_profile (packet->data mp4vparse->profile = gst_codec_utils_mpeg4video_get_profile (packet->data
+ packet->offset + 1, packet->offset); + packet->offset + 1, packet->offset);
mp4vparse->level = gst_codec_utils_mpeg4video_get_level (packet->data mp4vparse->level = gst_codec_utils_mpeg4video_get_level (packet->data
@ -381,6 +389,7 @@ gst_mpeg4vparse_process_sc (GstMpeg4VParse * mp4vparse, GstMpeg4Packet * packet,
break; break;
case GST_MPEG4_VISUAL_OBJ: case GST_MPEG4_VISUAL_OBJ:
GST_LOG_OBJECT (mp4vparse, "Visual Object"); GST_LOG_OBJECT (mp4vparse, "Visual Object");
mp4vparse->vo_offset = packet->offset;
break; break;
default: default:
if (packet->type >= GST_MPEG4_VIDEO_LAYER_FIRST && if (packet->type >= GST_MPEG4_VIDEO_LAYER_FIRST &&
@ -395,7 +404,6 @@ gst_mpeg4vparse_process_sc (GstMpeg4VParse * mp4vparse, GstMpeg4Packet * packet,
/* VO (video object) cases */ /* VO (video object) cases */
} else if (packet->type <= GST_MPEG4_VIDEO_OBJ_LAST) { } else if (packet->type <= GST_MPEG4_VIDEO_OBJ_LAST) {
GST_LOG_OBJECT (mp4vparse, "Video object"); GST_LOG_OBJECT (mp4vparse, "Video object");
mp4vparse->vo_found = TRUE;
} }
break; break;
} }
@ -805,6 +813,12 @@ gst_mpeg4vparse_set_caps (GstBaseParse * parse, GstCaps * caps)
packet.type <= GST_MPEG4_VIDEO_LAYER_LAST) packet.type <= GST_MPEG4_VIDEO_LAYER_LAST)
mp4vparse->vol_offset = packet.offset; mp4vparse->vol_offset = packet.offset;
else if (packet.type == GST_MPEG4_VISUAL_OBJ) {
gst_mpeg4_parse_visual_object (&mp4vparse->vo, NULL,
data + packet.offset, MIN (packet.size, size));
mp4vparse->vo_found = TRUE;
}
res = gst_mpeg4_parse (&packet, FALSE, NULL, data, packet.offset, size); res = gst_mpeg4_parse (&packet, FALSE, NULL, data, packet.offset, size);
} }

View file

@ -55,6 +55,9 @@ struct _GstMpeg4VParse {
gboolean vop_coded; gboolean vop_coded;
gboolean update_caps; gboolean update_caps;
GstMpeg4VisualObject vo;
gint vo_offset;
GstBuffer *config; GstBuffer *config;
GstMpeg4VideoObjectLayer vol; GstMpeg4VideoObjectLayer vol;
gboolean vol_offset; gboolean vol_offset;