Created
December 3, 2014 07:48
-
-
Save brianmario/7cb13d70b7620eee4e35 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
Changelog | 1 + | |
MAINTAINERS | 1 + | |
configure | 12 ++ | |
libavcodec/Makefile | 7 + | |
libavcodec/allcodecs.c | 4 + | |
libavcodec/h264.c | 1 + | |
libavcodec/mpeg12.c | 3 + | |
libavcodec/mpegvideo.c | 1 + | |
libavcodec/version.h | 2 +- | |
libavcodec/vt.c | 388 ++++++++++++++++++++++++++++++++++++++++++++++ | |
libavcodec/vt.h | 185 ++++++++++++++++++++++ | |
libavcodec/vt_h264.c | 94 +++++++++++ | |
libavcodec/vt_internal.h | 44 ++++++ | |
libavcodec/vt_mpeg2.c | 77 +++++++++ | |
libavcodec/vt_mpeg4.c | 92 +++++++++++ | |
libavutil/pixdesc.c | 6 + | |
libavutil/pixfmt.h | 1 + | |
17 files changed, 918 insertions(+), 1 deletion(-) | |
create mode 100644 libavcodec/vt.c | |
create mode 100644 libavcodec/vt.h | |
create mode 100644 libavcodec/vt_h264.c | |
create mode 100644 libavcodec/vt_internal.h | |
create mode 100644 libavcodec/vt_mpeg2.c | |
create mode 100644 libavcodec/vt_mpeg4.c | |
diff --git a/Changelog b/Changelog | |
index 64cbf00..a6b61eb 100644 | |
--- a/Changelog | |
+++ b/Changelog | |
@@ -59,6 +59,7 @@ version next: | |
- smartblur filter ported from MPlayer | |
- CPiA decoder | |
- decimate filter ported from MPlayer | |
+- OS X VideoToolbox (VT) support | |
version 0.11: | |
diff --git a/MAINTAINERS b/MAINTAINERS | |
index 1860b6e..6233b1c 100644 | |
--- a/MAINTAINERS | |
+++ b/MAINTAINERS | |
@@ -257,6 +257,7 @@ Hardware acceleration: | |
libstagefright.cpp Mohamed Naufal | |
vaapi* Gwenole Beauchesne | |
vda* Sebastien Zwickert | |
+ vt* Sebastien Zwickert | |
vdpau* Carl Eugen Hoyos | |
diff --git a/configure b/configure | |
index 7fac4e9..ff49eec 100755 | |
--- a/configure | |
+++ b/configure | |
@@ -133,6 +133,7 @@ Component options: | |
--enable-dxva2 enable DXVA2 code | |
--enable-vaapi enable VAAPI code [autodetect] | |
--enable-vda enable VDA code [autodetect] | |
+ --enable-vt enable VideoToolbox code [autodetect] | |
--enable-vdpau enable VDPAU code [autodetect] | |
Individual component options: | |
@@ -1171,6 +1172,7 @@ CONFIG_LIST=" | |
thumb | |
vaapi | |
vda | |
+ vt | |
vdpau | |
version3 | |
xmm_clobber_test | |
@@ -1601,6 +1603,7 @@ h261_encoder_select="aandcttables mpegvideoenc" | |
h263_decoder_select="error_resilience h263_parser mpegvideo" | |
h263_encoder_select="aandcttables error_resilience mpegvideoenc" | |
h263_vaapi_hwaccel_select="vaapi h263_decoder" | |
+h263_vt_hwaccel_select="vt h263_decoder" | |
h263i_decoder_select="h263_decoder" | |
h263p_encoder_select="h263_encoder" | |
h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser" | |
@@ -1611,6 +1614,7 @@ h264_vaapi_hwaccel_select="vaapi h264_decoder" | |
h264_vda_decoder_select="vda h264_parser h264_decoder" | |
h264_vda_hwaccel_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" | |
h264_vda_hwaccel_select="vda h264_decoder" | |
+h264_vt_hwaccel_select="vt h264_decoder" | |
h264_vdpau_decoder_select="vdpau h264_decoder" | |
huffyuv_encoder_select="huffman" | |
iac_decoder_select="fft mdct sinewin" | |
@@ -1646,12 +1650,14 @@ mpeg2_dxva2_hwaccel_deps="dxva2api_h" | |
mpeg2_dxva2_hwaccel_select="dxva2 mpeg2video_decoder" | |
mpeg2_vdpau_hwaccel_select="vdpau mpeg2video_decoder" | |
mpeg2_vaapi_hwaccel_select="vaapi mpeg2video_decoder" | |
+mpeg2_vt_hwaccel_select="vt mpeg2video_decoder" | |
mpeg2video_decoder_select="error_resilience mpegvideo" | |
mpeg2video_encoder_select="aandcttables error_resilience mpegvideoenc" | |
mpeg4_crystalhd_decoder_select="crystalhd" | |
mpeg4_decoder_select="h263_decoder mpeg4video_parser" | |
mpeg4_encoder_select="h263_encoder" | |
mpeg4_vaapi_hwaccel_select="vaapi mpeg4_decoder" | |
+mpeg4_vt_hwaccel_select="vt mpeg4_decoder" | |
mpeg4_vdpau_decoder_select="vdpau mpeg4_decoder" | |
msmpeg4_crystalhd_decoder_select="crystalhd" | |
msmpeg4v1_decoder_select="h263_decoder" | |
@@ -1732,6 +1738,7 @@ zmbv_encoder_select="zlib" | |
crystalhd_deps="libcrystalhd_libcrystalhd_if_h" | |
vaapi_deps="va_va_h" | |
vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" | |
+vt_deps="VideoToolbox_VideoToolbox_h" | |
vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h" | |
# parsers | |
@@ -3532,6 +3539,11 @@ if ! disabled vda; then | |
fi | |
fi | |
+# check for VideoToolbox header | |
+if ! disabled vda && check_header VideoToolbox/VideoToolbox.h; then | |
+ enable vt && add_extralibs -framework CoreFoundation -framework VideoToolbox -framework CoreMedia -framework QuartzCore | |
+fi | |
+ | |
if ! disabled w32threads && ! enabled pthreads; then | |
check_func _beginthreadex && enable w32threads | |
fi | |
diff --git a/libavcodec/Makefile b/libavcodec/Makefile | |
index ae2efb6..cef8c14 100644 | |
--- a/libavcodec/Makefile | |
+++ b/libavcodec/Makefile | |
@@ -9,6 +9,7 @@ HEADERS = avcodec.h \ | |
old_codec_ids.h \ | |
vaapi.h \ | |
vda.h \ | |
+ vt.h \ | |
vdpau.h \ | |
version.h \ | |
xvmc.h \ | |
@@ -65,6 +66,7 @@ RDFT-OBJS-$(CONFIG_HARDCODED_TABLES) += sin_tables.o | |
OBJS-$(CONFIG_RDFT) += rdft.o $(RDFT-OBJS-yes) | |
OBJS-$(CONFIG_SINEWIN) += sinewin.o | |
OBJS-$(CONFIG_VAAPI) += vaapi.o | |
+OBJS-$(CONFIG_VT) += vt.o | |
OBJS-$(CONFIG_VDPAU) += vdpau.o | |
OBJS-$(CONFIG_VP3DSP) += vp3dsp.o | |
@@ -208,6 +210,7 @@ OBJS-$(CONFIG_H263_DECODER) += h263dec.o h263.o ituh263dec.o \ | |
mpeg4video.o mpeg4videodec.o flvdec.o\ | |
intelh263dec.o | |
OBJS-$(CONFIG_H263_VAAPI_HWACCEL) += vaapi_mpeg4.o | |
+OBJS-$(CONFIG_H263_VT_HWACCEL) += vt_mpeg4.o | |
OBJS-$(CONFIG_H263_ENCODER) += mpeg4videoenc.o mpeg4video.o \ | |
h263.o ituh263enc.o flvenc.o | |
OBJS-$(CONFIG_H264_DECODER) += h264.o \ | |
@@ -218,6 +221,7 @@ OBJS-$(CONFIG_H264_DXVA2_HWACCEL) += dxva2_h264.o | |
OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o | |
OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o | |
OBJS-$(CONFIG_H264_VDA_DECODER) += vda_h264_dec.o | |
+OBJS-$(CONFIG_H264_VT_HWACCEL) += vt_h264.o | |
OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o | |
OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o | |
OBJS-$(CONFIG_IAC_DECODER) += imc.o | |
@@ -291,10 +295,12 @@ OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpeg12.o \ | |
timecode.o | |
OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o | |
OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o | |
+OBJS-$(CONFIG_MPEG2_VT_HWACCEL) += vt_mpeg2.o | |
OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12.o mpeg12data.o | |
OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12.o \ | |
timecode.o | |
OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o | |
+OBJS-$(CONFIG_MPEG4_VT_HWACCEL) += vt_mpeg4.o | |
OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4.o msmpeg4data.o | |
OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4.o msmpeg4data.o h263dec.o \ | |
h263.o ituh263dec.o mpeg4videodec.o | |
@@ -766,6 +772,7 @@ SKIPHEADERS-$(CONFIG_LIBUTVIDEO) += libutvideo.h | |
SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h | |
SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_internal.h | |
SKIPHEADERS-$(CONFIG_VDA) += vda.h | |
+SKIPHEADERS-$(CONFIG_VT) += vt.h vt_internal.h | |
SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h | |
SKIPHEADERS-$(HAVE_OS2THREADS) += os2threads.h | |
SKIPHEADERS-$(HAVE_W32THREADS) += w32pthreads.h | |
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c | |
index 8806c6a..6334060 100644 | |
--- a/libavcodec/allcodecs.c | |
+++ b/libavcodec/allcodecs.c | |
@@ -56,14 +56,18 @@ void avcodec_register_all(void) | |
/* hardware accelerators */ | |
REGISTER_HWACCEL (H263_VAAPI, h263_vaapi); | |
+ REGISTER_HWACCEL (H263_VT, h263_vt); | |
REGISTER_HWACCEL (H264_DXVA2, h264_dxva2); | |
REGISTER_HWACCEL (H264_VAAPI, h264_vaapi); | |
REGISTER_HWACCEL (H264_VDA, h264_vda); | |
+ REGISTER_HWACCEL (H264_VT, h264_vt); | |
REGISTER_HWACCEL (MPEG1_VDPAU, mpeg1_vdpau); | |
REGISTER_HWACCEL (MPEG2_DXVA2, mpeg2_dxva2); | |
REGISTER_HWACCEL (MPEG2_VAAPI, mpeg2_vaapi); | |
+ REGISTER_HWACCEL (MPEG2_VT, mpeg2_vt); | |
REGISTER_HWACCEL (MPEG2_VDPAU, mpeg2_vdpau); | |
REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi); | |
+ REGISTER_HWACCEL (MPEG4_VT, mpeg4_vt); | |
REGISTER_HWACCEL (VC1_DXVA2, vc1_dxva2); | |
REGISTER_HWACCEL (VC1_VAAPI, vc1_vaapi); | |
REGISTER_HWACCEL (WMV3_DXVA2, wmv3_dxva2); | |
diff --git a/libavcodec/h264.c b/libavcodec/h264.c | |
index 713fda7..bb42323 100644 | |
--- a/libavcodec/h264.c | |
+++ b/libavcodec/h264.c | |
@@ -70,6 +70,7 @@ static const enum PixelFormat hwaccel_pixfmt_list_h264_jpeg_420[] = { | |
PIX_FMT_DXVA2_VLD, | |
PIX_FMT_VAAPI_VLD, | |
PIX_FMT_VDA_VLD, | |
+ PIX_FMT_VT_VLD, | |
PIX_FMT_YUVJ420P, | |
PIX_FMT_NONE | |
}; | |
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c | |
index 1bf857e..09532a8 100644 | |
--- a/libavcodec/mpeg12.c | |
+++ b/libavcodec/mpeg12.c | |
@@ -1203,6 +1203,9 @@ static const enum PixelFormat mpeg2_hwaccel_pixfmt_list_420[] = { | |
#if CONFIG_MPEG2_VAAPI_HWACCEL | |
PIX_FMT_VAAPI_VLD, | |
#endif | |
+#if CONFIG_MPEG2_VT_HWACCEL | |
+ PIX_FMT_VT_VLD, | |
+#endif | |
PIX_FMT_YUV420P, | |
PIX_FMT_NONE | |
}; | |
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c | |
index 6b3d4e7..88bd4fd 100644 | |
--- a/libavcodec/mpegvideo.c | |
+++ b/libavcodec/mpegvideo.c | |
@@ -134,6 +134,7 @@ const enum PixelFormat ff_hwaccel_pixfmt_list_420[] = { | |
PIX_FMT_DXVA2_VLD, | |
PIX_FMT_VAAPI_VLD, | |
PIX_FMT_VDA_VLD, | |
+ PIX_FMT_VT_VLD, | |
PIX_FMT_YUV420P, | |
PIX_FMT_NONE | |
}; | |
diff --git a/libavcodec/version.h b/libavcodec/version.h | |
index a2e231b..3349789 100644 | |
--- a/libavcodec/version.h | |
+++ b/libavcodec/version.h | |
@@ -27,7 +27,7 @@ | |
*/ | |
#define LIBAVCODEC_VERSION_MAJOR 54 | |
-#define LIBAVCODEC_VERSION_MINOR 55 | |
+#define LIBAVCODEC_VERSION_MINOR 56 | |
#define LIBAVCODEC_VERSION_MICRO 100 | |
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | |
diff --git a/libavcodec/vt.c b/libavcodec/vt.c | |
new file mode 100644 | |
index 0000000..d8b9e0f | |
--- /dev/null | |
+++ b/libavcodec/vt.c | |
@@ -0,0 +1,388 @@ | |
+/* | |
+ * VideoToolbox hardware acceleration | |
+ * | |
+ * copyright (c) 2012 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 "libavutil/avutil.h" | |
+#include "vt_internal.h" | |
+ | |
+static int vt_write_mp4_descr_length(PutBitContext *pb, int length, int compact) | |
+{ | |
+ int i; | |
+ uint8_t b; | |
+ int nb; | |
+ | |
+ if (compact) { | |
+ if (length <= 0x7F) | |
+ nb = 1; | |
+ else if (length <= 0x3FFF) | |
+ nb = 2; | |
+ else if (length <= 0x1FFFFF) | |
+ nb = 3; | |
+ else | |
+ nb = 4; | |
+ } | |
+ else | |
+ nb = 4; | |
+ | |
+ for (i = nb-1; i >= 0; i--) { | |
+ b = (length >> (i * 7)) & 0x7F; | |
+ if (i != 0) { | |
+ b |= 0x80; | |
+ } | |
+ put_bits(pb, 8, b); | |
+ } | |
+ | |
+ return nb; | |
+} | |
+ | |
+static CFDataRef vt_esds_extradata_create(uint8_t *extradata, int size) | |
+{ | |
+ CFDataRef data; | |
+ uint8_t *rw_extradata; | |
+ PutBitContext pb; | |
+ int full_size = 3 + (5 + (13 + (5 + size))) + 3; | |
+ int config_size = 13 + 5 + size; | |
+ int padding = 12; | |
+ int s, i = 0; | |
+ | |
+ if (!(rw_extradata = av_mallocz(sizeof(uint8_t)*(full_size+padding)))) | |
+ return NULL; | |
+ | |
+ init_put_bits(&pb, rw_extradata, full_size+padding); | |
+ put_bits(&pb, 8, 0); ///< version | |
+ put_bits(&pb, 24, 0); ///< flags | |
+ | |
+ // elementary stream descriptor | |
+ put_bits(&pb, 8, 0x03); ///< ES_DescrTag | |
+ vt_write_mp4_descr_length(&pb, full_size, 0); | |
+ put_bits(&pb, 16, 0); ///< esid | |
+ put_bits(&pb, 8, 0); ///< stream priority (0-32) | |
+ | |
+ // decoder configuration descriptor | |
+ put_bits(&pb, 8, 0x04); ///< DecoderConfigDescrTag | |
+ vt_write_mp4_descr_length(&pb, config_size, 0); | |
+ put_bits(&pb, 8, 32); ///< object type indication. 32 = CODEC_ID_MPEG4 | |
+ put_bits(&pb, 8, 0x11); ///< stream type | |
+ put_bits(&pb, 24, 0); ///< buffer size | |
+ put_bits32(&pb, 0); ///< max bitrate | |
+ put_bits32(&pb, 0); ///< avg bitrate | |
+ | |
+ // decoder specific descriptor | |
+ put_bits(&pb, 8, 0x05); ///< DecSpecificInfoTag | |
+ vt_write_mp4_descr_length(&pb, size, 0); | |
+ for (i = 0; i < size; i++) | |
+ put_bits(&pb, 8, extradata[i]); | |
+ | |
+ // SLConfigDescriptor | |
+ put_bits(&pb, 8, 0x06); ///< SLConfigDescrTag | |
+ put_bits(&pb, 8, 0x01); ///< length | |
+ put_bits(&pb, 8, 0x02); ///< | |
+ | |
+ flush_put_bits(&pb); | |
+ s = put_bits_count(&pb) / 8; | |
+ | |
+ data = CFDataCreate(kCFAllocatorDefault, rw_extradata, s); | |
+ | |
+ av_freep(&rw_extradata); | |
+ return data; | |
+} | |
+ | |
+static CFDataRef vt_avcc_extradata_create(uint8_t *extradata, int size) | |
+{ | |
+ CFDataRef data; | |
+ /* Each VCL NAL in the bistream 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 (size >= 4 && (extradata[4] & 0x03) != 0x03) { | |
+ uint8_t *rw_extradata; | |
+ | |
+ if (!(rw_extradata = av_malloc(size))) | |
+ return NULL; | |
+ | |
+ memcpy(rw_extradata, extradata, size); | |
+ | |
+ rw_extradata[4] |= 0x03; | |
+ | |
+ data = CFDataCreate(kCFAllocatorDefault, rw_extradata, size); | |
+ | |
+ av_freep(&rw_extradata); | |
+ } else { | |
+ data = CFDataCreate(kCFAllocatorDefault, extradata, size); | |
+ } | |
+ | |
+ return data; | |
+} | |
+ | |
+static CMSampleBufferRef vt_sample_buffer_create(CMFormatDescriptionRef fmt_desc, | |
+ void *buffer, | |
+ int size) | |
+{ | |
+ OSStatus status; | |
+ CMBlockBufferRef block_buf; | |
+ CMSampleBufferRef sample_buf; | |
+ | |
+ block_buf = NULL; | |
+ sample_buf = NULL; | |
+ | |
+ status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,///< structureAllocator | |
+ buffer, ///< memoryBlock | |
+ size, ///< blockLength | |
+ kCFAllocatorNull, ///< blockAllocator | |
+ NULL, ///< customBlockSource | |
+ 0, ///< offsetToData | |
+ size, ///< dataLength | |
+ 0, ///< flags | |
+ &block_buf); | |
+ | |
+ if (!status) { | |
+ status = CMSampleBufferCreate(kCFAllocatorDefault, ///< allocator | |
+ block_buf, ///< dataBuffer | |
+ TRUE, ///< dataReady | |
+ 0, ///< makeDataReadyCallback | |
+ 0, ///< makeDataReadyRefcon | |
+ fmt_desc, ///< formatDescription | |
+ 1, ///< numSamples | |
+ 0, ///< numSampleTimingEntries | |
+ NULL, ///< sampleTimingArray | |
+ 0, ///< numSampleSizeEntries | |
+ NULL, ///< sampleSizeArray | |
+ &sample_buf); | |
+ } | |
+ | |
+ if (block_buf) | |
+ CFRelease(block_buf); | |
+ | |
+ return sample_buf; | |
+} | |
+ | |
+static void vt_decoder_callback(void *vt_hw_ctx, | |
+ void *sourceFrameRefCon, | |
+ OSStatus status, | |
+ VTDecodeInfoFlags flags, | |
+ CVImageBufferRef image_buffer, | |
+ CMTime pts, | |
+ CMTime duration) | |
+{ | |
+ struct vt_context *vt_ctx = vt_hw_ctx; | |
+ vt_ctx->cv_buffer = NULL; | |
+ | |
+ if (!image_buffer) | |
+ return; | |
+ | |
+ if (vt_ctx->cv_pix_fmt != CVPixelBufferGetPixelFormatType(image_buffer)) | |
+ return; | |
+ | |
+ vt_ctx->cv_buffer = CVPixelBufferRetain(image_buffer); | |
+} | |
+ | |
+int ff_vt_session_decode_frame(struct vt_context *vt_ctx) | |
+{ | |
+ OSStatus status; | |
+ CMSampleBufferRef sample_buf; | |
+ | |
+ sample_buf = vt_sample_buffer_create(vt_ctx->cm_fmt_desc, | |
+ vt_ctx->priv_bitstream, | |
+ vt_ctx->priv_bitstream_size); | |
+ | |
+ if (!sample_buf) | |
+ return -1; | |
+ | |
+ status = VTDecompressionSessionDecodeFrame(vt_ctx->session, | |
+ sample_buf, | |
+ 0, ///< decodeFlags | |
+ NULL, ///< sourceFrameRefCon | |
+ 0); ///< infoFlagsOut | |
+ if (status == noErr) | |
+ status = VTDecompressionSessionWaitForAsynchronousFrames(vt_ctx->session); | |
+ | |
+ CFRelease(sample_buf); | |
+ | |
+ return status; | |
+} | |
+ | |
+int ff_vt_buffer_copy(struct vt_context *vt_ctx, const uint8_t *buffer, uint32_t size) | |
+{ | |
+ void *tmp; | |
+ tmp = av_fast_realloc(vt_ctx->priv_bitstream, | |
+ &vt_ctx->priv_allocated_size, | |
+ size); | |
+ if (!tmp) | |
+ return AVERROR(ENOMEM); | |
+ | |
+ vt_ctx->priv_bitstream = tmp; | |
+ | |
+ memcpy(vt_ctx->priv_bitstream, buffer, size); | |
+ | |
+ vt_ctx->priv_bitstream_size = size; | |
+ | |
+ return 0; | |
+} | |
+ | |
+void ff_vt_end_frame(MpegEncContext *s) | |
+{ | |
+ struct vt_context * const vt_ctx = s->avctx->hwaccel_context; | |
+ AVFrame *frame = &s->current_picture_ptr->f; | |
+ | |
+ frame->data[3] = (void*)vt_ctx->cv_buffer; | |
+} | |
+ | |
+int ff_vt_session_create(struct vt_context *vt_ctx, | |
+ CMVideoFormatDescriptionRef fmt_desc, | |
+ CFDictionaryRef decoder_spec, | |
+ CFDictionaryRef buf_attr) | |
+{ | |
+ OSStatus status; | |
+ VTDecompressionOutputCallbackRecord decoder_cb; | |
+ | |
+ if (!fmt_desc) | |
+ return -1; | |
+ | |
+ vt_ctx->cm_fmt_desc = CFRetain(fmt_desc); | |
+ | |
+ decoder_cb.decompressionOutputCallback = vt_decoder_callback; | |
+ decoder_cb.decompressionOutputRefCon = vt_ctx; | |
+ | |
+ status = VTDecompressionSessionCreate(NULL, ///< allocator | |
+ fmt_desc, ///< videoFormatDescription | |
+ decoder_spec, ///< videoDecoderSpecification | |
+ buf_attr, ///< destinationImageBufferAttributes | |
+ &decoder_cb, ///< outputCallback | |
+ &vt_ctx->session);///< decompressionSessionOut | |
+ if (noErr != status) | |
+ return status; | |
+ | |
+ return 0; | |
+} | |
+ | |
+void ff_vt_session_invalidate(struct vt_context *vt_ctx) | |
+{ | |
+ if (vt_ctx->cm_fmt_desc) | |
+ CFRelease(vt_ctx->cm_fmt_desc); | |
+ | |
+ if (vt_ctx->session) | |
+ VTDecompressionSessionInvalidate(vt_ctx->session); | |
+ | |
+ av_freep(&vt_ctx->priv_bitstream); | |
+} | |
+ | |
+CFDictionaryRef ff_vt_decoder_config_create(CMVideoCodecType codec_type, | |
+ uint8_t *extradata, int size) | |
+{ | |
+ CFMutableDictionaryRef config_info = NULL; | |
+ if (size) { | |
+ CFMutableDictionaryRef avc_info; | |
+ CFDataRef data; | |
+ | |
+ config_info = CFDictionaryCreateMutable(kCFAllocatorDefault, | |
+ 1, | |
+ &kCFTypeDictionaryKeyCallBacks, | |
+ &kCFTypeDictionaryValueCallBacks); | |
+ avc_info = CFDictionaryCreateMutable(kCFAllocatorDefault, | |
+ 1, | |
+ &kCFTypeDictionaryKeyCallBacks, | |
+ &kCFTypeDictionaryValueCallBacks); | |
+ | |
+ switch (codec_type) { | |
+ case kCMVideoCodecType_MPEG4Video : | |
+ data = vt_esds_extradata_create(extradata, size); | |
+ if (data) | |
+ CFDictionarySetValue(avc_info, CFSTR("esds"), data); | |
+ break; | |
+ case kCMVideoCodecType_H264 : | |
+ data = vt_avcc_extradata_create(extradata, size); | |
+ if (data) | |
+ CFDictionarySetValue(avc_info, CFSTR("avcC"), data); | |
+ break; | |
+ default: | |
+ break; | |
+ } | |
+ | |
+ CFDictionarySetValue(config_info, | |
+ kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms, | |
+ avc_info); | |
+ | |
+ if (data) | |
+ CFRelease(data); | |
+ CFRelease(avc_info); | |
+ } | |
+ return config_info; | |
+} | |
+ | |
+CFDictionaryRef ff_vt_buffer_attributes_create(int width, int height, OSType pix_fmt) | |
+{ | |
+ CFMutableDictionaryRef buffer_attributes; | |
+ CFMutableDictionaryRef io_surface_properties; | |
+ CFNumberRef cv_pix_fmt; | |
+ CFNumberRef w; | |
+ CFNumberRef h; | |
+ | |
+ w = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width); | |
+ h = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height); | |
+ cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pix_fmt); | |
+ | |
+ buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, | |
+ 4, | |
+ &kCFTypeDictionaryKeyCallBacks, | |
+ &kCFTypeDictionaryValueCallBacks); | |
+ io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault, | |
+ 0, | |
+ &kCFTypeDictionaryKeyCallBacks, | |
+ &kCFTypeDictionaryValueCallBacks); | |
+ CFDictionarySetValue(buffer_attributes, | |
+ kCVPixelBufferPixelFormatTypeKey, | |
+ cv_pix_fmt); | |
+ CFDictionarySetValue(buffer_attributes, | |
+ kCVPixelBufferIOSurfacePropertiesKey, | |
+ io_surface_properties); | |
+ CFDictionarySetValue(buffer_attributes, | |
+ kCVPixelBufferWidthKey, | |
+ w); | |
+ CFDictionarySetValue(buffer_attributes, | |
+ kCVPixelBufferHeightKey, | |
+ h); | |
+ | |
+ CFRelease(io_surface_properties); | |
+ CFRelease(cv_pix_fmt); | |
+ CFRelease(w); | |
+ CFRelease(h); | |
+ | |
+ return buffer_attributes; | |
+} | |
+ | |
+CMVideoFormatDescriptionRef ff_vt_format_desc_create(CMVideoCodecType codec_type, | |
+ CFDictionaryRef decoder_spec, | |
+ int width, int height) | |
+{ | |
+ CMFormatDescriptionRef cm_fmt_desc; | |
+ OSStatus status; | |
+ | |
+ status = CMVideoFormatDescriptionCreate(kCFAllocatorDefault, | |
+ codec_type, | |
+ width, | |
+ height, | |
+ decoder_spec, ///< Dictionary of extension | |
+ &cm_fmt_desc); | |
+ | |
+ if (status) | |
+ return NULL; | |
+ | |
+ return cm_fmt_desc; | |
+} | |
diff --git a/libavcodec/vt.h b/libavcodec/vt.h | |
new file mode 100644 | |
index 0000000..711216e | |
--- /dev/null | |
+++ b/libavcodec/vt.h | |
@@ -0,0 +1,185 @@ | |
+/* | |
+ * VideoToolbox hardware acceleration | |
+ * | |
+ * copyright (c) 2012 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_VT_H | |
+#define AVCODEC_VT_H | |
+ | |
+/** | |
+ * @file | |
+ * @ingroup lavc_codec_hwaccel_vt | |
+ * Public libavcodec VideoToolbox header. | |
+ */ | |
+ | |
+#include <stdint.h> | |
+ | |
+#define Picture QuickdrawPicture | |
+#include <VideoToolbox/VideoToolbox.h> | |
+#undef Picture | |
+ | |
+/** | |
+ * This structure is used to provide the necessary configurations and data | |
+ * to the VideoToolbox Libav HWAccel implementation. | |
+ * | |
+ * The application must make it available as AVCodecContext.hwaccel_context. | |
+ */ | |
+struct vt_context { | |
+ /** | |
+ * VideoToolbox decompression session. | |
+ * | |
+ * - encoding: unused. | |
+ * - decoding: Set/Unset by libavcodec. | |
+ */ | |
+ VTDecompressionSessionRef session; | |
+ | |
+ /** | |
+ * The width of encoded video. | |
+ * | |
+ * - encoding: unused. | |
+ * - decoding: Set/Unset by user. | |
+ */ | |
+ int width; | |
+ | |
+ /** | |
+ * The height of encoded video. | |
+ * | |
+ * - encoding: unused. | |
+ * - decoding: Set/Unset by user. | |
+ */ | |
+ int height; | |
+ | |
+ /** | |
+ * The type of video compression. | |
+ * | |
+ * - encoding: unused. | |
+ * - decoding: Set/Unset by user. | |
+ */ | |
+ int cm_codec_type; | |
+ | |
+ /** | |
+ * The pixel format for output image buffers. | |
+ * | |
+ * - encoding: unused. | |
+ * - decoding: Set/Unset by user. | |
+ */ | |
+ OSType cv_pix_fmt; | |
+ | |
+ /** | |
+ * The video format description. | |
+ * | |
+ * encoding: unused. | |
+ * decoding: Set by user. Unset by libavcodec. | |
+ */ | |
+ CMVideoFormatDescriptionRef cm_fmt_desc; | |
+ | |
+ /** | |
+ * The Core Video pixel buffer that contains the current image data. | |
+ * | |
+ * encoding: unused. | |
+ * decoding: Set by libavcodec. Unset by user. | |
+ */ | |
+ CVImageBufferRef cv_buffer; | |
+ | |
+ /** | |
+ * The current bitstream buffer. | |
+ */ | |
+ uint8_t *priv_bitstream; | |
+ | |
+ /** | |
+ * The current size of the bitstream. | |
+ */ | |
+ int priv_bitstream_size; | |
+ | |
+ /** | |
+ * The allocated size used for fast reallocation. | |
+ */ | |
+ int priv_allocated_size; | |
+}; | |
+ | |
+/** | |
+ * Create a decompression session. | |
+ * | |
+ * @param vt_ctx The VideoToolbox context. | |
+ * @param fmt_desc The video format description. | |
+ * @param decoder_spec The specific decoder configuration. | |
+ * @param buf_attr The output buffer attributes. | |
+ * @return Status. | |
+ */ | |
+int ff_vt_session_create(struct vt_context *vt_ctx, | |
+ CMVideoFormatDescriptionRef fmt_desc, | |
+ CFDictionaryRef decoder_spec, | |
+ CFDictionaryRef buf_attr); | |
+ | |
+/** | |
+ * Destroy a decompression session. | |
+ * | |
+ * @param vt_ctx The VideoToolbox context. | |
+ */ | |
+void ff_vt_session_invalidate(struct vt_context *vt_ctx); | |
+ | |
+/** | |
+ * Create the decoder configuration dictionary. | |
+ * | |
+ * It is the user's responsability to release the returned object (using CFRelease) when | |
+ * user has finished with it. | |
+ * | |
+ * @param codec_type The type of video compression. | |
+ * @param extradata The stream extradata. | |
+ * @param size The extradata size. | |
+ * @return A CoreFoundation dictionary or NULL if there was a problem creating the object. | |
+ */ | |
+CFDictionaryRef ff_vt_decoder_config_create(CMVideoCodecType codec_type, | |
+ uint8_t *extradata, int size); | |
+ | |
+/** | |
+ * Create the output buffer attributes. | |
+ * | |
+ * It is the user's responsability to release the returned object (using CFRelease) when | |
+ * user has finished with it. | |
+ * | |
+ * @param width The width of output image. | |
+ * @param height The height of output image. | |
+ * @param pix_fmt The pixel format of output image. | |
+ * @return A CoreFoundation dictionary. | |
+ */ | |
+CFDictionaryRef ff_vt_buffer_attributes_create(int width, int height, OSType pix_fmt); | |
+ | |
+/** | |
+ * Create the video format description. | |
+ * | |
+ * It is the user's responsability to release the returned object (using CFRelease) when | |
+ * user has finished with it. | |
+ * | |
+ * @param codec_type The type of video compression. | |
+ * @param decoder_spec The specific decoder configuration. | |
+ * @param width The width of encoded video. | |
+ * @param height The height of encoded video. | |
+ * @return A CoreMedia video format object. | |
+ */ | |
+CMVideoFormatDescriptionRef ff_vt_format_desc_create(CMVideoCodecType codec_type, | |
+ CFDictionaryRef decoder_spec, | |
+ int width, int height); | |
+ | |
+/** | |
+ * @} | |
+ */ | |
+ | |
+#endif /* AVCODEC_VT_H */ | |
diff --git a/libavcodec/vt_h264.c b/libavcodec/vt_h264.c | |
new file mode 100644 | |
index 0000000..763e091 | |
--- /dev/null | |
+++ b/libavcodec/vt_h264.c | |
@@ -0,0 +1,94 @@ | |
+/* | |
+ * VideoToolbox H264 hardware acceleration | |
+ * | |
+ * copyright (c) 2012 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 "h264.h" | |
+#include "vt_internal.h" | |
+ | |
+static int start_frame(AVCodecContext *avctx, | |
+ av_unused const uint8_t *buffer, | |
+ av_unused uint32_t size) | |
+{ | |
+ struct vt_context *vt_ctx = avctx->hwaccel_context; | |
+ | |
+ if (!vt_ctx->session) | |
+ return -1; | |
+ | |
+ vt_ctx->priv_bitstream_size = 0; | |
+ | |
+ return 0; | |
+} | |
+ | |
+static int decode_slice(AVCodecContext *avctx, | |
+ const uint8_t *buffer, | |
+ uint32_t size) | |
+{ | |
+ struct vt_context *vt_ctx = avctx->hwaccel_context; | |
+ void *tmp; | |
+ | |
+ if (!vt_ctx->session) | |
+ return -1; | |
+ | |
+ tmp = av_fast_realloc(vt_ctx->priv_bitstream, | |
+ &vt_ctx->priv_allocated_size, | |
+ vt_ctx->priv_bitstream_size+size+4); | |
+ if (!tmp) | |
+ return AVERROR(ENOMEM); | |
+ | |
+ vt_ctx->priv_bitstream = tmp; | |
+ | |
+ AV_WB32(vt_ctx->priv_bitstream + vt_ctx->priv_bitstream_size, size); | |
+ memcpy(vt_ctx->priv_bitstream + vt_ctx->priv_bitstream_size + 4, buffer, size); | |
+ | |
+ vt_ctx->priv_bitstream_size += size + 4; | |
+ | |
+ return 0; | |
+} | |
+ | |
+static int end_frame(AVCodecContext *avctx) | |
+{ | |
+ struct vt_context *vt_ctx = avctx->hwaccel_context; | |
+ int status; | |
+ | |
+ if (!vt_ctx->session || !vt_ctx->priv_bitstream) | |
+ return -1; | |
+ | |
+ status = ff_vt_session_decode_frame(vt_ctx); | |
+ | |
+ if (status) { | |
+ av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status); | |
+ return status; | |
+ } | |
+ | |
+ ff_vt_end_frame(avctx->priv_data); | |
+ | |
+ return status; | |
+} | |
+ | |
+AVHWAccel ff_h264_vt_hwaccel = { | |
+ .name = "h264_vt", | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .id = CODEC_ID_H264, | |
+ .pix_fmt = PIX_FMT_VT_VLD, | |
+ .start_frame = start_frame, | |
+ .decode_slice = decode_slice, | |
+ .end_frame = end_frame, | |
+}; | |
diff --git a/libavcodec/vt_internal.h b/libavcodec/vt_internal.h | |
new file mode 100644 | |
index 0000000..e882c8c | |
--- /dev/null | |
+++ b/libavcodec/vt_internal.h | |
@@ -0,0 +1,44 @@ | |
+/* | |
+ * VideoToolbox hardware acceleration | |
+ * | |
+ * copyright (c) 2012 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_VT_INTERNAL_H | |
+#define AVCODEC_VT_INTERNAL_H | |
+ | |
+#include "vt.h" | |
+#include "mpegvideo.h" | |
+ | |
+/** | |
+ * @addtogroup VT_Decoding | |
+ * | |
+ * @{ | |
+ */ | |
+ | |
+int ff_vt_session_decode_frame(struct vt_context *vt_ctx); | |
+ | |
+int ff_vt_buffer_copy(struct vt_context *vt_ctx, | |
+ const uint8_t *buffer, | |
+ uint32_t size); | |
+void ff_vt_end_frame(MpegEncContext *s); | |
+ | |
+/* @} */ | |
+ | |
+#endif /* AVCODEC_VT_INTERNAL_H */ | |
diff --git a/libavcodec/vt_mpeg2.c b/libavcodec/vt_mpeg2.c | |
new file mode 100644 | |
index 0000000..c3ffba2 | |
--- /dev/null | |
+++ b/libavcodec/vt_mpeg2.c | |
@@ -0,0 +1,77 @@ | |
+/* | |
+ * VideoToolbox MPEG2 hardware acceleration | |
+ * | |
+ * copyright (c) 2012 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 "vt_internal.h" | |
+ | |
+static int start_frame(AVCodecContext *avctx, | |
+ const uint8_t *buffer, | |
+ uint32_t size) | |
+{ | |
+ struct vt_context *vt_ctx = avctx->hwaccel_context; | |
+ | |
+ if (!vt_ctx->session) | |
+ return -1; | |
+ | |
+ return ff_vt_buffer_copy(vt_ctx, buffer, size); | |
+} | |
+ | |
+static int decode_slice(AVCodecContext *avctx, | |
+ const uint8_t *buffer, | |
+ uint32_t size) | |
+{ | |
+ struct vt_context *vt_ctx = avctx->hwaccel_context; | |
+ | |
+ if (!vt_ctx->session) | |
+ return -1; | |
+ | |
+ return 0; | |
+} | |
+ | |
+static int end_frame(AVCodecContext *avctx) | |
+{ | |
+ struct vt_context *vt_ctx = avctx->hwaccel_context; | |
+ int status; | |
+ | |
+ if (!vt_ctx->session || !vt_ctx->priv_bitstream) | |
+ return -1; | |
+ | |
+ status = ff_vt_session_decode_frame(vt_ctx); | |
+ | |
+ if (status) { | |
+ av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status); | |
+ return status; | |
+ } | |
+ | |
+ ff_vt_end_frame(avctx->priv_data); | |
+ | |
+ return status; | |
+} | |
+ | |
+AVHWAccel ff_mpeg2_vt_hwaccel = { | |
+ .name = "mpeg2_vt", | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .id = AV_CODEC_ID_MPEG2VIDEO, | |
+ .pix_fmt = PIX_FMT_VT_VLD, | |
+ .start_frame = start_frame, | |
+ .end_frame = end_frame, | |
+ .decode_slice = decode_slice, | |
+}; | |
diff --git a/libavcodec/vt_mpeg4.c b/libavcodec/vt_mpeg4.c | |
new file mode 100644 | |
index 0000000..43bde56 | |
--- /dev/null | |
+++ b/libavcodec/vt_mpeg4.c | |
@@ -0,0 +1,92 @@ | |
+/* | |
+ * VideoToolbox MPEG4 / H263 hardware acceleration | |
+ * | |
+ * copyright (c) 2012 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 "vt_internal.h" | |
+ | |
+static int start_frame(AVCodecContext *avctx, | |
+ const uint8_t *buffer, | |
+ uint32_t size) | |
+{ | |
+ struct vt_context *vt_ctx = avctx->hwaccel_context; | |
+ | |
+ if (!vt_ctx->session) | |
+ return -1; | |
+ | |
+ return ff_vt_buffer_copy(vt_ctx, buffer, size); | |
+} | |
+ | |
+static int decode_slice(AVCodecContext *avctx, | |
+ const uint8_t *buffer, | |
+ uint32_t size) | |
+{ | |
+ struct vt_context *vt_ctx = avctx->hwaccel_context; | |
+ | |
+ if (!vt_ctx->session) | |
+ return -1; | |
+ | |
+ return 0; | |
+} | |
+ | |
+static int end_frame(AVCodecContext *avctx) | |
+{ | |
+ struct vt_context *vt_ctx = avctx->hwaccel_context; | |
+ int status; | |
+ | |
+ if (!vt_ctx->session || !vt_ctx->priv_bitstream) | |
+ return -1; | |
+ | |
+ status = ff_vt_session_decode_frame(vt_ctx); | |
+ | |
+ if (status) { | |
+ av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status); | |
+ return status; | |
+ } | |
+ | |
+ ff_vt_end_frame(avctx->priv_data); | |
+ | |
+ return status; | |
+} | |
+ | |
+#if CONFIG_MPEG4_VT_HWACCEL | |
+AVHWAccel ff_mpeg4_vt_hwaccel = { | |
+ .name = "mpeg4_vt", | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .id = AV_CODEC_ID_MPEG4, | |
+ .pix_fmt = PIX_FMT_VT_VLD, | |
+ .start_frame = start_frame, | |
+ .end_frame = end_frame, | |
+ .decode_slice = decode_slice, | |
+}; | |
+#endif | |
+ | |
+#if CONFIG_H263_VT_HWACCEL | |
+AVHWAccel ff_h263_vt_hwaccel = { | |
+ .name = "h263_vt", | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .id = AV_CODEC_ID_H263, | |
+ .pix_fmt = PIX_FMT_VT_VLD, | |
+ .start_frame = start_frame, | |
+ .end_frame = end_frame, | |
+ .decode_slice = decode_slice, | |
+}; | |
+#endif | |
+ | |
diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c | |
index d64d300..1143bcc 100644 | |
--- a/libavutil/pixdesc.c | |
+++ b/libavutil/pixdesc.c | |
@@ -1274,6 +1274,12 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[PIX_FMT_NB] = { | |
.log2_chroma_h = 1, | |
.flags = PIX_FMT_HWACCEL, | |
}, | |
+ [PIX_FMT_VT_VLD] = { | |
+ .name = "vt_vld", | |
+ .log2_chroma_w = 1, | |
+ .log2_chroma_h = 1, | |
+ .flags = PIX_FMT_HWACCEL, | |
+ }, | |
[PIX_FMT_GRAY8A] = { | |
.name = "gray8a", | |
.nb_components = 2, | |
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h | |
index fa771bc..d47d911 100644 | |
--- a/libavutil/pixfmt.h | |
+++ b/libavutil/pixfmt.h | |
@@ -201,6 +201,7 @@ enum PixelFormat { | |
PIX_FMT_GBRP12LE, ///< planar GBR 4:4:4 36bpp, little endian | |
PIX_FMT_GBRP14BE, ///< planar GBR 4:4:4 42bpp, big endian | |
PIX_FMT_GBRP14LE, ///< planar GBR 4:4:4 42bpp, little endian | |
+ PIX_FMT_VT_VLD, ///< hardware decoding through VideoToolbox | |
PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions | |
}; | |
-- | |
1.7.9.6 (Apple Git-31.1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment