Ejemplo n.º 1
0
static void
gst_vaapi_decoder_vp8_init (GstVaapiDecoderVp8 * decoder)
{
  GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder);

  gst_vaapi_decoder_vp8_create (base_decoder);
}
Ejemplo n.º 2
0
static void
gst_vaapi_decoder_jpeg_init (GstVaapiDecoderJpeg * decoder)
{
  GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder);

  gst_vaapi_decoder_jpeg_create (base_decoder);
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}