24 #if CONFIG_VIDEOTOOLBOX
35 #ifndef kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder
36 # define kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder CFSTR("RequireHardwareAcceleratedVideoDecoder")
39 #define VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING 12
43 CVPixelBufferRef cv_buffer = (CVImageBufferRef)data;
44 CVPixelBufferRelease(cv_buffer);
80 #define AV_W8(p, v) *(p) = (v)
108 av_assert0(p - vt_extradata == vt_extradata_size);
110 data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size);
120 sizeof(vtctx->
frame),
124 if (!frame->
buf[0]) {
183 CVPixelBufferRelease(vtctx->
frame);
189 #if CONFIG_VIDEOTOOLBOX
195 for (i = 3; i >= 0; i--) {
196 b = (length >> (i * 7)) & 0x7F;
200 bytestream2_put_byteu(pb, b);
204 static CFDataRef videotoolbox_esds_extradata_create(
AVCodecContext *avctx)
218 bytestream2_put_byteu(&pb, 0);
222 bytestream2_put_byteu(&pb, 0x03);
223 videotoolbox_write_mp4_descr_length(&pb, full_size);
225 bytestream2_put_byteu(&pb, 0);
228 bytestream2_put_byteu(&pb, 0x04);
229 videotoolbox_write_mp4_descr_length(&pb, config_size);
230 bytestream2_put_byteu(&pb, 32);
231 bytestream2_put_byteu(&pb, 0x11);
237 bytestream2_put_byteu(&pb, 0x05);
243 bytestream2_put_byteu(&pb, 0x06);
244 bytestream2_put_byteu(&pb, 0x01);
245 bytestream2_put_byteu(&pb, 0x02);
249 data = CFDataCreate(kCFAllocatorDefault, rw_extradata, s);
255 static CMSampleBufferRef videotoolbox_sample_buffer_create(CMFormatDescriptionRef fmt_desc,
260 CMBlockBufferRef block_buf;
261 CMSampleBufferRef sample_buf;
266 status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,
277 status = CMSampleBufferCreate(kCFAllocatorDefault,
292 CFRelease(block_buf);
297 static void videotoolbox_decoder_callback(
void *opaque,
298 void *sourceFrameRefCon,
300 VTDecodeInfoFlags
flags,
301 CVImageBufferRef image_buffer,
309 CVPixelBufferRelease(vtctx->
frame);
318 vtctx->
frame = CVPixelBufferRetain(image_buffer);
321 static OSStatus videotoolbox_session_decode_frame(
AVCodecContext *avctx)
324 CMSampleBufferRef sample_buf;
328 sample_buf = videotoolbox_sample_buffer_create(videotoolbox->
cm_fmt_desc,
335 status = VTDecompressionSessionDecodeFrame(videotoolbox->
session,
341 status = VTDecompressionSessionWaitForAsynchronousFrames(videotoolbox->
session);
343 CFRelease(sample_buf);
359 status = videotoolbox_session_decode_frame(avctx);
377 return videotoolbox_common_end_frame(avctx, frame);
401 return videotoolbox_common_end_frame(avctx, frame);
404 static CFDictionaryRef videotoolbox_decoder_config_create(CMVideoCodecType
codec_type,
407 CFMutableDictionaryRef config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
409 &kCFTypeDictionaryKeyCallBacks,
410 &kCFTypeDictionaryValueCallBacks);
412 CFDictionarySetValue(config_info,
417 CFMutableDictionaryRef avc_info;
418 CFDataRef data =
NULL;
420 avc_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
422 &kCFTypeDictionaryKeyCallBacks,
423 &kCFTypeDictionaryValueCallBacks);
425 switch (codec_type) {
426 case kCMVideoCodecType_MPEG4Video :
427 data = videotoolbox_esds_extradata_create(avctx);
429 CFDictionarySetValue(avc_info, CFSTR(
"esds"), data);
431 case kCMVideoCodecType_H264 :
434 CFDictionarySetValue(avc_info, CFSTR(
"avcC"), data);
440 CFDictionarySetValue(config_info,
441 kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms,
452 static CFDictionaryRef videotoolbox_buffer_attributes_create(
int width,
456 CFMutableDictionaryRef buffer_attributes;
457 CFMutableDictionaryRef io_surface_properties;
458 CFNumberRef cv_pix_fmt;
462 w = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width);
463 h = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height);
464 cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pix_fmt);
466 buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
468 &kCFTypeDictionaryKeyCallBacks,
469 &kCFTypeDictionaryValueCallBacks);
470 io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault,
472 &kCFTypeDictionaryKeyCallBacks,
473 &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 CFRelease(io_surface_properties);
481 CFRelease(cv_pix_fmt);
485 return buffer_attributes;
488 static CMVideoFormatDescriptionRef videotoolbox_format_desc_create(CMVideoCodecType codec_type,
489 CFDictionaryRef decoder_spec,
493 CMFormatDescriptionRef cm_fmt_desc;
496 status = CMVideoFormatDescriptionCreate(kCFAllocatorDefault,
513 VTDecompressionOutputCallbackRecord decoder_cb;
514 CFDictionaryRef decoder_spec;
515 CFDictionaryRef buf_attr;
542 decoder_spec = videotoolbox_decoder_config_create(videotoolbox->
cm_codec_type, avctx);
550 CFRelease(decoder_spec);
556 buf_attr = videotoolbox_buffer_attributes_create(avctx->
width,
560 decoder_cb.decompressionOutputCallback = videotoolbox_decoder_callback;
561 decoder_cb.decompressionOutputRefCon = avctx;
563 status = VTDecompressionSessionCreate(
NULL,
571 CFRelease(decoder_spec);
576 case kVTVideoDecoderNotAvailableNowErr:
577 case kVTVideoDecoderUnsupportedDataFormatErr:
579 case kVTVideoDecoderMalfunctionErr:
581 case kVTVideoDecoderBadDataErr :
599 VTDecompressionSessionInvalidate(videotoolbox->
session);
600 CFRelease(videotoolbox->
session);
605 AVHWAccel ff_h263_videotoolbox_hwaccel = {
606 .
name =
"h263_videotoolbox",
611 .start_frame = videotoolbox_mpeg_start_frame,
612 .decode_slice = videotoolbox_mpeg_decode_slice,
613 .end_frame = videotoolbox_mpeg_end_frame,
618 AVHWAccel ff_h264_videotoolbox_hwaccel = {
619 .
name =
"h264_videotoolbox",
626 .end_frame = videotoolbox_h264_end_frame,
631 AVHWAccel ff_mpeg1_videotoolbox_hwaccel = {
632 .
name =
"mpeg1_videotoolbox",
637 .start_frame = videotoolbox_mpeg_start_frame,
638 .decode_slice = videotoolbox_mpeg_decode_slice,
639 .end_frame = videotoolbox_mpeg_end_frame,
644 AVHWAccel ff_mpeg2_videotoolbox_hwaccel = {
645 .
name =
"mpeg2_videotoolbox",
650 .start_frame = videotoolbox_mpeg_start_frame,
651 .decode_slice = videotoolbox_mpeg_decode_slice,
652 .end_frame = videotoolbox_mpeg_end_frame,
657 AVHWAccel ff_mpeg4_videotoolbox_hwaccel = {
658 .
name =
"mpeg4_videotoolbox",
663 .start_frame = videotoolbox_mpeg_start_frame,
664 .decode_slice = videotoolbox_mpeg_decode_slice,
665 .end_frame = videotoolbox_mpeg_end_frame,
676 ret->
cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
692 return videotoolbox_default_init(avctx);
698 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.
int is_avc
Used to parse AVC variant of H.264.
#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.
H.264 / AVC / MPEG-4 part10 codec.
int width
width and height of the video frame
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given block if it is not large enough, otherwise do nothing.
#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
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...
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
static av_always_inline int bytestream2_size_p(PutByteContext *p)