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); | |||