24 #if CONFIG_VIDEOTOOLBOX
34 #include <TargetConditionals.h>
36 #ifndef kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder
37 # define kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder CFSTR("RequireHardwareAcceleratedVideoDecoder")
40 #define VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING 12
44 CVPixelBufferRef cv_buffer = (CVImageBufferRef)data;
45 CVPixelBufferRelease(cv_buffer);
81 #define AV_W8(p, v) *(p) = (v)
109 av_assert0(p - vt_extradata == vt_extradata_size);
111 data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size);
121 sizeof(vtctx->
frame),
125 if (!frame->
buf[0]) {
184 CVPixelBufferRelease(vtctx->
frame);
190 #if CONFIG_VIDEOTOOLBOX
196 for (i = 3; i >= 0; i--) {
197 b = (length >> (i * 7)) & 0x7F;
201 bytestream2_put_byteu(pb, b);
205 static CFDataRef videotoolbox_esds_extradata_create(
AVCodecContext *avctx)
219 bytestream2_put_byteu(&pb, 0);
223 bytestream2_put_byteu(&pb, 0x03);
224 videotoolbox_write_mp4_descr_length(&pb, full_size);
226 bytestream2_put_byteu(&pb, 0);
229 bytestream2_put_byteu(&pb, 0x04);
230 videotoolbox_write_mp4_descr_length(&pb, config_size);
231 bytestream2_put_byteu(&pb, 32);
232 bytestream2_put_byteu(&pb, 0x11);
238 bytestream2_put_byteu(&pb, 0x05);
244 bytestream2_put_byteu(&pb, 0x06);
245 bytestream2_put_byteu(&pb, 0x01);
246 bytestream2_put_byteu(&pb, 0x02);
250 data = CFDataCreate(kCFAllocatorDefault, rw_extradata, s);
256 static CMSampleBufferRef videotoolbox_sample_buffer_create(CMFormatDescriptionRef fmt_desc,
261 CMBlockBufferRef block_buf;
262 CMSampleBufferRef sample_buf;
267 status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,
278 status = CMSampleBufferCreate(kCFAllocatorDefault,
293 CFRelease(block_buf);
298 static void videotoolbox_decoder_callback(
void *opaque,
299 void *sourceFrameRefCon,
301 VTDecodeInfoFlags
flags,
302 CVImageBufferRef image_buffer,
310 CVPixelBufferRelease(vtctx->
frame);
319 vtctx->
frame = CVPixelBufferRetain(image_buffer);
322 static OSStatus videotoolbox_session_decode_frame(
AVCodecContext *avctx)
325 CMSampleBufferRef sample_buf;
329 sample_buf = videotoolbox_sample_buffer_create(videotoolbox->
cm_fmt_desc,
336 status = VTDecompressionSessionDecodeFrame(videotoolbox->
session,
342 status = VTDecompressionSessionWaitForAsynchronousFrames(videotoolbox->
session);
344 CFRelease(sample_buf);
358 status = videotoolbox_session_decode_frame(avctx);
376 return videotoolbox_common_end_frame(avctx, frame);
400 return videotoolbox_common_end_frame(avctx, frame);
403 static CFDictionaryRef videotoolbox_decoder_config_create(CMVideoCodecType
codec_type,
406 CFMutableDictionaryRef config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
408 &kCFTypeDictionaryKeyCallBacks,
409 &kCFTypeDictionaryValueCallBacks);
411 CFDictionarySetValue(config_info,
416 CFMutableDictionaryRef avc_info;
417 CFDataRef data =
NULL;
419 avc_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
421 &kCFTypeDictionaryKeyCallBacks,
422 &kCFTypeDictionaryValueCallBacks);
424 switch (codec_type) {
425 case kCMVideoCodecType_MPEG4Video :
426 data = videotoolbox_esds_extradata_create(avctx);
428 CFDictionarySetValue(avc_info, CFSTR(
"esds"), data);
430 case kCMVideoCodecType_H264 :
433 CFDictionarySetValue(avc_info, CFSTR(
"avcC"), data);
439 CFDictionarySetValue(config_info,
440 kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms,
451 static CFDictionaryRef videotoolbox_buffer_attributes_create(
int width,
455 CFMutableDictionaryRef buffer_attributes;
456 CFMutableDictionaryRef io_surface_properties;
457 CFNumberRef cv_pix_fmt;
461 w = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width);
462 h = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height);
463 cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pix_fmt);
465 buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
467 &kCFTypeDictionaryKeyCallBacks,
468 &kCFTypeDictionaryValueCallBacks);
469 io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault,
471 &kCFTypeDictionaryKeyCallBacks,
472 &kCFTypeDictionaryValueCallBacks);
475 CFDictionarySetValue(buffer_attributes, kCVPixelBufferPixelFormatTypeKey, cv_pix_fmt);
476 CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfacePropertiesKey, io_surface_properties);
477 CFDictionarySetValue(buffer_attributes, kCVPixelBufferWidthKey, w);
478 CFDictionarySetValue(buffer_attributes, kCVPixelBufferHeightKey, h);
480 CFDictionarySetValue(buffer_attributes, kCVPixelBufferOpenGLESCompatibilityKey, kCFBooleanTrue);
482 CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfaceOpenGLTextureCompatibilityKey, kCFBooleanTrue);
485 CFRelease(io_surface_properties);
486 CFRelease(cv_pix_fmt);
490 return buffer_attributes;
493 static CMVideoFormatDescriptionRef videotoolbox_format_desc_create(CMVideoCodecType codec_type,
494 CFDictionaryRef decoder_spec,
498 CMFormatDescriptionRef cm_fmt_desc;
501 status = CMVideoFormatDescriptionCreate(kCFAllocatorDefault,
518 VTDecompressionOutputCallbackRecord decoder_cb;
519 CFDictionaryRef decoder_spec;
520 CFDictionaryRef buf_attr;
547 decoder_spec = videotoolbox_decoder_config_create(videotoolbox->
cm_codec_type, avctx);
555 CFRelease(decoder_spec);
561 buf_attr = videotoolbox_buffer_attributes_create(avctx->
width,
565 decoder_cb.decompressionOutputCallback = videotoolbox_decoder_callback;
566 decoder_cb.decompressionOutputRefCon = avctx;
568 status = VTDecompressionSessionCreate(
NULL,
576 CFRelease(decoder_spec);
581 case kVTVideoDecoderNotAvailableNowErr:
582 case kVTVideoDecoderUnsupportedDataFormatErr:
584 case kVTVideoDecoderMalfunctionErr:
586 case kVTVideoDecoderBadDataErr :
604 VTDecompressionSessionInvalidate(videotoolbox->
session);
605 CFRelease(videotoolbox->
session);
610 AVHWAccel ff_h263_videotoolbox_hwaccel = {
611 .
name =
"h263_videotoolbox",
616 .start_frame = videotoolbox_mpeg_start_frame,
617 .decode_slice = videotoolbox_mpeg_decode_slice,
618 .end_frame = videotoolbox_mpeg_end_frame,
623 AVHWAccel ff_h264_videotoolbox_hwaccel = {
624 .
name =
"h264_videotoolbox",
631 .end_frame = videotoolbox_h264_end_frame,
636 AVHWAccel ff_mpeg1_videotoolbox_hwaccel = {
637 .
name =
"mpeg1_videotoolbox",
642 .start_frame = videotoolbox_mpeg_start_frame,
643 .decode_slice = videotoolbox_mpeg_decode_slice,
644 .end_frame = videotoolbox_mpeg_end_frame,
649 AVHWAccel ff_mpeg2_videotoolbox_hwaccel = {
650 .
name =
"mpeg2_videotoolbox",
655 .start_frame = videotoolbox_mpeg_start_frame,
656 .decode_slice = videotoolbox_mpeg_decode_slice,
657 .end_frame = videotoolbox_mpeg_end_frame,
662 AVHWAccel ff_mpeg4_videotoolbox_hwaccel = {
663 .
name =
"mpeg4_videotoolbox",
668 .start_frame = videotoolbox_mpeg_start_frame,
669 .decode_slice = videotoolbox_mpeg_decode_slice,
670 .end_frame = videotoolbox_mpeg_end_frame,
681 ret->
cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
697 return videotoolbox_default_init(avctx);
703 videotoolbox_default_free(avctx);
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
static enum AVPixelFormat pix_fmt
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
This structure describes decoded (raw) audio or video data.
ptrdiff_t const GLvoid * data
int cm_codec_type
CoreMedia codec type that Videotoolbox will use to create the decompression session.
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
hardware decoding through Videotoolbox
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
enum AVMediaType codec_type
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Convenience header that includes libavutil's core.
int is_avc
Used to parse AVC variant of H.264.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
#define av_assert0(cond)
assert() equivalent, that is always enabled.
void * hwaccel_context
Hardware accelerator context.
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
int width
width and height of the video frame
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
AVBufferRef * av_buffer_create(uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
VTDecompressionSessionRef session
Videotoolbox decompression session object.
const char * name
Name of the hardware accelerated codec.
int width
picture width / height.
Picture * current_picture_ptr
pointer to the current picture
H.264 / AVC / MPEG-4 part10 codec.
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p, const uint8_t *src, unsigned int size)
preferred ID for MPEG-1/2 video decoding
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
AVBufferRef * av_buffer_alloc(int size)
Allocate an AVBuffer of the given size using av_malloc().
Public libavcodec VDA header.
#define bytestream2_put_ne24
main external API structure.
CMVideoFormatDescriptionRef cm_fmt_desc
CoreMedia Format Description that Videotoolbox will use to create the decompression session...
H264Picture * cur_pic_ptr
OSType cv_pix_fmt_type
CVPixelBuffer Format Type that Videotoolbox will use for decoded frames.
static int64_t pts
Global timestamp for the audio frames.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
VTDecompressionOutputCallback output_callback
The output callback that must be passed to the session.
void * hwaccel_priv_data
hwaccel-specific private data
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
struct AVCodecInternal * internal
Private context used for internal data.
#define bytestream2_put_ne32
#define bytestream2_put_ne16
This struct holds all the information that needs to be passed between the caller and libavcodec for i...
static av_always_inline int bytestream2_size_p(PutByteContext *p)