static void gst_vaapi_decoder_vp8_init (GstVaapiDecoderVp8 * decoder) { GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder); gst_vaapi_decoder_vp8_create (base_decoder); }
static void gst_vaapi_decoder_jpeg_init (GstVaapiDecoderJpeg * decoder) { GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder); gst_vaapi_decoder_jpeg_create (base_decoder); }
static void gst_vaapi_decoder_jpeg_finalize (GObject * object) { GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (object); gst_vaapi_decoder_jpeg_destroy (base_decoder); G_OBJECT_CLASS (gst_vaapi_decoder_jpeg_parent_class)->finalize (object); }
static void gst_vaapi_decoder_notify_caps(GObject *obj, GParamSpec *pspec, void *user_data) { GstVaapiDecode * const decode = GST_VAAPIDECODE(user_data); GstCaps *caps; g_assert(decode->decoder == GST_VAAPI_DECODER(obj)); caps = gst_vaapi_decoder_get_caps(decode->decoder); gst_vaapidecode_update_src_caps(decode, caps); }
static GstVaapiDecoderStatus ensure_context(GstVaapiDecoderVC1 *decoder) { GstVaapiDecoderVC1Private * const priv = decoder->priv; GstVaapiProfile profiles[2]; GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD; guint i, n_profiles = 0; gboolean reset_context = FALSE; if (priv->profile_changed) { GST_DEBUG("profile changed"); priv->profile_changed = FALSE; reset_context = TRUE; profiles[n_profiles++] = priv->profile; if (priv->profile == GST_VAAPI_PROFILE_VC1_SIMPLE) profiles[n_profiles++] = GST_VAAPI_PROFILE_VC1_MAIN; for (i = 0; i < n_profiles; i++) { if (gst_vaapi_display_has_decoder(GST_VAAPI_DECODER_DISPLAY(decoder), profiles[i], entrypoint)) break; } if (i == n_profiles) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; priv->profile = profiles[i]; } if (priv->size_changed) { GST_DEBUG("size changed"); priv->size_changed = FALSE; reset_context = TRUE; } if (reset_context) { GstVaapiContextInfo info; info.profile = priv->profile; info.entrypoint = entrypoint; info.width = priv->width; info.height = priv->height; info.ref_frames = 2; reset_context = gst_vaapi_decoder_ensure_context( GST_VAAPI_DECODER(decoder), &info ); if (!reset_context) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } return GST_VAAPI_DECODER_STATUS_SUCCESS; }
static GstVaapiDecoderStatus ensure_context(GstVaapiDecoderJpeg *decoder) { GstVaapiDecoderJpegPrivate * const priv = &decoder->priv; GstVaapiProfile profiles[2]; GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD; guint i, n_profiles = 0; gboolean reset_context = FALSE; if (priv->profile_changed) { GST_DEBUG("profile changed"); priv->profile_changed = FALSE; reset_context = TRUE; profiles[n_profiles++] = priv->profile; //if (priv->profile == GST_VAAPI_PROFILE_JPEG_EXTENDED) // profiles[n_profiles++] = GST_VAAPI_PROFILE_JPEG_BASELINE; for (i = 0; i < n_profiles; i++) { if (gst_vaapi_display_has_decoder(GST_VAAPI_DECODER_DISPLAY(decoder), profiles[i], entrypoint)) break; } if (i == n_profiles) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; priv->profile = profiles[i]; } if (reset_context) { GstVaapiContextInfo info; info.profile = priv->profile; info.entrypoint = entrypoint; info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; info.width = priv->width; info.height = priv->height; info.ref_frames = 2; reset_context = gst_vaapi_decoder_ensure_context( GST_VAAPI_DECODER(decoder), &info ); if (!reset_context) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } return GST_VAAPI_DECODER_STATUS_SUCCESS; }
/** Ensures VA context is correctly set up for the current FFmpeg context */ static GstVaapiContext * get_context(AVCodecContext *avctx) { GstVaapiContextFfmpeg * const vactx = avctx->hwaccel_context; GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(vactx->decoder); GstVaapiDisplay *display; GstVaapiContext *context; gboolean success; if (!avctx->coded_width || !avctx->coded_height) return NULL; gst_vaapi_decoder_set_framerate( decoder, avctx->time_base.den / avctx->ticks_per_frame, avctx->time_base.num ); gst_vaapi_decoder_set_pixel_aspect_ratio( decoder, avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den ); success = gst_vaapi_decoder_ensure_context( decoder, vactx->profile, vactx->entrypoint, avctx->coded_width, avctx->coded_height ); if (!success) { GST_DEBUG("failed to reset VA context:"); GST_DEBUG(" profile 0x%08x", vactx->profile); GST_DEBUG(" entrypoint %d", vactx->entrypoint); GST_DEBUG(" surface size %dx%d", avctx->width, avctx->height); return NULL; } display = GST_VAAPI_DECODER_DISPLAY(decoder); context = GST_VAAPI_DECODER_CONTEXT(decoder); vactx->base.display = GST_VAAPI_DISPLAY_VADISPLAY(display); vactx->base.context_id = GST_VAAPI_OBJECT_ID(context); return context; }
static GstVaapiDecoderStatus ensure_context (GstVaapiDecoderVp8 * decoder) { GstVaapiDecoderVp8Private *const priv = &decoder->priv; const GstVaapiProfile profile = GST_VAAPI_PROFILE_VP8; const GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD; gboolean reset_context = FALSE; if (priv->profile != profile) { if (!gst_vaapi_display_has_decoder (GST_VAAPI_DECODER_DISPLAY (decoder), profile, entrypoint)) return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; priv->profile = profile; reset_context = TRUE; } if (priv->size_changed) { GST_DEBUG ("size changed"); priv->size_changed = FALSE; reset_context = TRUE; } if (reset_context) { GstVaapiContextInfo info; info.profile = priv->profile; info.entrypoint = entrypoint; info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; info.width = priv->width; info.height = priv->height; info.ref_frames = 3; reset_context = gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info); if (!reset_context) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; } return GST_VAAPI_DECODER_STATUS_SUCCESS; }
static GstVaapiDecoderStatus decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu) { GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder); GstVaapiDecoderVC1Private * const priv = decoder->priv; GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr; GstVC1AdvancedSeqHdr * const adv_hdr = &seq_hdr->advanced; GstVC1SeqStructC * const structc = &seq_hdr->struct_c; GstVC1ParserResult result; GstVaapiProfile profile; guint width, height, fps_n, fps_d; result = gst_vc1_parse_sequence_header( rbdu->data + rbdu->offset, rbdu->size, seq_hdr ); if (result != GST_VC1_PARSER_OK) { GST_DEBUG("failed to parse sequence layer"); return get_status(result); } priv->has_entrypoint = FALSE; /* Validate profile */ switch (seq_hdr->profile) { case GST_VC1_PROFILE_SIMPLE: case GST_VC1_PROFILE_MAIN: case GST_VC1_PROFILE_ADVANCED: break; default: GST_DEBUG("unsupported profile %d", seq_hdr->profile); return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE; } fps_n = 0; fps_d = 0; switch (seq_hdr->profile) { case GST_VC1_PROFILE_SIMPLE: case GST_VC1_PROFILE_MAIN: if (structc->wmvp) { fps_n = structc->framerate; fps_d = 1; } break; case GST_VC1_PROFILE_ADVANCED: if (adv_hdr->display_ext && adv_hdr->framerate_flag) { if (adv_hdr->framerateind) { // 6.1.14.4.4 - Frame Rate Explicit fps_n = adv_hdr->framerateexp + 1; fps_d = 32; } else { // 6.1.14.4.2 - Frame Rate Numerator static const guint frameratenr_table[] = { [1] = 24000, [2] = 25000, [3] = 30000, [4] = 50000, [5] = 60000, [6] = 48000, [7] = 72000 }; // 6.1.14.4.3 - Frame Rate Denominator static const guint frameratedr_table[] = { [1] = 1000, [2] = 1001 }; if (adv_hdr->frameratenr < 1 || adv_hdr->frameratenr > 7) { GST_DEBUG("unsupported FRAMERATENR value"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } fps_n = frameratenr_table[adv_hdr->frameratenr]; if (adv_hdr->frameratedr < 1 || adv_hdr->frameratedr > 2) { GST_DEBUG("unsupported FRAMERATEDR value"); return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER; } fps_d = frameratedr_table[adv_hdr->frameratedr]; } } break; default: g_assert(0 && "XXX: we already validated the profile above"); break; } if (fps_n && fps_d) { priv->fps_n = fps_n; priv->fps_d = fps_d; gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d); } switch (seq_hdr->profile) { case GST_VC1_PROFILE_SIMPLE: case GST_VC1_PROFILE_MAIN: width = seq_hdr->struct_c.coded_width; height = seq_hdr->struct_c.coded_height; break; case GST_VC1_PROFILE_ADVANCED: width = seq_hdr->advanced.max_coded_width; height = seq_hdr->advanced.max_coded_height; break; default: g_assert(0 && "XXX: we already validated the profile above"); break; } if (priv->width != width) { priv->width = width; priv->size_changed = TRUE; } if (priv->height != height) { priv->height = height; priv->size_changed = TRUE; } switch (seq_hdr->profile) { case GST_VC1_PROFILE_SIMPLE: profile = GST_VAAPI_PROFILE_VC1_SIMPLE; break; case GST_VC1_PROFILE_MAIN: profile = GST_VAAPI_PROFILE_VC1_MAIN; break; case GST_VC1_PROFILE_ADVANCED: profile = GST_VAAPI_PROFILE_VC1_ADVANCED; break; default: g_assert(0 && "XXX: we already validated the profile above"); break; } if (priv->profile != profile) { priv->profile = profile; priv->profile_changed = TRUE; } return GST_VAAPI_DECODER_STATUS_SUCCESS; }