static gboolean gst_vaapi_decoder_vc1_create(GstVaapiDecoderVC1 *decoder) { if (!GST_VAAPI_DECODER_CODEC(decoder)) return FALSE; return TRUE; }
static gboolean gst_vaapi_decoder_ffmpeg_create(GstVaapiDecoderFfmpeg *ffdecoder) { GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv; if (!GST_VAAPI_DECODER_CODEC(ffdecoder)) return FALSE; if (!priv->frame) { priv->frame = avcodec_alloc_frame(); if (!priv->frame) return FALSE; } if (!priv->avctx) { priv->avctx = avcodec_alloc_context(); if (!priv->avctx) return FALSE; } if (!priv->vactx) { priv->vactx = g_new(GstVaapiContextFfmpeg, 1); if (!priv->vactx) return FALSE; } memset(&priv->vactx->base, 0, sizeof(priv->vactx->base)); priv->vactx->decoder = ffdecoder; priv->avctx->hwaccel_context = priv->vactx; priv->avctx->get_format = gst_vaapi_decoder_ffmpeg_get_format; priv->avctx->get_buffer = gst_vaapi_decoder_ffmpeg_get_buffer; priv->avctx->reget_buffer = gst_vaapi_decoder_ffmpeg_reget_buffer; priv->avctx->release_buffer = gst_vaapi_decoder_ffmpeg_release_buffer; priv->avctx->thread_count = 1; priv->avctx->draw_horiz_band = NULL; priv->avctx->slice_flags = SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD; return TRUE; }
static gboolean gst_vaapi_decoder_ffmpeg_open(GstVaapiDecoderFfmpeg *ffdecoder, GstBuffer *buffer) { 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; gboolean try_parser, need_parser; int ret; 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; ffcodec = avcodec_find_decoder(codec_id); if (!ffcodec) return FALSE; switch (codec_id) { case CODEC_ID_H264: /* For AVC1 formats, sequence headers are in extradata and input encoded buffers represent the whole NAL unit */ try_parser = priv->avctx->extradata_size == 0; need_parser = try_parser; break; case CODEC_ID_WMV3: /* There is no WMV3 parser in FFmpeg */ try_parser = FALSE; need_parser = FALSE; break; case CODEC_ID_VC1: /* For VC-1, sequence headers ae in extradata and input encoded buffers represent the whole slice */ try_parser = priv->avctx->extradata_size == 0; need_parser = FALSE; break; default: try_parser = TRUE; need_parser = TRUE; break; } if (try_parser) { priv->pctx = av_parser_init(codec_id); if (!priv->pctx && need_parser) 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 && 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; } if (priv->pctx && !need_parser) { av_parser_close(priv->pctx); priv->pctx = NULL; } /* Use size information from the demuxer, whenever available */ priv->avctx->coded_width = GST_VAAPI_DECODER_WIDTH(ffdecoder); priv->avctx->coded_height = GST_VAAPI_DECODER_HEIGHT(ffdecoder); GST_VAAPI_DISPLAY_LOCK(display); ret = avcodec_open(priv->avctx, ffcodec); GST_VAAPI_DISPLAY_UNLOCK(display); if (ret < 0) return FALSE; return TRUE; }