e.g. VC-1 sequence headers for elementary streams.
PROP_DISPLAY,
PROP_CODEC,
+ PROP_CODEC_DATA
};
static gboolean
return buffer;
}
+static inline void
+set_codec_data(GstVaapiDecoder *decoder, GstBuffer *codec_data)
+{
+ GstVaapiDecoderPrivate * const priv = decoder->priv;
+
+ if (priv->codec_data) {
+ gst_buffer_unref(priv->codec_data);
+ priv->codec_data = NULL;
+ }
+
+ if (codec_data)
+ priv->codec_data = gst_buffer_ref(codec_data);
+}
+
static void
clear_async_queue(GAsyncQueue *q)
{
gst_vaapi_decoder_stop(decoder);
+ set_codec_data(decoder, NULL);
+
if (priv->context) {
g_object_unref(priv->context);
priv->context = NULL;
case PROP_CODEC:
priv->codec = g_value_get_uint(value);
break;
+ case PROP_CODEC_DATA:
+ set_codec_data(GST_VAAPI_DECODER(object), gst_value_get_buffer(value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
case PROP_CODEC:
g_value_set_uint(value, priv->codec);
break;
+ case PROP_CODEC_DATA:
+ gst_value_set_buffer(value, priv->codec_data);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
"The codec handled by the decoder",
0, G_MAXINT32, 0,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_CODEC_DATA,
+ gst_param_spec_mini_object("codec-data",
+ "Codec data",
+ "Extra codec data",
+ GST_TYPE_BUFFER,
+ G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
}
static void
decoder->priv = priv;
priv->context = NULL;
priv->codec = 0;
+ priv->codec_data = NULL;
priv->fps_n = 1000;
priv->fps_d = 30;
priv->next_ts = 0;
}
if (priv->avctx) {
+ av_freep(&priv->avctx->extradata);
avcodec_close(priv->avctx);
priv->avctx = NULL;
}
GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(ffdecoder);
GstVaapiDecoderFfmpegPrivate * const priv = ffdecoder->priv;
GstVaapiCodec codec = GST_VAAPI_DECODER_CODEC(decoder);
+ GstBuffer * const codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
enum CodecID codec_id;
AVCodec *ffcodec;
return FALSE;
}
+ if (codec_data) {
+ const guchar *data = GST_BUFFER_DATA(codec_data);
+ const guint size = GST_BUFFER_SIZE(codec_data);
+ av_freep(&priv->avctx->extradata);
+ priv->avctx->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!priv->avctx->extradata)
+ return FALSE;
+ priv->avctx->extradata_size = size;
+ memcpy(priv->avctx->extradata, data, size);
+ memset(priv->avctx->extradata + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ }
+
if (!priv->vactx) {
priv->vactx = g_new(GstVaapiContextFfmpeg, 1);
if (!priv->vactx)
* gst_vaapi_decoder_ffmpeg_new:
* @display: a #GstVaapiDisplay
* @codec: a #GstVaapiCodec
+ * @codec_data: an optional #GstBuffer holding extra codec data, or %NULL
*
* Creates a new #GstVaapiDecoder with the specified @codec bound to
- * @display. If @codec is zero, the first video stream will be
- * selected. Otherwise, the first video stream matching @codec is
- * used, if any.
+ * @display. @codec_data holds extra codec data like sequence headers.
*
* Return value: the newly allocated #GstVaapiDecoder object
*/
GstVaapiDecoder *
-gst_vaapi_decoder_ffmpeg_new(GstVaapiDisplay *display, GstVaapiCodec codec)
+gst_vaapi_decoder_ffmpeg_new(
+ GstVaapiDisplay *display,
+ GstVaapiCodec codec,
+ GstBuffer *codec_data
+)
{
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
return g_object_new(GST_VAAPI_TYPE_DECODER_FFMPEG,
- "display", display,
- "codec", codec,
+ "display", display,
+ "codec", codec,
+ "codec-data", codec_data,
NULL);
}
gst_vaapi_decoder_ffmpeg_get_type(void);
GstVaapiDecoder *
-gst_vaapi_decoder_ffmpeg_new(GstVaapiDisplay *display, GstVaapiCodec codec);
+gst_vaapi_decoder_ffmpeg_new(
+ GstVaapiDisplay *display,
+ GstVaapiCodec codec,
+ GstBuffer *codec_data
+);
G_END_DECLS
#define GST_VAAPI_DECODER_CODEC(decoder) \
GST_VAAPI_DECODER_CAST(decoder)->priv->codec
+/**
+ * GST_VAAPI_DECODER_CODEC_DATA:
+ * @decoder: a #GstVaapiDecoder
+ *
+ * Macro that evaluates to the #GstBuffer holding optional codec data
+ * for @decoder.
+ * This is an internal macro that does not do any run-time type check.
+ */
+#undef GST_VAAPI_DECODER_CODEC_DATA
+#define GST_VAAPI_DECODER_CODEC_DATA(decoder) \
+ GST_VAAPI_DECODER_CAST(decoder)->priv->codec_data
+
/* End-of-Stream buffer */
#define GST_BUFFER_FLAG_EOS (GST_BUFFER_FLAG_LAST + 0)
GstVaapiDisplay *display;
GstVaapiContext *context;
GstVaapiCodec codec;
+ GstBuffer *codec_data;
guint fps_n;
guint fps_d;
GstClockTime next_ts;
g_error("could not create window");
codec->get_video_data(&vdata, &vdata_size);
- decoder = gst_vaapi_decoder_ffmpeg_new(display, codec->codec);
+ decoder = gst_vaapi_decoder_ffmpeg_new(display, codec->codec, NULL);
if (!decoder)
g_error("could not create FFmpeg decoder");