34 #include <TargetConditionals.h>
36 #ifndef kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder
37 # define kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder CFSTR("RequireHardwareAcceleratedVideoDecoder")
40 #if !HAVE_KCMVIDEOCODECTYPE_HEVC
44 #define VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING 12
48 CVPixelBufferRef cv_buffer = *(CVPixelBufferRef *)data;
49 CVPixelBufferRelease(cv_buffer);
76 CVPixelBufferRef
ref = *(CVPixelBufferRef *)frame->
buf[0]->
data;
91 size_t size =
sizeof(CVPixelBufferRef);
119 #define AV_W8(p, v) *(p) = (v)
148 av_assert0(p - vt_extradata == vt_extradata_size);
155 data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size);
172 int vt_extradata_size = 23 + 5 + vps->
data_size + 5 +
sps->data_size + 3;
183 vt_extradata =
av_malloc(vt_extradata_size);
235 AV_W8(p + 15, 0xfc | parallelismType);
241 AV_W8(p + 16,
sps->chroma_format_idc | 0xfc);
247 AV_W8(p + 17, (
sps->bit_depth - 8) | 0xfc);
253 AV_W8(p + 18, (
sps->bit_depth_chroma - 8) | 0xfc);
264 AV_W8(p + 21, 0 << 6 |
265 sps->max_sub_layers << 3 |
266 sps->temporal_id_nesting_flag << 2 |
294 memcpy(p + 5,
sps->data,
sps->data_size);
295 p += 5 +
sps->data_size;
311 av_assert0(p - vt_extradata == vt_extradata_size);
313 data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size);
321 if (!frame->
buf[0] || frame->
data[3]) {
327 CVPixelBufferRef *
ref = (CVPixelBufferRef *)frame->
buf[0]->
data;
330 CVPixelBufferRelease(*ref);
365 if (size > 4 && memcmp(vtctx->
sps, buffer + 1, 3) != 0) {
367 memcpy(vtctx->
sps, buffer + 1, 3);
408 CVPixelBufferRelease(vtctx->
frame);
414 #if CONFIG_VIDEOTOOLBOX
432 CVPixelBufferRef pixbuf = (CVPixelBufferRef)vtctx->
frame;
433 OSType pixel_format = CVPixelBufferGetPixelFormatType(pixbuf);
435 int width = CVPixelBufferGetWidth(pixbuf);
436 int height = CVPixelBufferGetHeight(pixbuf);
451 cached_frames->
width != width ||
452 cached_frames->
height != height) {
461 hw_frames->
width = width;
462 hw_frames->
height = height;
487 for (i = 3; i >= 0; i--) {
488 b = (length >> (i * 7)) & 0x7F;
492 bytestream2_put_byteu(pb, b);
496 static CFDataRef videotoolbox_esds_extradata_create(
AVCodecContext *avctx)
510 bytestream2_put_byteu(&pb, 0);
514 bytestream2_put_byteu(&pb, 0x03);
515 videotoolbox_write_mp4_descr_length(&pb, full_size);
517 bytestream2_put_byteu(&pb, 0);
520 bytestream2_put_byteu(&pb, 0x04);
521 videotoolbox_write_mp4_descr_length(&pb, config_size);
522 bytestream2_put_byteu(&pb, 32);
523 bytestream2_put_byteu(&pb, 0x11);
529 bytestream2_put_byteu(&pb, 0x05);
535 bytestream2_put_byteu(&pb, 0x06);
536 bytestream2_put_byteu(&pb, 0x01);
537 bytestream2_put_byteu(&pb, 0x02);
541 data = CFDataCreate(kCFAllocatorDefault, rw_extradata, s);
547 static CMSampleBufferRef videotoolbox_sample_buffer_create(CMFormatDescriptionRef fmt_desc,
552 CMBlockBufferRef block_buf;
553 CMSampleBufferRef sample_buf;
558 status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,
569 status = CMSampleBufferCreate(kCFAllocatorDefault,
584 CFRelease(block_buf);
589 static void videotoolbox_decoder_callback(
void *opaque,
590 void *sourceFrameRefCon,
592 VTDecodeInfoFlags
flags,
593 CVImageBufferRef image_buffer,
601 CVPixelBufferRelease(vtctx->
frame);
610 vtctx->
frame = CVPixelBufferRetain(image_buffer);
613 static OSStatus videotoolbox_session_decode_frame(
AVCodecContext *avctx)
616 CMSampleBufferRef sample_buf;
620 sample_buf = videotoolbox_sample_buffer_create(videotoolbox->
cm_fmt_desc,
627 status = VTDecompressionSessionDecodeFrame(videotoolbox->
session,
633 status = VTDecompressionSessionWaitForAsynchronousFrames(videotoolbox->
session);
635 CFRelease(sample_buf);
640 static CMVideoFormatDescriptionRef videotoolbox_format_desc_create(CMVideoCodecType
codec_type,
641 CFDictionaryRef decoder_spec,
645 CMFormatDescriptionRef cm_fmt_desc;
648 status = CMVideoFormatDescriptionCreate(kCFAllocatorDefault,
661 static CFDictionaryRef videotoolbox_buffer_attributes_create(
int width,
665 CFMutableDictionaryRef buffer_attributes;
666 CFMutableDictionaryRef io_surface_properties;
667 CFNumberRef cv_pix_fmt;
671 w = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width);
672 h = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height);
673 cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pix_fmt);
675 buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
677 &kCFTypeDictionaryKeyCallBacks,
678 &kCFTypeDictionaryValueCallBacks);
679 io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault,
681 &kCFTypeDictionaryKeyCallBacks,
682 &kCFTypeDictionaryValueCallBacks);
685 CFDictionarySetValue(buffer_attributes, kCVPixelBufferPixelFormatTypeKey, cv_pix_fmt);
686 CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfacePropertiesKey, io_surface_properties);
687 CFDictionarySetValue(buffer_attributes, kCVPixelBufferWidthKey, w);
688 CFDictionarySetValue(buffer_attributes, kCVPixelBufferHeightKey, h);
690 CFDictionarySetValue(buffer_attributes, kCVPixelBufferOpenGLESCompatibilityKey, kCFBooleanTrue);
692 CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfaceOpenGLTextureCompatibilityKey, kCFBooleanTrue);
695 CFRelease(io_surface_properties);
696 CFRelease(cv_pix_fmt);
700 return buffer_attributes;
703 static CFDictionaryRef videotoolbox_decoder_config_create(CMVideoCodecType codec_type,
706 CFMutableDictionaryRef config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
708 &kCFTypeDictionaryKeyCallBacks,
709 &kCFTypeDictionaryValueCallBacks);
711 CFDictionarySetValue(config_info,
715 CFMutableDictionaryRef avc_info;
716 CFDataRef data =
NULL;
718 avc_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
720 &kCFTypeDictionaryKeyCallBacks,
721 &kCFTypeDictionaryValueCallBacks);
723 switch (codec_type) {
724 case kCMVideoCodecType_MPEG4Video :
726 data = videotoolbox_esds_extradata_create(avctx);
728 CFDictionarySetValue(avc_info, CFSTR(
"esds"), data);
730 case kCMVideoCodecType_H264 :
733 CFDictionarySetValue(avc_info, CFSTR(
"avcC"), data);
738 CFDictionarySetValue(avc_info, CFSTR(
"hvcC"), data);
744 CFDictionarySetValue(config_info,
745 kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms,
759 VTDecompressionOutputCallbackRecord decoder_cb;
760 CFDictionaryRef decoder_spec;
761 CFDictionaryRef buf_attr;
791 decoder_spec = videotoolbox_decoder_config_create(videotoolbox->
cm_codec_type, avctx);
804 CFRelease(decoder_spec);
810 buf_attr = videotoolbox_buffer_attributes_create(avctx->
width,
814 decoder_cb.decompressionOutputCallback = videotoolbox_decoder_callback;
815 decoder_cb.decompressionOutputRefCon = avctx;
817 status = VTDecompressionSessionCreate(
NULL,
825 CFRelease(decoder_spec);
830 case kVTVideoDecoderNotAvailableNowErr:
833 case kVTVideoDecoderUnsupportedDataFormatErr:
836 case kVTVideoDecoderMalfunctionErr:
839 case kVTVideoDecoderBadDataErr:
845 av_log(avctx,
AV_LOG_VERBOSE,
"Unknown VideoToolbox session creation error %u\n", (
unsigned)status);
862 VTDecompressionSessionInvalidate(videotoolbox->
session);
863 CFRelease(videotoolbox->
session);
868 static const char *videotoolbox_error_string(OSStatus status)
871 case kVTVideoDecoderBadDataErr:
873 case kVTVideoDecoderMalfunctionErr:
874 return "decoder malfunction";
875 case kVTInvalidSessionErr:
876 return "invalid session";
890 videotoolbox_stop(avctx);
891 if (videotoolbox_start(avctx) != 0) {
899 status = videotoolbox_session_decode_frame(avctx);
900 if (status != noErr) {
901 if (status == kVTVideoDecoderMalfunctionErr || status == kVTInvalidSessionErr)
903 av_log(avctx,
AV_LOG_ERROR,
"Failed to decode frame (%s, %d)\n", videotoolbox_error_string(status), (
int)status);
912 return videotoolbox_buffer_create(avctx, frame);
920 int ret = videotoolbox_common_end_frame(avctx, frame);
940 ret = videotoolbox_common_end_frame(avctx, frame);
966 return videotoolbox_common_end_frame(avctx, frame);
978 videotoolbox_stop(avctx);
998 "Either hw_frames_ctx or hw_device_ctx must be set.\n");
1044 err = videotoolbox_start(avctx);
1069 .
name =
"h263_videotoolbox",
1074 .start_frame = videotoolbox_mpeg_start_frame,
1075 .decode_slice = videotoolbox_mpeg_decode_slice,
1076 .end_frame = videotoolbox_mpeg_end_frame,
1077 .frame_params = videotoolbox_frame_params,
1078 .init = videotoolbox_common_init,
1084 .
name =
"hevc_videotoolbox",
1091 .decode_params = videotoolbox_hevc_decode_params,
1092 .end_frame = videotoolbox_hevc_end_frame,
1093 .frame_params = videotoolbox_frame_params,
1094 .init = videotoolbox_common_init,
1100 .
name =
"h264_videotoolbox",
1108 .end_frame = videotoolbox_h264_end_frame,
1109 .frame_params = videotoolbox_frame_params,
1110 .init = videotoolbox_common_init,
1116 .
name =
"mpeg1_videotoolbox",
1121 .start_frame = videotoolbox_mpeg_start_frame,
1122 .decode_slice = videotoolbox_mpeg_decode_slice,
1123 .end_frame = videotoolbox_mpeg_end_frame,
1124 .frame_params = videotoolbox_frame_params,
1125 .init = videotoolbox_common_init,
1131 .
name =
"mpeg2_videotoolbox",
1136 .start_frame = videotoolbox_mpeg_start_frame,
1137 .decode_slice = videotoolbox_mpeg_decode_slice,
1138 .end_frame = videotoolbox_mpeg_end_frame,
1139 .frame_params = videotoolbox_frame_params,
1140 .init = videotoolbox_common_init,
1146 .
name =
"mpeg4_videotoolbox",
1151 .start_frame = videotoolbox_mpeg_start_frame,
1152 .decode_slice = videotoolbox_mpeg_decode_slice,
1153 .end_frame = videotoolbox_mpeg_end_frame,
1154 .frame_params = videotoolbox_frame_params,
1155 .init = videotoolbox_common_init,
1166 ret->
cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
1182 return videotoolbox_start(avctx);
1188 videotoolbox_stop(avctx);
int min_spatial_segmentation_idc
#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.
AVBufferRef * vps_list[HEVC_MAX_VPS_COUNT]
ptrdiff_t const GLvoid * data
int coded_width
Bitstream width / height, may be different from width/height e.g.
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)
uint32_t av_map_videotoolbox_format_from_pixfmt(enum AVPixelFormat pix_fmt)
Convert an AVPixelFormat to a VideoToolbox (actually CoreVideo) format.
int width
The allocated dimensions of the frames in this pool.
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.
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
const AVHWAccel ff_h264_videotoolbox_hwaccel
uint8_t entropy_coding_sync_enabled_flag
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame...
int(* post_process)(void *logctx, AVFrame *frame)
The callback to perform some delayed processing on the frame right before it is returned to the calle...
#define av_assert0(cond)
assert() equivalent, that is always enabled.
AVBufferRef * sps_list[HEVC_MAX_SPS_COUNT]
uint8_t profile_compatibility_flag[32]
int ff_attach_decode_data(AVFrame *frame)
void * hwaccel_context
Hardware accelerator context.
AVBufferRef * private_ref
AVBufferRef for internal use by a single libav* library.
An API-specific header for AV_HWDEVICE_TYPE_VIDEOTOOLBOX.
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
#define AV_LOG_VERBOSE
Detailed information.
AVBufferRef * pps_list[HEVC_MAX_PPS_COUNT]
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
uint8_t frame_only_constraint_flag
const AVHWAccel ff_mpeg2_videotoolbox_hwaccel
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
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.
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
uint8_t tiles_enabled_flag
const AVHWAccel ff_hevc_videotoolbox_hwaccel
const char * name
Name of the hardware accelerated codec.
int width
picture width / height.
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames...
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...
#define bytestream2_put_ne24
main external API structure.
uint8_t * data
The data buffer.
CMVideoFormatDescriptionRef cm_fmt_desc
CoreMedia Format Description that Videotoolbox will use to create the decompression session...
static int FUNC() pps(CodedBitstreamContext *ctx, RWContext *rw, H264RawPPS *current)
This struct describes a set or pool of "hardware" frames (i.e.
H264Picture * cur_pic_ptr
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
OSType cv_pix_fmt_type
CVPixelBuffer Format Type that Videotoolbox will use for decoded frames.
const AVHWAccel ff_mpeg1_videotoolbox_hwaccel
static int FUNC() vps(CodedBitstreamContext *ctx, RWContext *rw, H265RawVPS *current)
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
const AVHWAccel ff_mpeg4_videotoolbox_hwaccel
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
A reference to a data buffer.
This struct stores per-frame lavc-internal data and is attached to it via private_ref.
VTDecompressionOutputCallback output_callback
The output callback that must be passed to the session.
static int ref[MAX_W *MAX_W]
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
void * hwaccel_priv_data
hwaccel-specific private data
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
struct AVVideotoolboxContext * vt_ctx
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
enum AVPixelFormat av_map_videotoolbox_format_to_pixfmt(uint32_t cv_fmt)
Convert a VideoToolbox (actually CoreVideo) format to AVPixelFormat.
struct AVCodecInternal * internal
Private context used for internal data.
const AVHWAccel ff_h263_videotoolbox_hwaccel
struct AVBufferRef * cached_hw_frames_ctx
#define bytestream2_put_ne32
uint8_t progressive_source_flag
#define bytestream2_put_ne16
AVBufferRef * hw_device_ctx
A reference to the AVHWDeviceContext describing the device which will be used by a hardware encoder/d...
uint8_t non_packed_constraint_flag
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
#define AVERROR_EXTERNAL
Generic error in an external library.
AVPixelFormat
Pixel format.
uint8_t interlaced_source_flag
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)