diff options
Diffstat (limited to 'gst/videoparsers/gstmpegvideoparse.c')
-rw-r--r-- | gst/videoparsers/gstmpegvideoparse.c | 104 |
1 files changed, 54 insertions, 50 deletions
diff --git a/gst/videoparsers/gstmpegvideoparse.c b/gst/videoparsers/gstmpegvideoparse.c index 78dc85eb..073a3304 100644 --- a/gst/videoparsers/gstmpegvideoparse.c +++ b/gst/videoparsers/gstmpegvideoparse.c @@ -263,12 +263,11 @@ gst_mpegv_parse_stop (GstBaseParse * parse) } static gboolean -gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf, +gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstMapInfo * info, guint size) { GstMpegVideoPacket packet; guint8 *data_with_prefix; - GstMapInfo map; gint i; if (mpvparse->seq_offset < 4) { @@ -277,9 +276,7 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf, return FALSE; } - gst_buffer_map (buf, &map, GST_MAP_READ); - g_assert (size <= map.size); - packet.data = map.data; + packet.data = info->data; packet.type = GST_MPEG_VIDEO_PACKET_SEQUENCE; packet.offset = mpvparse->seq_offset; packet.size = size - mpvparse->seq_offset; @@ -287,13 +284,12 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf, used for codec private data */ data_with_prefix = (guint8 *) packet.data + packet.offset - 4; - /* only do stuff if something new; only compare first 11 bytes, changes in - quantiser matrix doesn't matter here. Also changing the matrices in - codec_data seems to cause problem with decoders */ + /* only do stuff if something new; only compare first 8 bytes, changes in + quantiser matrix or bitrate don't matter here. Also changing the + matrices in codec_data seems to cause problem with decoders */ if (mpvparse->config && gst_buffer_memcmp (mpvparse->config, 0, data_with_prefix, MIN (size, - 11)) == 0) { - gst_buffer_unmap (buf, &map); + 8)) == 0) { return TRUE; } @@ -302,7 +298,6 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf, GST_DEBUG_OBJECT (mpvparse, "failed to parse config data (size %d) at offset %d", size, mpvparse->seq_offset); - gst_buffer_unmap (buf, &map); return FALSE; } @@ -374,8 +369,6 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf, /* trigger src caps update */ mpvparse->update_caps = TRUE; - gst_buffer_unmap (buf, &map); - return TRUE; } @@ -440,17 +433,14 @@ picture_type_name (guint8 pct) #endif /* GST_DISABLE_GST_DEBUG */ static void -parse_packet_extension (GstMpegvParse * mpvparse, GstBuffer * buf, guint off) +parse_packet_extension (GstMpegvParse * mpvparse, GstMapInfo * info, guint off) { - GstMapInfo map; GstMpegVideoPacket packet; - gst_buffer_map (buf, &map, GST_MAP_READ); - - packet.data = map.data; + packet.data = info->data; packet.type = GST_MPEG_VIDEO_PACKET_EXTENSION; packet.offset = off; - packet.size = map.size - off; + packet.size = info->size - off; /* FIXME : WE ARE ASSUMING IT IS A *PICTURE* EXTENSION */ if (gst_mpeg_video_packet_parse_picture_extension (&packet, @@ -469,8 +459,6 @@ parse_packet_extension (GstMpegvParse * mpvparse, GstBuffer * buf, guint off) } mpvparse->picext_updated = TRUE; } - - gst_buffer_unmap (buf, &map); } /* caller guarantees at least start code in @buf at @off */ @@ -478,16 +466,14 @@ parse_packet_extension (GstMpegvParse * mpvparse, GstBuffer * buf, guint off) * otherwise returns TRUE if code terminates preceding frame */ static gboolean gst_mpegv_parse_process_sc (GstMpegvParse * mpvparse, - GstBuffer * buf, gint off, guint8 code) + GstMapInfo * info, gint off, GstMpegVideoPacket * packet) { - gboolean ret = FALSE, packet = TRUE; - - g_return_val_if_fail (buf && gst_buffer_get_size (buf) >= 4, FALSE); + gboolean ret = FALSE, checkconfig = TRUE; - GST_LOG_OBJECT (mpvparse, "process startcode %x (%s) offset:%d", code, - picture_start_code_name (code), off); + GST_LOG_OBJECT (mpvparse, "process startcode %x (%s) offset:%d", packet->type, + picture_start_code_name (packet->type), off); - switch (code) { + switch (packet->type) { case GST_MPEG_VIDEO_PACKET_PICTURE: GST_LOG_OBJECT (mpvparse, "startcode is PICTURE"); /* picture is aggregated with preceding sequence/gop, if any. @@ -515,49 +501,45 @@ gst_mpegv_parse_process_sc (GstMpegvParse * mpvparse, break; case GST_MPEG_VIDEO_PACKET_EXTENSION: GST_LOG_OBJECT (mpvparse, "startcode is VIDEO PACKET EXTENSION"); - parse_packet_extension (mpvparse, buf, off); + parse_packet_extension (mpvparse, info, off); if (mpvparse->ext_count < G_N_ELEMENTS (mpvparse->ext_offsets)) mpvparse->ext_offsets[mpvparse->ext_count++] = off; - packet = FALSE; + checkconfig = FALSE; break; default: - if (GST_MPEG_VIDEO_PACKET_IS_SLICE (code)) { + if (GST_MPEG_VIDEO_PACKET_IS_SLICE (packet->type)) { mpvparse->slice_count++; if (mpvparse->slice_offset == 0) mpvparse->slice_offset = off - 4; } - packet = FALSE; + checkconfig = FALSE; break; } /* set size to avoid processing config again */ - if (mpvparse->seq_offset >= 0 && off != mpvparse->seq_offset && - !mpvparse->seq_size && packet) { + if (checkconfig && mpvparse->seq_offset >= 0 && off != mpvparse->seq_offset && + !mpvparse->seq_size) { /* should always be at start */ g_assert (mpvparse->seq_offset <= 4); - gst_mpegv_parse_process_config (mpvparse, buf, off - mpvparse->seq_offset); + gst_mpegv_parse_process_config (mpvparse, info, off - mpvparse->seq_offset); mpvparse->seq_size = off - mpvparse->seq_offset; } /* extract some picture info if there is any in the frame being terminated */ if (ret && mpvparse->pic_offset >= 0 && mpvparse->pic_offset < off) { - GstMapInfo map; - GstMpegVideoPacket packet; + GstMpegVideoPacket header; - gst_buffer_map (buf, &map, GST_MAP_READ); - packet.data = map.data; - packet.type = GST_MPEG_VIDEO_PACKET_PICTURE; - packet.offset = mpvparse->pic_offset; - packet.size = map.size - mpvparse->pic_offset; - if (gst_mpeg_video_packet_parse_picture_header (&packet, &mpvparse->pichdr)) + header.data = info->data; + header.type = GST_MPEG_VIDEO_PACKET_PICTURE; + header.offset = mpvparse->pic_offset; + header.size = info->size - mpvparse->pic_offset; + if (gst_mpeg_video_packet_parse_picture_header (&header, &mpvparse->pichdr)) GST_LOG_OBJECT (mpvparse, "picture_coding_type %d (%s), ending" "frame of size %d", mpvparse->pichdr.pic_type, picture_type_name (mpvparse->pichdr.pic_type), off - 4); else GST_LOG_OBJECT (mpvparse, "Couldn't parse picture at offset %d", mpvparse->pic_offset); - - gst_buffer_unmap (buf, &map); } return ret; @@ -631,7 +613,7 @@ retry: /* note: initial start code is assumed at offset 0 by subsequent code */ /* examine start code, see if it looks like an initial start code */ - if (gst_mpegv_parse_process_sc (mpvparse, buf, 4, packet.type)) { + if (gst_mpegv_parse_process_sc (mpvparse, &map, 4, &packet)) { /* found sc */ GST_LOG_OBJECT (mpvparse, "valid start code found"); mpvparse->last_sc = 0; @@ -676,7 +658,7 @@ next: } } else { /* decide whether this startcode ends a frame */ - ret = gst_mpegv_parse_process_sc (mpvparse, buf, off + 4, packet.type); + ret = gst_mpegv_parse_process_sc (mpvparse, &map, off + 4, &packet); } if (!ret) @@ -737,8 +719,26 @@ gst_mpegv_parse_update_src_caps (GstMpegvParse * mpvparse) "parsed", G_TYPE_BOOLEAN, TRUE, NULL); if (mpvparse->sequencehdr.width > 0 && mpvparse->sequencehdr.height > 0) { - gst_caps_set_simple (caps, "width", G_TYPE_INT, mpvparse->sequencehdr.width, - "height", G_TYPE_INT, mpvparse->sequencehdr.height, NULL); + GstMpegVideoSequenceDisplayExt *seqdispext; + gint width, height; + + width = mpvparse->sequencehdr.width; + height = mpvparse->sequencehdr.height; + + if (mpvparse->config_flags & FLAG_SEQUENCE_DISPLAY_EXT) { + seqdispext = &mpvparse->sequencedispext; + + if (seqdispext->display_horizontal_size <= width + && seqdispext->display_vertical_size <= height) { + width = seqdispext->display_horizontal_size; + height = seqdispext->display_vertical_size; + GST_INFO_OBJECT (mpvparse, + "stream has display extension: display_width=%d display_height=%d", + width, height); + } + } + gst_caps_set_simple (caps, "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, NULL); } /* perhaps we have a framerate */ @@ -966,10 +966,14 @@ gst_mpegv_parse_set_caps (GstBaseParse * parse, GstCaps * caps) if ((value = gst_structure_get_value (s, "codec_data")) != NULL && (buf = gst_value_get_buffer (value))) { + GstMapInfo map; + gst_buffer_map (buf, &map, GST_MAP_READ); /* best possible parse attempt, * src caps are based on sink caps so it will end up in there * whether sucessful or not */ - gst_mpegv_parse_process_config (mpvparse, buf, gst_buffer_get_size (buf)); + mpvparse->seq_offset = 4; + gst_mpegv_parse_process_config (mpvparse, &map, gst_buffer_get_size (buf)); + gst_buffer_unmap (buf, &map); gst_mpegv_parse_reset_frame (mpvparse); } |