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)
110 av_assert0(p - vt_extradata == vt_extradata_size);
112 data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size);
122 sizeof(vtctx->
frame),
126 if (!frame->
buf[0]) {
185 CVPixelBufferRelease(vtctx->
frame);
191 #if CONFIG_VIDEOTOOLBOX
197 for (i = 3; i >= 0; i--) {
198 b = (length >> (i * 7)) & 0x7F;
202 bytestream2_put_byteu(pb, b);
206 static CFDataRef videotoolbox_esds_extradata_create(
AVCodecContext *avctx)
220 bytestream2_put_byteu(&pb, 0);
224 bytestream2_put_byteu(&pb, 0x03);
225 videotoolbox_write_mp4_descr_length(&pb, full_size);
227 bytestream2_put_byteu(&pb, 0);
230 bytestream2_put_byteu(&pb, 0x04);
231 videotoolbox_write_mp4_descr_length(&pb, config_size);
232 bytestream2_put_byteu(&pb, 32);
233 bytestream2_put_byteu(&pb, 0x11);
239 bytestream2_put_byteu(&pb, 0x05);
245 bytestream2_put_byteu(&pb, 0x06);
246 bytestream2_put_byteu(&pb, 0x01);
247 bytestream2_put_byteu(&pb, 0x02);
251 data = CFDataCreate(kCFAllocatorDefault, rw_extradata, s);
257 static CMSampleBufferRef videotoolbox_sample_buffer_create(CMFormatDescriptionRef fmt_desc,
262 CMBlockBufferRef block_buf;
263 CMSampleBufferRef sample_buf;
268 status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,
279 status = CMSampleBufferCreate(kCFAllocatorDefault,
294 CFRelease(block_buf);
299 static void videotoolbox_decoder_callback(
void *opaque,
300 void *sourceFrameRefCon,
302 VTDecodeInfoFlags
flags,
303 CVImageBufferRef image_buffer,
311 CVPixelBufferRelease(vtctx->
frame);
320 vtctx->
frame = CVPixelBufferRetain(image_buffer);
323 static OSStatus videotoolbox_session_decode_frame(
AVCodecContext *avctx)
326 CMSampleBufferRef sample_buf;
330 sample_buf = videotoolbox_sample_buffer_create(videotoolbox->
cm_fmt_desc,
337 status = VTDecompressionSessionDecodeFrame(videotoolbox->
session,
343 status = VTDecompressionSessionWaitForAsynchronousFrames(videotoolbox->
session);
345 CFRelease(sample_buf);
361 status = videotoolbox_session_decode_frame(avctx);
379 return videotoolbox_common_end_frame(avctx, frame);
403 return videotoolbox_common_end_frame(avctx, frame);
406 static CFDictionaryRef videotoolbox_decoder_config_create(CMVideoCodecType
codec_type,
409 CFMutableDictionaryRef config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
411 &kCFTypeDictionaryKeyCallBacks,
412 &kCFTypeDictionaryValueCallBacks);
414 CFDictionarySetValue(config_info,
419 CFMutableDictionaryRef avc_info;
420 CFDataRef data =
NULL;
422 avc_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
424 &kCFTypeDictionaryKeyCallBacks,
425 &kCFTypeDictionaryValueCallBacks);
427 switch (codec_type) {
428 case kCMVideoCodecType_MPEG4Video :
429 data = videotoolbox_esds_extradata_create(avctx);
431 CFDictionarySetValue(avc_info, CFSTR(
"esds"), data);
433 case kCMVideoCodecType_H264 :
436 CFDictionarySetValue(avc_info, CFSTR(
"avcC"), data);
442 CFDictionarySetValue(config_info,
443 kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms,
454 static CFDictionaryRef videotoolbox_buffer_attributes_create(
int width,
458 CFMutableDictionaryRef buffer_attributes;
459 CFMutableDictionaryRef io_surface_properties;
460 CFNumberRef cv_pix_fmt;
464 w = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width);
465 h = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height);
466 cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pix_fmt);
468 buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
470 &kCFTypeDictionaryKeyCallBacks,
471 &kCFTypeDictionaryValueCallBacks);
472 io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault,
474 &kCFTypeDictionaryKeyCallBacks,
475 &kCFTypeDictionaryValueCallBacks);
477 CFDictionarySetValue(buffer_attributes, kCVPixelBufferPixelFormatTypeKey, cv_pix_fmt);
478 CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfacePropertiesKey, io_surface_properties);
479 CFDictionarySetValue(buffer_attributes, kCVPixelBufferWidthKey, w);
480 CFDictionarySetValue(buffer_attributes, kCVPixelBufferHeightKey, h);
482 CFRelease(io_surface_properties);
483 CFRelease(cv_pix_fmt);
487 return buffer_attributes;
490 static CMVideoFormatDescriptionRef videotoolbox_format_desc_create(CMVideoCodecType codec_type,
491 CFDictionaryRef decoder_spec,
495 CMFormatDescriptionRef cm_fmt_desc;
498 status = CMVideoFormatDescriptionCreate(kCFAllocatorDefault,
515 VTDecompressionOutputCallbackRecord decoder_cb;
516 CFDictionaryRef decoder_spec;
517 CFDictionaryRef buf_attr;
544 decoder_spec = videotoolbox_decoder_config_create(videotoolbox->
cm_codec_type, avctx);
552 CFRelease(decoder_spec);
558 buf_attr = videotoolbox_buffer_attributes_create(avctx->
width,
562 decoder_cb.decompressionOutputCallback = videotoolbox_decoder_callback;
563 decoder_cb.decompressionOutputRefCon = avctx;
565 status = VTDecompressionSessionCreate(
NULL,
573 CFRelease(decoder_spec);
578 case kVTVideoDecoderNotAvailableNowErr:
579 case kVTVideoDecoderUnsupportedDataFormatErr:
581 case kVTVideoDecoderMalfunctionErr:
583 case kVTVideoDecoderBadDataErr :
601 VTDecompressionSessionInvalidate(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 h264.
#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 / MPEG4 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...
BYTE int const BYTE int int int height
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)