static gboolean gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf, guint size) { guint8 *data; guint8 *data_with_prefix; GstMapInfo map; gint i, offset; if (mpvparse->seq_offset < 4) { /* This shouldn't happen, but just in case... */ GST_WARNING_OBJECT (mpvparse, "Sequence header start code missing."); return FALSE; } gst_buffer_map (buf, &map, GST_MAP_READ); data = map.data + mpvparse->seq_offset; g_assert (size <= map.size); /* pointer to sequence header data including the start code prefix - used for codec private data */ data_with_prefix = data - 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 */ if (mpvparse->config && size == gst_buffer_get_size (mpvparse->config) && gst_buffer_memcmp (mpvparse->config, 0, data_with_prefix, MIN (size, 11)) == 0) { gst_buffer_unmap (buf, &map); return TRUE; } if (!gst_mpeg_video_parse_sequence_header (&mpvparse->sequencehdr, data, size - mpvparse->seq_offset, 0)) { 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; } GST_LOG_OBJECT (mpvparse, "accepting parsed config size %d", size); /* Set mpeg version, and parse sequence extension */ mpvparse->config_flags = FLAG_NONE; for (i = 0; i < mpvparse->ext_count; ++i) { offset = mpvparse->ext_offsets[i]; mpvparse->config_flags |= FLAG_MPEG2; if (offset < size) { if (gst_mpeg_video_parse_sequence_extension (&mpvparse->sequenceext, map.data, size, offset)) { GST_LOG_OBJECT (mpvparse, "Read Sequence Extension"); mpvparse->config_flags |= FLAG_SEQUENCE_EXT; } else if (gst_mpeg_video_parse_sequence_display_extension (&mpvparse->sequencedispext, map.data, size, offset)) { GST_LOG_OBJECT (mpvparse, "Read Sequence Display Extension"); mpvparse->config_flags |= FLAG_SEQUENCE_DISPLAY_EXT; } } } if (mpvparse->config_flags & FLAG_MPEG2) { /* Update the sequence header based on extensions */ GstMpegVideoSequenceExt *seqext = NULL; GstMpegVideoSequenceDisplayExt *seqdispext = NULL; if (mpvparse->config_flags & FLAG_SEQUENCE_EXT) seqext = &mpvparse->sequenceext; if (mpvparse->config_flags & FLAG_SEQUENCE_DISPLAY_EXT) seqdispext = &mpvparse->sequencedispext; gst_mpeg_video_finalise_mpeg2_sequence_header (&mpvparse->sequencehdr, seqext, seqdispext); } if (mpvparse->fps_num == 0 || mpvparse->fps_den == 0) { mpvparse->fps_num = mpvparse->sequencehdr.fps_n; mpvparse->fps_den = mpvparse->sequencehdr.fps_d; } /* parsing ok, so accept it as new config */ if (mpvparse->config != NULL) gst_buffer_unref (mpvparse->config); mpvparse->config = gst_buffer_new_and_alloc (size); gst_buffer_fill (mpvparse->config, 0, data_with_prefix, size); /* trigger src caps update */ mpvparse->update_caps = TRUE; gst_buffer_unmap (buf, &map); return TRUE; }
static gboolean gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstMapInfo * info, guint size) { GstMpegVideoPacket packet; guint8 *data_with_prefix; gint i; if (mpvparse->seq_offset < 4) { /* This shouldn't happen, but just in case... */ GST_WARNING_OBJECT (mpvparse, "Sequence header start code missing."); return FALSE; } packet.data = info->data; packet.type = GST_MPEG_VIDEO_PACKET_SEQUENCE; packet.offset = mpvparse->seq_offset; packet.size = size - mpvparse->seq_offset; /* pointer to sequence header data including the start code prefix - used for codec private data */ data_with_prefix = (guint8 *) packet.data + packet.offset - 4; /* 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, 8)) == 0) { return TRUE; } if (!gst_mpeg_video_packet_parse_sequence_header (&packet, &mpvparse->sequencehdr)) { GST_DEBUG_OBJECT (mpvparse, "failed to parse config data (size %d) at offset %d", size, mpvparse->seq_offset); return FALSE; } mpvparse->seqhdr_updated = TRUE; GST_LOG_OBJECT (mpvparse, "accepting parsed config size %d", size); /* Set mpeg version, and parse sequence extension */ mpvparse->config_flags = FLAG_NONE; for (i = 0; i < mpvparse->ext_count; ++i) { packet.type = GST_MPEG_VIDEO_PACKET_EXTENSION; packet.offset = mpvparse->ext_offsets[i]; packet.size = (gint) size - mpvparse->ext_offsets[i]; mpvparse->config_flags |= FLAG_MPEG2; if (packet.size > 1) { switch (packet.data[packet.offset] >> 4) { case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: if (gst_mpeg_video_packet_parse_sequence_extension (&packet, &mpvparse->sequenceext)) { GST_LOG_OBJECT (mpvparse, "Read Sequence Extension"); mpvparse->config_flags |= FLAG_SEQUENCE_EXT; mpvparse->seqext_updated = TRUE; } break; case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY: if (gst_mpeg_video_packet_parse_sequence_display_extension (&packet, &mpvparse->sequencedispext)) { GST_LOG_OBJECT (mpvparse, "Read Sequence Display Extension"); mpvparse->config_flags |= FLAG_SEQUENCE_DISPLAY_EXT; mpvparse->seqdispext_updated = TRUE; } break; case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: if (gst_mpeg_video_packet_parse_quant_matrix_extension (&packet, &mpvparse->quantmatrext)) { GST_LOG_OBJECT (mpvparse, "Read Quantization Matrix Extension"); mpvparse->quantmatrext_updated = TRUE; } break; } } } if (mpvparse->config_flags & FLAG_MPEG2) { /* Update the sequence header based on extensions */ GstMpegVideoSequenceExt *seqext = NULL; GstMpegVideoSequenceDisplayExt *seqdispext = NULL; if (mpvparse->config_flags & FLAG_SEQUENCE_EXT) seqext = &mpvparse->sequenceext; if (mpvparse->config_flags & FLAG_SEQUENCE_DISPLAY_EXT) seqdispext = &mpvparse->sequencedispext; gst_mpeg_video_finalise_mpeg2_sequence_header (&mpvparse->sequencehdr, seqext, seqdispext); } if (mpvparse->fps_num == 0 || mpvparse->fps_den == 0) { mpvparse->fps_num = mpvparse->sequencehdr.fps_n; mpvparse->fps_den = mpvparse->sequencehdr.fps_d; } /* parsing ok, so accept it as new config */ if (mpvparse->config != NULL) gst_buffer_unref (mpvparse->config); mpvparse->config = gst_buffer_new_and_alloc (size); gst_buffer_fill (mpvparse->config, 0, data_with_prefix, size); /* trigger src caps update */ mpvparse->update_caps = TRUE; return TRUE; }