Deprecated (aka removed) in OSX 10.11, and we have a replacement for it (VideoToolbox).tags/n4.0
@@ -5,6 +5,7 @@ version <next>: | |||
- Bitstream filters for editing metadata in H.264, HEVC and MPEG-2 streams | |||
- Dropped support for OpenJPEG versions 2.0 and below. Using OpenJPEG now | |||
requires 2.1 (or later) and pkg-config. | |||
- VDA dropped (use VideoToolbox instead) | |||
version 3.4: | |||
@@ -244,7 +244,6 @@ Codecs: | |||
txd.c Ivo van Poorten | |||
vc2* Rostislav Pehlivanov | |||
vcr1.c Michael Niedermayer | |||
vda_h264_dec.c Xidorn Quan | |||
videotoolboxenc.c Rick Kern | |||
vima.c Paul B Mahol | |||
vorbisdec.c Denes Balatoni, David Conrad | |||
@@ -318,7 +318,6 @@ External library support: | |||
--enable-omx-rpi enable OpenMAX IL code for Raspberry Pi [no] | |||
--enable-rkmpp enable Rockchip Media Process Platform code [no] | |||
--disable-vaapi disable Video Acceleration API (mainly Unix/Intel) code [autodetect] | |||
--disable-vda disable Apple Video Decode Acceleration code [autodetect] | |||
--disable-vdpau disable Nvidia Video Decode and Presentation API for Unix code [autodetect] | |||
--disable-videotoolbox disable VideoToolbox code [autodetect] | |||
@@ -1650,7 +1649,6 @@ HWACCEL_AUTODETECT_LIBRARY_LIST=" | |||
dxva2 | |||
nvenc | |||
vaapi | |||
vda | |||
vdpau | |||
videotoolbox | |||
v4l2_m2m | |||
@@ -2660,10 +2658,6 @@ cuda_deps_any="libdl LoadLibrary" | |||
cuvid_deps="cuda" | |||
d3d11va_deps="d3d11_h dxva_h ID3D11VideoDecoder ID3D11VideoContext" | |||
dxva2_deps="dxva2api_h DXVA2_ConfigPictureDecode ole32 user32" | |||
vda_framework_deps="VideoDecodeAcceleration_VDADecoder_h blocks_extension" | |||
vda_framework_extralibs="-framework VideoDecodeAcceleration" | |||
vda_deps="vda_framework pthreads corefoundation" | |||
vda_extralibs="-framework QuartzCore" | |||
videotoolbox_hwaccel_deps="videotoolbox pthreads" | |||
videotoolbox_hwaccel_extralibs="-framework QuartzCore" | |||
xvmc_deps="X11_extensions_XvMClib_h" | |||
@@ -2685,10 +2679,6 @@ h264_mmal_hwaccel_deps="mmal" | |||
h264_qsv_hwaccel_deps="libmfx" | |||
h264_vaapi_hwaccel_deps="vaapi" | |||
h264_vaapi_hwaccel_select="h264_decoder" | |||
h264_vda_hwaccel_deps="vda" | |||
h264_vda_hwaccel_select="h264_decoder" | |||
h264_vda_old_hwaccel_deps="vda" | |||
h264_vda_old_hwaccel_select="h264_decoder" | |||
h264_vdpau_hwaccel_deps="vdpau" | |||
h264_vdpau_hwaccel_select="h264_decoder" | |||
h264_videotoolbox_hwaccel_deps="videotoolbox" | |||
@@ -2822,8 +2812,6 @@ h264_rkmpp_decoder_deps="rkmpp" | |||
h264_rkmpp_decoder_select="h264_mp4toannexb_bsf" | |||
h264_vaapi_encoder_deps="VAEncPictureParameterBufferH264" | |||
h264_vaapi_encoder_select="cbs_h264 vaapi_encode" | |||
h264_vda_decoder_deps="vda" | |||
h264_vda_decoder_select="h264_decoder" | |||
h264_vdpau_decoder_deps="vdpau" | |||
h264_vdpau_decoder_select="h264_decoder" | |||
h264_v4l2m2m_decoder_deps="v4l2_m2m h264_v4l2_m2m" | |||
@@ -3011,7 +2999,6 @@ libzvbi_teletext_decoder_deps="libzvbi" | |||
videotoolbox_suggest="coreservices" | |||
videotoolbox_deps="corefoundation coremedia corevideo" | |||
videotoolbox_encoder_deps="videotoolbox VTCompressionSessionPrepareToEncodeFrames" | |||
videotoolbox_encoder_suggest="vda_framework" | |||
# demuxers / muxers | |||
ac3_demuxer_select="ac3_parser" | |||
@@ -5847,7 +5834,6 @@ check_header sys/un.h | |||
check_header termios.h | |||
check_header unistd.h | |||
check_header valgrind/valgrind.h | |||
check_header VideoDecodeAcceleration/VDADecoder.h | |||
check_func_headers VideoToolbox/VTCompressionSession.h VTCompressionSessionPrepareToEncodeFrames -framework VideoToolbox | |||
check_header windows.h | |||
check_header X11/extensions/XvMClib.h | |||
@@ -786,9 +786,6 @@ Do not use any hardware acceleration (the default). | |||
@item auto | |||
Automatically select the hardware acceleration method. | |||
@item vda | |||
Use Apple VDA hardware acceleration. | |||
@item vdpau | |||
Use VDPAU (Video Decode and Presentation API for Unix) hardware acceleration. | |||
@@ -63,7 +63,6 @@ enum HWAccelID { | |||
HWACCEL_AUTO, | |||
HWACCEL_VDPAU, | |||
HWACCEL_DXVA2, | |||
HWACCEL_VDA, | |||
HWACCEL_VIDEOTOOLBOX, | |||
HWACCEL_QSV, | |||
HWACCEL_VAAPI, | |||
@@ -661,7 +660,6 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame); | |||
int ffmpeg_parse_options(int argc, char **argv); | |||
int vda_init(AVCodecContext *s); | |||
int videotoolbox_init(AVCodecContext *s); | |||
int qsv_init(AVCodecContext *s); | |||
int cuvid_init(AVCodecContext *s); | |||
@@ -78,10 +78,6 @@ const HWAccel hwaccels[] = { | |||
{ "dxva2", hwaccel_decode_init, HWACCEL_DXVA2, AV_PIX_FMT_DXVA2_VLD, | |||
AV_HWDEVICE_TYPE_DXVA2 }, | |||
#endif | |||
#if CONFIG_VDA | |||
{ "vda", videotoolbox_init, HWACCEL_VDA, AV_PIX_FMT_VDA, | |||
AV_HWDEVICE_TYPE_NONE }, | |||
#endif | |||
#if CONFIG_VIDEOTOOLBOX | |||
{ "videotoolbox", videotoolbox_init, HWACCEL_VIDEOTOOLBOX, AV_PIX_FMT_VIDEOTOOLBOX, | |||
AV_HWDEVICE_TYPE_NONE }, | |||
@@ -3631,7 +3627,7 @@ const OptionDef options[] = { | |||
{ "hwaccel_output_format", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT | | |||
OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccel_output_formats) }, | |||
"select output format used with HW accelerated decoding", "format" }, | |||
#if CONFIG_VDA || CONFIG_VIDEOTOOLBOX | |||
#if CONFIG_VIDEOTOOLBOX | |||
{ "videotoolbox_pixfmt", HAS_ARG | OPT_STRING | OPT_EXPERT, { &videotoolbox_pixfmt}, "" }, | |||
#endif | |||
{ "hwaccels", OPT_EXIT, { .func_arg = show_hwaccels }, | |||
@@ -23,12 +23,7 @@ | |||
#endif | |||
#include "libavcodec/avcodec.h" | |||
#if CONFIG_VDA | |||
# include "libavcodec/vda.h" | |||
#endif | |||
#if CONFIG_VIDEOTOOLBOX | |||
# include "libavcodec/videotoolbox.h" | |||
#endif | |||
#include "libavcodec/videotoolbox.h" | |||
#include "libavutil/imgutils.h" | |||
#include "ffmpeg.h" | |||
@@ -114,15 +109,7 @@ static void videotoolbox_uninit(AVCodecContext *s) | |||
av_frame_free(&vt->tmp_frame); | |||
if (ist->hwaccel_id == HWACCEL_VIDEOTOOLBOX) { | |||
#if CONFIG_VIDEOTOOLBOX | |||
av_videotoolbox_default_free(s); | |||
#endif | |||
} else { | |||
#if CONFIG_VDA | |||
av_vda_default_free(s); | |||
#endif | |||
} | |||
av_videotoolbox_default_free(s); | |||
av_freep(&ist->hwaccel_ctx); | |||
} | |||
@@ -147,8 +134,7 @@ int videotoolbox_init(AVCodecContext *s) | |||
goto fail; | |||
} | |||
if (ist->hwaccel_id == HWACCEL_VIDEOTOOLBOX) { | |||
#if CONFIG_VIDEOTOOLBOX | |||
// TODO: reindent | |||
if (!videotoolbox_pixfmt) { | |||
ret = av_videotoolbox_default_init(s); | |||
} else { | |||
@@ -166,31 +152,8 @@ int videotoolbox_init(AVCodecContext *s) | |||
ret = av_videotoolbox_default_init2(s, vtctx); | |||
CFRelease(pixfmt_str); | |||
} | |||
#endif | |||
} else { | |||
#if CONFIG_VDA | |||
if (!videotoolbox_pixfmt) { | |||
ret = av_vda_default_init(s); | |||
} else { | |||
AVVDAContext *vdactx = av_vda_alloc_context(); | |||
CFStringRef pixfmt_str = CFStringCreateWithCString(kCFAllocatorDefault, | |||
videotoolbox_pixfmt, | |||
kCFStringEncodingUTF8); | |||
#if HAVE_UTGETOSTYPEFROMSTRING | |||
vdactx->cv_pix_fmt_type = UTGetOSTypeFromString(pixfmt_str); | |||
#else | |||
av_log(s, loglevel, "UTGetOSTypeFromString() is not available " | |||
"on this platform, %s pixel format can not be honored from " | |||
"the command line\n", videotoolbox_pixfmt); | |||
#endif | |||
ret = av_vda_default_init2(s, vdactx); | |||
CFRelease(pixfmt_str); | |||
} | |||
#endif | |||
} | |||
if (ret < 0) { | |||
av_log(NULL, loglevel, | |||
"Error creating %s decoder.\n", ist->hwaccel_id == HWACCEL_VIDEOTOOLBOX ? "Videotoolbox" : "VDA"); | |||
av_log(NULL, loglevel, "Error creating Videotoolbox decoder.\n"); | |||
goto fail; | |||
} | |||
@@ -12,7 +12,6 @@ HEADERS = avcodec.h \ | |||
mediacodec.h \ | |||
qsv.h \ | |||
vaapi.h \ | |||
vda.h \ | |||
vdpau.h \ | |||
version.h \ | |||
videotoolbox.h \ | |||
@@ -338,7 +337,6 @@ OBJS-$(CONFIG_H264_MMAL_DECODER) += mmaldec.o | |||
OBJS-$(CONFIG_H264_NVENC_ENCODER) += nvenc_h264.o | |||
OBJS-$(CONFIG_NVENC_ENCODER) += nvenc_h264.o | |||
OBJS-$(CONFIG_NVENC_H264_ENCODER) += nvenc_h264.o | |||
OBJS-$(CONFIG_H264_VDA_DECODER) += vda_h264_dec.o | |||
OBJS-$(CONFIG_H264_OMX_ENCODER) += omx.o | |||
OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec_h2645.o | |||
OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o | |||
@@ -824,7 +822,6 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o | |||
OBJS-$(CONFIG_D3D11VA) += dxva2.o | |||
OBJS-$(CONFIG_DXVA2) += dxva2.o | |||
OBJS-$(CONFIG_VAAPI) += vaapi_decode.o | |||
OBJS-$(CONFIG_VDA) += vda.o videotoolbox.o | |||
OBJS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.o | |||
OBJS-$(CONFIG_VDPAU) += vdpau.o | |||
@@ -834,7 +831,6 @@ OBJS-$(CONFIG_H264_D3D11VA_HWACCEL) += dxva2_h264.o | |||
OBJS-$(CONFIG_H264_DXVA2_HWACCEL) += dxva2_h264.o | |||
OBJS-$(CONFIG_H264_QSV_HWACCEL) += qsvdec_h2645.o | |||
OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o | |||
OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o | |||
OBJS-$(CONFIG_H264_VDPAU_HWACCEL) += vdpau_h264.o | |||
OBJS-$(CONFIG_H264_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o | |||
OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL) += dxva2_hevc.o | |||
@@ -1066,9 +1062,8 @@ SKIPHEADERS-$(CONFIG_QSVDEC) += qsvdec.h | |||
SKIPHEADERS-$(CONFIG_QSVENC) += qsvenc.h | |||
SKIPHEADERS-$(CONFIG_XVMC) += xvmc.h | |||
SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_decode.h vaapi_encode.h | |||
SKIPHEADERS-$(CONFIG_VDA) += vda.h vda_vt_internal.h | |||
SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h vdpau_internal.h | |||
SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.h vda_vt_internal.h | |||
SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.h vt_internal.h | |||
SKIPHEADERS-$(CONFIG_V4L2_M2M) += v4l2_buffers.h v4l2_context.h v4l2_m2m.h | |||
TESTPROGS = avpacket \ | |||
@@ -72,8 +72,6 @@ static void register_all(void) | |||
REGISTER_HWACCEL(H264_MMAL, h264_mmal); | |||
REGISTER_HWACCEL(H264_QSV, h264_qsv); | |||
REGISTER_HWACCEL(H264_VAAPI, h264_vaapi); | |||
REGISTER_HWACCEL(H264_VDA, h264_vda); | |||
REGISTER_HWACCEL(H264_VDA_OLD, h264_vda_old); | |||
REGISTER_HWACCEL(H264_VDPAU, h264_vdpau); | |||
REGISTER_HWACCEL(H264_VIDEOTOOLBOX, h264_videotoolbox); | |||
REGISTER_HWACCEL(HEVC_CUVID, hevc_cuvid); | |||
@@ -217,7 +215,6 @@ static void register_all(void) | |||
REGISTER_DECODER(H264_MMAL, h264_mmal); | |||
REGISTER_DECODER(H264_QSV, h264_qsv); | |||
REGISTER_DECODER(H264_RKMPP, h264_rkmpp); | |||
REGISTER_DECODER(H264_VDA, h264_vda); | |||
#if FF_API_VDPAU | |||
REGISTER_DECODER(H264_VDPAU, h264_vdpau); | |||
#endif | |||
@@ -755,7 +755,6 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback) | |||
#define HWACCEL_MAX (CONFIG_H264_DXVA2_HWACCEL + \ | |||
(CONFIG_H264_D3D11VA_HWACCEL * 2) + \ | |||
CONFIG_H264_VAAPI_HWACCEL + \ | |||
(CONFIG_H264_VDA_HWACCEL * 2) + \ | |||
CONFIG_H264_VIDEOTOOLBOX_HWACCEL + \ | |||
CONFIG_H264_VDPAU_HWACCEL) | |||
enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts; | |||
@@ -834,10 +833,6 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback) | |||
#if CONFIG_H264_VAAPI_HWACCEL | |||
*fmt++ = AV_PIX_FMT_VAAPI; | |||
#endif | |||
#if CONFIG_H264_VDA_HWACCEL | |||
*fmt++ = AV_PIX_FMT_VDA_VLD; | |||
*fmt++ = AV_PIX_FMT_VDA; | |||
#endif | |||
#if CONFIG_H264_VIDEOTOOLBOX_HWACCEL | |||
*fmt++ = AV_PIX_FMT_VIDEOTOOLBOX; | |||
#endif | |||
@@ -1,84 +0,0 @@ | |||
/* | |||
* This file is part of FFmpeg. | |||
* | |||
* FFmpeg is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 2.1 of the License, or (at your option) any later version. | |||
* | |||
* FFmpeg is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with FFmpeg; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
*/ | |||
#include "config.h" | |||
#include "libavutil/mem.h" | |||
#include "vda.h" | |||
#include "vda_vt_internal.h" | |||
#if CONFIG_H264_VDA_HWACCEL | |||
AVVDAContext *av_vda_alloc_context(void) | |||
{ | |||
AVVDAContext *ret = av_mallocz(sizeof(*ret)); | |||
if (ret) { | |||
ret->output_callback = ff_vda_output_callback; | |||
ret->cv_pix_fmt_type = kCVPixelFormatType_422YpCbCr8; | |||
} | |||
return ret; | |||
} | |||
int av_vda_default_init(AVCodecContext *avctx) | |||
{ | |||
return av_vda_default_init2(avctx, NULL); | |||
} | |||
int av_vda_default_init2(AVCodecContext *avctx, AVVDAContext *vdactx) | |||
{ | |||
avctx->hwaccel_context = vdactx ?: av_vda_alloc_context(); | |||
if (!avctx->hwaccel_context) | |||
return AVERROR(ENOMEM); | |||
return ff_vda_default_init(avctx); | |||
} | |||
void av_vda_default_free(AVCodecContext *avctx) | |||
{ | |||
ff_vda_default_free(avctx); | |||
av_freep(&avctx->hwaccel_context); | |||
} | |||
void ff_vda_default_free(AVCodecContext *avctx) | |||
{ | |||
AVVDAContext *vda = avctx->hwaccel_context; | |||
if (vda && vda->decoder) | |||
VDADecoderDestroy(vda->decoder); | |||
} | |||
#else | |||
AVVDAContext *av_vda_alloc_context(void) | |||
{ | |||
return NULL; | |||
} | |||
int av_vda_default_init(AVCodecContext *avctx) | |||
{ | |||
return AVERROR(ENOSYS); | |||
} | |||
int av_vda_default_init2(AVCodecContext *avctx, AVVDAContext *vdactx) | |||
{ | |||
return AVERROR(ENOSYS); | |||
} | |||
void av_vda_default_free(AVCodecContext *ctx) | |||
{ | |||
} | |||
#endif |
@@ -1,230 +0,0 @@ | |||
/* | |||
* VDA HW acceleration | |||
* | |||
* copyright (c) 2011 Sebastien Zwickert | |||
* | |||
* This file is part of FFmpeg. | |||
* | |||
* FFmpeg is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 2.1 of the License, or (at your option) any later version. | |||
* | |||
* FFmpeg is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with FFmpeg; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
*/ | |||
#ifndef AVCODEC_VDA_H | |||
#define AVCODEC_VDA_H | |||
/** | |||
* @file | |||
* @ingroup lavc_codec_hwaccel_vda | |||
* Public libavcodec VDA header. | |||
*/ | |||
#include "libavcodec/avcodec.h" | |||
#include <stdint.h> | |||
// emmintrin.h is unable to compile with -std=c99 -Werror=missing-prototypes | |||
// http://openradar.appspot.com/8026390 | |||
#undef __GNUC_STDC_INLINE__ | |||
#define Picture QuickdrawPicture | |||
#include <VideoDecodeAcceleration/VDADecoder.h> | |||
#undef Picture | |||
#include "libavcodec/version.h" | |||
// extra flags not defined in VDADecoder.h | |||
enum { | |||
kVDADecodeInfo_Asynchronous = 1UL << 0, | |||
kVDADecodeInfo_FrameDropped = 1UL << 1 | |||
}; | |||
/** | |||
* @defgroup lavc_codec_hwaccel_vda VDA | |||
* @ingroup lavc_codec_hwaccel | |||
* | |||
* @{ | |||
*/ | |||
/** | |||
* This structure is used to provide the necessary configurations and data | |||
* to the VDA FFmpeg HWAccel implementation. | |||
* | |||
* The application must make it available as AVCodecContext.hwaccel_context. | |||
*/ | |||
struct vda_context { | |||
/** | |||
* VDA decoder object. | |||
* | |||
* - encoding: unused | |||
* - decoding: Set/Unset by libavcodec. | |||
*/ | |||
VDADecoder decoder; | |||
/** | |||
* The Core Video pixel buffer that contains the current image data. | |||
* | |||
* encoding: unused | |||
* decoding: Set by libavcodec. Unset by user. | |||
*/ | |||
CVPixelBufferRef cv_buffer; | |||
/** | |||
* Use the hardware decoder in synchronous mode. | |||
* | |||
* encoding: unused | |||
* decoding: Set by user. | |||
*/ | |||
int use_sync_decoding; | |||
/** | |||
* The frame width. | |||
* | |||
* - encoding: unused | |||
* - decoding: Set/Unset by user. | |||
*/ | |||
int width; | |||
/** | |||
* The frame height. | |||
* | |||
* - encoding: unused | |||
* - decoding: Set/Unset by user. | |||
*/ | |||
int height; | |||
/** | |||
* The frame format. | |||
* | |||
* - encoding: unused | |||
* - decoding: Set/Unset by user. | |||
*/ | |||
int format; | |||
/** | |||
* The pixel format for output image buffers. | |||
* | |||
* - encoding: unused | |||
* - decoding: Set/Unset by user. | |||
*/ | |||
OSType cv_pix_fmt_type; | |||
/** | |||
* unused | |||
*/ | |||
uint8_t *priv_bitstream; | |||
/** | |||
* unused | |||
*/ | |||
int priv_bitstream_size; | |||
/** | |||
* unused | |||
*/ | |||
int priv_allocated_size; | |||
/** | |||
* Use av_buffer to manage buffer. | |||
* When the flag is set, the CVPixelBuffers returned by the decoder will | |||
* be released automatically, so you have to retain them if necessary. | |||
* Not setting this flag may cause memory leak. | |||
* | |||
* encoding: unused | |||
* decoding: Set by user. | |||
*/ | |||
int use_ref_buffer; | |||
}; | |||
/** Create the video decoder. */ | |||
int ff_vda_create_decoder(struct vda_context *vda_ctx, | |||
uint8_t *extradata, | |||
int extradata_size); | |||
/** Destroy the video decoder. */ | |||
int ff_vda_destroy_decoder(struct vda_context *vda_ctx); | |||
/** | |||
* This struct holds all the information that needs to be passed | |||
* between the caller and libavcodec for initializing VDA decoding. | |||
* Its size is not a part of the public ABI, it must be allocated with | |||
* av_vda_alloc_context() and freed with av_free(). | |||
*/ | |||
typedef struct AVVDAContext { | |||
/** | |||
* VDA decoder object. Created and freed by the caller. | |||
*/ | |||
VDADecoder decoder; | |||
/** | |||
* The output callback that must be passed to VDADecoderCreate. | |||
* Set by av_vda_alloc_context(). | |||
*/ | |||
VDADecoderOutputCallback output_callback; | |||
/** | |||
* CVPixelBuffer Format Type that VDA will use for decoded frames; set by | |||
* the caller. | |||
*/ | |||
OSType cv_pix_fmt_type; | |||
} AVVDAContext; | |||
/** | |||
* Allocate and initialize a VDA context. | |||
* | |||
* This function should be called from the get_format() callback when the caller | |||
* selects the AV_PIX_FMT_VDA format. The caller must then create the decoder | |||
* object (using the output callback provided by libavcodec) that will be used | |||
* for VDA-accelerated decoding. | |||
* | |||
* When decoding with VDA is finished, the caller must destroy the decoder | |||
* object and free the VDA context using av_free(). | |||
* | |||
* @return the newly allocated context or NULL on failure | |||
*/ | |||
AVVDAContext *av_vda_alloc_context(void); | |||
/** | |||
* This is a convenience function that creates and sets up the VDA context using | |||
* an internal implementation. | |||
* | |||
* @param avctx the corresponding codec context | |||
* | |||
* @return >= 0 on success, a negative AVERROR code on failure | |||
*/ | |||
int av_vda_default_init(AVCodecContext *avctx); | |||
/** | |||
* This is a convenience function that creates and sets up the VDA context using | |||
* an internal implementation. | |||
* | |||
* @param avctx the corresponding codec context | |||
* @param vdactx the VDA context to use | |||
* | |||
* @return >= 0 on success, a negative AVERROR code on failure | |||
*/ | |||
int av_vda_default_init2(AVCodecContext *avctx, AVVDAContext *vdactx); | |||
/** | |||
* This function must be called to free the VDA context initialized with | |||
* av_vda_default_init(). | |||
* | |||
* @param avctx the corresponding codec context | |||
*/ | |||
void av_vda_default_free(AVCodecContext *avctx); | |||
/** | |||
* @} | |||
*/ | |||
#endif /* AVCODEC_VDA_H */ |
@@ -1,425 +0,0 @@ | |||
/* | |||
* VDA H264 HW acceleration. | |||
* | |||
* copyright (c) 2011 Sebastien Zwickert | |||
* | |||
* This file is part of FFmpeg. | |||
* | |||
* FFmpeg is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 2.1 of the License, or (at your option) any later version. | |||
* | |||
* FFmpeg is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with FFmpeg; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
*/ | |||
#include <CoreFoundation/CFDictionary.h> | |||
#include <CoreFoundation/CFNumber.h> | |||
#include <CoreFoundation/CFData.h> | |||
#include "vda.h" | |||
#include "libavutil/avutil.h" | |||
#include "h264dec.h" | |||
struct vda_buffer { | |||
CVPixelBufferRef cv_buffer; | |||
}; | |||
#include "internal.h" | |||
#include "vda_vt_internal.h" | |||
/* Decoder callback that adds the vda frame to the queue in display order. */ | |||
static void vda_decoder_callback(void *vda_hw_ctx, | |||
CFDictionaryRef user_info, | |||
OSStatus status, | |||
uint32_t infoFlags, | |||
CVImageBufferRef image_buffer) | |||
{ | |||
struct vda_context *vda_ctx = vda_hw_ctx; | |||
if (infoFlags & kVDADecodeInfo_FrameDropped) | |||
vda_ctx->cv_buffer = NULL; | |||
if (!image_buffer) | |||
return; | |||
if (vda_ctx->cv_pix_fmt_type != CVPixelBufferGetPixelFormatType(image_buffer)) | |||
return; | |||
vda_ctx->cv_buffer = CVPixelBufferRetain(image_buffer); | |||
} | |||
static int vda_sync_decode(VTContext *ctx, struct vda_context *vda_ctx) | |||
{ | |||
OSStatus status; | |||
CFDataRef coded_frame; | |||
uint32_t flush_flags = 1 << 0; ///< kVDADecoderFlush_emitFrames | |||
coded_frame = CFDataCreate(kCFAllocatorDefault, | |||
ctx->bitstream, | |||
ctx->bitstream_size); | |||
status = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, NULL); | |||
if (kVDADecoderNoErr == status) | |||
status = VDADecoderFlush(vda_ctx->decoder, flush_flags); | |||
CFRelease(coded_frame); | |||
return status; | |||
} | |||
static int vda_old_h264_start_frame(AVCodecContext *avctx, | |||
av_unused const uint8_t *buffer, | |||
av_unused uint32_t size) | |||
{ | |||
VTContext *vda = avctx->internal->hwaccel_priv_data; | |||
struct vda_context *vda_ctx = avctx->hwaccel_context; | |||
if (!vda_ctx->decoder) | |||
return -1; | |||
vda->bitstream_size = 0; | |||
return 0; | |||
} | |||
static int vda_old_h264_decode_slice(AVCodecContext *avctx, | |||
const uint8_t *buffer, | |||
uint32_t size) | |||
{ | |||
VTContext *vda = avctx->internal->hwaccel_priv_data; | |||
struct vda_context *vda_ctx = avctx->hwaccel_context; | |||
void *tmp; | |||
if (!vda_ctx->decoder) | |||
return -1; | |||
tmp = av_fast_realloc(vda->bitstream, | |||
&vda->allocated_size, | |||
vda->bitstream_size + size + 4); | |||
if (!tmp) | |||
return AVERROR(ENOMEM); | |||
vda->bitstream = tmp; | |||
AV_WB32(vda->bitstream + vda->bitstream_size, size); | |||
memcpy(vda->bitstream + vda->bitstream_size + 4, buffer, size); | |||
vda->bitstream_size += size + 4; | |||
return 0; | |||
} | |||
static void vda_h264_release_buffer(void *opaque, uint8_t *data) | |||
{ | |||
struct vda_buffer *context = opaque; | |||
CVPixelBufferRelease(context->cv_buffer); | |||
av_free(context); | |||
} | |||
static int vda_old_h264_end_frame(AVCodecContext *avctx) | |||
{ | |||
H264Context *h = avctx->priv_data; | |||
VTContext *vda = avctx->internal->hwaccel_priv_data; | |||
struct vda_context *vda_ctx = avctx->hwaccel_context; | |||
AVFrame *frame = h->cur_pic_ptr->f; | |||
struct vda_buffer *context; | |||
AVBufferRef *buffer; | |||
int status; | |||
if (!vda_ctx->decoder || !vda->bitstream) | |||
return -1; | |||
status = vda_sync_decode(vda, vda_ctx); | |||
frame->data[3] = (void*)vda_ctx->cv_buffer; | |||
if (status) | |||
av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status); | |||
if (!vda_ctx->use_ref_buffer || status) | |||
return status; | |||
context = av_mallocz(sizeof(*context)); | |||
buffer = av_buffer_create(NULL, 0, vda_h264_release_buffer, context, 0); | |||
if (!context || !buffer) { | |||
CVPixelBufferRelease(vda_ctx->cv_buffer); | |||
av_free(context); | |||
return -1; | |||
} | |||
context->cv_buffer = vda_ctx->cv_buffer; | |||
frame->buf[3] = buffer; | |||
return status; | |||
} | |||
int ff_vda_create_decoder(struct vda_context *vda_ctx, | |||
uint8_t *extradata, | |||
int extradata_size) | |||
{ | |||
OSStatus status; | |||
CFNumberRef height; | |||
CFNumberRef width; | |||
CFNumberRef format; | |||
CFDataRef avc_data; | |||
CFMutableDictionaryRef config_info; | |||
CFMutableDictionaryRef buffer_attributes; | |||
CFMutableDictionaryRef io_surface_properties; | |||
CFNumberRef cv_pix_fmt; | |||
vda_ctx->priv_bitstream = NULL; | |||
vda_ctx->priv_allocated_size = 0; | |||
/* Each VCL NAL in the bitstream sent to the decoder | |||
* is preceded by a 4 bytes length header. | |||
* Change the avcC atom header if needed, to signal headers of 4 bytes. */ | |||
if (extradata_size >= 4 && (extradata[4] & 0x03) != 0x03) { | |||
uint8_t *rw_extradata; | |||
if (!(rw_extradata = av_malloc(extradata_size))) | |||
return AVERROR(ENOMEM); | |||
memcpy(rw_extradata, extradata, extradata_size); | |||
rw_extradata[4] |= 0x03; | |||
avc_data = CFDataCreate(kCFAllocatorDefault, rw_extradata, extradata_size); | |||
av_freep(&rw_extradata); | |||
} else { | |||
avc_data = CFDataCreate(kCFAllocatorDefault, extradata, extradata_size); | |||
} | |||
config_info = CFDictionaryCreateMutable(kCFAllocatorDefault, | |||
4, | |||
&kCFTypeDictionaryKeyCallBacks, | |||
&kCFTypeDictionaryValueCallBacks); | |||
height = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->height); | |||
width = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->width); | |||
format = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->format); | |||
CFDictionarySetValue(config_info, kVDADecoderConfiguration_Height, height); | |||
CFDictionarySetValue(config_info, kVDADecoderConfiguration_Width, width); | |||
CFDictionarySetValue(config_info, kVDADecoderConfiguration_SourceFormat, format); | |||
CFDictionarySetValue(config_info, kVDADecoderConfiguration_avcCData, avc_data); | |||
buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, | |||
2, | |||
&kCFTypeDictionaryKeyCallBacks, | |||
&kCFTypeDictionaryValueCallBacks); | |||
io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault, | |||
0, | |||
&kCFTypeDictionaryKeyCallBacks, | |||
&kCFTypeDictionaryValueCallBacks); | |||
cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, | |||
kCFNumberSInt32Type, | |||
&vda_ctx->cv_pix_fmt_type); | |||
CFDictionarySetValue(buffer_attributes, | |||
kCVPixelBufferPixelFormatTypeKey, | |||
cv_pix_fmt); | |||
CFDictionarySetValue(buffer_attributes, | |||
kCVPixelBufferIOSurfacePropertiesKey, | |||
io_surface_properties); | |||
status = VDADecoderCreate(config_info, | |||
buffer_attributes, | |||
(VDADecoderOutputCallback *)vda_decoder_callback, | |||
vda_ctx, | |||
&vda_ctx->decoder); | |||
CFRelease(height); | |||
CFRelease(width); | |||
CFRelease(format); | |||
CFRelease(avc_data); | |||
CFRelease(config_info); | |||
CFRelease(io_surface_properties); | |||
CFRelease(cv_pix_fmt); | |||
CFRelease(buffer_attributes); | |||
return status; | |||
} | |||
int ff_vda_destroy_decoder(struct vda_context *vda_ctx) | |||
{ | |||
OSStatus status = kVDADecoderNoErr; | |||
if (vda_ctx->decoder) | |||
status = VDADecoderDestroy(vda_ctx->decoder); | |||
return status; | |||
} | |||
AVHWAccel ff_h264_vda_old_hwaccel = { | |||
.name = "h264_vda", | |||
.type = AVMEDIA_TYPE_VIDEO, | |||
.id = AV_CODEC_ID_H264, | |||
.pix_fmt = AV_PIX_FMT_VDA_VLD, | |||
.start_frame = vda_old_h264_start_frame, | |||
.decode_slice = vda_old_h264_decode_slice, | |||
.end_frame = vda_old_h264_end_frame, | |||
.uninit = ff_videotoolbox_uninit, | |||
.priv_data_size = sizeof(VTContext), | |||
}; | |||
void ff_vda_output_callback(void *opaque, | |||
CFDictionaryRef user_info, | |||
OSStatus status, | |||
uint32_t infoFlags, | |||
CVImageBufferRef image_buffer) | |||
{ | |||
AVCodecContext *ctx = opaque; | |||
VTContext *vda = ctx->internal->hwaccel_priv_data; | |||
if (vda->frame) { | |||
CVPixelBufferRelease(vda->frame); | |||
vda->frame = NULL; | |||
} | |||
if (!image_buffer) | |||
return; | |||
vda->frame = CVPixelBufferRetain(image_buffer); | |||
} | |||
static int vda_h264_end_frame(AVCodecContext *avctx) | |||
{ | |||
H264Context *h = avctx->priv_data; | |||
VTContext *vda = avctx->internal->hwaccel_priv_data; | |||
AVVDAContext *vda_ctx = avctx->hwaccel_context; | |||
AVFrame *frame = h->cur_pic_ptr->f; | |||
uint32_t flush_flags = 1 << 0; ///< kVDADecoderFlush_emitFrames | |||
CFDataRef coded_frame; | |||
OSStatus status; | |||
if (!vda->bitstream_size) | |||
return AVERROR_INVALIDDATA; | |||
coded_frame = CFDataCreate(kCFAllocatorDefault, | |||
vda->bitstream, | |||
vda->bitstream_size); | |||
status = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, NULL); | |||
if (status == kVDADecoderNoErr) | |||
status = VDADecoderFlush(vda_ctx->decoder, flush_flags); | |||
CFRelease(coded_frame); | |||
if (!vda->frame) | |||
return AVERROR_UNKNOWN; | |||
if (status != kVDADecoderNoErr) { | |||
av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status); | |||
return AVERROR_UNKNOWN; | |||
} | |||
return ff_videotoolbox_buffer_create(vda, frame); | |||
} | |||
int ff_vda_default_init(AVCodecContext *avctx) | |||
{ | |||
AVVDAContext *vda_ctx = avctx->hwaccel_context; | |||
OSStatus status = kVDADecoderNoErr; | |||
CFNumberRef height; | |||
CFNumberRef width; | |||
CFNumberRef format; | |||
CFDataRef avc_data; | |||
CFMutableDictionaryRef config_info; | |||
CFMutableDictionaryRef buffer_attributes; | |||
CFMutableDictionaryRef io_surface_properties; | |||
CFNumberRef cv_pix_fmt; | |||
int32_t fmt = 'avc1', pix_fmt = vda_ctx->cv_pix_fmt_type; | |||
// kCVPixelFormatType_420YpCbCr8Planar; | |||
avc_data = ff_videotoolbox_avcc_extradata_create(avctx); | |||
config_info = CFDictionaryCreateMutable(kCFAllocatorDefault, | |||
4, | |||
&kCFTypeDictionaryKeyCallBacks, | |||
&kCFTypeDictionaryValueCallBacks); | |||
height = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &avctx->height); | |||
width = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &avctx->width); | |||
format = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &fmt); | |||
CFDictionarySetValue(config_info, kVDADecoderConfiguration_Height, height); | |||
CFDictionarySetValue(config_info, kVDADecoderConfiguration_Width, width); | |||
CFDictionarySetValue(config_info, kVDADecoderConfiguration_avcCData, avc_data); | |||
CFDictionarySetValue(config_info, kVDADecoderConfiguration_SourceFormat, format); | |||
buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, | |||
2, | |||
&kCFTypeDictionaryKeyCallBacks, | |||
&kCFTypeDictionaryValueCallBacks); | |||
io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault, | |||
0, | |||
&kCFTypeDictionaryKeyCallBacks, | |||
&kCFTypeDictionaryValueCallBacks); | |||
cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, | |||
kCFNumberSInt32Type, | |||
&pix_fmt); | |||
CFDictionarySetValue(buffer_attributes, | |||
kCVPixelBufferPixelFormatTypeKey, | |||
cv_pix_fmt); | |||
CFDictionarySetValue(buffer_attributes, | |||
kCVPixelBufferIOSurfacePropertiesKey, | |||
io_surface_properties); | |||
status = VDADecoderCreate(config_info, | |||
buffer_attributes, | |||
(VDADecoderOutputCallback *)ff_vda_output_callback, | |||
avctx, | |||
&vda_ctx->decoder); | |||
CFRelease(format); | |||
CFRelease(height); | |||
CFRelease(width); | |||
CFRelease(avc_data); | |||
CFRelease(config_info); | |||
CFRelease(cv_pix_fmt); | |||
CFRelease(io_surface_properties); | |||
CFRelease(buffer_attributes); | |||
if (status != kVDADecoderNoErr) { | |||
av_log(avctx, AV_LOG_ERROR, "Cannot initialize VDA %d\n", status); | |||
} | |||
switch (status) { | |||
case kVDADecoderHardwareNotSupportedErr: | |||
case kVDADecoderFormatNotSupportedErr: | |||
return AVERROR(ENOSYS); | |||
case kVDADecoderConfigurationError: | |||
return AVERROR(EINVAL); | |||
case kVDADecoderDecoderFailedErr: | |||
return AVERROR_INVALIDDATA; | |||
case kVDADecoderNoErr: | |||
return 0; | |||
default: | |||
return AVERROR_UNKNOWN; | |||
} | |||
} | |||
AVHWAccel ff_h264_vda_hwaccel = { | |||
.name = "h264_vda", | |||
.type = AVMEDIA_TYPE_VIDEO, | |||
.id = AV_CODEC_ID_H264, | |||
.pix_fmt = AV_PIX_FMT_VDA, | |||
.alloc_frame = ff_videotoolbox_alloc_frame, | |||
.start_frame = ff_videotoolbox_h264_start_frame, | |||
.decode_slice = ff_videotoolbox_h264_decode_slice, | |||
.end_frame = vda_h264_end_frame, | |||
.uninit = ff_videotoolbox_uninit, | |||
.priv_data_size = sizeof(VTContext), | |||
}; |
@@ -1,263 +0,0 @@ | |||
/* | |||
* Copyright (c) 2012, Xidorn Quan | |||
* | |||
* This file is part of FFmpeg. | |||
* | |||
* FFmpeg is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 2.1 of the License, or (at your option) any later version. | |||
* | |||
* FFmpeg is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with FFmpeg; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
*/ | |||
/** | |||
* @file | |||
* H.264 decoder via VDA | |||
* @author Xidorn Quan <quanxunzhen@gmail.com> | |||
*/ | |||
#include <string.h> | |||
#include <CoreFoundation/CoreFoundation.h> | |||
#include "vda.h" | |||
#include "h264dec.h" | |||
#include "avcodec.h" | |||
#ifndef kCFCoreFoundationVersionNumber10_7 | |||
#define kCFCoreFoundationVersionNumber10_7 635.00 | |||
#endif | |||
extern AVCodec ff_h264_decoder, ff_h264_vda_decoder; | |||
static const enum AVPixelFormat vda_pixfmts_prior_10_7[] = { | |||
AV_PIX_FMT_UYVY422, | |||
AV_PIX_FMT_YUV420P, | |||
AV_PIX_FMT_NONE | |||
}; | |||
static const enum AVPixelFormat vda_pixfmts[] = { | |||
AV_PIX_FMT_UYVY422, | |||
AV_PIX_FMT_YUYV422, | |||
AV_PIX_FMT_NV12, | |||
AV_PIX_FMT_YUV420P, | |||
AV_PIX_FMT_NONE | |||
}; | |||
typedef struct { | |||
H264Context h264ctx; | |||
int h264_initialized; | |||
struct vda_context vda_ctx; | |||
enum AVPixelFormat pix_fmt; | |||
/* for backing-up fields set by user. | |||
* we have to gain full control of such fields here */ | |||
void *hwaccel_context; | |||
enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt); | |||
int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags); | |||
} VDADecoderContext; | |||
static enum AVPixelFormat get_format(struct AVCodecContext *avctx, | |||
const enum AVPixelFormat *fmt) | |||
{ | |||
return AV_PIX_FMT_VDA_VLD; | |||
} | |||
typedef struct { | |||
CVPixelBufferRef cv_buffer; | |||
} VDABufferContext; | |||
static void release_buffer(void *opaque, uint8_t *data) | |||
{ | |||
VDABufferContext *context = opaque; | |||
CVPixelBufferUnlockBaseAddress(context->cv_buffer, 0); | |||
CVPixelBufferRelease(context->cv_buffer); | |||
av_free(context); | |||
} | |||
static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flag) | |||
{ | |||
VDABufferContext *context = av_mallocz(sizeof(VDABufferContext)); | |||
AVBufferRef *buffer = av_buffer_create(NULL, 0, release_buffer, context, 0); | |||
if (!context || !buffer) { | |||
av_free(context); | |||
return AVERROR(ENOMEM); | |||
} | |||
pic->buf[0] = buffer; | |||
pic->data[0] = (void *)1; | |||
return 0; | |||
} | |||
static inline void set_context(AVCodecContext *avctx) | |||
{ | |||
VDADecoderContext *ctx = avctx->priv_data; | |||
ctx->hwaccel_context = avctx->hwaccel_context; | |||
avctx->hwaccel_context = &ctx->vda_ctx; | |||
ctx->get_format = avctx->get_format; | |||
avctx->get_format = get_format; | |||
ctx->get_buffer2 = avctx->get_buffer2; | |||
avctx->get_buffer2 = get_buffer2; | |||
} | |||
static inline void restore_context(AVCodecContext *avctx) | |||
{ | |||
VDADecoderContext *ctx = avctx->priv_data; | |||
avctx->hwaccel_context = ctx->hwaccel_context; | |||
avctx->get_format = ctx->get_format; | |||
avctx->get_buffer2 = ctx->get_buffer2; | |||
} | |||
static int vdadec_decode(AVCodecContext *avctx, | |||
void *data, int *got_frame, AVPacket *avpkt) | |||
{ | |||
VDADecoderContext *ctx = avctx->priv_data; | |||
AVFrame *pic = data; | |||
int ret; | |||
set_context(avctx); | |||
ret = ff_h264_decoder.decode(avctx, data, got_frame, avpkt); | |||
restore_context(avctx); | |||
if (*got_frame) { | |||
AVBufferRef *buffer = pic->buf[0]; | |||
VDABufferContext *context = av_buffer_get_opaque(buffer); | |||
CVPixelBufferRef cv_buffer = (CVPixelBufferRef)pic->data[3]; | |||
CVPixelBufferRetain(cv_buffer); | |||
CVPixelBufferLockBaseAddress(cv_buffer, 0); | |||
context->cv_buffer = cv_buffer; | |||
pic->format = ctx->pix_fmt; | |||
if (CVPixelBufferIsPlanar(cv_buffer)) { | |||
int i, count = CVPixelBufferGetPlaneCount(cv_buffer); | |||
av_assert0(count < 4); | |||
for (i = 0; i < count; i++) { | |||
pic->data[i] = CVPixelBufferGetBaseAddressOfPlane(cv_buffer, i); | |||
pic->linesize[i] = CVPixelBufferGetBytesPerRowOfPlane(cv_buffer, i); | |||
} | |||
} else { | |||
pic->data[0] = CVPixelBufferGetBaseAddress(cv_buffer); | |||
pic->linesize[0] = CVPixelBufferGetBytesPerRow(cv_buffer); | |||
} | |||
} | |||
avctx->pix_fmt = ctx->pix_fmt; | |||
return ret; | |||
} | |||
static av_cold int vdadec_close(AVCodecContext *avctx) | |||
{ | |||
VDADecoderContext *ctx = avctx->priv_data; | |||
/* release buffers and decoder */ | |||
ff_vda_destroy_decoder(&ctx->vda_ctx); | |||
/* close H.264 decoder */ | |||
if (ctx->h264_initialized) { | |||
set_context(avctx); | |||
ff_h264_decoder.close(avctx); | |||
restore_context(avctx); | |||
} | |||
return 0; | |||
} | |||
static av_cold int vdadec_init(AVCodecContext *avctx) | |||
{ | |||
VDADecoderContext *ctx = avctx->priv_data; | |||
struct vda_context *vda_ctx = &ctx->vda_ctx; | |||
OSStatus status; | |||
int ret, i; | |||
ctx->h264_initialized = 0; | |||
/* init pix_fmts of codec */ | |||
if (!ff_h264_vda_decoder.pix_fmts) { | |||
if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber10_7) | |||
ff_h264_vda_decoder.pix_fmts = vda_pixfmts_prior_10_7; | |||
else | |||
ff_h264_vda_decoder.pix_fmts = vda_pixfmts; | |||
} | |||
/* init vda */ | |||
memset(vda_ctx, 0, sizeof(struct vda_context)); | |||
vda_ctx->width = avctx->width; | |||
vda_ctx->height = avctx->height; | |||
vda_ctx->format = 'avc1'; | |||
vda_ctx->use_sync_decoding = 1; | |||
vda_ctx->use_ref_buffer = 1; | |||
ctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts); | |||
switch (ctx->pix_fmt) { | |||
case AV_PIX_FMT_UYVY422: | |||
vda_ctx->cv_pix_fmt_type = '2vuy'; | |||
break; | |||
case AV_PIX_FMT_YUYV422: | |||
vda_ctx->cv_pix_fmt_type = 'yuvs'; | |||
break; | |||
case AV_PIX_FMT_NV12: | |||
vda_ctx->cv_pix_fmt_type = '420v'; | |||
break; | |||
case AV_PIX_FMT_YUV420P: | |||
vda_ctx->cv_pix_fmt_type = 'y420'; | |||
break; | |||
default: | |||
av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format: %d\n", avctx->pix_fmt); | |||
goto failed; | |||
} | |||
status = ff_vda_create_decoder(vda_ctx, | |||
avctx->extradata, avctx->extradata_size); | |||
if (status != kVDADecoderNoErr) { | |||
av_log(avctx, AV_LOG_ERROR, | |||
"Failed to init VDA decoder: %d.\n", status); | |||
goto failed; | |||
} | |||
/* init H.264 decoder */ | |||
set_context(avctx); | |||
ret = ff_h264_decoder.init(avctx); | |||
restore_context(avctx); | |||
if (ret < 0) { | |||
av_log(avctx, AV_LOG_ERROR, "Failed to open H.264 decoder.\n"); | |||
goto failed; | |||
} | |||
ctx->h264_initialized = 1; | |||
for (i = 0; i < MAX_SPS_COUNT; i++) { | |||
const SPS *sps = ctx->h264ctx.ps.sps_list[i] ? (const SPS*)ctx->h264ctx.ps.sps_list[i]->data : NULL; | |||
if (sps && (sps->bit_depth_luma != 8 || | |||
sps->chroma_format_idc == 2 || | |||
sps->chroma_format_idc == 3)) { | |||
av_log(avctx, AV_LOG_ERROR, "Format is not supported.\n"); | |||
goto failed; | |||
} | |||
} | |||
return 0; | |||
failed: | |||
vdadec_close(avctx); | |||
return -1; | |||
} | |||
static void vdadec_flush(AVCodecContext *avctx) | |||
{ | |||
set_context(avctx); | |||
ff_h264_decoder.flush(avctx); | |||
restore_context(avctx); | |||
} | |||
AVCodec ff_h264_vda_decoder = { | |||
.name = "h264_vda", | |||
.type = AVMEDIA_TYPE_VIDEO, | |||
.id = AV_CODEC_ID_H264, | |||
.priv_data_size = sizeof(VDADecoderContext), | |||
.init = vdadec_init, | |||
.close = vdadec_close, | |||
.decode = vdadec_decode, | |||
.capabilities = AV_CODEC_CAP_DELAY, | |||
.flush = vdadec_flush, | |||
.long_name = NULL_IF_CONFIG_SMALL("H.264 (VDA acceleration)"), | |||
}; |
@@ -21,13 +21,9 @@ | |||
*/ | |||
#include "config.h" | |||
#if CONFIG_VIDEOTOOLBOX | |||
# include "videotoolbox.h" | |||
# include "libavutil/hwcontext_videotoolbox.h" | |||
#else | |||
# include "vda.h" | |||
#endif | |||
#include "vda_vt_internal.h" | |||
#include "videotoolbox.h" | |||
#include "libavutil/hwcontext_videotoolbox.h" | |||
#include "vt_internal.h" | |||
#include "libavutil/avutil.h" | |||
#include "libavutil/hwcontext.h" | |||
#include "bytestream.h" | |||
@@ -16,17 +16,8 @@ | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
*/ | |||
#ifndef AVCODEC_VDA_VT_INTERNAL_H | |||
#define AVCODEC_VDA_VT_INTERNAL_H | |||
void ff_vda_output_callback(void *vda_hw_ctx, | |||
CFDictionaryRef user_info, | |||
OSStatus status, | |||
uint32_t infoFlags, | |||
CVImageBufferRef image_buffer); | |||
int ff_vda_default_init(AVCodecContext *avctx); | |||
void ff_vda_default_free(AVCodecContext *avctx); | |||
#ifndef AVCODEC_VT_INTERNAL_H | |||
#define AVCODEC_VT_INTERNAL_H | |||
typedef struct VTContext { | |||
// The current bitstream buffer. | |||
@@ -60,4 +51,5 @@ int ff_videotoolbox_h264_decode_slice(AVCodecContext *avctx, | |||
uint32_t size); | |||
CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx); | |||
CFDataRef ff_videotoolbox_hvcc_extradata_create(AVCodecContext *avctx); | |||
#endif /* AVCODEC_VDA_VT_INTERNAL_H */ | |||
#endif /* AVCODEC_VT_INTERNAL_H */ |
@@ -1670,12 +1670,6 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { | |||
.log2_chroma_h = 1, | |||
.flags = AV_PIX_FMT_FLAG_HWACCEL, | |||
}, | |||
[AV_PIX_FMT_VDA_VLD] = { | |||
.name = "vda_vld", | |||
.log2_chroma_w = 1, | |||
.log2_chroma_h = 1, | |||
.flags = AV_PIX_FMT_FLAG_HWACCEL, | |||
}, | |||
[AV_PIX_FMT_YA8] = { | |||
.name = "ya8", | |||
.nb_components = 2, | |||
@@ -2029,10 +2023,6 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { | |||
}, | |||
.flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE, | |||
}, | |||
[AV_PIX_FMT_VDA] = { | |||
.name = "vda", | |||
.flags = AV_PIX_FMT_FLAG_HWACCEL, | |||
}, | |||
[AV_PIX_FMT_QSV] = { | |||
.name = "qsv", | |||
.flags = AV_PIX_FMT_FLAG_HWACCEL, | |||
@@ -176,7 +176,6 @@ enum AVPixelFormat { | |||
AV_PIX_FMT_YUV444P10LE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian | |||
AV_PIX_FMT_YUV422P9BE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian | |||
AV_PIX_FMT_YUV422P9LE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian | |||
AV_PIX_FMT_VDA_VLD, ///< hardware decoding through VDA | |||
AV_PIX_FMT_GBRP, ///< planar GBR 4:4:4 24bpp | |||
AV_PIX_FMT_GBR24P = AV_PIX_FMT_GBRP, // alias for #AV_PIX_FMT_GBRP | |||
AV_PIX_FMT_GBRP9BE, ///< planar GBR 4:4:4 27bpp, big-endian | |||
@@ -221,8 +220,6 @@ enum AVPixelFormat { | |||
AV_PIX_FMT_YVYU422, ///< packed YUV 4:2:2, 16bpp, Y0 Cr Y1 Cb | |||
AV_PIX_FMT_VDA, ///< HW acceleration through VDA, data[3] contains a CVPixelBufferRef | |||
AV_PIX_FMT_YA16BE, ///< 16 bits gray, 16 bits alpha (big-endian) | |||
AV_PIX_FMT_YA16LE, ///< 16 bits gray, 16 bits alpha (little-endian) | |||
@@ -41,9 +41,6 @@ unsigned avutil_version(void) | |||
if (checks_done) | |||
return LIBAVUTIL_VERSION_INT; | |||
#if FF_API_VDPAU | |||
av_assert0(AV_PIX_FMT_VDA_VLD == 81); //check if the pix fmt enum has not had anything inserted or removed by mistake | |||
#endif | |||
av_assert0(AV_SAMPLE_FMT_DBLP == 9); | |||
av_assert0(AVMEDIA_TYPE_ATTACHMENT == 4); | |||
av_assert0(AV_PICTURE_TYPE_BI == 7); | |||