gst_vaapi_mini_object_new(gst_vaapi_parser_info_mpeg2_class());
}
+static inline GstVaapiParserInfoMpeg2 *
+gst_vaapi_parser_info_mpeg2_ensure(GstVaapiParserInfoMpeg2 **pi_ptr)
+{
+ GstVaapiParserInfoMpeg2 *pi = *pi_ptr;
+
+ if (G_LIKELY(pi != NULL))
+ return pi;
+
+ *pi_ptr = pi = gst_vaapi_parser_info_mpeg2_new();
+ return pi;
+}
+
#define gst_vaapi_parser_info_mpeg2_ref(pi) \
gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pi))
GstVaapiParserInfoMpeg2 *seq_ext;
GstVaapiParserInfoMpeg2 *seq_display_ext;
GstVaapiParserInfoMpeg2 *seq_scalable_ext;
+ GstVaapiParserInfoMpeg2 *gop;
GstVaapiParserInfoMpeg2 *pic_hdr;
GstVaapiParserInfoMpeg2 *pic_ext;
GstVaapiParserInfoMpeg2 *quant_matrix;
+ GstVaapiParserInfoMpeg2 *slice_hdr;
GstVaapiPicture *current_picture;
GstVaapiDpb *dpb;
PTSGenerator tsg;
gst_vaapi_parser_info_mpeg2_replace(&priv->seq_ext, NULL);
gst_vaapi_parser_info_mpeg2_replace(&priv->seq_display_ext, NULL);
gst_vaapi_parser_info_mpeg2_replace(&priv->seq_scalable_ext, NULL);
+ gst_vaapi_parser_info_mpeg2_replace(&priv->gop, NULL);
gst_vaapi_parser_info_mpeg2_replace(&priv->pic_hdr, NULL);
gst_vaapi_parser_info_mpeg2_replace(&priv->pic_ext, NULL);
gst_vaapi_parser_info_mpeg2_replace(&priv->quant_matrix, NULL);
+ gst_vaapi_parser_info_mpeg2_replace(&priv->slice_hdr, NULL);
if (priv->dpb) {
gst_vaapi_dpb_unref(priv->dpb);
}
static GstVaapiDecoderStatus
-parse_sequence(GstVaapiDecoderUnit *unit)
+parse_sequence(GstVaapiDecoderMpeg2 *decoder,
+ GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
- GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info;
- GstMpegVideoPacket * const packet = &pi->packet;
+ GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
+ GstMpegVideoSequenceHdr *seq_hdr;
- if (!gst_mpeg_video_parse_sequence_header(&pi->data.seq_hdr,
+ if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->seq_hdr)) {
+ GST_ERROR("failed to allocate parser info for sequence header");
+ return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
+ }
+
+ seq_hdr = &priv->seq_hdr->data.seq_hdr;
+
+ if (!gst_mpeg_video_parse_sequence_header(seq_hdr,
packet->data, packet->size, packet->offset)) {
GST_ERROR("failed to parse sequence header");
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
}
+
+ gst_vaapi_decoder_unit_set_parsed_info(unit, seq_hdr, NULL);
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
{
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder);
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
- GstMpegVideoSequenceHdr *seq_hdr;
+ GstMpegVideoSequenceHdr * const seq_hdr = unit->parsed_info;
- gst_vaapi_parser_info_mpeg2_replace(&priv->seq_hdr, unit->parsed_info);
- seq_hdr = &priv->seq_hdr->data.seq_hdr;
gst_vaapi_parser_info_mpeg2_replace(&priv->seq_ext, NULL);
gst_vaapi_parser_info_mpeg2_replace(&priv->seq_display_ext, NULL);
}
static GstVaapiDecoderStatus
-parse_sequence_ext(GstVaapiDecoderUnit *unit)
+parse_sequence_ext(GstVaapiDecoderMpeg2 *decoder,
+ GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
- GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info;
- GstMpegVideoPacket * const packet = &pi->packet;
+ GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
+ GstMpegVideoSequenceExt *seq_ext;
+
+ if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->seq_ext)) {
+ GST_ERROR("failed to allocate parser info for sequence extension");
+ return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
+ }
- if (!gst_mpeg_video_parse_sequence_extension(&pi->data.seq_ext,
+ seq_ext = &priv->seq_ext->data.seq_ext;
+
+ if (!gst_mpeg_video_parse_sequence_extension(seq_ext,
packet->data, packet->size, packet->offset)) {
GST_ERROR("failed to parse sequence-extension");
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
}
+
+ gst_vaapi_decoder_unit_set_parsed_info(unit, seq_ext, NULL);
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
static GstVaapiDecoderStatus
-decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder,
- GstVaapiDecoderUnit *unit)
+decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder);
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
- GstMpegVideoSequenceExt *seq_ext;
+ GstMpegVideoSequenceExt * const seq_ext = unit->parsed_info;
GstVaapiProfile profile;
guint width, height;
- gst_vaapi_parser_info_mpeg2_replace(&priv->seq_ext, unit->parsed_info);
- seq_ext = &priv->seq_ext->data.seq_ext;
-
priv->progressive_sequence = seq_ext->progressive;
gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence);
}
static GstVaapiDecoderStatus
-parse_sequence_display_ext(GstVaapiDecoderUnit *unit)
+parse_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder,
+ GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
- GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info;
- GstMpegVideoPacket * const packet = &pi->packet;
+ GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
+ GstMpegVideoSequenceDisplayExt *seq_display_ext;
+
+ if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->seq_display_ext)) {
+ GST_ERROR("failed to allocate parser info for sequence display extension");
+ return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
+ }
+
+ seq_display_ext = &priv->seq_display_ext->data.seq_display_ext;
- if (!gst_mpeg_video_parse_sequence_display_extension(
- &pi->data.seq_display_ext,
+ if (!gst_mpeg_video_parse_sequence_display_extension(seq_display_ext,
packet->data, packet->size, packet->offset)) {
GST_ERROR("failed to parse sequence-display-extension");
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
}
+
+ gst_vaapi_decoder_unit_set_parsed_info(unit, seq_display_ext, NULL);
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
decode_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder,
GstVaapiDecoderUnit *unit)
{
- GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
-
- gst_vaapi_parser_info_mpeg2_replace(&priv->seq_display_ext,
- unit->parsed_info);
-
/* XXX: handle color primaries and cropping */
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
}
static GstVaapiDecoderStatus
-parse_quant_matrix_ext(GstVaapiDecoderUnit *unit)
+parse_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder,
+ GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
- GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info;
- GstMpegVideoPacket * const packet = &pi->packet;
+ GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
+ GstMpegVideoQuantMatrixExt *quant_matrix;
+
+ if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->quant_matrix)) {
+ GST_ERROR("failed to allocate parser info for quantization matrix");
+ return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
+ }
+
+ quant_matrix = &priv->quant_matrix->data.quant_matrix;
- if (!gst_mpeg_video_parse_quant_matrix_extension(&pi->data.quant_matrix,
+ if (!gst_mpeg_video_parse_quant_matrix_extension(quant_matrix,
packet->data, packet->size, packet->offset)) {
GST_ERROR("failed to parse quant-matrix-extension");
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
}
+
+ gst_vaapi_decoder_unit_set_parsed_info(unit, quant_matrix, NULL);
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
- gst_vaapi_parser_info_mpeg2_replace(&priv->quant_matrix, unit->parsed_info);
priv->quant_matrix_changed = TRUE;
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
static GstVaapiDecoderStatus
-parse_gop(GstVaapiDecoderUnit *unit)
+parse_gop(GstVaapiDecoderMpeg2 *decoder,
+ GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
- GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info;
- GstMpegVideoPacket * const packet = &pi->packet;
+ GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
+ GstMpegVideoGop *gop;
+
+ if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->gop)) {
+ GST_ERROR("failed to allocate parser info for GOP");
+ return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
+ }
- if (!gst_mpeg_video_parse_gop(&pi->data.gop,
+ gop = &priv->gop->data.gop;
+
+ if (!gst_mpeg_video_parse_gop(gop,
packet->data, packet->size, packet->offset)) {
GST_ERROR("failed to parse GOP");
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
}
+
+ gst_vaapi_decoder_unit_set_parsed_info(unit, gop, NULL);
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
decode_gop(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
- GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info;
- GstMpegVideoGop * const gop = &pi->data.gop;
+ GstMpegVideoGop * const gop = unit->parsed_info;
priv->closed_gop = gop->closed_gop;
priv->broken_link = gop->broken_link;
}
static GstVaapiDecoderStatus
-parse_picture(GstVaapiDecoderUnit *unit)
+parse_picture(GstVaapiDecoderMpeg2 *decoder,
+ GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
- GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info;
- GstMpegVideoPacket * const packet = &pi->packet;
+ GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
+ GstMpegVideoPictureHdr *pic_hdr;
- if (!gst_mpeg_video_parse_picture_header(&pi->data.pic_hdr,
+ if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->pic_hdr)) {
+ GST_ERROR("failed to allocate parser info for picture header");
+ return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
+ }
+
+ pic_hdr = &priv->pic_hdr->data.pic_hdr;
+
+ if (!gst_mpeg_video_parse_picture_header(pic_hdr,
packet->data, packet->size, packet->offset)) {
GST_ERROR("failed to parse picture header");
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
}
+
+ gst_vaapi_decoder_unit_set_parsed_info(unit, pic_hdr, NULL);
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
static GstVaapiDecoderStatus
-parse_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit)
+parse_slice(GstVaapiDecoderMpeg2 *decoder,
+ GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
- GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info;
- GstMpegVideoSliceHdr * const slice_hdr = &pi->data.slice_hdr;
- GstMpegVideoPacket * const packet = &pi->packet;
+ GstMpegVideoSliceHdr *slice_hdr;
GstBitReader br;
gint mb_x, mb_y, mb_inc;
guint8 slice_vertical_position_extension;
guint8 extra_bit_slice, junk8;
+ if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->slice_hdr)) {
+ GST_ERROR("failed to allocate parser info for slice header");
+ return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
+ }
+
+ slice_hdr = &priv->slice_hdr->data.slice_hdr;
+
gst_bit_reader_init(&br, packet->data + packet->offset, packet->size);
if (priv->height > 2800)
READ_UINT8(&br, slice_vertical_position_extension, 3);
slice_hdr->slice_horizontal_position = mb_x;
slice_hdr->slice_vertical_position = mb_y;
+
+ gst_vaapi_decoder_unit_set_parsed_info(unit, slice_hdr, NULL);
return GST_VAAPI_DECODER_STATUS_SUCCESS;
failed:
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
- gst_vaapi_parser_info_mpeg2_replace(&priv->pic_hdr, unit->parsed_info);
gst_vaapi_parser_info_mpeg2_replace(&priv->pic_ext, NULL);
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
static GstVaapiDecoderStatus
-parse_picture_ext(GstVaapiDecoderUnit *unit)
+parse_picture_ext(GstVaapiDecoderMpeg2 *decoder,
+ GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
- GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info;
- GstMpegVideoPacket * const packet = &pi->packet;
+ GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
+ GstMpegVideoPictureExt *pic_ext;
+
+ if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->pic_ext)) {
+ GST_ERROR("failed to allocate parser info for picture extension");
+ return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
+ }
- if (!gst_mpeg_video_parse_picture_extension(&pi->data.pic_ext,
+ pic_ext = &priv->pic_ext->data.pic_ext;
+
+ if (!gst_mpeg_video_parse_picture_extension(pic_ext,
packet->data, packet->size, packet->offset)) {
GST_ERROR("failed to parse picture-extension");
return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
}
+
+ gst_vaapi_decoder_unit_set_parsed_info(unit, pic_ext, NULL);
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
static GstVaapiDecoderStatus
-decode_picture_ext(GstVaapiDecoderMpeg2 *decoder,
- GstVaapiDecoderUnit *unit)
+decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
- GstMpegVideoPictureExt *pic_ext;
-
- gst_vaapi_parser_info_mpeg2_replace(&priv->pic_ext, unit->parsed_info);
- pic_ext = &priv->pic_ext->data.pic_ext;
+ GstMpegVideoPictureExt * const pic_ext = unit->parsed_info;
if (priv->progressive_sequence && !pic_ext->progressive_frame) {
GST_WARNING("invalid interlaced frame in progressive sequence, fixing");
decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
- GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info;
GstVaapiPicture * const picture = priv->current_picture;
GstVaapiSlice *slice;
VASliceParameterBufferMPEG2 *slice_param;
- GstMpegVideoSliceHdr * const slice_hdr = &pi->data.slice_hdr;
+ GstMpegVideoSliceHdr * const slice_hdr = unit->parsed_info;
GST_DEBUG("slice %d (%u bytes)", slice_hdr->slice_vertical_position,
unit->size);
}
static GstVaapiDecoderStatus
-decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit)
+parse_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit,
+ GstMpegVideoPacket *packet)
+{
+ GstMpegVideoPacketTypeCode type;
+ GstMpegVideoPacketExtensionCode ext_type;
+ GstVaapiDecoderStatus status;
+
+ type = packet->type;
+ switch (type) {
+ case GST_MPEG_VIDEO_PACKET_PICTURE:
+ status = parse_picture(decoder, unit, packet);
+ break;
+ case GST_MPEG_VIDEO_PACKET_SEQUENCE:
+ status = parse_sequence(decoder, unit, packet);
+ break;
+ case GST_MPEG_VIDEO_PACKET_EXTENSION:
+ ext_type = packet->data[4] >> 4;
+ switch (ext_type) {
+ case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE:
+ status = parse_sequence_ext(decoder, unit, packet);
+ break;
+ case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY:
+ status = parse_sequence_display_ext(decoder, unit, packet);
+ break;
+ case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX:
+ status = parse_quant_matrix_ext(decoder, unit, packet);
+ break;
+ case GST_MPEG_VIDEO_PACKET_EXT_PICTURE:
+ status = parse_picture_ext(decoder, unit, packet);
+ break;
+ default:
+ status = GST_VAAPI_DECODER_STATUS_SUCCESS;
+ break;
+ }
+ break;
+ case GST_MPEG_VIDEO_PACKET_GOP:
+ status = parse_gop(decoder, unit, packet);
+ break;
+ default:
+ if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN &&
+ type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) {
+ status = parse_slice(decoder, unit, packet);
+ break;
+ }
+ status = GST_VAAPI_DECODER_STATUS_SUCCESS;
+ break;
+ }
+ return status;
+}
+
+static GstVaapiDecoderStatus
+decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit,
+ GstMpegVideoPacket *packet)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
- GstVaapiParserInfoMpeg2 * const pi = unit->parsed_info;
+ GstMpegVideoPacketTypeCode type;
+ GstMpegVideoPacketExtensionCode ext_type;
GstVaapiDecoderStatus status;
- switch (pi->packet.type) {
+ type = packet->type;
+ switch (type) {
case GST_MPEG_VIDEO_PACKET_PICTURE:
if (!priv->width || !priv->height)
goto unknown_picture_size;
status = decode_sequence(decoder, unit);
break;
case GST_MPEG_VIDEO_PACKET_EXTENSION:
- switch (pi->extension_type) {
+ ext_type = packet->data[4] >> 4;
+ switch (ext_type) {
case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE:
status = decode_sequence_ext(decoder, unit);
break;
break;
default:
// Ignore unknown start-code extensions
- GST_WARNING("unsupported packet extension type 0x%02x",
- pi->extension_type);
+ GST_WARNING("unsupported packet extension type 0x%02x", ext_type);
status = GST_VAAPI_DECODER_STATUS_SUCCESS;
break;
}
status = decode_gop(decoder, unit);
break;
default:
- if (pi->packet.type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN &&
- pi->packet.type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) {
+ if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN &&
+ type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) {
status = decode_slice(decoder, unit);
break;
}
- GST_WARNING("unsupported packet type 0x%02x", pi->packet.type);
+ GST_WARNING("unsupported packet type 0x%02x", type);
status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
break;
}
GstVaapiDecoderMpeg2 * const decoder =
GST_VAAPI_DECODER_MPEG2_CAST(base_decoder);
GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder);
- GstVaapiParserInfoMpeg2 *pi;
GstVaapiDecoderStatus status;
- GstMpegVideoPacket *packet;
+ GstMpegVideoPacketTypeCode type;
const guchar *buf;
guint32 start_code;
guint size, buf_size, flags;
unit->size = buf_size;
- pi = gst_vaapi_parser_info_mpeg2_new();
- if (!pi)
- return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
-
- gst_vaapi_decoder_unit_set_parsed_info(unit,
- pi, (GDestroyNotify)gst_vaapi_mini_object_unref);
-
- packet = &pi->packet;
- packet->data = buf;
- packet->size = buf_size;
- packet->offset = 4;
- packet->type = start_code & 0xff;
-
- /* Parse data */
- switch (packet->type) {
- case GST_MPEG_VIDEO_PACKET_SEQUENCE:
- status = parse_sequence(unit);
- break;
- case GST_MPEG_VIDEO_PACKET_GOP:
- status = parse_gop(unit);
- break;
- case GST_MPEG_VIDEO_PACKET_PICTURE:
- status = parse_picture(unit);
- break;
- case GST_MPEG_VIDEO_PACKET_EXTENSION:
- if (G_UNLIKELY(buf_size < 5)) {
- status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
- break;
- }
- pi->extension_type = buf[4] >> 4;
- switch (pi->extension_type) {
- case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE:
- status = parse_sequence_ext(unit);
- break;
- case GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY:
- status = parse_sequence_display_ext(unit);
- break;
- case GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX:
- status = parse_quant_matrix_ext(unit);
- break;
- case GST_MPEG_VIDEO_PACKET_EXT_PICTURE:
- status = parse_picture_ext(unit);
- break;
- default:
- status = GST_VAAPI_DECODER_STATUS_SUCCESS;
- break;
- }
- break;
- 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;
- break;
- }
- if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
- return status;
+ type = start_code & 0xff;
/* Check for start of new picture */
flags = 0;
- switch (packet->type) {
+ switch (type) {
case GST_MPEG_VIDEO_PACKET_SEQUENCE_END:
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END;
case GST_MPEG_VIDEO_PACKET_PICTURE:
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
break;
+ case GST_MPEG_VIDEO_PACKET_EXTENSION:
+ if (G_UNLIKELY(buf_size < 5))
+ return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
+ break;
default:
- if (packet->type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN &&
- packet->type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX)
+ if (type >= GST_MPEG_VIDEO_PACKET_SLICE_MIN &&
+ type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX)
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
// Ignore system start codes (PES headers)
- else if (packet->type >= 0xb9 && packet->type <= 0xff)
+ else if (type >= 0xb9 && type <= 0xff)
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
break;
}
GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags);
-
- pi->packet.data = NULL;
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
GstVaapiDecoderMpeg2 * const decoder =
GST_VAAPI_DECODER_MPEG2_CAST(base_decoder);
GstVaapiDecoderStatus status;
+ GstMpegVideoPacket packet;
status = ensure_decoder(decoder);
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
return status;
- return decode_unit(decoder, unit);
+
+ packet.data =
+ (GST_BUFFER_DATA(GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer) +
+ unit->offset);
+ packet.size = unit->size;
+ packet.type = packet.data[3];
+ packet.offset = 4;
+
+ status = parse_unit(decoder, unit, &packet);
+ if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
+ return status;
+ return decode_unit(decoder, unit, &packet);
}
static GstVaapiDecoderStatus