mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-28 04:31:06 +00:00
Fix H.264 decoding with AVC1 format bitstreams.
This commit is contained in:
parent
e7c9845374
commit
fcede672df
1 changed files with 43 additions and 34 deletions
|
@ -245,6 +245,7 @@ gst_vaapi_decoder_ffmpeg_close(GstVaapiDecoderFfmpeg *ffdecoder)
|
|||
|
||||
if (priv->avctx) {
|
||||
av_freep(&priv->avctx->extradata);
|
||||
priv->avctx->extradata_size = 0;
|
||||
avcodec_close(priv->avctx);
|
||||
}
|
||||
|
||||
|
@ -259,6 +260,7 @@ gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffe
|
|||
{
|
||||
GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv;
|
||||
GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(ffdecoder);
|
||||
GstBuffer * const codec_data = GST_VAAPI_DECODER_CODEC_DATA(ffdecoder);
|
||||
GstVaapiCodec codec = GST_VAAPI_DECODER_CODEC(ffdecoder);
|
||||
enum CodecID codec_id;
|
||||
AVCodec *ffcodec;
|
||||
|
@ -266,6 +268,13 @@ gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffe
|
|||
|
||||
gst_vaapi_decoder_ffmpeg_close(ffdecoder);
|
||||
|
||||
if (codec_data) {
|
||||
const guchar *data = GST_BUFFER_DATA(codec_data);
|
||||
const guint size = GST_BUFFER_SIZE(codec_data);
|
||||
if (!set_codec_data(priv->avctx, data, size))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
codec_id = get_codec_id_from_codec(codec);
|
||||
if (codec_id == CODEC_ID_NONE)
|
||||
return FALSE;
|
||||
|
@ -274,18 +283,20 @@ gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffe
|
|||
if (!ffcodec)
|
||||
return FALSE;
|
||||
|
||||
priv->pctx = av_parser_init(codec_id);
|
||||
if (!priv->pctx)
|
||||
return FALSE;
|
||||
|
||||
/* XXX: av_find_stream_info() does this and some codecs really
|
||||
want hard an extradata buffer for initialization (e.g. VC-1) */
|
||||
if (!priv->avctx->extradata && priv->pctx->parser->split) {
|
||||
const guchar *buf = GST_BUFFER_DATA(buffer);
|
||||
guint buf_size = GST_BUFFER_SIZE(buffer);
|
||||
buf_size = priv->pctx->parser->split(priv->avctx, buf, buf_size);
|
||||
if (buf_size > 0 && !set_codec_data(priv->avctx, buf, buf_size))
|
||||
if (codec_id != CODEC_ID_H264 || priv->avctx->extradata_size == 0) {
|
||||
priv->pctx = av_parser_init(codec_id);
|
||||
if (!priv->pctx)
|
||||
return FALSE;
|
||||
|
||||
/* XXX: av_find_stream_info() does this and some codecs really
|
||||
want hard an extradata buffer for initialization (e.g. VC-1) */
|
||||
if (!priv->avctx->extradata && priv->pctx->parser->split) {
|
||||
const guchar *buf = GST_BUFFER_DATA(buffer);
|
||||
guint buf_size = GST_BUFFER_SIZE(buffer);
|
||||
buf_size = priv->pctx->parser->split(priv->avctx, buf, buf_size);
|
||||
if (buf_size > 0 && !set_codec_data(priv->avctx, buf, buf_size))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK(display);
|
||||
|
@ -313,9 +324,7 @@ gst_vaapi_decoder_ffmpeg_destroy(GstVaapiDecoderFfmpeg *ffdecoder)
|
|||
static gboolean
|
||||
gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder)
|
||||
{
|
||||
GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(ffdecoder);
|
||||
GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv;
|
||||
GstBuffer * const codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
|
||||
|
||||
if (!priv->frame) {
|
||||
priv->frame = avcodec_alloc_frame();
|
||||
|
@ -329,13 +338,6 @@ gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (codec_data) {
|
||||
const guchar *data = GST_BUFFER_DATA(codec_data);
|
||||
const guint size = GST_BUFFER_SIZE(codec_data);
|
||||
if (!set_codec_data(priv->avctx, data, size))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!priv->vactx) {
|
||||
priv->vactx = g_new(GstVaapiContextFfmpeg, 1);
|
||||
if (!priv->vactx)
|
||||
|
@ -410,21 +412,28 @@ gst_vaapi_decoder_ffmpeg_decode(GstVaapiDecoder *decoder, GstBuffer *buffer)
|
|||
inbuf_size = GST_BUFFER_SIZE(buffer);
|
||||
inbuf_ts = GST_BUFFER_TIMESTAMP(buffer);
|
||||
|
||||
do {
|
||||
int parsed_size = av_parser_parse(
|
||||
priv->pctx,
|
||||
priv->avctx,
|
||||
&outbuf, &outbuf_size,
|
||||
inbuf, inbuf_size,
|
||||
inbuf_ts, inbuf_ts
|
||||
);
|
||||
got_frame = outbuf && outbuf_size > 0;
|
||||
if (priv->pctx) {
|
||||
do {
|
||||
int parsed_size = av_parser_parse(
|
||||
priv->pctx,
|
||||
priv->avctx,
|
||||
&outbuf, &outbuf_size,
|
||||
inbuf, inbuf_size,
|
||||
inbuf_ts, inbuf_ts
|
||||
);
|
||||
got_frame = outbuf && outbuf_size > 0;
|
||||
|
||||
if (parsed_size > 0) {
|
||||
inbuf += parsed_size;
|
||||
inbuf_size -= parsed_size;
|
||||
}
|
||||
} while (!got_frame && inbuf_size > 0);
|
||||
if (parsed_size > 0) {
|
||||
inbuf += parsed_size;
|
||||
inbuf_size -= parsed_size;
|
||||
}
|
||||
} while (!got_frame && inbuf_size > 0);
|
||||
}
|
||||
else {
|
||||
outbuf = inbuf;
|
||||
outbuf_size = inbuf_size;
|
||||
got_frame = inbuf && inbuf_size > 0;
|
||||
}
|
||||
|
||||
if (!got_frame && !GST_BUFFER_IS_EOS(buffer))
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
|
||||
|
|
Loading…
Reference in a new issue