mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
codecparsers: mpeg2: add slice header parsing API.
Add API to parse the Slice header. This also calculates the macroblock position as specified in 6.3.16. https://bugzilla.gnome.org/show_bug.cgi?id=664274 Signed-off-by: Sreerenj Balachandran <sreerenj.balachandran@intel.com> Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
This commit is contained in:
parent
2adfbe36f1
commit
9a2ed78532
2 changed files with 164 additions and 0 deletions
|
@ -78,6 +78,49 @@ static const guint8 mpeg_zigzag_8x8[64] = {
|
||||||
53, 60, 61, 54, 47, 55, 62, 63
|
53, 60, 61, 54, 47, 55, 62, 63
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
GST_MPEG_VIDEO_MACROBLOCK_ESCAPE = G_MAXUINT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Table B-1: Variable length codes for macroblock_address_increment */
|
||||||
|
static const VLCTable mpeg2_mbaddr_vlc_table[] = {
|
||||||
|
{1, 0x01, 1},
|
||||||
|
{2, 0x03, 3},
|
||||||
|
{3, 0x02, 3},
|
||||||
|
{4, 0x03, 4},
|
||||||
|
{5, 0x02, 4},
|
||||||
|
{6, 0x03, 5},
|
||||||
|
{7, 0x02, 5},
|
||||||
|
{8, 0x07, 7},
|
||||||
|
{9, 0x06, 7},
|
||||||
|
{10, 0x0b, 8},
|
||||||
|
{11, 0x0a, 8},
|
||||||
|
{12, 0x09, 8},
|
||||||
|
{13, 0x08, 8},
|
||||||
|
{14, 0x07, 8},
|
||||||
|
{15, 0x06, 8},
|
||||||
|
{16, 0x17, 10},
|
||||||
|
{17, 0x16, 10},
|
||||||
|
{18, 0x15, 10},
|
||||||
|
{19, 0x14, 10},
|
||||||
|
{20, 0x13, 10},
|
||||||
|
{21, 0x12, 10},
|
||||||
|
{22, 0x23, 11},
|
||||||
|
{23, 0x22, 11},
|
||||||
|
{24, 0x21, 11},
|
||||||
|
{25, 0x20, 11},
|
||||||
|
{26, 0x1f, 11},
|
||||||
|
{27, 0x1e, 11},
|
||||||
|
{28, 0x1d, 11},
|
||||||
|
{29, 0x1c, 11},
|
||||||
|
{30, 0x1b, 11},
|
||||||
|
{31, 0x1a, 11},
|
||||||
|
{32, 0x19, 11},
|
||||||
|
{33, 0x18, 11},
|
||||||
|
{GST_MPEG_VIDEO_MACROBLOCK_ESCAPE, 0x08, 11}
|
||||||
|
};
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY (mpegvideo_parser_debug);
|
GST_DEBUG_CATEGORY (mpegvideo_parser_debug);
|
||||||
#define GST_CAT_DEFAULT mpegvideo_parser_debug
|
#define GST_CAT_DEFAULT mpegvideo_parser_debug
|
||||||
|
|
||||||
|
@ -893,6 +936,95 @@ failed:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_mpeg_video_packet_parse_slice_header:
|
||||||
|
* @packet: The #GstMpegVideoPacket that carries the data
|
||||||
|
* @slice_hdr: (out): The #GstMpegVideoSliceHdr structure to fill
|
||||||
|
* @seqhdr: The #GstMpegVideoSequenceHdr header
|
||||||
|
* @seqscaleext: The #GstMpegVideoSequenceScalableExt header
|
||||||
|
*
|
||||||
|
* Parses the @GstMpegVideoSliceHdr structure members from @data
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the slice could be parsed correctly, %FALSE otherwize.
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_mpeg_video_packet_parse_slice_header (const GstMpegVideoPacket * packet,
|
||||||
|
GstMpegVideoSliceHdr * slice_hdr, GstMpegVideoSequenceHdr * seqhdr,
|
||||||
|
GstMpegVideoSequenceScalableExt * seqscaleext)
|
||||||
|
{
|
||||||
|
GstBitReader br;
|
||||||
|
guint height;
|
||||||
|
guint mb_inc;
|
||||||
|
guint8 bits, extra_bits;
|
||||||
|
guint8 vertical_position, vertical_position_extension = 0;
|
||||||
|
|
||||||
|
g_return_val_if_fail (seqhdr != NULL, FALSE);
|
||||||
|
|
||||||
|
if (packet->size < 5)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
gst_bit_reader_init (&br, &packet->data[packet->offset], packet->size);
|
||||||
|
|
||||||
|
if (packet->type < GST_MPEG_VIDEO_PACKET_SLICE_MIN ||
|
||||||
|
packet->type > GST_MPEG_VIDEO_PACKET_SLICE_MAX) {
|
||||||
|
GST_DEBUG ("Not parsing a slice");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
vertical_position = packet->type - GST_MPEG_VIDEO_PACKET_SLICE_MIN;
|
||||||
|
|
||||||
|
height = seqhdr->height;
|
||||||
|
if (height > 2800)
|
||||||
|
READ_UINT8 (&br, vertical_position_extension, 3);
|
||||||
|
|
||||||
|
if (seqscaleext)
|
||||||
|
if (seqscaleext->scalable_mode ==
|
||||||
|
GST_MPEG_VIDEO_SEQ_SCALABLE_MODE_DATA_PARTITIONING)
|
||||||
|
READ_UINT8 (&br, slice_hdr->priority_breakpoint, 7);
|
||||||
|
|
||||||
|
READ_UINT8 (&br, slice_hdr->quantiser_scale_code, 5);
|
||||||
|
|
||||||
|
READ_UINT8 (&br, extra_bits, 1);
|
||||||
|
if (!extra_bits)
|
||||||
|
slice_hdr->intra_slice = 0;
|
||||||
|
else {
|
||||||
|
READ_UINT8 (&br, slice_hdr->intra_slice, 1);
|
||||||
|
SKIP (&br, 1);
|
||||||
|
READ_UINT8 (&br, slice_hdr->slice_picture_id, 6);
|
||||||
|
|
||||||
|
READ_UINT8 (&br, bits, 1);
|
||||||
|
while (bits) {
|
||||||
|
READ_UINT8 (&br, extra_bits, 8);
|
||||||
|
READ_UINT8 (&br, bits, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
slice_hdr->header_size = gst_bit_reader_get_pos (&br);
|
||||||
|
|
||||||
|
if (height > 2800)
|
||||||
|
slice_hdr->mb_row = (vertical_position_extension << 7) + vertical_position;
|
||||||
|
else
|
||||||
|
slice_hdr->mb_row = vertical_position;
|
||||||
|
|
||||||
|
slice_hdr->mb_column = -1;
|
||||||
|
do {
|
||||||
|
if (!decode_vlc (&br, &mb_inc, mpeg2_mbaddr_vlc_table,
|
||||||
|
G_N_ELEMENTS (mpeg2_mbaddr_vlc_table))) {
|
||||||
|
GST_WARNING ("failed to decode first macroblock_address_increment");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
slice_hdr->mb_column +=
|
||||||
|
mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE ? 33 : mb_inc;
|
||||||
|
} while (mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
failed:
|
||||||
|
GST_WARNING ("error parsing \"Slice\"");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_mpeg_video_quant_matrix_get_raster_from_zigzag:
|
* gst_mpeg_video_quant_matrix_get_raster_from_zigzag:
|
||||||
* @out_quant: (out): The resulting quantization matrix
|
* @out_quant: (out): The resulting quantization matrix
|
||||||
|
|
|
@ -197,6 +197,7 @@ typedef struct _GstMpegVideoPictureHdr GstMpegVideoPictureHdr;
|
||||||
typedef struct _GstMpegVideoGop GstMpegVideoGop;
|
typedef struct _GstMpegVideoGop GstMpegVideoGop;
|
||||||
typedef struct _GstMpegVideoPictureExt GstMpegVideoPictureExt;
|
typedef struct _GstMpegVideoPictureExt GstMpegVideoPictureExt;
|
||||||
typedef struct _GstMpegVideoQuantMatrixExt GstMpegVideoQuantMatrixExt;
|
typedef struct _GstMpegVideoQuantMatrixExt GstMpegVideoQuantMatrixExt;
|
||||||
|
typedef struct _GstMpegVideoSliceHdr GstMpegVideoSliceHdr;
|
||||||
typedef struct _GstMpegVideoPacket GstMpegVideoPacket;
|
typedef struct _GstMpegVideoPacket GstMpegVideoPacket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -438,6 +439,32 @@ struct _GstMpegVideoGop
|
||||||
guint8 broken_link;
|
guint8 broken_link;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstMpegVideoSliceHdr:
|
||||||
|
* @slice_vertical_position_extension: Extension to slice_vertical_position
|
||||||
|
* @priority_breakpoint: Point where the bitstream shall be partitioned
|
||||||
|
* @quantiser_scale_code: Quantiser value (range: 1-31)
|
||||||
|
* @intra_slice: Equal to one if all the macroblocks are intra macro blocks.
|
||||||
|
* @slice_picture_id: Intended to aid recovery on severe bursts of
|
||||||
|
* errors for certain types of applications
|
||||||
|
*
|
||||||
|
* The Mpeg2 Video Slice Header structure.
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
struct _GstMpegVideoSliceHdr
|
||||||
|
{
|
||||||
|
guint8 priority_breakpoint;
|
||||||
|
guint8 quantiser_scale_code;
|
||||||
|
guint8 intra_slice;
|
||||||
|
guint8 slice_picture_id;
|
||||||
|
|
||||||
|
/* Calculated values */
|
||||||
|
guint header_size; /* slice_header size in bits */
|
||||||
|
gint mb_row; /* macroblock row */
|
||||||
|
gint mb_column; /* macroblock column */
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstMpegVideoTypeOffsetSize:
|
* GstMpegVideoTypeOffsetSize:
|
||||||
* @type: the type of the packet that start at @offset
|
* @type: the type of the packet that start at @offset
|
||||||
|
@ -479,6 +506,11 @@ gboolean gst_mpeg_video_packet_parse_picture_extension (const GstMpegVideoPacke
|
||||||
gboolean gst_mpeg_video_packet_parse_gop (const GstMpegVideoPacket * packet,
|
gboolean gst_mpeg_video_packet_parse_gop (const GstMpegVideoPacket * packet,
|
||||||
GstMpegVideoGop * gop);
|
GstMpegVideoGop * gop);
|
||||||
|
|
||||||
|
gboolean gst_mpeg_video_packet_parse_slice_header (const GstMpegVideoPacket * packet,
|
||||||
|
GstMpegVideoSliceHdr * slice_hdr,
|
||||||
|
GstMpegVideoSequenceHdr * seq_hdr,
|
||||||
|
GstMpegVideoSequenceScalableExt * seqscaleext);
|
||||||
|
|
||||||
gboolean gst_mpeg_video_packet_parse_quant_matrix_extension (const GstMpegVideoPacket * packet,
|
gboolean gst_mpeg_video_packet_parse_quant_matrix_extension (const GstMpegVideoPacket * packet,
|
||||||
GstMpegVideoQuantMatrixExt * quant);
|
GstMpegVideoQuantMatrixExt * quant);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue