#define GST_VAAPI_DECODE_FLOW_PARSE_DATA GST_FLOW_CUSTOM_SUCCESS_2
-GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapidecode);
+GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapidecode);
#define GST_CAT_DEFAULT gst_debug_vaapidecode
/* Default templates */
#define GST_CAPS_CODEC(CODEC) CODEC "; "
+/* *INDENT-OFF* */
static const char gst_vaapidecode_sink_caps_str[] =
GST_CAPS_CODEC("video/mpeg, mpegversion=2, systemstream=(boolean)false")
GST_CAPS_CODEC("video/mpeg, mpegversion=4")
gst_vaapidecode,
GST_TYPE_VIDEO_DECODER,
GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES)
+/* *INDENT-ON* */
-static gboolean
-gst_vaapidecode_update_src_caps(GstVaapiDecode *decode);
+static gboolean gst_vaapidecode_update_src_caps (GstVaapiDecode * decode);
static gboolean
-gst_vaapi_decode_input_state_replace(GstVaapiDecode *decode,
- const GstVideoCodecState *new_state);
+gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode,
+ const GstVideoCodecState * new_state);
static void
-gst_vaapi_decoder_state_changed(GstVaapiDecoder *decoder,
- const GstVideoCodecState *codec_state, gpointer user_data)
+gst_vaapi_decoder_state_changed (GstVaapiDecoder * decoder,
+ const GstVideoCodecState * codec_state, gpointer user_data)
{
- GstVaapiDecode * const decode = GST_VAAPIDECODE(user_data);
- GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode);
- GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(vdec);
-
- g_assert(decode->decoder == decoder);
-
- if (!gst_vaapi_decode_input_state_replace(decode, codec_state))
- return;
- if (!gst_vaapidecode_update_src_caps(decode))
- return;
- if (!gst_video_decoder_negotiate(vdec))
- return;
- if (!gst_vaapi_plugin_base_set_caps(plugin, NULL, decode->srcpad_caps))
- return;
+ GstVaapiDecode *const decode = GST_VAAPIDECODE (user_data);
+ GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode);
+ GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec);
+
+ g_assert (decode->decoder == decoder);
+
+ if (!gst_vaapi_decode_input_state_replace (decode, codec_state))
+ return;
+ if (!gst_vaapidecode_update_src_caps (decode))
+ return;
+ if (!gst_video_decoder_negotiate (vdec))
+ return;
+ if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps))
+ return;
}
static gboolean
-gst_vaapi_decode_input_state_replace(GstVaapiDecode *decode,
- const GstVideoCodecState *new_state)
+gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode,
+ const GstVideoCodecState * new_state)
{
- if (decode->input_state) {
- if (new_state) {
- const GstCaps *curcaps = decode->input_state->caps;
- if (gst_caps_is_always_compatible(curcaps, new_state->caps))
- return FALSE;
- }
- gst_video_codec_state_unref(decode->input_state);
+ if (decode->input_state) {
+ if (new_state) {
+ const GstCaps *curcaps = decode->input_state->caps;
+ if (gst_caps_is_always_compatible (curcaps, new_state->caps))
+ return FALSE;
}
+ gst_video_codec_state_unref (decode->input_state);
+ }
- if (new_state)
- decode->input_state = gst_video_codec_state_ref
- ((GstVideoCodecState*) new_state);
- else
- decode->input_state = NULL;
+ if (new_state)
+ decode->input_state = gst_video_codec_state_ref
+ ((GstVideoCodecState *) new_state);
+ else
+ decode->input_state = NULL;
- return TRUE;
+ return TRUE;
}
static inline gboolean
-gst_vaapidecode_update_sink_caps(GstVaapiDecode *decode, GstCaps *caps)
+gst_vaapidecode_update_sink_caps (GstVaapiDecode * decode, GstCaps * caps)
{
- gst_caps_replace(&decode->sinkpad_caps, caps);
- return TRUE;
+ gst_caps_replace (&decode->sinkpad_caps, caps);
+ return TRUE;
}
static gboolean
-gst_vaapidecode_update_src_caps(GstVaapiDecode *decode)
+gst_vaapidecode_update_src_caps (GstVaapiDecode * decode)
{
- GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode);
- GstVideoCodecState *state, *ref_state;
- GstVideoInfo *vi;
- GstVideoFormat format = GST_VIDEO_FORMAT_I420;
+ GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode);
+ GstVideoCodecState *state, *ref_state;
+ GstVideoInfo *vi;
+ GstVideoFormat format = GST_VIDEO_FORMAT_I420;
- if (!decode->input_state)
- return FALSE;
+ if (!decode->input_state)
+ return FALSE;
- ref_state = decode->input_state;
+ ref_state = decode->input_state;
#if GST_CHECK_VERSION(1,1,0)
- GstCapsFeatures *features = NULL;
- GstVaapiCapsFeature feature;
+ GstCapsFeatures *features = NULL;
+ GstVaapiCapsFeature feature;
- feature = gst_vaapi_find_preferred_caps_feature(
- GST_VIDEO_DECODER_SRC_PAD(vdec),
- GST_VIDEO_INFO_FORMAT(&ref_state->info), &format);
+ feature =
+ gst_vaapi_find_preferred_caps_feature (GST_VIDEO_DECODER_SRC_PAD (vdec),
+ GST_VIDEO_INFO_FORMAT (&ref_state->info), &format);
- if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED)
- return FALSE;
+ if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED)
+ return FALSE;
- switch (feature) {
+ switch (feature) {
#if (USE_GLX || USE_EGL)
case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META:
- if (decode->has_texture_upload_meta)
- features = gst_caps_features_new(
- GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL);
- else
- format = GST_VIDEO_FORMAT_I420;
- break;
+ if (decode->has_texture_upload_meta)
+ features =
+ gst_caps_features_new
+ (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL);
+ else
+ format = GST_VIDEO_FORMAT_I420;
+ break;
#endif
#if GST_CHECK_VERSION(1,5,0)
case GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE:
- features = gst_caps_features_new(
- GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, NULL);
- break;
+ features =
+ gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, NULL);
+ break;
#endif
default:
- break;
- }
+ break;
+ }
#endif
- state = gst_video_decoder_set_output_state(vdec, format,
- ref_state->info.width, ref_state->info.height,
- (GstVideoCodecState *)ref_state);
- if (!state || state->info.width == 0 || state->info.height == 0)
- return FALSE;
+ state = gst_video_decoder_set_output_state (vdec, format,
+ ref_state->info.width, ref_state->info.height,
+ (GstVideoCodecState *) ref_state);
+ if (!state || state->info.width == 0 || state->info.height == 0)
+ return FALSE;
- vi = &state->info;
+ vi = &state->info;
#if GST_CHECK_VERSION(1,1,0)
- state->caps = gst_video_info_to_caps(vi);
- if (features)
- gst_caps_set_features(state->caps, 0, features);
+ state->caps = gst_video_info_to_caps (vi);
+ if (features)
+ gst_caps_set_features (state->caps, 0, features);
#else
- /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not
- reconstruct suitable caps for "encoded" video formats */
- state->caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME);
- if (!state->caps)
- return FALSE;
-
- gst_caps_set_simple(state->caps,
- "type", G_TYPE_STRING, "vaapi",
- "opengl", G_TYPE_BOOLEAN, USE_GLX,
- "width", G_TYPE_INT, vi->width,
- "height", G_TYPE_INT, vi->height,
- "framerate", GST_TYPE_FRACTION, vi->fps_n, vi->fps_d,
- "pixel-aspect-ratio", GST_TYPE_FRACTION, vi->par_n, vi->par_d,
- NULL);
-
- gst_caps_set_interlaced(state->caps, vi);
+ /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not
+ reconstruct suitable caps for "encoded" video formats */
+ state->caps = gst_caps_from_string (GST_VAAPI_SURFACE_CAPS_NAME);
+ if (!state->caps)
+ return FALSE;
+
+ gst_caps_set_simple (state->caps,
+ "type", G_TYPE_STRING, "vaapi",
+ "opengl", G_TYPE_BOOLEAN, USE_GLX,
+ "width", G_TYPE_INT, vi->width,
+ "height", G_TYPE_INT, vi->height,
+ "framerate", GST_TYPE_FRACTION, vi->fps_n, vi->fps_d,
+ "pixel-aspect-ratio", GST_TYPE_FRACTION, vi->par_n, vi->par_d, NULL);
+
+ gst_caps_set_interlaced (state->caps, vi);
#endif
- gst_caps_replace(&decode->srcpad_caps, state->caps);
- gst_video_codec_state_unref(state);
- return TRUE;
+ gst_caps_replace (&decode->srcpad_caps, state->caps);
+ gst_video_codec_state_unref (state);
+ return TRUE;
}
static void
-gst_vaapidecode_release(GstVaapiDecode *decode)
+gst_vaapidecode_release (GstVaapiDecode * decode)
{
- g_mutex_lock(&decode->surface_ready_mutex);
- g_cond_signal(&decode->surface_ready);
- g_mutex_unlock(&decode->surface_ready_mutex);
+ g_mutex_lock (&decode->surface_ready_mutex);
+ g_cond_signal (&decode->surface_ready);
+ g_mutex_unlock (&decode->surface_ready_mutex);
}
static GstFlowReturn
-gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec,
- GstVideoCodecFrame *out_frame)
+gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec,
+ GstVideoCodecFrame * out_frame)
{
- GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
- GstVaapiSurfaceProxy *proxy;
- GstFlowReturn ret;
+ GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec);
+ GstVaapiSurfaceProxy *proxy;
+ GstFlowReturn ret;
#if GST_CHECK_VERSION(1,0,0)
- const GstVaapiRectangle *crop_rect;
- GstVaapiVideoMeta *meta;
- guint flags;
+ const GstVaapiRectangle *crop_rect;
+ GstVaapiVideoMeta *meta;
+ guint flags;
#endif
- if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(out_frame)) {
- proxy = gst_video_codec_frame_get_user_data(out_frame);
+ if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (out_frame)) {
+ proxy = gst_video_codec_frame_get_user_data (out_frame);
- gst_vaapi_surface_proxy_set_destroy_notify(proxy,
- (GDestroyNotify)gst_vaapidecode_release, decode);
+ gst_vaapi_surface_proxy_set_destroy_notify (proxy,
+ (GDestroyNotify) gst_vaapidecode_release, decode);
#if GST_CHECK_VERSION(1,0,0)
- ret = gst_video_decoder_allocate_output_frame(vdec, out_frame);
- if (ret != GST_FLOW_OK)
- goto error_create_buffer;
-
- meta = gst_buffer_get_vaapi_video_meta(out_frame->output_buffer);
- if (!meta)
- goto error_get_meta;
- gst_vaapi_video_meta_set_surface_proxy(meta, proxy);
-
- flags = gst_vaapi_surface_proxy_get_flags(proxy);
- if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED) {
- guint out_flags = GST_VIDEO_BUFFER_FLAG_INTERLACED;
- if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF)
- out_flags |= GST_VIDEO_BUFFER_FLAG_TFF;
- if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF)
- out_flags |= GST_VIDEO_BUFFER_FLAG_RFF;
- if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD)
- out_flags |= GST_VIDEO_BUFFER_FLAG_ONEFIELD;
- GST_BUFFER_FLAG_SET(out_frame->output_buffer, out_flags);
- }
-
- crop_rect = gst_vaapi_surface_proxy_get_crop_rect(proxy);
- if (crop_rect) {
- GstVideoCropMeta * const crop_meta =
- gst_buffer_add_video_crop_meta(out_frame->output_buffer);
- if (crop_meta) {
- crop_meta->x = crop_rect->x;
- crop_meta->y = crop_rect->y;
- crop_meta->width = crop_rect->width;
- crop_meta->height = crop_rect->height;
- }
- }
+ ret = gst_video_decoder_allocate_output_frame (vdec, out_frame);
+ if (ret != GST_FLOW_OK)
+ goto error_create_buffer;
+
+ meta = gst_buffer_get_vaapi_video_meta (out_frame->output_buffer);
+ if (!meta)
+ goto error_get_meta;
+ gst_vaapi_video_meta_set_surface_proxy (meta, proxy);
+
+ flags = gst_vaapi_surface_proxy_get_flags (proxy);
+ if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED) {
+ guint out_flags = GST_VIDEO_BUFFER_FLAG_INTERLACED;
+ if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF)
+ out_flags |= GST_VIDEO_BUFFER_FLAG_TFF;
+ if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF)
+ out_flags |= GST_VIDEO_BUFFER_FLAG_RFF;
+ if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD)
+ out_flags |= GST_VIDEO_BUFFER_FLAG_ONEFIELD;
+ GST_BUFFER_FLAG_SET (out_frame->output_buffer, out_flags);
+ }
+ crop_rect = gst_vaapi_surface_proxy_get_crop_rect (proxy);
+ if (crop_rect) {
+ GstVideoCropMeta *const crop_meta =
+ gst_buffer_add_video_crop_meta (out_frame->output_buffer);
+ if (crop_meta) {
+ crop_meta->x = crop_rect->x;
+ crop_meta->y = crop_rect->y;
+ crop_meta->width = crop_rect->width;
+ crop_meta->height = crop_rect->height;
+ }
+ }
#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL)
- if (decode->has_texture_upload_meta)
- gst_buffer_ensure_texture_upload_meta(out_frame->output_buffer);
+ if (decode->has_texture_upload_meta)
+ gst_buffer_ensure_texture_upload_meta (out_frame->output_buffer);
#endif
#else
- out_frame->output_buffer =
- gst_vaapi_video_buffer_new_with_surface_proxy(proxy);
- if (!out_frame->output_buffer)
- goto error_create_buffer;
+ out_frame->output_buffer =
+ gst_vaapi_video_buffer_new_with_surface_proxy (proxy);
+ if (!out_frame->output_buffer)
+ goto error_create_buffer;
#endif
- }
+ }
- ret = gst_video_decoder_finish_frame(vdec, out_frame);
- if (ret != GST_FLOW_OK)
- goto error_commit_buffer;
+ ret = gst_video_decoder_finish_frame (vdec, out_frame);
+ if (ret != GST_FLOW_OK)
+ goto error_commit_buffer;
- gst_video_codec_frame_unref(out_frame);
- return GST_FLOW_OK;
+ gst_video_codec_frame_unref (out_frame);
+ return GST_FLOW_OK;
- /* ERRORS */
+ /* ERRORS */
error_create_buffer:
- {
- const GstVaapiID surface_id =
- gst_vaapi_surface_get_id(GST_VAAPI_SURFACE_PROXY_SURFACE(proxy));
-
- GST_ELEMENT_ERROR(vdec, STREAM, FAILED,
- ("Failed to create sink buffer"),
- ("video sink failed to create video buffer for proxy'ed "
- "surface %" GST_VAAPI_ID_FORMAT,
- GST_VAAPI_ID_ARGS(surface_id)));
- gst_video_decoder_drop_frame(vdec, out_frame);
- gst_video_codec_frame_unref(out_frame);
- return GST_FLOW_ERROR;
- }
+ {
+ const GstVaapiID surface_id =
+ gst_vaapi_surface_get_id (GST_VAAPI_SURFACE_PROXY_SURFACE (proxy));
+
+ GST_ELEMENT_ERROR (vdec, STREAM, FAILED,
+ ("Failed to create sink buffer"),
+ ("video sink failed to create video buffer for proxy'ed "
+ "surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)));
+ gst_video_decoder_drop_frame (vdec, out_frame);
+ gst_video_codec_frame_unref (out_frame);
+ return GST_FLOW_ERROR;
+ }
#if GST_CHECK_VERSION(1,0,0)
error_get_meta:
- {
- GST_ELEMENT_ERROR(vdec, STREAM, FAILED,
- ("Failed to get vaapi video meta attached to video buffer"),
- ("Failed to get vaapi video meta attached to video buffer"));
- gst_video_decoder_drop_frame(vdec, out_frame);
- gst_video_codec_frame_unref(out_frame);
- return GST_FLOW_ERROR;
- }
+ {
+ GST_ELEMENT_ERROR (vdec, STREAM, FAILED,
+ ("Failed to get vaapi video meta attached to video buffer"),
+ ("Failed to get vaapi video meta attached to video buffer"));
+ gst_video_decoder_drop_frame (vdec, out_frame);
+ gst_video_codec_frame_unref (out_frame);
+ return GST_FLOW_ERROR;
+ }
#endif
error_commit_buffer:
- {
- if (ret != GST_FLOW_FLUSHING)
- GST_ERROR("video sink rejected the video buffer (error: %s [%d])",
- gst_flow_get_name (ret), ret);
- gst_video_codec_frame_unref(out_frame);
- return ret;
- }
+ {
+ if (ret != GST_FLOW_FLUSHING)
+ GST_ERROR ("video sink rejected the video buffer (error: %s [%d])",
+ gst_flow_get_name (ret), ret);
+ gst_video_codec_frame_unref (out_frame);
+ return ret;
+ }
}
static GstFlowReturn
-gst_vaapidecode_push_all_decoded_frames(GstVaapiDecode *decode)
+gst_vaapidecode_push_all_decoded_frames (GstVaapiDecode * decode)
{
- GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode);
- GstVaapiDecoderStatus status;
- GstVideoCodecFrame *out_frame;
- GstFlowReturn ret;
-
- for (;;) {
- status = gst_vaapi_decoder_get_frame(decode->decoder, &out_frame);
-
- switch (status) {
- case GST_VAAPI_DECODER_STATUS_SUCCESS:
- ret = gst_vaapidecode_push_decoded_frame(vdec, out_frame);
- if (ret != GST_FLOW_OK)
- return ret;
- break;
- case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA:
- return GST_FLOW_OK;
- default:
- GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding failed"),
- ("Unknown decoding error"));
- return GST_FLOW_ERROR;
- }
+ GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode);
+ GstVaapiDecoderStatus status;
+ GstVideoCodecFrame *out_frame;
+ GstFlowReturn ret;
+
+ for (;;) {
+ status = gst_vaapi_decoder_get_frame (decode->decoder, &out_frame);
+
+ switch (status) {
+ case GST_VAAPI_DECODER_STATUS_SUCCESS:
+ ret = gst_vaapidecode_push_decoded_frame (vdec, out_frame);
+ if (ret != GST_FLOW_OK)
+ return ret;
+ break;
+ case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA:
+ return GST_FLOW_OK;
+ default:
+ GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding failed"),
+ ("Unknown decoding error"));
+ return GST_FLOW_ERROR;
}
- g_assert_not_reached();
+ }
+ g_assert_not_reached ();
}
static GstFlowReturn
-gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame)
+gst_vaapidecode_handle_frame (GstVideoDecoder * vdec,
+ GstVideoCodecFrame * frame)
{
- GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
- GstVaapiDecoderStatus status;
- GstFlowReturn ret;
-
- if (!decode->input_state)
- goto not_negotiated;
-
- if (G_UNLIKELY(!decode->active) ||
- gst_pad_needs_reconfigure(GST_VIDEO_DECODER_SRC_PAD(vdec))) {
- GST_DEBUG_OBJECT(decode, "activating the decoder");
- if (!gst_vaapidecode_update_src_caps(decode))
- goto not_negotiated;
-
- if (!gst_video_decoder_negotiate(vdec))
- goto not_negotiated;
-
- GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(vdec);
- if (!gst_vaapi_plugin_base_set_caps(plugin, NULL, decode->srcpad_caps))
- goto not_negotiated;
-
- decode->active = TRUE;
+ GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec);
+ GstVaapiDecoderStatus status;
+ GstFlowReturn ret;
+
+ if (!decode->input_state)
+ goto not_negotiated;
+
+ if (G_UNLIKELY (!decode->active) ||
+ gst_pad_needs_reconfigure (GST_VIDEO_DECODER_SRC_PAD (vdec))) {
+ GST_DEBUG_OBJECT (decode, "activating the decoder");
+ if (!gst_vaapidecode_update_src_caps (decode))
+ goto not_negotiated;
+
+ if (!gst_video_decoder_negotiate (vdec))
+ goto not_negotiated;
+
+ GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec);
+ if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps))
+ goto not_negotiated;
+
+ decode->active = TRUE;
+ }
+
+ /* Decode current frame */
+ for (;;) {
+ status = gst_vaapi_decoder_decode (decode->decoder, frame);
+ if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) {
+ /* Make sure that there are no decoded frames waiting in the
+ output queue. */
+ ret = gst_vaapidecode_push_all_decoded_frames (decode);
+ if (ret != GST_FLOW_OK)
+ goto error_push_all_decoded_frames;
+
+ g_mutex_lock (&decode->surface_ready_mutex);
+ if (gst_vaapi_decoder_check_status (decode->decoder) ==
+ GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE)
+ g_cond_wait (&decode->surface_ready, &decode->surface_ready_mutex);
+ g_mutex_unlock (&decode->surface_ready_mutex);
+ continue;
}
-
- /* Decode current frame */
- for (;;) {
- status = gst_vaapi_decoder_decode(decode->decoder, frame);
- if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) {
- /* Make sure that there are no decoded frames waiting in the
- output queue. */
- ret = gst_vaapidecode_push_all_decoded_frames(decode);
- if (ret != GST_FLOW_OK)
- goto error_push_all_decoded_frames;
-
- g_mutex_lock(&decode->surface_ready_mutex);
- if (gst_vaapi_decoder_check_status (decode->decoder) == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE)
- g_cond_wait(&decode->surface_ready, &decode->surface_ready_mutex);
- g_mutex_unlock(&decode->surface_ready_mutex);
- continue;
- }
- if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
- goto error_decode;
- break;
- }
-
- /* Note that gst_vaapi_decoder_decode cannot return success without
- completing the decode and pushing all decoded frames into the output
- queue */
- ret = gst_vaapidecode_push_all_decoded_frames(decode);
- if (ret != GST_FLOW_OK && ret != GST_FLOW_FLUSHING)
- GST_ERROR("push loop error after decoding %d", ret);
- return ret;
-
- /* ERRORS */
+ if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
+ goto error_decode;
+ break;
+ }
+
+ /* Note that gst_vaapi_decoder_decode cannot return success without
+ completing the decode and pushing all decoded frames into the output
+ queue */
+ ret = gst_vaapidecode_push_all_decoded_frames (decode);
+ if (ret != GST_FLOW_OK && ret != GST_FLOW_FLUSHING)
+ GST_ERROR ("push loop error after decoding %d", ret);
+ return ret;
+
+ /* ERRORS */
error_push_all_decoded_frames:
- {
- GST_ERROR("push loop error while decoding %d", ret);
- gst_video_decoder_drop_frame(vdec, frame);
- return ret;
- }
+ {
+ GST_ERROR ("push loop error while decoding %d", ret);
+ gst_video_decoder_drop_frame (vdec, frame);
+ return ret;
+ }
error_decode:
- {
- GST_ERROR("decode error %d", status);
- switch (status) {
- case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC:
- case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE:
- case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT:
- ret = GST_FLOW_NOT_SUPPORTED;
- break;
- default:
- GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding error"),
- ("Decode error %d", status));
- ret = GST_FLOW_ERROR;
- break;
- }
- gst_video_decoder_drop_frame(vdec, frame);
- return ret;
+ {
+ GST_ERROR ("decode error %d", status);
+ switch (status) {
+ case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC:
+ case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE:
+ case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT:
+ ret = GST_FLOW_NOT_SUPPORTED;
+ break;
+ default:
+ GST_ELEMENT_ERROR (vdec, STREAM, DECODE, ("Decoding error"),
+ ("Decode error %d", status));
+ ret = GST_FLOW_ERROR;
+ break;
}
+ gst_video_decoder_drop_frame (vdec, frame);
+ return ret;
+ }
not_negotiated:
- {
- GST_ERROR_OBJECT (decode, "not negotiated");
- ret = GST_FLOW_NOT_NEGOTIATED;
- gst_video_decoder_drop_frame (vdec, frame);
- return ret;
- }
+ {
+ GST_ERROR_OBJECT (decode, "not negotiated");
+ ret = GST_FLOW_NOT_NEGOTIATED;
+ gst_video_decoder_drop_frame (vdec, frame);
+ return ret;
+ }
}
static gboolean
-gst_vaapidecode_flush(GstVideoDecoder *vdec)
+gst_vaapidecode_flush (GstVideoDecoder * vdec)
{
- GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
- GstVaapiDecoderStatus status;
+ GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec);
+ GstVaapiDecoderStatus status;
- if (!decode->decoder)
- return TRUE;
+ if (!decode->decoder)
+ return TRUE;
- /* If there is something in GstVideoDecoder's output adapter, then
- submit the frame for decoding */
- if (decode->current_frame_size) {
- gst_video_decoder_have_frame(vdec);
- decode->current_frame_size = 0;
- }
+ /* If there is something in GstVideoDecoder's output adapter, then
+ submit the frame for decoding */
+ if (decode->current_frame_size) {
+ gst_video_decoder_have_frame (vdec);
+ decode->current_frame_size = 0;
+ }
- status = gst_vaapi_decoder_flush(decode->decoder);
- if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
- goto error_flush;
- return TRUE;
+ status = gst_vaapi_decoder_flush (decode->decoder);
+ if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
+ goto error_flush;
+ return TRUE;
- /* ERRORS */
+ /* ERRORS */
error_flush:
- {
- GST_ERROR("failed to flush decoder (status %d)", status);
- return FALSE;
- }
+ {
+ GST_ERROR ("failed to flush decoder (status %d)", status);
+ return FALSE;
+ }
}
static GstFlowReturn
-gst_vaapidecode_finish(GstVideoDecoder *vdec)
+gst_vaapidecode_finish (GstVideoDecoder * vdec)
{
- GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
- GstFlowReturn ret = GST_FLOW_OK;
+ GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec);
+ GstFlowReturn ret = GST_FLOW_OK;
- if (!decode->decoder)
- return GST_FLOW_OK;
+ if (!decode->decoder)
+ return GST_FLOW_OK;
- if (!gst_vaapidecode_flush(vdec)) {
- gst_vaapidecode_push_all_decoded_frames(decode);
- return GST_FLOW_ERROR;
- }
+ if (!gst_vaapidecode_flush (vdec)) {
+ gst_vaapidecode_push_all_decoded_frames (decode);
+ return GST_FLOW_ERROR;
+ }
- return gst_vaapidecode_push_all_decoded_frames(decode);
+ return gst_vaapidecode_push_all_decoded_frames (decode);
}
#if GST_CHECK_VERSION(1,0,0)
static gboolean
-gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query)
+gst_vaapidecode_decide_allocation (GstVideoDecoder * vdec, GstQuery * query)
{
- GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
- GstCaps *caps = NULL;
- GstVideoCodecState *state;
- GstVaapiCapsFeature feature;
- GstVideoFormat out_format;
-
- gst_query_parse_allocation(query, &caps, NULL);
-
- feature =
- gst_vaapi_find_preferred_caps_feature(GST_VIDEO_DECODER_SRC_PAD(vdec),
- GST_VIDEO_FORMAT_ENCODED, &out_format);
- decode->has_texture_upload_meta = FALSE;
+ GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec);
+ GstCaps *caps = NULL;
+ GstVideoCodecState *state;
+ GstVaapiCapsFeature feature;
+ GstVideoFormat out_format;
+
+ gst_query_parse_allocation (query, &caps, NULL);
+
+ feature =
+ gst_vaapi_find_preferred_caps_feature (GST_VIDEO_DECODER_SRC_PAD (vdec),
+ GST_VIDEO_FORMAT_ENCODED, &out_format);
+ decode->has_texture_upload_meta = FALSE;
#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL)
- decode->has_texture_upload_meta =
- (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) &&
- gst_query_find_allocation_meta (query,
- GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL);
+ decode->has_texture_upload_meta =
+ (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) &&
+ gst_query_find_allocation_meta (query,
+ GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL);
#endif
- /* Update src caps if feature is not handled downstream */
- state = gst_video_decoder_get_output_state(vdec);
- if (!gst_caps_is_always_compatible(caps, state->caps))
- gst_vaapidecode_update_src_caps(decode);
- gst_video_codec_state_unref(state);
+ /* Update src caps if feature is not handled downstream */
+ state = gst_video_decoder_get_output_state (vdec);
+ if (!gst_caps_is_always_compatible (caps, state->caps))
+ gst_vaapidecode_update_src_caps (decode);
+ gst_video_codec_state_unref (state);
- return gst_vaapi_plugin_base_decide_allocation(GST_VAAPI_PLUGIN_BASE(vdec),
- query, feature);
+ return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (vdec),
+ query, feature);
}
#endif
static inline gboolean
-gst_vaapidecode_ensure_display(GstVaapiDecode *decode)
+gst_vaapidecode_ensure_display (GstVaapiDecode * decode)
{
- return gst_vaapi_plugin_base_ensure_display(GST_VAAPI_PLUGIN_BASE(decode));
+ return gst_vaapi_plugin_base_ensure_display (GST_VAAPI_PLUGIN_BASE (decode));
}
static inline guint
-gst_vaapi_codec_from_caps(GstCaps *caps)
+gst_vaapi_codec_from_caps (GstCaps * caps)
{
- return gst_vaapi_profile_get_codec(gst_vaapi_profile_from_caps(caps));
+ return gst_vaapi_profile_get_codec (gst_vaapi_profile_from_caps (caps));
}
static gboolean
-gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps)
+gst_vaapidecode_create (GstVaapiDecode * decode, GstCaps * caps)
{
- GstVaapiDisplay *dpy;
+ GstVaapiDisplay *dpy;
- if (!gst_vaapidecode_ensure_display(decode))
- return FALSE;
- dpy = GST_VAAPI_PLUGIN_BASE_DISPLAY(decode);
+ if (!gst_vaapidecode_ensure_display (decode))
+ return FALSE;
+ dpy = GST_VAAPI_PLUGIN_BASE_DISPLAY (decode);
- switch (gst_vaapi_codec_from_caps(caps)) {
+ switch (gst_vaapi_codec_from_caps (caps)) {
case GST_VAAPI_CODEC_MPEG2:
- decode->decoder = gst_vaapi_decoder_mpeg2_new(dpy, caps);
- break;
+ decode->decoder = gst_vaapi_decoder_mpeg2_new (dpy, caps);
+ break;
case GST_VAAPI_CODEC_MPEG4:
case GST_VAAPI_CODEC_H263:
- decode->decoder = gst_vaapi_decoder_mpeg4_new(dpy, caps);
- break;
+ decode->decoder = gst_vaapi_decoder_mpeg4_new (dpy, caps);
+ break;
case GST_VAAPI_CODEC_H264:
- decode->decoder = gst_vaapi_decoder_h264_new(dpy, caps);
-
- /* Set the stream buffer alignment for better optimizations */
- if (decode->decoder && caps) {
- GstStructure * const structure = gst_caps_get_structure(caps, 0);
- const gchar *str = NULL;
-
- if ((str = gst_structure_get_string(structure, "alignment"))) {
- GstVaapiStreamAlignH264 alignment;
- if (g_strcmp0(str, "au") == 0)
- alignment = GST_VAAPI_STREAM_ALIGN_H264_AU;
- else if (g_strcmp0(str, "nal") == 0)
- alignment = GST_VAAPI_STREAM_ALIGN_H264_NALU;
- else
- alignment = GST_VAAPI_STREAM_ALIGN_H264_NONE;
- gst_vaapi_decoder_h264_set_alignment(
- GST_VAAPI_DECODER_H264(decode->decoder), alignment);
- }
+ decode->decoder = gst_vaapi_decoder_h264_new (dpy, caps);
+
+ /* Set the stream buffer alignment for better optimizations */
+ if (decode->decoder && caps) {
+ GstStructure *const structure = gst_caps_get_structure (caps, 0);
+ const gchar *str = NULL;
+
+ if ((str = gst_structure_get_string (structure, "alignment"))) {
+ GstVaapiStreamAlignH264 alignment;
+ if (g_strcmp0 (str, "au") == 0)
+ alignment = GST_VAAPI_STREAM_ALIGN_H264_AU;
+ else if (g_strcmp0 (str, "nal") == 0)
+ alignment = GST_VAAPI_STREAM_ALIGN_H264_NALU;
+ else
+ alignment = GST_VAAPI_STREAM_ALIGN_H264_NONE;
+ gst_vaapi_decoder_h264_set_alignment (GST_VAAPI_DECODER_H264 (decode->
+ decoder), alignment);
}
- break;
+ }
+ break;
case GST_VAAPI_CODEC_WMV3:
case GST_VAAPI_CODEC_VC1:
- decode->decoder = gst_vaapi_decoder_vc1_new(dpy, caps);
- break;
+ decode->decoder = gst_vaapi_decoder_vc1_new (dpy, caps);
+ break;
#if USE_JPEG_DECODER
case GST_VAAPI_CODEC_JPEG:
- decode->decoder = gst_vaapi_decoder_jpeg_new(dpy, caps);
- break;
+ decode->decoder = gst_vaapi_decoder_jpeg_new (dpy, caps);
+ break;
#endif
#if USE_VP8_DECODER
case GST_VAAPI_CODEC_VP8:
- decode->decoder = gst_vaapi_decoder_vp8_new(dpy, caps);
- break;
+ decode->decoder = gst_vaapi_decoder_vp8_new (dpy, caps);
+ break;
#endif
default:
- decode->decoder = NULL;
- break;
- }
- if (!decode->decoder)
- return FALSE;
+ decode->decoder = NULL;
+ break;
+ }
+ if (!decode->decoder)
+ return FALSE;
- gst_vaapi_decoder_set_codec_state_changed_func(decode->decoder,
- gst_vaapi_decoder_state_changed, decode);
+ gst_vaapi_decoder_set_codec_state_changed_func (decode->decoder,
+ gst_vaapi_decoder_state_changed, decode);
- decode->decoder_caps = gst_caps_ref(caps);
- return TRUE;
+ decode->decoder_caps = gst_caps_ref (caps);
+ return TRUE;
}
static void
-gst_vaapidecode_destroy(GstVaapiDecode *decode)
+gst_vaapidecode_destroy (GstVaapiDecode * decode)
{
- gst_vaapi_decoder_replace(&decode->decoder, NULL);
- gst_caps_replace(&decode->decoder_caps, NULL);
+ gst_vaapi_decoder_replace (&decode->decoder, NULL);
+ gst_caps_replace (&decode->decoder_caps, NULL);
- decode->active = FALSE;
+ decode->active = FALSE;
- gst_vaapidecode_release(decode);
+ gst_vaapidecode_release (decode);
}
static gboolean
-gst_vaapidecode_reset_full(GstVaapiDecode *decode, GstCaps *caps, gboolean hard)
+gst_vaapidecode_reset_full (GstVaapiDecode * decode, GstCaps * caps,
+ gboolean hard)
{
- GstVaapiCodec codec;
+ GstVaapiCodec codec;
- decode->has_texture_upload_meta = FALSE;
+ decode->has_texture_upload_meta = FALSE;
- /* Reset tracked frame size */
- decode->current_frame_size = 0;
+ /* Reset tracked frame size */
+ decode->current_frame_size = 0;
- /* Reset timers if hard reset was requested (e.g. seek) */
- if (hard) {
- GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode);
- GstVideoCodecFrame *out_frame = NULL;
+ /* Reset timers if hard reset was requested (e.g. seek) */
+ if (hard) {
+ GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode);
+ GstVideoCodecFrame *out_frame = NULL;
- gst_vaapi_decoder_flush(decode->decoder);
+ gst_vaapi_decoder_flush (decode->decoder);
- /* Purge all decoded frames as we don't need them (e.g. seek) */
- while (gst_vaapi_decoder_get_frame_with_timeout(decode->decoder,
- &out_frame, 0) == GST_VAAPI_DECODER_STATUS_SUCCESS) {
- gst_video_codec_frame_unref(out_frame);
- out_frame = NULL;
- }
+ /* Purge all decoded frames as we don't need them (e.g. seek) */
+ while (gst_vaapi_decoder_get_frame_with_timeout (decode->decoder,
+ &out_frame, 0) == GST_VAAPI_DECODER_STATUS_SUCCESS) {
+ gst_video_codec_frame_unref (out_frame);
+ out_frame = NULL;
}
+ }
- /* Only reset decoder if codec type changed */
- else if (decode->decoder && decode->decoder_caps) {
- if (gst_caps_is_always_compatible(caps, decode->decoder_caps))
- return TRUE;
- codec = gst_vaapi_codec_from_caps(caps);
- if (codec == gst_vaapi_decoder_get_codec(decode->decoder))
- return TRUE;
- }
+ /* Only reset decoder if codec type changed */
+ else if (decode->decoder && decode->decoder_caps) {
+ if (gst_caps_is_always_compatible (caps, decode->decoder_caps))
+ return TRUE;
+ codec = gst_vaapi_codec_from_caps (caps);
+ if (codec == gst_vaapi_decoder_get_codec (decode->decoder))
+ return TRUE;
+ }
- gst_vaapidecode_destroy(decode);
- return gst_vaapidecode_create(decode, caps);
+ gst_vaapidecode_destroy (decode);
+ return gst_vaapidecode_create (decode, caps);
}
static void
-gst_vaapidecode_finalize(GObject *object)
+gst_vaapidecode_finalize (GObject * object)
{
- GstVaapiDecode * const decode = GST_VAAPIDECODE(object);
+ GstVaapiDecode *const decode = GST_VAAPIDECODE (object);
- gst_caps_replace(&decode->sinkpad_caps, NULL);
- gst_caps_replace(&decode->srcpad_caps, NULL);
- gst_caps_replace(&decode->allowed_caps, NULL);
+ gst_caps_replace (&decode->sinkpad_caps, NULL);
+ gst_caps_replace (&decode->srcpad_caps, NULL);
+ gst_caps_replace (&decode->allowed_caps, NULL);
- g_cond_clear(&decode->surface_ready);
- g_mutex_clear(&decode->surface_ready_mutex);
+ g_cond_clear (&decode->surface_ready);
+ g_mutex_clear (&decode->surface_ready_mutex);
- gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object));
- G_OBJECT_CLASS(gst_vaapidecode_parent_class)->finalize(object);
+ gst_vaapi_plugin_base_finalize (GST_VAAPI_PLUGIN_BASE (object));
+ G_OBJECT_CLASS (gst_vaapidecode_parent_class)->finalize (object);
}
static gboolean
-gst_vaapidecode_open(GstVideoDecoder *vdec)
+gst_vaapidecode_open (GstVideoDecoder * vdec)
{
- GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
- GstVaapiDisplay * const old_display = GST_VAAPI_PLUGIN_BASE_DISPLAY(decode);
- gboolean success;
-
- if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(decode)))
- return FALSE;
-
- /* Let GstVideoContext ask for a proper display to its neighbours */
- /* Note: steal old display that may be allocated from get_caps()
- so that to retain a reference to it, thus avoiding extra
- initialization steps if we turn out to simply re-use the
- existing (cached) VA display */
- GST_VAAPI_PLUGIN_BASE_DISPLAY(decode) = NULL;
- success = gst_vaapidecode_ensure_display(decode);
- if (old_display)
- gst_vaapi_display_unref(old_display);
- return success;
+ GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec);
+ GstVaapiDisplay *const old_display = GST_VAAPI_PLUGIN_BASE_DISPLAY (decode);
+ gboolean success;
+
+ if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (decode)))
+ return FALSE;
+
+ /* Let GstVideoContext ask for a proper display to its neighbours */
+ /* Note: steal old display that may be allocated from get_caps()
+ so that to retain a reference to it, thus avoiding extra
+ initialization steps if we turn out to simply re-use the
+ existing (cached) VA display */
+ GST_VAAPI_PLUGIN_BASE_DISPLAY (decode) = NULL;
+ success = gst_vaapidecode_ensure_display (decode);
+ if (old_display)
+ gst_vaapi_display_unref (old_display);
+ return success;
}
static gboolean
-gst_vaapidecode_close(GstVideoDecoder *vdec)
+gst_vaapidecode_close (GstVideoDecoder * vdec)
{
- GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
+ GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec);
- gst_vaapi_decode_input_state_replace(decode, NULL);
- gst_vaapidecode_destroy(decode);
- gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(decode));
- return TRUE;
+ gst_vaapi_decode_input_state_replace (decode, NULL);
+ gst_vaapidecode_destroy (decode);
+ gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (decode));
+ return TRUE;
}
static gboolean
-gst_vaapidecode_reset(GstVideoDecoder *vdec, gboolean hard)
+gst_vaapidecode_reset (GstVideoDecoder * vdec, gboolean hard)
{
- GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
+ GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec);
- /* In GStreamer 1.0 context, this means a flush */
- if (decode->decoder && !hard && !gst_vaapidecode_flush(vdec))
- return FALSE;
- return gst_vaapidecode_reset_full(decode, decode->sinkpad_caps, hard);
+ /* In GStreamer 1.0 context, this means a flush */
+ if (decode->decoder && !hard && !gst_vaapidecode_flush (vdec))
+ return FALSE;
+ return gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, hard);
}
static gboolean
-gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state)
+gst_vaapidecode_set_format (GstVideoDecoder * vdec, GstVideoCodecState * state)
{
- GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(vdec);
- GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
-
- if (!gst_vaapi_decode_input_state_replace(decode, state))
- return TRUE;
- if (!gst_vaapidecode_update_sink_caps(decode, state->caps))
- return FALSE;
- if (!gst_vaapi_plugin_base_set_caps(plugin, decode->sinkpad_caps, NULL))
- return FALSE;
- if (!gst_vaapidecode_reset_full(decode, decode->sinkpad_caps, FALSE))
- return FALSE;
+ GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec);
+ GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec);
+ if (!gst_vaapi_decode_input_state_replace (decode, state))
return TRUE;
+ if (!gst_vaapidecode_update_sink_caps (decode, state->caps))
+ return FALSE;
+ if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL))
+ return FALSE;
+ if (!gst_vaapidecode_reset_full (decode, decode->sinkpad_caps, FALSE))
+ return FALSE;
+
+ return TRUE;
}
static GstFlowReturn
-gst_vaapidecode_parse_frame(GstVideoDecoder *vdec,
- GstVideoCodecFrame *frame, GstAdapter *adapter, gboolean at_eos)
+gst_vaapidecode_parse_frame (GstVideoDecoder * vdec,
+ GstVideoCodecFrame * frame, GstAdapter * adapter, gboolean at_eos)
{
- GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
- GstVaapiDecoderStatus status;
- GstFlowReturn ret;
- guint got_unit_size;
- gboolean got_frame;
+ GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec);
+ GstVaapiDecoderStatus status;
+ GstFlowReturn ret;
+ guint got_unit_size;
+ gboolean got_frame;
- status = gst_vaapi_decoder_parse(decode->decoder, frame,
- adapter, at_eos, &got_unit_size, &got_frame);
+ status = gst_vaapi_decoder_parse (decode->decoder, frame,
+ adapter, at_eos, &got_unit_size, &got_frame);
- switch (status) {
+ switch (status) {
case GST_VAAPI_DECODER_STATUS_SUCCESS:
- if (got_unit_size > 0) {
- gst_video_decoder_add_to_frame(vdec, got_unit_size);
- decode->current_frame_size += got_unit_size;
- }
- if (got_frame) {
- ret = gst_video_decoder_have_frame(vdec);
- decode->current_frame_size = 0;
- }
- else
- ret = GST_VAAPI_DECODE_FLOW_PARSE_DATA;
- break;
+ if (got_unit_size > 0) {
+ gst_video_decoder_add_to_frame (vdec, got_unit_size);
+ decode->current_frame_size += got_unit_size;
+ }
+ if (got_frame) {
+ ret = gst_video_decoder_have_frame (vdec);
+ decode->current_frame_size = 0;
+ } else
+ ret = GST_VAAPI_DECODE_FLOW_PARSE_DATA;
+ break;
case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA:
- ret = GST_VIDEO_DECODER_FLOW_NEED_DATA;
- break;
+ ret = GST_VIDEO_DECODER_FLOW_NEED_DATA;
+ break;
case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC:
case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE:
case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT:
- GST_WARNING("parse error %d", status);
- ret = GST_FLOW_NOT_SUPPORTED;
- decode->current_frame_size = 0;
- break;
+ GST_WARNING ("parse error %d", status);
+ ret = GST_FLOW_NOT_SUPPORTED;
+ decode->current_frame_size = 0;
+ break;
default:
- GST_ERROR("parse error %d", status);
- ret = GST_FLOW_EOS;
- decode->current_frame_size = 0;
- break;
- }
- return ret;
+ GST_ERROR ("parse error %d", status);
+ ret = GST_FLOW_EOS;
+ decode->current_frame_size = 0;
+ break;
+ }
+ return ret;
}
static GstFlowReturn
-gst_vaapidecode_parse(GstVideoDecoder *vdec,
- GstVideoCodecFrame *frame, GstAdapter *adapter, gboolean at_eos)
+gst_vaapidecode_parse (GstVideoDecoder * vdec,
+ GstVideoCodecFrame * frame, GstAdapter * adapter, gboolean at_eos)
{
- GstFlowReturn ret;
+ GstFlowReturn ret;
- do {
- ret = gst_vaapidecode_parse_frame(vdec, frame, adapter, at_eos);
- } while (ret == GST_VAAPI_DECODE_FLOW_PARSE_DATA);
- return ret;
+ do {
+ ret = gst_vaapidecode_parse_frame (vdec, frame, adapter, at_eos);
+ } while (ret == GST_VAAPI_DECODE_FLOW_PARSE_DATA);
+ return ret;
}
static void
-gst_vaapidecode_class_init(GstVaapiDecodeClass *klass)
+gst_vaapidecode_class_init (GstVaapiDecodeClass * klass)
{
- GObjectClass * const object_class = G_OBJECT_CLASS(klass);
- GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
- GstVideoDecoderClass * const vdec_class = GST_VIDEO_DECODER_CLASS(klass);
- GstPadTemplate *pad_template;
+ GObjectClass *const object_class = G_OBJECT_CLASS (klass);
+ GstElementClass *const element_class = GST_ELEMENT_CLASS (klass);
+ GstVideoDecoderClass *const vdec_class = GST_VIDEO_DECODER_CLASS (klass);
+ GstPadTemplate *pad_template;
- GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidecode,
- GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC);
+ GST_DEBUG_CATEGORY_INIT (gst_debug_vaapidecode,
+ GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC);
- gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass));
+ gst_vaapi_plugin_base_class_init (GST_VAAPI_PLUGIN_BASE_CLASS (klass));
- object_class->finalize = gst_vaapidecode_finalize;
+ object_class->finalize = gst_vaapidecode_finalize;
- vdec_class->open = GST_DEBUG_FUNCPTR(gst_vaapidecode_open);
- vdec_class->close = GST_DEBUG_FUNCPTR(gst_vaapidecode_close);
- vdec_class->set_format = GST_DEBUG_FUNCPTR(gst_vaapidecode_set_format);
- vdec_class->reset = GST_DEBUG_FUNCPTR(gst_vaapidecode_reset);
- vdec_class->parse = GST_DEBUG_FUNCPTR(gst_vaapidecode_parse);
- vdec_class->handle_frame = GST_DEBUG_FUNCPTR(gst_vaapidecode_handle_frame);
- vdec_class->finish = GST_DEBUG_FUNCPTR(gst_vaapidecode_finish);
+ vdec_class->open = GST_DEBUG_FUNCPTR (gst_vaapidecode_open);
+ vdec_class->close = GST_DEBUG_FUNCPTR (gst_vaapidecode_close);
+ vdec_class->set_format = GST_DEBUG_FUNCPTR (gst_vaapidecode_set_format);
+ vdec_class->reset = GST_DEBUG_FUNCPTR (gst_vaapidecode_reset);
+ vdec_class->parse = GST_DEBUG_FUNCPTR (gst_vaapidecode_parse);
+ vdec_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vaapidecode_handle_frame);
+ vdec_class->finish = GST_DEBUG_FUNCPTR (gst_vaapidecode_finish);
#if GST_CHECK_VERSION(1,0,0)
- vdec_class->decide_allocation =
- GST_DEBUG_FUNCPTR(gst_vaapidecode_decide_allocation);
+ vdec_class->decide_allocation =
+ GST_DEBUG_FUNCPTR (gst_vaapidecode_decide_allocation);
#endif
- gst_element_class_set_static_metadata(element_class,
- "VA-API decoder",
- "Codec/Decoder/Video",
- GST_PLUGIN_DESC,
- "Gwenole Beauchesne <gwenole.beauchesne@intel.com>");
+ gst_element_class_set_static_metadata (element_class,
+ "VA-API decoder",
+ "Codec/Decoder/Video",
+ GST_PLUGIN_DESC, "Gwenole Beauchesne <gwenole.beauchesne@intel.com>");
- /* sink pad */
- pad_template = gst_static_pad_template_get(&gst_vaapidecode_sink_factory);
- gst_element_class_add_pad_template(element_class, pad_template);
+ /* sink pad */
+ pad_template = gst_static_pad_template_get (&gst_vaapidecode_sink_factory);
+ gst_element_class_add_pad_template (element_class, pad_template);
- /* src pad */
- pad_template = gst_static_pad_template_get(&gst_vaapidecode_src_factory);
- gst_element_class_add_pad_template(element_class, pad_template);
+ /* src pad */
+ pad_template = gst_static_pad_template_get (&gst_vaapidecode_src_factory);
+ gst_element_class_add_pad_template (element_class, pad_template);
}
static gboolean
-gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode)
+gst_vaapidecode_ensure_allowed_caps (GstVaapiDecode * decode)
{
- GstCaps *caps, *allowed_caps;
- GArray *profiles;
- guint i;
-
- if (decode->allowed_caps)
- return TRUE;
-
- if (!gst_vaapidecode_ensure_display(decode))
- goto error_no_display;
-
- profiles = gst_vaapi_display_get_decode_profiles(
- GST_VAAPI_PLUGIN_BASE_DISPLAY(decode));
- if (!profiles)
- goto error_no_profiles;
-
- allowed_caps = gst_caps_new_empty();
- if (!allowed_caps)
- goto error_no_memory;
-
- for (i = 0; i < profiles->len; i++) {
- const GstVaapiProfile profile =
- g_array_index(profiles, GstVaapiProfile, i);
- const gchar *media_type_name;
- const gchar *profile_name;
- GstStructure *structure;
-
- media_type_name = gst_vaapi_profile_get_media_type_name(profile);
- if (!media_type_name)
- continue;
-
- caps = gst_caps_from_string(media_type_name);
- if (!caps)
- continue;
- structure = gst_caps_get_structure (caps, 0);
-
- profile_name = gst_vaapi_profile_get_name(profile);
- if (profile_name)
- gst_structure_set(structure, "profile", G_TYPE_STRING,
- profile_name, NULL);
-
- allowed_caps = gst_caps_merge(allowed_caps, caps);
- }
- decode->allowed_caps = gst_caps_simplify (allowed_caps);
+ GstCaps *caps, *allowed_caps;
+ GArray *profiles;
+ guint i;
- g_array_unref(profiles);
+ if (decode->allowed_caps)
return TRUE;
- /* ERRORS */
+ if (!gst_vaapidecode_ensure_display (decode))
+ goto error_no_display;
+
+ profiles =
+ gst_vaapi_display_get_decode_profiles (GST_VAAPI_PLUGIN_BASE_DISPLAY
+ (decode));
+ if (!profiles)
+ goto error_no_profiles;
+
+ allowed_caps = gst_caps_new_empty ();
+ if (!allowed_caps)
+ goto error_no_memory;
+
+ for (i = 0; i < profiles->len; i++) {
+ const GstVaapiProfile profile =
+ g_array_index (profiles, GstVaapiProfile, i);
+ const gchar *media_type_name;
+ const gchar *profile_name;
+ GstStructure *structure;
+
+ media_type_name = gst_vaapi_profile_get_media_type_name (profile);
+ if (!media_type_name)
+ continue;
+
+ caps = gst_caps_from_string (media_type_name);
+ if (!caps)
+ continue;
+ structure = gst_caps_get_structure (caps, 0);
+
+ profile_name = gst_vaapi_profile_get_name (profile);
+ if (profile_name)
+ gst_structure_set (structure, "profile", G_TYPE_STRING,
+ profile_name, NULL);
+
+ allowed_caps = gst_caps_merge (allowed_caps, caps);
+ }
+ decode->allowed_caps = gst_caps_simplify (allowed_caps);
+
+ g_array_unref (profiles);
+ return TRUE;
+
+ /* ERRORS */
error_no_display:
- {
- GST_ERROR("failed to retrieve VA display");
- return FALSE;
- }
+ {
+ GST_ERROR ("failed to retrieve VA display");
+ return FALSE;
+ }
error_no_profiles:
- {
- GST_ERROR("failed to retrieve VA decode profiles");
- return FALSE;
- }
+ {
+ GST_ERROR ("failed to retrieve VA decode profiles");
+ return FALSE;
+ }
error_no_memory:
- {
- GST_ERROR("failed to allocate allowed-caps set");
- g_array_unref(profiles);
- return FALSE;
- }
+ {
+ GST_ERROR ("failed to allocate allowed-caps set");
+ g_array_unref (profiles);
+ return FALSE;
+ }
}
static GstCaps *
-gst_vaapidecode_get_caps(GstPad *pad)
+gst_vaapidecode_get_caps (GstPad * pad)
{
- GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad));
+ GstVaapiDecode *const decode = GST_VAAPIDECODE (GST_OBJECT_PARENT (pad));
- if (!gst_vaapidecode_ensure_allowed_caps(decode))
- return gst_caps_new_empty();
+ if (!gst_vaapidecode_ensure_allowed_caps (decode))
+ return gst_caps_new_empty ();
- return gst_caps_ref(decode->allowed_caps);
+ return gst_caps_ref (decode->allowed_caps);
}
static gboolean
-gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS)
+gst_vaapidecode_query (GST_PAD_QUERY_FUNCTION_ARGS)
{
- GstVaapiDecode * const decode =
- GST_VAAPIDECODE(gst_pad_get_parent_element(pad));
- GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(decode);
- gboolean res;
+ GstVaapiDecode *const decode =
+ GST_VAAPIDECODE (gst_pad_get_parent_element (pad));
+ GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (decode);
+ gboolean res;
+
+ GST_INFO_OBJECT (decode, "query type %s", GST_QUERY_TYPE_NAME (query));
+
+ if (gst_vaapi_reply_to_query (query, plugin->display)) {
+ GST_DEBUG ("sharing display %p", plugin->display);
+ res = TRUE;
+ } else if (GST_PAD_IS_SINK (pad)) {
+ switch (GST_QUERY_TYPE (query)) {
+#if GST_CHECK_VERSION(1,0,0)
+ case GST_QUERY_CAPS:{
+ GstCaps *filter, *caps = NULL;
- GST_INFO_OBJECT(decode, "query type %s", GST_QUERY_TYPE_NAME(query));
+ gst_query_parse_caps (query, &filter);
+ caps = gst_vaapidecode_get_caps (pad);
- if (gst_vaapi_reply_to_query(query, plugin->display)) {
- GST_DEBUG("sharing display %p", plugin->display);
- res = TRUE;
- }
- else if (GST_PAD_IS_SINK(pad)) {
- switch (GST_QUERY_TYPE(query)) {
-#if GST_CHECK_VERSION(1,0,0)
- case GST_QUERY_CAPS: {
- GstCaps *filter, *caps = NULL;
-
- gst_query_parse_caps(query, &filter);
- caps = gst_vaapidecode_get_caps(pad);
-
- if (filter) {
- GstCaps *tmp = caps;
- caps = gst_caps_intersect_full(filter, tmp,
- GST_CAPS_INTERSECT_FIRST);
- gst_caps_unref(tmp);
- }
-
- GST_DEBUG_OBJECT(decode, "Returning sink caps %" GST_PTR_FORMAT,
- caps);
-
- gst_query_set_caps_result(query, caps);
- gst_caps_unref(caps);
- res = TRUE;
- break;
+ if (filter) {
+ GstCaps *tmp = caps;
+ caps = gst_caps_intersect_full (filter, tmp,
+ GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (tmp);
}
+
+ GST_DEBUG_OBJECT (decode, "Returning sink caps %" GST_PTR_FORMAT, caps);
+
+ gst_query_set_caps_result (query, caps);
+ gst_caps_unref (caps);
+ res = TRUE;
+ break;
+ }
#endif
- default:
- res = GST_PAD_QUERY_FUNCTION_CALL(plugin->sinkpad_query, pad,
- parent, query);
- break;
- }
+ default:
+ res = GST_PAD_QUERY_FUNCTION_CALL (plugin->sinkpad_query, pad,
+ parent, query);
+ break;
}
- else {
- switch (GST_QUERY_TYPE(query)) {
+ } else {
+ switch (GST_QUERY_TYPE (query)) {
#if GST_CHECK_VERSION(1,0,0)
- case GST_QUERY_CAPS: {
- GstCaps *filter, *caps = NULL;
-
- gst_query_parse_caps(query, &filter);
- caps = gst_pad_get_pad_template_caps(pad);
-
- if (filter) {
- GstCaps *tmp = caps;
- caps = gst_caps_intersect_full(filter, tmp,
- GST_CAPS_INTERSECT_FIRST);
- gst_caps_unref(tmp);
- }
-
- GST_DEBUG_OBJECT(decode, "Returning src caps %" GST_PTR_FORMAT,
- caps);
-
- gst_query_set_caps_result(query, caps);
- gst_caps_unref(caps);
- res = TRUE;
- break;
+ case GST_QUERY_CAPS:{
+ GstCaps *filter, *caps = NULL;
+
+ gst_query_parse_caps (query, &filter);
+ caps = gst_pad_get_pad_template_caps (pad);
+
+ if (filter) {
+ GstCaps *tmp = caps;
+ caps = gst_caps_intersect_full (filter, tmp,
+ GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (tmp);
}
+
+ GST_DEBUG_OBJECT (decode, "Returning src caps %" GST_PTR_FORMAT, caps);
+
+ gst_query_set_caps_result (query, caps);
+ gst_caps_unref (caps);
+ res = TRUE;
+ break;
+ }
#endif
- default:
- res = GST_PAD_QUERY_FUNCTION_CALL(plugin->srcpad_query, pad,
- parent, query);
- break;
- }
+ default:
+ res = GST_PAD_QUERY_FUNCTION_CALL (plugin->srcpad_query, pad,
+ parent, query);
+ break;
}
+ }
- gst_object_unref(decode);
- return res;
+ gst_object_unref (decode);
+ return res;
}
static void
-gst_vaapidecode_init(GstVaapiDecode *decode)
+gst_vaapidecode_init (GstVaapiDecode * decode)
{
- GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode);
- GstPad *pad;
+ GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode);
+ GstPad *pad;
- gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(decode), GST_CAT_DEFAULT);
+ gst_vaapi_plugin_base_init (GST_VAAPI_PLUGIN_BASE (decode), GST_CAT_DEFAULT);
- decode->decoder = NULL;
- decode->decoder_caps = NULL;
- decode->allowed_caps = NULL;
+ decode->decoder = NULL;
+ decode->decoder_caps = NULL;
+ decode->allowed_caps = NULL;
- g_mutex_init(&decode->surface_ready_mutex);
- g_cond_init(&decode->surface_ready);
+ g_mutex_init (&decode->surface_ready_mutex);
+ g_cond_init (&decode->surface_ready);
- gst_video_decoder_set_packetized(vdec, FALSE);
+ gst_video_decoder_set_packetized (vdec, FALSE);
- /* Pad through which data comes in to the element */
- pad = GST_VAAPI_PLUGIN_BASE_SINK_PAD(decode);
- gst_pad_set_query_function(pad, GST_DEBUG_FUNCPTR(gst_vaapidecode_query));
+ /* Pad through which data comes in to the element */
+ pad = GST_VAAPI_PLUGIN_BASE_SINK_PAD (decode);
+ gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_vaapidecode_query));
#if !GST_CHECK_VERSION(1,0,0)
- gst_pad_set_getcaps_function(pad, gst_vaapidecode_get_caps);
+ gst_pad_set_getcaps_function (pad, gst_vaapidecode_get_caps);
#endif
- /* Pad through which data goes out of the element */
- pad = GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode);
- gst_pad_set_query_function(pad, GST_DEBUG_FUNCPTR(gst_vaapidecode_query));
+ /* Pad through which data goes out of the element */
+ pad = GST_VAAPI_PLUGIN_BASE_SRC_PAD (decode);
+ gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_vaapidecode_query));
}