mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
decoder: sanitize codec-data decoding.
Add a new GstVaapiDecoder::decode_codec_data() hook to actually decode codec-data in the decoder sub-class. Provide a common shared helper function to do the actual work and delegating further to the sub-class.
This commit is contained in:
parent
ba8a7ab6cd
commit
4009430bec
6 changed files with 75 additions and 43 deletions
|
@ -956,3 +956,28 @@ gst_vaapi_decoder_flush(GstVaapiDecoder *decoder)
|
||||||
|
|
||||||
return do_flush(decoder);
|
return do_flush(decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GstVaapiDecoderStatus
|
||||||
|
gst_vaapi_decoder_decode_codec_data(GstVaapiDecoder *decoder)
|
||||||
|
{
|
||||||
|
GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder);
|
||||||
|
GstBuffer * const codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
|
||||||
|
GstVaapiDecoderStatus status;
|
||||||
|
const guchar *buf;
|
||||||
|
guint buf_size;
|
||||||
|
|
||||||
|
if (!codec_data)
|
||||||
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* FIXME: add a meaningful error code? */
|
||||||
|
if (!klass->decode_codec_data)
|
||||||
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
buf = GST_BUFFER_DATA(codec_data);
|
||||||
|
buf_size = GST_BUFFER_SIZE(codec_data);
|
||||||
|
if (!buf || buf_size == 0)
|
||||||
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
status = klass->decode_codec_data(decoder, buf, buf_size);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
|
@ -124,6 +124,8 @@ struct _GstVaapiDecoderClass {
|
||||||
struct _GstVaapiDecoderUnit *unit);
|
struct _GstVaapiDecoderUnit *unit);
|
||||||
GstVaapiDecoderStatus (*end_frame)(GstVaapiDecoder *decoder);
|
GstVaapiDecoderStatus (*end_frame)(GstVaapiDecoder *decoder);
|
||||||
GstVaapiDecoderStatus (*flush)(GstVaapiDecoder *decoder);
|
GstVaapiDecoderStatus (*flush)(GstVaapiDecoder *decoder);
|
||||||
|
GstVaapiDecoderStatus (*decode_codec_data)(GstVaapiDecoder *decoder,
|
||||||
|
const guchar *buf, guint buf_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
GType
|
GType
|
||||||
|
|
|
@ -2763,24 +2763,20 @@ decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstVaapiDecoderStatus
|
static GstVaapiDecoderStatus
|
||||||
decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
|
gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder,
|
||||||
|
const guchar *buf, guint buf_size)
|
||||||
{
|
{
|
||||||
|
GstVaapiDecoderH264 * const decoder =
|
||||||
|
GST_VAAPI_DECODER_H264_CAST(base_decoder);
|
||||||
GstVaapiDecoderH264Private * const priv = decoder->priv;
|
GstVaapiDecoderH264Private * const priv = decoder->priv;
|
||||||
GstVaapiDecoderStatus status;
|
GstVaapiDecoderStatus status;
|
||||||
GstVaapiDecoderUnit unit;
|
GstVaapiDecoderUnit unit;
|
||||||
GstVaapiParserInfoH264 pi;
|
GstVaapiParserInfoH264 pi;
|
||||||
GstH264ParserResult result;
|
GstH264ParserResult result;
|
||||||
guchar *buf;
|
|
||||||
guint buf_size;
|
|
||||||
guint i, ofs, num_sps, num_pps;
|
guint i, ofs, num_sps, num_pps;
|
||||||
|
|
||||||
unit.parsed_info = π
|
unit.parsed_info = π
|
||||||
|
|
||||||
buf = GST_BUFFER_DATA(buffer);
|
|
||||||
buf_size = GST_BUFFER_SIZE(buffer);
|
|
||||||
if (!buf || buf_size == 0)
|
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
if (buf_size < 8)
|
if (buf_size < 8)
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
|
return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
|
||||||
|
|
||||||
|
@ -2836,7 +2832,6 @@ ensure_decoder(GstVaapiDecoderH264 *decoder)
|
||||||
{
|
{
|
||||||
GstVaapiDecoderH264Private * const priv = decoder->priv;
|
GstVaapiDecoderH264Private * const priv = decoder->priv;
|
||||||
GstVaapiDecoderStatus status;
|
GstVaapiDecoderStatus status;
|
||||||
GstBuffer *codec_data;
|
|
||||||
|
|
||||||
g_return_val_if_fail(priv->is_constructed,
|
g_return_val_if_fail(priv->is_constructed,
|
||||||
GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
|
GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
|
||||||
|
@ -2846,12 +2841,10 @@ ensure_decoder(GstVaapiDecoderH264 *decoder)
|
||||||
if (!priv->is_opened)
|
if (!priv->is_opened)
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
|
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
|
||||||
|
|
||||||
codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
|
status = gst_vaapi_decoder_decode_codec_data(
|
||||||
if (codec_data) {
|
GST_VAAPI_DECODER_CAST(decoder));
|
||||||
status = decode_codec_data(decoder, codec_data);
|
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
return status;
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -3091,6 +3084,9 @@ gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass)
|
||||||
decoder_class->start_frame = gst_vaapi_decoder_h264_start_frame;
|
decoder_class->start_frame = gst_vaapi_decoder_h264_start_frame;
|
||||||
decoder_class->end_frame = gst_vaapi_decoder_h264_end_frame;
|
decoder_class->end_frame = gst_vaapi_decoder_h264_end_frame;
|
||||||
decoder_class->flush = gst_vaapi_decoder_h264_flush;
|
decoder_class->flush = gst_vaapi_decoder_h264_flush;
|
||||||
|
|
||||||
|
decoder_class->decode_codec_data =
|
||||||
|
gst_vaapi_decoder_h264_decode_codec_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -41,6 +41,9 @@ G_DEFINE_TYPE(GstVaapiDecoderMpeg4,
|
||||||
gst_vaapi_decoder_mpeg4,
|
gst_vaapi_decoder_mpeg4,
|
||||||
GST_VAAPI_TYPE_DECODER)
|
GST_VAAPI_TYPE_DECODER)
|
||||||
|
|
||||||
|
#define GST_VAAPI_DECODER_MPEG4_CAST(decoder) \
|
||||||
|
((GstVaapiDecoderMpeg4 *)(decoder))
|
||||||
|
|
||||||
#define GST_VAAPI_DECODER_MPEG4_GET_PRIVATE(obj) \
|
#define GST_VAAPI_DECODER_MPEG4_GET_PRIVATE(obj) \
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
|
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
|
||||||
GST_VAAPI_TYPE_DECODER_MPEG4, \
|
GST_VAAPI_TYPE_DECODER_MPEG4, \
|
||||||
|
@ -921,14 +924,15 @@ decode_buffer(GstVaapiDecoderMpeg4 *decoder, const guchar *buf, guint buf_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstVaapiDecoderStatus
|
static GstVaapiDecoderStatus
|
||||||
decode_codec_data(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer)
|
gst_vaapi_decoder_mpeg4_decode_codec_data(GstVaapiDecoder *base_decoder,
|
||||||
|
const guchar *_buf, guint _buf_size)
|
||||||
{
|
{
|
||||||
|
GstVaapiDecoderMpeg4 * const decoder =
|
||||||
|
GST_VAAPI_DECODER_MPEG4_CAST(base_decoder);
|
||||||
GstVaapiDecoderStatus status;
|
GstVaapiDecoderStatus status;
|
||||||
guchar *buf, *_buf;
|
guchar *buf;
|
||||||
guint pos, buf_size, _buf_size;
|
guint pos, buf_size;
|
||||||
|
|
||||||
_buf = GST_BUFFER_DATA(buffer);
|
|
||||||
_buf_size = GST_BUFFER_SIZE(buffer);
|
|
||||||
// add additional 0x000001b2 to enclose the last header
|
// add additional 0x000001b2 to enclose the last header
|
||||||
buf_size = _buf_size + 4;
|
buf_size = _buf_size + 4;
|
||||||
buf = malloc(buf_size);
|
buf = malloc(buf_size);
|
||||||
|
@ -965,7 +969,6 @@ ensure_decoder(GstVaapiDecoderMpeg4 *decoder)
|
||||||
{
|
{
|
||||||
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
|
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
|
||||||
GstVaapiDecoderStatus status;
|
GstVaapiDecoderStatus status;
|
||||||
GstBuffer *codec_data;
|
|
||||||
|
|
||||||
g_return_val_if_fail(priv->is_constructed,
|
g_return_val_if_fail(priv->is_constructed,
|
||||||
GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
|
GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
|
||||||
|
@ -975,12 +978,10 @@ ensure_decoder(GstVaapiDecoderMpeg4 *decoder)
|
||||||
if (!priv->is_opened)
|
if (!priv->is_opened)
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
|
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
|
||||||
|
|
||||||
codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
|
status = gst_vaapi_decoder_decode_codec_data(
|
||||||
if (codec_data) {
|
GST_VAAPI_DECODER_CAST(decoder));
|
||||||
status = decode_codec_data(decoder, codec_data);
|
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
return status;
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1137,6 +1138,9 @@ gst_vaapi_decoder_mpeg4_class_init(GstVaapiDecoderMpeg4Class *klass)
|
||||||
|
|
||||||
decoder_class->parse = gst_vaapi_decoder_mpeg4_parse;
|
decoder_class->parse = gst_vaapi_decoder_mpeg4_parse;
|
||||||
decoder_class->decode = gst_vaapi_decoder_mpeg4_decode;
|
decoder_class->decode = gst_vaapi_decoder_mpeg4_decode;
|
||||||
|
|
||||||
|
decoder_class->decode_codec_data =
|
||||||
|
gst_vaapi_decoder_mpeg4_decode_codec_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -222,6 +222,10 @@ G_GNUC_INTERNAL
|
||||||
GstVaapiDecoderStatus
|
GstVaapiDecoderStatus
|
||||||
gst_vaapi_decoder_check_status(GstVaapiDecoder *decoder);
|
gst_vaapi_decoder_check_status(GstVaapiDecoder *decoder);
|
||||||
|
|
||||||
|
G_GNUC_INTERNAL
|
||||||
|
GstVaapiDecoderStatus
|
||||||
|
gst_vaapi_decoder_decode_codec_data(GstVaapiDecoder *decoder);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* GST_VAAPI_DECODER_PRIV_H */
|
#endif /* GST_VAAPI_DECODER_PRIV_H */
|
||||||
|
|
|
@ -42,6 +42,9 @@ G_DEFINE_TYPE(GstVaapiDecoderVC1,
|
||||||
gst_vaapi_decoder_vc1,
|
gst_vaapi_decoder_vc1,
|
||||||
GST_VAAPI_TYPE_DECODER)
|
GST_VAAPI_TYPE_DECODER)
|
||||||
|
|
||||||
|
#define GST_VAAPI_DECODER_VC1_CAST(decoder) \
|
||||||
|
((GstVaapiDecoderVC1 *)(decoder))
|
||||||
|
|
||||||
#define GST_VAAPI_DECODER_VC1_GET_PRIVATE(obj) \
|
#define GST_VAAPI_DECODER_VC1_GET_PRIVATE(obj) \
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
|
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
|
||||||
GST_VAAPI_TYPE_DECODER_VC1, \
|
GST_VAAPI_TYPE_DECODER_VC1, \
|
||||||
|
@ -1061,8 +1064,11 @@ decode_buffer(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstVaapiDecoderStatus
|
static GstVaapiDecoderStatus
|
||||||
decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer)
|
gst_vaapi_decoder_vc1_decode_codec_data(GstVaapiDecoder *base_decoder,
|
||||||
|
const guchar *buf, guint buf_size)
|
||||||
{
|
{
|
||||||
|
GstVaapiDecoderVC1 * const decoder =
|
||||||
|
GST_VAAPI_DECODER_VC1_CAST(base_decoder);
|
||||||
GstVaapiDecoderVC1Private * const priv = decoder->priv;
|
GstVaapiDecoderVC1Private * const priv = decoder->priv;
|
||||||
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
|
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
|
||||||
GstVaapiDecoderStatus status;
|
GstVaapiDecoderStatus status;
|
||||||
|
@ -1070,16 +1076,12 @@ decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer)
|
||||||
GstVC1BDU ebdu;
|
GstVC1BDU ebdu;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
guchar *buf;
|
guint ofs;
|
||||||
guint buf_size, ofs;
|
|
||||||
gint width, height;
|
gint width, height;
|
||||||
guint32 format;
|
guint32 format;
|
||||||
gint version;
|
gint version;
|
||||||
|
|
||||||
buf = GST_BUFFER_DATA(buffer);
|
priv->has_codec_data = TRUE;
|
||||||
buf_size = GST_BUFFER_SIZE(buffer);
|
|
||||||
if (!buf || buf_size == 0)
|
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
width = GST_VAAPI_DECODER_WIDTH(decoder);
|
width = GST_VAAPI_DECODER_WIDTH(decoder);
|
||||||
height = GST_VAAPI_DECODER_HEIGHT(decoder);
|
height = GST_VAAPI_DECODER_HEIGHT(decoder);
|
||||||
|
@ -1109,7 +1111,7 @@ decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer)
|
||||||
ebdu.size = buf_size;
|
ebdu.size = buf_size;
|
||||||
ebdu.sc_offset = 0;
|
ebdu.sc_offset = 0;
|
||||||
ebdu.offset = 0;
|
ebdu.offset = 0;
|
||||||
ebdu.data = buf;
|
ebdu.data = (guint8 *)buf;
|
||||||
return decode_ebdu(decoder, &ebdu);
|
return decode_ebdu(decoder, &ebdu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1149,7 +1151,6 @@ ensure_decoder(GstVaapiDecoderVC1 *decoder)
|
||||||
{
|
{
|
||||||
GstVaapiDecoderVC1Private * const priv = decoder->priv;
|
GstVaapiDecoderVC1Private * const priv = decoder->priv;
|
||||||
GstVaapiDecoderStatus status;
|
GstVaapiDecoderStatus status;
|
||||||
GstBuffer *codec_data;
|
|
||||||
|
|
||||||
g_return_val_if_fail(priv->is_constructed,
|
g_return_val_if_fail(priv->is_constructed,
|
||||||
GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
|
GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
|
||||||
|
@ -1159,13 +1160,10 @@ ensure_decoder(GstVaapiDecoderVC1 *decoder)
|
||||||
if (!priv->is_opened)
|
if (!priv->is_opened)
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
|
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
|
||||||
|
|
||||||
codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
|
status = gst_vaapi_decoder_decode_codec_data(
|
||||||
if (codec_data) {
|
GST_VAAPI_DECODER_CAST(decoder));
|
||||||
status = decode_codec_data(decoder, codec_data);
|
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
return status;
|
||||||
return status;
|
|
||||||
priv->has_codec_data = TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1355,6 +1353,9 @@ gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass)
|
||||||
decoder_class->start_frame = gst_vaapi_decoder_vc1_start_frame;
|
decoder_class->start_frame = gst_vaapi_decoder_vc1_start_frame;
|
||||||
decoder_class->end_frame = gst_vaapi_decoder_vc1_end_frame;
|
decoder_class->end_frame = gst_vaapi_decoder_vc1_end_frame;
|
||||||
decoder_class->flush = gst_vaapi_decoder_vc1_flush;
|
decoder_class->flush = gst_vaapi_decoder_vc1_flush;
|
||||||
|
|
||||||
|
decoder_class->decode_codec_data =
|
||||||
|
gst_vaapi_decoder_vc1_decode_codec_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue