diff --git a/gst-libs/gst/codecparsers/gstmpegvideoparser.c b/gst-libs/gst/codecparsers/gstmpegvideoparser.c index 094a6c687c..f498316744 100644 --- a/gst-libs/gst/codecparsers/gstmpegvideoparser.c +++ b/gst-libs/gst/codecparsers/gstmpegvideoparser.c @@ -480,6 +480,70 @@ gst_mpeg_video_packet_parse_sequence_display_extension (const GstMpegVideoPacket return TRUE; } +/** + * gst_mpeg_video_packet_parse_sequence_scalable_extension: + * @packet: The #GstMpegVideoPacket that carries the data + * @seqscaleext: (out): The #GstMpegVideoSequenceScalableExt structure to fill + * + * Parses the @seqscaleext MPEG Video Sequence Scalable Extension structure + * members from video @packet + * + * Returns: %TRUE if the seqext could be parsed correctly, %FALSE otherwize. + * + * Since: 1.2 + */ +gboolean + gst_mpeg_video_packet_parse_sequence_scalable_extension + (const GstMpegVideoPacket * packet, + GstMpegVideoSequenceScalableExt * seqscaleext) { + GstBitReader br; + + g_return_val_if_fail (seqscaleext != NULL, FALSE); + + if (packet->size < 5) { + GST_DEBUG ("not enough bytes to parse the extension"); + return FALSE; + } + + gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size); + + if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) != + GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_SCALABLE) { + GST_DEBUG ("Not parsing a sequence scalable extension"); + return FALSE; + } + + READ_UINT8 (&br, seqscaleext->scalable_mode, 2); + READ_UINT8 (&br, seqscaleext->layer_id, 4); + + if (seqscaleext->scalable_mode == GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_SPATIAL) { + READ_UINT16 (&br, seqscaleext->lower_layer_prediction_horizontal_size, 14); + + SKIP (&br, 1); + + READ_UINT16 (&br, seqscaleext->lower_layer_prediction_vertical_size, 14); + + READ_UINT8 (&br, seqscaleext->horizontal_subsampling_factor_m, 5); + READ_UINT8 (&br, seqscaleext->horizontal_subsampling_factor_n, 5); + READ_UINT8 (&br, seqscaleext->vertical_subsampling_factor_m, 5); + READ_UINT8 (&br, seqscaleext->vertical_subsampling_factor_n, 5); + } + + if (seqscaleext->scalable_mode == GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_TEMPORAL) { + READ_UINT8 (&br, seqscaleext->picture_mux_enable, 1); + if (seqscaleext->picture_mux_enable) + READ_UINT8 (&br, seqscaleext->mux_to_progressive_sequence, 1); + READ_UINT8 (&br, seqscaleext->picture_mux_order, 3); + READ_UINT8 (&br, seqscaleext->picture_mux_factor, 3); + } + + return TRUE; + +failed: + GST_WARNING ("error parsing \"Sequence Scalable Extension\""); + return FALSE; +} + gboolean gst_mpeg_video_finalise_mpeg2_sequence_header (GstMpegVideoSequenceHdr * seqhdr, GstMpegVideoSequenceExt * seqext, diff --git a/gst-libs/gst/codecparsers/gstmpegvideoparser.h b/gst-libs/gst/codecparsers/gstmpegvideoparser.h index 981fe067d6..414a0e5eb8 100644 --- a/gst-libs/gst/codecparsers/gstmpegvideoparser.h +++ b/gst-libs/gst/codecparsers/gstmpegvideoparser.h @@ -78,6 +78,7 @@ typedef enum { * @GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: Sequence extension code * @GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY: Sequence Display extension code * @GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: Quantization Matrix extension code + * @GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_SCALABLE: Sequence Scalable extension code * @GST_MPEG_VIDEO_PACKET_EXT_PICTURE: Picture coding extension * * Indicates what type of packets are in this block, some are mutually @@ -85,12 +86,27 @@ typedef enum { * Picture may occur together or separately. */ typedef enum { - GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE = 0x01, - GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY = 0x02, - GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX = 0x03, - GST_MPEG_VIDEO_PACKET_EXT_PICTURE = 0x08 + GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE = 0x01, + GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY = 0x02, + GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX = 0x03, + GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_SCALABLE = 0x05, + GST_MPEG_VIDEO_PACKET_EXT_PICTURE = 0x08 } GstMpegVideoPacketExtensionCode; +/** + * GstMpegVideoSequenceScalableMode: + * GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_DATA_PARTITIONING: Data partitioning + * GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_SPATIAL: Spatial Scalability + * GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_SNR: SNR Scalability + * GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_TEMPORAL: Temporal Scalability + */ +typedef enum { + GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_DATA_PARTITIONING = 0x00, + GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_SPATIAL = 0x01, + GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_SNR = 0x02, + GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_TEMPORAL = 0x03 +} GstMpegVideoSequenceScalableMode; + /** * GstMpegVideoLevel: * @GST_MPEG_VIDEO_LEVEL_LOW: Low level (LL) @@ -176,6 +192,7 @@ typedef enum { typedef struct _GstMpegVideoSequenceHdr GstMpegVideoSequenceHdr; typedef struct _GstMpegVideoSequenceExt GstMpegVideoSequenceExt; typedef struct _GstMpegVideoSequenceDisplayExt GstMpegVideoSequenceDisplayExt; +typedef struct _GstMpegVideoSequenceScalableExt GstMpegVideoSequenceScalableExt; typedef struct _GstMpegVideoPictureHdr GstMpegVideoPictureHdr; typedef struct _GstMpegVideoGop GstMpegVideoGop; typedef struct _GstMpegVideoPictureExt GstMpegVideoPictureExt; @@ -272,6 +289,45 @@ struct _GstMpegVideoSequenceDisplayExt guint16 display_vertical_size; }; +/** + * GstMpegVideoSequenceScalableExt: + * @scalable_mode: + * @layer_id: + * @lower_layer_prediction_horizontal_size: + * @lower_layer_prediction_vertical_size: + * @horizontal_subsampling_factor_m: + * @horizontal_subsampling_factor_n: + * @vertical_subsampling_factor_m: + * @vertical_subsampling_factor_n: + * @picture_mux_enable: + * @mux_to_progressive_sequence: + * @picture_mux_order: + * @picture_mux_factor: + * + * The Sequence Scalable Extension structure. + * + * Since: 1.2 + */ +struct _GstMpegVideoSequenceScalableExt +{ + guint8 scalable_mode; + guint8 layer_id; + + /* if spatial scalability */ + guint16 lower_layer_prediction_horizontal_size; + guint16 lower_layer_prediction_vertical_size; + guint8 horizontal_subsampling_factor_m; + guint8 horizontal_subsampling_factor_n; + guint8 vertical_subsampling_factor_m; + guint8 vertical_subsampling_factor_n; + + /* if temporal scalability */ + guint8 picture_mux_enable; + guint8 mux_to_progressive_sequence; + guint8 picture_mux_order; + guint8 picture_mux_factor; +}; + /** * GstMpegVideoQuantMatrixExt: * @load_intra_quantiser_matrix: @@ -411,6 +467,9 @@ gboolean gst_mpeg_video_packet_parse_sequence_extension (const GstMpegVideoPacke gboolean gst_mpeg_video_packet_parse_sequence_display_extension (const GstMpegVideoPacket * packet, GstMpegVideoSequenceDisplayExt * seqdisplayext); +gboolean gst_mpeg_video_packet_parse_sequence_scalable_extension (const GstMpegVideoPacket * packet, + GstMpegVideoSequenceScalableExt * seqscaleext); + gboolean gst_mpeg_video_packet_parse_picture_header (const GstMpegVideoPacket * packet, GstMpegVideoPictureHdr* pichdr);