Esempio n. 1
0
// hwaccel_context
bool VideoDecoderDXVAPrivate::setup(AVCodecContext *avctx)
{
    const int w = codedWidth(avctx);
    const int h = codedHeight(avctx);
    if (decoder && surface_width == aligned(w) && surface_height == aligned(h)) {
        avctx->hwaccel_context = &hw_ctx;
        return true;
    }
    width = avctx->width; // not necessary. set in decode()
    height = avctx->height;
    releaseUSWC();
    DxDestroyVideoDecoder();
    avctx->hwaccel_context = NULL;
    /* FIXME transmit a video_format_t by VaSetup directly */
    if (!DxCreateVideoDecoder(avctx->codec_id, w, h))
        return false;
    avctx->hwaccel_context = &hw_ctx;
    hw_ctx.decoder = decoder;
    hw_ctx.cfg = &cfg;
    hw_ctx.surface_count = surface_count;
    hw_ctx.surface = hw_surfaces;
    memset(hw_surfaces, 0, sizeof(hw_surfaces));
    for (unsigned i = 0; i < surface_count; i++)
        hw_ctx.surface[i] = surfaces[i].d3d;
    initUSWC(surface_width);
    return true;
}
bool VideoDecoderVDAPrivate::setup(AVCodecContext *avctx)
{
    const int w = codedWidth(avctx);
    const int h = codedHeight(avctx);
    if (hw_ctx.width == w && hw_ctx.height == h && hw_ctx.decoder) {
        avctx->hwaccel_context = &hw_ctx;
        return true;
    }
    if (hw_ctx.decoder) {
        ff_vda_destroy_decoder(&hw_ctx);
        releaseUSWC();
    } else {
        memset(&hw_ctx, 0, sizeof(hw_ctx));
        hw_ctx.format = 'avc1'; //fourcc
        hw_ctx.cv_pix_fmt_type = out_fmt; // has the same value as cv pixel format
    }
    /* Setup the libavcodec hardware context */
    hw_ctx.width = w;
    hw_ctx.height = h;
    width = avctx->width; // not necessary. set in decode()
    height = avctx->height;
    avctx->hwaccel_context = NULL;
    /* create the decoder */
    int status = ff_vda_create_decoder(&hw_ctx, codec_ctx->extradata, codec_ctx->extradata_size);
    if (status) {
        qWarning("Failed to create decoder (%i): %s", status, vda_err_str(status));
        return false;
    }
    avctx->hwaccel_context = &hw_ctx;
    initUSWC(hw_ctx.width);
    qDebug("VDA decoder created");
    return true;
}
Esempio n. 3
0
bool VideoDecoderD3DPrivate::setup(AVCodecContext *avctx)
{
    const int w = codedWidth(avctx);
    const int h = codedHeight(avctx);
    if (avctx->hwaccel_context && surface_width == aligned(w) && surface_height == aligned(h))
        return true;
    width = avctx->width; // not necessary. set in decode()
    height = avctx->height;
    codec_ctx->hwaccel_context = NULL;
    releaseUSWC();
    destroyDecoder();
    avctx->hwaccel_context = NULL;

    /* Allocates all surfaces needed for the decoder */
    if (surface_auto) {
        switch (codec_ctx->codec_id) {
        case QTAV_CODEC_ID(HEVC):
        case QTAV_CODEC_ID(H264):
            surface_count = 16 + 4;
            break;
        case QTAV_CODEC_ID(MPEG1VIDEO):
        case QTAV_CODEC_ID(MPEG2VIDEO):
            surface_count = 2 + 4;
        default:
            surface_count = 2 + 4;
            break;
        }
        if (avctx->active_thread_type & FF_THREAD_FRAME)
            surface_count += avctx->thread_count;
    }
    qDebug(">>>>>>>>>>>>>>>>>>>>>surfaces: %d, active_thread_type: %d, threads: %d, refs: %d", surface_count, avctx->active_thread_type, avctx->thread_count, avctx->refs);
    if (surface_count == 0) {
        qWarning("internal error: wrong surface count.  %u auto=%d", surface_count, surface_auto);
        surface_count = 16 + 4;
    }
    qDeleteAll(surfaces);
    surfaces.clear();
    hw_surfaces.clear();
    surfaces.resize(surface_count);
    if (!createDecoder(codec_ctx->codec_id, w, h, surfaces))
        return false;
    hw_surfaces.resize(surface_count);
    for (int i = 0; i < surfaces.size(); ++i) {
        hw_surfaces[i] = surfaces[i]->getSurface();
    }
    surface_order = 0;
    surface_width = aligned(w);
    surface_height = aligned(h);
    setupAVVAContext(avctx); //can not use codec_ctx for threaded mode!
    initUSWC(surface_width);
    return true;
}
Esempio n. 4
0
// hwaccel_context
bool VideoDecoderDXVAPrivate::setup(AVCodecContext *avctx)
{
    const int w = codedWidth(avctx);
    const int h = codedHeight(avctx);
    if (decoder && surface_width == aligned(w) && surface_height == aligned(h)) {
        avctx->hwaccel_context = &hw_ctx;
        return true;
    }
    width = avctx->width; // not necessary. set in decode()
    height = avctx->height;
    releaseUSWC();
    DxDestroyVideoDecoder();
    avctx->hwaccel_context = NULL;
    /* FIXME transmit a video_format_t by VaSetup directly */
    if (!DxCreateVideoDecoder(avctx->codec_id, w, h))
        return false;
    avctx->hwaccel_context = &hw_ctx;
    // TODO: FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG
    if (IsEqualGUID(input, DXVA_Intel_H264_NoFGT_ClearVideo)) {
#ifdef FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO //2014-03-07 - 8b2a130 - lavc 55.50.0 / 55.53.100 - dxva2.h
        qDebug("FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO");
        hw_ctx.workaround |= FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO;
#endif
    } else {
        hw_ctx.workaround = 0;
    }

    hw_ctx.decoder = decoder;
    hw_ctx.cfg = &cfg;
    hw_ctx.surface_count = surface_count;
    hw_ctx.surface = hw_surfaces;
    memset(hw_surfaces, 0, sizeof(hw_surfaces));
    for (unsigned i = 0; i < surface_count; i++)
        hw_ctx.surface[i] = surfaces[i].d3d;
    initUSWC(surface_width);
    return true;
}