mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 16:08:51 +00:00
mpeg2: parse slice() header earlier.
Parse slice() header and first macroblock position earlier in _parse() function instead of waiting for the _decode() stage. This doesn't change anything but readability.
This commit is contained in:
parent
549b5a9389
commit
4a39efa9f6
1 changed files with 78 additions and 50 deletions
|
@ -171,6 +171,17 @@ pts_eval(PTSGenerator *tsg, GstClockTime pic_pts, guint pic_tsn)
|
||||||
/* --- MPEG-2 Decoder Units --- */
|
/* --- MPEG-2 Decoder Units --- */
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
typedef struct _GstMpegVideoSliceHdr GstMpegVideoSliceHdr;
|
||||||
|
struct _GstMpegVideoSliceHdr {
|
||||||
|
guint16 slice_horizontal_position;
|
||||||
|
guint16 slice_vertical_position;
|
||||||
|
guint8 quantiser_scale_code;
|
||||||
|
guint8 intra_slice;
|
||||||
|
|
||||||
|
/* Size of the slice() header in bits */
|
||||||
|
guint header_size;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct _GstVaapiDecoderUnitMpeg2 GstVaapiDecoderUnitMpeg2;
|
typedef struct _GstVaapiDecoderUnitMpeg2 GstVaapiDecoderUnitMpeg2;
|
||||||
struct _GstVaapiDecoderUnitMpeg2 {
|
struct _GstVaapiDecoderUnitMpeg2 {
|
||||||
GstVaapiDecoderUnit base;
|
GstVaapiDecoderUnit base;
|
||||||
|
@ -183,6 +194,7 @@ struct _GstVaapiDecoderUnitMpeg2 {
|
||||||
GstMpegVideoQuantMatrixExt quant_matrix;
|
GstMpegVideoQuantMatrixExt quant_matrix;
|
||||||
GstMpegVideoPictureHdr pic_hdr;
|
GstMpegVideoPictureHdr pic_hdr;
|
||||||
GstMpegVideoPictureExt pic_ext;
|
GstMpegVideoPictureExt pic_ext;
|
||||||
|
GstMpegVideoSliceHdr slice_hdr;
|
||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -733,6 +745,58 @@ parse_picture(GstVaapiDecoderUnitMpeg2 *unit)
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstVaapiDecoderStatus
|
||||||
|
parse_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit)
|
||||||
|
{
|
||||||
|
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
|
||||||
|
GstMpegVideoSliceHdr * const slice_hdr = &unit->data.slice_hdr;
|
||||||
|
GstMpegVideoPacket * const packet = &unit->packet;
|
||||||
|
GstBitReader br;
|
||||||
|
gint mb_x, mb_y, mb_inc;
|
||||||
|
guint8 slice_vertical_position_extension;
|
||||||
|
guint8 extra_bit_slice, junk8;
|
||||||
|
|
||||||
|
gst_bit_reader_init(&br, packet->data + packet->offset, packet->size);
|
||||||
|
if (priv->height > 2800)
|
||||||
|
READ_UINT8(&br, slice_vertical_position_extension, 3);
|
||||||
|
if (priv->has_seq_scalable_ext) {
|
||||||
|
GST_ERROR("failed to parse slice with sequence_scalable_extension()");
|
||||||
|
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
|
||||||
|
}
|
||||||
|
READ_UINT8(&br, slice_hdr->quantiser_scale_code, 5);
|
||||||
|
READ_UINT8(&br, extra_bit_slice, 1);
|
||||||
|
if (!extra_bit_slice)
|
||||||
|
slice_hdr->intra_slice = 0;
|
||||||
|
else {
|
||||||
|
READ_UINT8(&br, slice_hdr->intra_slice, 1);
|
||||||
|
READ_UINT8(&br, junk8, 7);
|
||||||
|
READ_UINT8(&br, extra_bit_slice, 1);
|
||||||
|
while (extra_bit_slice) {
|
||||||
|
READ_UINT8(&br, junk8, 8);
|
||||||
|
READ_UINT8(&br, extra_bit_slice, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
slice_hdr->header_size = 32 + gst_bit_reader_get_pos(&br);
|
||||||
|
|
||||||
|
mb_y = packet->type - GST_MPEG_VIDEO_PACKET_SLICE_MIN;
|
||||||
|
mb_x = -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;
|
||||||
|
}
|
||||||
|
mb_x += mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE ? 33 : mb_inc;
|
||||||
|
} while (mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE);
|
||||||
|
|
||||||
|
slice_hdr->slice_horizontal_position = mb_x;
|
||||||
|
slice_hdr->slice_vertical_position = mb_y;
|
||||||
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
failed:
|
||||||
|
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
|
||||||
|
}
|
||||||
|
|
||||||
static GstVaapiDecoderStatus
|
static GstVaapiDecoderStatus
|
||||||
decode_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit)
|
decode_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit)
|
||||||
{
|
{
|
||||||
|
@ -970,16 +1034,10 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit)
|
||||||
GstVaapiSlice *slice;
|
GstVaapiSlice *slice;
|
||||||
VASliceParameterBufferMPEG2 *slice_param;
|
VASliceParameterBufferMPEG2 *slice_param;
|
||||||
GstMpegVideoPacket * const packet = &unit->packet;
|
GstMpegVideoPacket * const packet = &unit->packet;
|
||||||
const gint slice_no = packet->type - GST_MPEG_VIDEO_PACKET_SLICE_MIN;
|
GstMpegVideoSliceHdr * const slice_hdr = &unit->data.slice_hdr;
|
||||||
GstBitReader br;
|
|
||||||
gint mb_x, mb_y, mb_inc;
|
|
||||||
guint macroblock_offset;
|
|
||||||
guint8 slice_vertical_position_extension;
|
|
||||||
guint8 quantiser_scale_code;
|
|
||||||
guint8 intra_slice = 0;
|
|
||||||
guint8 extra_bit_slice, junk8;
|
|
||||||
|
|
||||||
GST_DEBUG("slice %d (%u bytes)", slice_no, packet->size);
|
GST_DEBUG("slice %d (%u bytes)", slice_hdr->slice_vertical_position,
|
||||||
|
packet->size);
|
||||||
|
|
||||||
if (!picture)
|
if (!picture)
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
|
@ -1003,50 +1061,14 @@ decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnitMpeg2 *unit)
|
||||||
}
|
}
|
||||||
gst_vaapi_picture_add_slice(picture, slice);
|
gst_vaapi_picture_add_slice(picture, slice);
|
||||||
|
|
||||||
/* Parse slice */
|
|
||||||
gst_bit_reader_init(&br, GST_BUFFER_DATA(unit->base.buffer), packet->size);
|
|
||||||
SKIP(&br, 32); /* slice_start_code */
|
|
||||||
if (priv->height > 2800)
|
|
||||||
READ_UINT8(&br, slice_vertical_position_extension, 3);
|
|
||||||
if (priv->has_seq_scalable_ext) {
|
|
||||||
GST_ERROR("failed to parse slice %d. Unsupported sequence_scalable_extension()", slice_no);
|
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
|
|
||||||
}
|
|
||||||
READ_UINT8(&br, quantiser_scale_code, 5);
|
|
||||||
READ_UINT8(&br, extra_bit_slice, 1);
|
|
||||||
if (extra_bit_slice == 1) {
|
|
||||||
READ_UINT8(&br, intra_slice, 1);
|
|
||||||
READ_UINT8(&br, junk8, 7);
|
|
||||||
READ_UINT8(&br, extra_bit_slice, 1);
|
|
||||||
while (extra_bit_slice == 1) {
|
|
||||||
READ_UINT8(&br, junk8, 8);
|
|
||||||
READ_UINT8(&br, extra_bit_slice, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
macroblock_offset = gst_bit_reader_get_pos(&br);
|
|
||||||
|
|
||||||
mb_y = slice_no;
|
|
||||||
mb_x = -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;
|
|
||||||
}
|
|
||||||
mb_x += mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE ? 33 : mb_inc;
|
|
||||||
} while (mb_inc == GST_MPEG_VIDEO_MACROBLOCK_ESCAPE);
|
|
||||||
|
|
||||||
/* Fill in VASliceParameterBufferMPEG2 */
|
/* Fill in VASliceParameterBufferMPEG2 */
|
||||||
slice_param = slice->param;
|
slice_param = slice->param;
|
||||||
slice_param->macroblock_offset = macroblock_offset;
|
slice_param->macroblock_offset = slice_hdr->header_size;
|
||||||
slice_param->slice_horizontal_position = mb_x;
|
slice_param->slice_horizontal_position = slice_hdr->slice_horizontal_position;
|
||||||
slice_param->slice_vertical_position = mb_y;
|
slice_param->slice_vertical_position = slice_hdr->slice_vertical_position;
|
||||||
slice_param->quantiser_scale_code = quantiser_scale_code;
|
slice_param->quantiser_scale_code = slice_hdr->quantiser_scale_code;
|
||||||
slice_param->intra_slice_flag = intra_slice;
|
slice_param->intra_slice_flag = slice_hdr->intra_slice;
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
|
|
||||||
failed:
|
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline gint
|
static inline gint
|
||||||
|
@ -1221,6 +1243,12 @@ gst_vaapi_decoder_mpeg2_parse(GstVaapiDecoder *base_decoder,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
if (packet->type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN &&
|
||||||
|
packet->type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) {
|
||||||
|
status = parse_slice(decoder, unit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
status = GST_VAAPI_DECODER_STATUS_SUCCESS;
|
status = GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue