Skip to content

Commit

Permalink
vda: use hwaccel 1.2 api wang-bin#810
Browse files Browse the repository at this point in the history
old api is not built in ffmpeg 3.2
  • Loading branch information
wang-bin committed Jan 24, 2017
1 parent 1626af3 commit 8dd77bf
Showing 1 changed file with 43 additions and 20 deletions.
63 changes: 43 additions & 20 deletions src/codec/video/VideoDecoderVDA.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/******************************************************************************
QtAV: Multimedia framework based on Qt and FFmpeg
Copyright (C) 2012-2016 Wang Bin <[email protected]>
Copyright (C) 2012-2017 Wang Bin <[email protected]>
* This file is part of QtAV (from 2014)
Expand Down Expand Up @@ -37,6 +37,12 @@ extern "C" {
#include <VideoDecodeAcceleration/VDADecoder.h>
#include "utils/Logger.h"

// av_vda_default_init2: 2015-05-13 - cc48409 / e7c5e17 - lavc 56.39.100 / 56.23.0
// I(wang bin) found the nv12 is the best format on mac. Then mpv developers confirmed it and pigoz added it to ffmpeg
#if AV_MODULE_CHECK(LIBAVCODEC, 56, 23, 0, 39, 100)
#define AV_VDA_NEW
#endif

#ifdef MAC_OS_X_VERSION_MIN_REQUIRED
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 //MAC_OS_X_VERSION_10_7
#define OSX_TARGET_MIN_LION
Expand All @@ -46,6 +52,7 @@ extern "C" {
#define kCFCoreFoundationVersionNumber10_7 635.00
#endif

// hwaccel 1.2: av_vda_xxx
namespace QtAV {
namespace cv {
VideoFormat::PixelFormat format_from_cv(int cv);
Expand Down Expand Up @@ -90,7 +97,9 @@ class VideoDecoderVDAPrivate Q_DECL_FINAL: public VideoDecoderFFmpegHWPrivate
out_fmt = VideoDecoderVDA::UYVY;
copy_mode = VideoDecoderFFmpegHW::ZeroCopy;
description = QStringLiteral("VDA");
#ifndef AV_VDA_NEW
memset(&hw_ctx, 0, sizeof(hw_ctx));
#endif
}
~VideoDecoderVDAPrivate() {qDebug("~VideoDecoderVDAPrivate");}
bool open() Q_DECL_OVERRIDE;
Expand All @@ -99,10 +108,18 @@ class VideoDecoderVDAPrivate Q_DECL_FINAL: public VideoDecoderFFmpegHWPrivate
void* setup(AVCodecContext *avctx) Q_DECL_OVERRIDE;
bool getBuffer(void **opaque, uint8_t **data) Q_DECL_OVERRIDE;
void releaseBuffer(void *opaque, uint8_t *data) Q_DECL_OVERRIDE;
AVPixelFormat vaPixelFormat() const Q_DECL_OVERRIDE { return QTAV_PIX_FMT_C(VDA_VLD);}
AVPixelFormat vaPixelFormat() const Q_DECL_OVERRIDE {
#ifdef AV_VDA_NEW
return AV_PIX_FMT_VDA;
#else
return QTAV_PIX_FMT_C(VDA_VLD);
#endif
}

VideoDecoderVDA::PixelFormat out_fmt;
#ifndef AV_VDA_NEW
struct vda_context hw_ctx;
#endif
};

typedef struct {
Expand Down Expand Up @@ -175,7 +192,9 @@ VideoFrame VideoDecoderVDA::frame()
CVPixelBufferRef cvbuf; // keep ref until video frame is destroyed
public:
SurfaceInteropCVBuffer(CVPixelBufferRef cv, bool gl) : glinterop(gl), cvbuf(cv) {
//CVPixelBufferRetain(cvbuf);
#ifdef AV_VDA_NEW
CVPixelBufferRetain(cvbuf);
#endif
}
~SurfaceInteropCVBuffer() {
CVPixelBufferRelease(cvbuf);
Expand Down Expand Up @@ -348,11 +367,17 @@ VideoDecoderVDA::PixelFormat VideoDecoderVDA::format() const

void* VideoDecoderVDAPrivate::setup(AVCodecContext *avctx)
{
releaseUSWC();
#ifdef AV_VDA_NEW
av_vda_default_free(avctx);
AVVDAContext* hw_ctx = av_vda_alloc_context();
hw_ctx->cv_pix_fmt_type = out_fmt;
int status = av_vda_default_init2(avctx, hw_ctx);
#else
const int w = codedWidth(avctx);
const int h = codedHeight(avctx);
if (hw_ctx.decoder) {
ff_vda_destroy_decoder(&hw_ctx);
releaseUSWC();
} else {
memset(&hw_ctx, 0, sizeof(hw_ctx));
hw_ctx.format = 'avc1'; //fourcc
Expand All @@ -365,13 +390,18 @@ void* VideoDecoderVDAPrivate::setup(AVCodecContext *avctx)
height = avctx->height;
/* create the decoder */
int status = ff_vda_create_decoder(&hw_ctx, codec_ctx->extradata, codec_ctx->extradata_size);
#endif
if (status) {
qWarning("Failed to create decoder (%i): %s", status, vda_err_str(status));
qWarning("Failed to init VDA decoder (%#x %s): %s", status, av_err2str(status), vda_err_str(status));
return NULL;
}
initUSWC(hw_ctx.width);
initUSWC(codedWidth(avctx));
qDebug() << "VDA decoder created. format: " << cv::format_from_cv(out_fmt);
#ifdef AV_VDA_NEW
return hw_ctx;
#else
return &hw_ctx;
#endif
}

bool VideoDecoderVDAPrivate::getBuffer(void **opaque, uint8_t **data)
Expand All @@ -385,13 +415,6 @@ void VideoDecoderVDAPrivate::releaseBuffer(void *opaque, uint8_t *data)
{
Q_UNUSED(opaque);
Q_UNUSED(data)
#if 0
// released in getBuffer?
CVPixelBufferRef cv_buffer = (CVPixelBufferRef)data;
if (!cv_buffer)
return;
CVPixelBufferRelease(cv_buffer);
#endif
}

bool VideoDecoderVDAPrivate::open()
Expand All @@ -415,20 +438,20 @@ bool VideoDecoderVDAPrivate::open()
default:
break;
}
#if 0
if (!codec_ctx->extradata || codec_ctx->extradata_size < 7) {
qWarning("VDA requires extradata.");
return false;
}
#endif
return setup(codec_ctx);
return true;
//return setup(codec_ctx); // must be in get_format() in hwa 1.2
}

void VideoDecoderVDAPrivate::close()
{
restore(); //IMPORTANT. can not call restore in dtor because ctx is 0 there
qDebug("destroying VDA decoder");
#ifdef AV_VDA_NEW
if (codec_ctx)
av_vda_default_free(codec_ctx);
#else
ff_vda_destroy_decoder(&hw_ctx);
#endif
releaseUSWC();
}

Expand Down

0 comments on commit 8dd77bf

Please sign in to comment.