You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1257 lines
42KB

  1. /*
  2. * Videotoolbox hardware acceleration
  3. *
  4. * copyright (c) 2012 Sebastien Zwickert
  5. *
  6. * This file is part of FFmpeg.
  7. *
  8. * FFmpeg is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * FFmpeg is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with FFmpeg; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. #include "config.h"
  23. #include "videotoolbox.h"
  24. #include "libavutil/hwcontext_videotoolbox.h"
  25. #include "vt_internal.h"
  26. #include "libavutil/avutil.h"
  27. #include "libavutil/hwcontext.h"
  28. #include "libavutil/pixdesc.h"
  29. #include "bytestream.h"
  30. #include "decode.h"
  31. #include "h264dec.h"
  32. #include "hevcdec.h"
  33. #include "mpegvideo.h"
  34. #include <TargetConditionals.h>
  35. #ifndef kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder
  36. # define kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder CFSTR("RequireHardwareAcceleratedVideoDecoder")
  37. #endif
  38. #ifndef kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder
  39. # define kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder CFSTR("EnableHardwareAcceleratedVideoDecoder")
  40. #endif
  41. #if !HAVE_KCMVIDEOCODECTYPE_HEVC
  42. enum { kCMVideoCodecType_HEVC = 'hvc1' };
  43. #endif
  44. #define VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING 12
  45. typedef struct VTHWFrame {
  46. CVPixelBufferRef pixbuf;
  47. AVBufferRef *hw_frames_ctx;
  48. } VTHWFrame;
  49. static void videotoolbox_buffer_release(void *opaque, uint8_t *data)
  50. {
  51. VTHWFrame *ref = (VTHWFrame *)data;
  52. av_buffer_unref(&ref->hw_frames_ctx);
  53. CVPixelBufferRelease(ref->pixbuf);
  54. av_free(data);
  55. }
  56. static int videotoolbox_buffer_copy(VTContext *vtctx,
  57. const uint8_t *buffer,
  58. uint32_t size)
  59. {
  60. void *tmp;
  61. tmp = av_fast_realloc(vtctx->bitstream,
  62. &vtctx->allocated_size,
  63. size);
  64. if (!tmp)
  65. return AVERROR(ENOMEM);
  66. vtctx->bitstream = tmp;
  67. memcpy(vtctx->bitstream, buffer, size);
  68. vtctx->bitstream_size = size;
  69. return 0;
  70. }
  71. static int videotoolbox_postproc_frame(void *avctx, AVFrame *frame)
  72. {
  73. VTHWFrame *ref = (VTHWFrame *)frame->buf[0]->data;
  74. if (!ref->pixbuf) {
  75. av_log(avctx, AV_LOG_ERROR, "No frame decoded?\n");
  76. av_frame_unref(frame);
  77. return AVERROR_EXTERNAL;
  78. }
  79. frame->crop_right = 0;
  80. frame->crop_left = 0;
  81. frame->crop_top = 0;
  82. frame->crop_bottom = 0;
  83. frame->data[3] = (uint8_t*)ref->pixbuf;
  84. if (ref->hw_frames_ctx) {
  85. av_buffer_unref(&frame->hw_frames_ctx);
  86. frame->hw_frames_ctx = av_buffer_ref(ref->hw_frames_ctx);
  87. if (!frame->hw_frames_ctx)
  88. return AVERROR(ENOMEM);
  89. }
  90. return 0;
  91. }
  92. int ff_videotoolbox_alloc_frame(AVCodecContext *avctx, AVFrame *frame)
  93. {
  94. size_t size = sizeof(VTHWFrame);
  95. uint8_t *data = NULL;
  96. AVBufferRef *buf = NULL;
  97. int ret = ff_attach_decode_data(frame);
  98. FrameDecodeData *fdd;
  99. if (ret < 0)
  100. return ret;
  101. data = av_mallocz(size);
  102. if (!data)
  103. return AVERROR(ENOMEM);
  104. buf = av_buffer_create(data, size, videotoolbox_buffer_release, NULL, 0);
  105. if (!buf) {
  106. av_freep(&data);
  107. return AVERROR(ENOMEM);
  108. }
  109. frame->buf[0] = buf;
  110. fdd = (FrameDecodeData*)frame->private_ref->data;
  111. fdd->post_process = videotoolbox_postproc_frame;
  112. frame->width = avctx->width;
  113. frame->height = avctx->height;
  114. frame->format = avctx->pix_fmt;
  115. return 0;
  116. }
  117. #define AV_W8(p, v) *(p) = (v)
  118. CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx)
  119. {
  120. VTContext *vtctx = avctx->internal->hwaccel_priv_data;
  121. H264Context *h = avctx->priv_data;
  122. CFDataRef data = NULL;
  123. uint8_t *p;
  124. int vt_extradata_size = 6 + 2 + h->ps.sps->data_size + 3 + h->ps.pps->data_size;
  125. uint8_t *vt_extradata = av_malloc(vt_extradata_size);
  126. if (!vt_extradata)
  127. return NULL;
  128. p = vt_extradata;
  129. AV_W8(p + 0, 1); /* version */
  130. AV_W8(p + 1, h->ps.sps->data[1]); /* profile */
  131. AV_W8(p + 2, h->ps.sps->data[2]); /* profile compat */
  132. AV_W8(p + 3, h->ps.sps->data[3]); /* level */
  133. AV_W8(p + 4, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 3 (11) */
  134. AV_W8(p + 5, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */
  135. AV_WB16(p + 6, h->ps.sps->data_size);
  136. memcpy(p + 8, h->ps.sps->data, h->ps.sps->data_size);
  137. p += 8 + h->ps.sps->data_size;
  138. AV_W8(p + 0, 1); /* number of pps */
  139. AV_WB16(p + 1, h->ps.pps->data_size);
  140. memcpy(p + 3, h->ps.pps->data, h->ps.pps->data_size);
  141. p += 3 + h->ps.pps->data_size;
  142. av_assert0(p - vt_extradata == vt_extradata_size);
  143. // save sps header (profile/level) used to create decoder session,
  144. // so we can detect changes and recreate it.
  145. if (vtctx)
  146. memcpy(vtctx->sps, h->ps.sps->data + 1, 3);
  147. data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size);
  148. av_free(vt_extradata);
  149. return data;
  150. }
  151. CFDataRef ff_videotoolbox_hvcc_extradata_create(AVCodecContext *avctx)
  152. {
  153. HEVCContext *h = avctx->priv_data;
  154. int i, num_vps = 0, num_sps = 0, num_pps = 0;
  155. const HEVCVPS *vps = h->ps.vps;
  156. const HEVCSPS *sps = h->ps.sps;
  157. const HEVCPPS *pps = h->ps.pps;
  158. PTLCommon ptlc = vps->ptl.general_ptl;
  159. VUI vui = sps->vui;
  160. uint8_t parallelismType;
  161. CFDataRef data = NULL;
  162. uint8_t *p;
  163. int vt_extradata_size = 23 + 3 + 3 + 3;
  164. uint8_t *vt_extradata;
  165. #define COUNT_SIZE_PS(T, t) \
  166. for (i = 0; i < HEVC_MAX_##T##PS_COUNT; i++) { \
  167. if (h->ps.t##ps_list[i]) { \
  168. const HEVC##T##PS *lps = (const HEVC##T##PS *)h->ps.t##ps_list[i]->data; \
  169. vt_extradata_size += 2 + lps->data_size; \
  170. num_##t##ps++; \
  171. } \
  172. }
  173. COUNT_SIZE_PS(V, v)
  174. COUNT_SIZE_PS(S, s)
  175. COUNT_SIZE_PS(P, p)
  176. vt_extradata = av_malloc(vt_extradata_size);
  177. if (!vt_extradata)
  178. return NULL;
  179. p = vt_extradata;
  180. /* unsigned int(8) configurationVersion = 1; */
  181. AV_W8(p + 0, 1);
  182. /*
  183. * unsigned int(2) general_profile_space;
  184. * unsigned int(1) general_tier_flag;
  185. * unsigned int(5) general_profile_idc;
  186. */
  187. AV_W8(p + 1, ptlc.profile_space << 6 |
  188. ptlc.tier_flag << 5 |
  189. ptlc.profile_idc);
  190. /* unsigned int(32) general_profile_compatibility_flags; */
  191. memcpy(p + 2, ptlc.profile_compatibility_flag, 4);
  192. /* unsigned int(48) general_constraint_indicator_flags; */
  193. AV_W8(p + 6, ptlc.progressive_source_flag << 7 |
  194. ptlc.interlaced_source_flag << 6 |
  195. ptlc.non_packed_constraint_flag << 5 |
  196. ptlc.frame_only_constraint_flag << 4);
  197. AV_W8(p + 7, 0);
  198. AV_WN32(p + 8, 0);
  199. /* unsigned int(8) general_level_idc; */
  200. AV_W8(p + 12, ptlc.level_idc);
  201. /*
  202. * bit(4) reserved = ‘1111’b;
  203. * unsigned int(12) min_spatial_segmentation_idc;
  204. */
  205. AV_W8(p + 13, 0xf0 | (vui.min_spatial_segmentation_idc >> 4));
  206. AV_W8(p + 14, vui.min_spatial_segmentation_idc & 0xff);
  207. /*
  208. * bit(6) reserved = ‘111111’b;
  209. * unsigned int(2) parallelismType;
  210. */
  211. if (!vui.min_spatial_segmentation_idc)
  212. parallelismType = 0;
  213. else if (pps->entropy_coding_sync_enabled_flag && pps->tiles_enabled_flag)
  214. parallelismType = 0;
  215. else if (pps->entropy_coding_sync_enabled_flag)
  216. parallelismType = 3;
  217. else if (pps->tiles_enabled_flag)
  218. parallelismType = 2;
  219. else
  220. parallelismType = 1;
  221. AV_W8(p + 15, 0xfc | parallelismType);
  222. /*
  223. * bit(6) reserved = ‘111111’b;
  224. * unsigned int(2) chromaFormat;
  225. */
  226. AV_W8(p + 16, sps->chroma_format_idc | 0xfc);
  227. /*
  228. * bit(5) reserved = ‘11111’b;
  229. * unsigned int(3) bitDepthLumaMinus8;
  230. */
  231. AV_W8(p + 17, (sps->bit_depth - 8) | 0xfc);
  232. /*
  233. * bit(5) reserved = ‘11111’b;
  234. * unsigned int(3) bitDepthChromaMinus8;
  235. */
  236. AV_W8(p + 18, (sps->bit_depth_chroma - 8) | 0xfc);
  237. /* bit(16) avgFrameRate; */
  238. AV_WB16(p + 19, 0);
  239. /*
  240. * bit(2) constantFrameRate;
  241. * bit(3) numTemporalLayers;
  242. * bit(1) temporalIdNested;
  243. * unsigned int(2) lengthSizeMinusOne;
  244. */
  245. AV_W8(p + 21, 0 << 6 |
  246. sps->max_sub_layers << 3 |
  247. sps->temporal_id_nesting_flag << 2 |
  248. 3);
  249. /* unsigned int(8) numOfArrays; */
  250. AV_W8(p + 22, 3);
  251. p += 23;
  252. #define APPEND_PS(T, t) \
  253. /* \
  254. * bit(1) array_completeness; \
  255. * unsigned int(1) reserved = 0; \
  256. * unsigned int(6) NAL_unit_type; \
  257. */ \
  258. AV_W8(p, 1 << 7 | \
  259. HEVC_NAL_##T##PS & 0x3f); \
  260. /* unsigned int(16) numNalus; */ \
  261. AV_WB16(p + 1, num_##t##ps); \
  262. p += 3; \
  263. for (i = 0; i < HEVC_MAX_##T##PS_COUNT; i++) { \
  264. if (h->ps.t##ps_list[i]) { \
  265. const HEVC##T##PS *lps = (const HEVC##T##PS *)h->ps.t##ps_list[i]->data; \
  266. /* unsigned int(16) nalUnitLength; */ \
  267. AV_WB16(p, lps->data_size); \
  268. /* bit(8*nalUnitLength) nalUnit; */ \
  269. memcpy(p + 2, lps->data, lps->data_size); \
  270. p += 2 + lps->data_size; \
  271. } \
  272. }
  273. APPEND_PS(V, v)
  274. APPEND_PS(S, s)
  275. APPEND_PS(P, p)
  276. av_assert0(p - vt_extradata == vt_extradata_size);
  277. data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size);
  278. av_free(vt_extradata);
  279. return data;
  280. }
  281. int ff_videotoolbox_h264_start_frame(AVCodecContext *avctx,
  282. const uint8_t *buffer,
  283. uint32_t size)
  284. {
  285. VTContext *vtctx = avctx->internal->hwaccel_priv_data;
  286. H264Context *h = avctx->priv_data;
  287. if (h->is_avc == 1) {
  288. return videotoolbox_buffer_copy(vtctx, buffer, size);
  289. }
  290. return 0;
  291. }
  292. static int videotoolbox_h264_decode_params(AVCodecContext *avctx,
  293. int type,
  294. const uint8_t *buffer,
  295. uint32_t size)
  296. {
  297. VTContext *vtctx = avctx->internal->hwaccel_priv_data;
  298. H264Context *h = avctx->priv_data;
  299. // save sps header (profile/level) used to create decoder session
  300. if (!vtctx->sps[0])
  301. memcpy(vtctx->sps, h->ps.sps->data + 1, 3);
  302. if (type == H264_NAL_SPS) {
  303. if (size > 4 && memcmp(vtctx->sps, buffer + 1, 3) != 0) {
  304. vtctx->reconfig_needed = true;
  305. memcpy(vtctx->sps, buffer + 1, 3);
  306. }
  307. }
  308. // pass-through SPS/PPS changes to the decoder
  309. return ff_videotoolbox_h264_decode_slice(avctx, buffer, size);
  310. }
  311. static int videotoolbox_common_decode_slice(AVCodecContext *avctx,
  312. const uint8_t *buffer,
  313. uint32_t size)
  314. {
  315. VTContext *vtctx = avctx->internal->hwaccel_priv_data;
  316. void *tmp;
  317. tmp = av_fast_realloc(vtctx->bitstream,
  318. &vtctx->allocated_size,
  319. vtctx->bitstream_size+size+4);
  320. if (!tmp)
  321. return AVERROR(ENOMEM);
  322. vtctx->bitstream = tmp;
  323. AV_WB32(vtctx->bitstream + vtctx->bitstream_size, size);
  324. memcpy(vtctx->bitstream + vtctx->bitstream_size + 4, buffer, size);
  325. vtctx->bitstream_size += size + 4;
  326. return 0;
  327. }
  328. int ff_videotoolbox_h264_decode_slice(AVCodecContext *avctx,
  329. const uint8_t *buffer,
  330. uint32_t size)
  331. {
  332. H264Context *h = avctx->priv_data;
  333. if (h->is_avc == 1)
  334. return 0;
  335. return videotoolbox_common_decode_slice(avctx, buffer, size);
  336. }
  337. int ff_videotoolbox_uninit(AVCodecContext *avctx)
  338. {
  339. VTContext *vtctx = avctx->internal->hwaccel_priv_data;
  340. if (vtctx) {
  341. av_freep(&vtctx->bitstream);
  342. if (vtctx->frame)
  343. CVPixelBufferRelease(vtctx->frame);
  344. }
  345. return 0;
  346. }
  347. #if CONFIG_VIDEOTOOLBOX
  348. // Return the AVVideotoolboxContext that matters currently. Where it comes from
  349. // depends on the API used.
  350. static AVVideotoolboxContext *videotoolbox_get_context(AVCodecContext *avctx)
  351. {
  352. // Somewhat tricky because the user can call av_videotoolbox_default_free()
  353. // at any time, even when the codec is closed.
  354. if (avctx->internal && avctx->internal->hwaccel_priv_data) {
  355. VTContext *vtctx = avctx->internal->hwaccel_priv_data;
  356. if (vtctx->vt_ctx)
  357. return vtctx->vt_ctx;
  358. }
  359. return avctx->hwaccel_context;
  360. }
  361. static int videotoolbox_buffer_create(AVCodecContext *avctx, AVFrame *frame)
  362. {
  363. VTContext *vtctx = avctx->internal->hwaccel_priv_data;
  364. CVPixelBufferRef pixbuf = (CVPixelBufferRef)vtctx->frame;
  365. OSType pixel_format = CVPixelBufferGetPixelFormatType(pixbuf);
  366. enum AVPixelFormat sw_format = av_map_videotoolbox_format_to_pixfmt(pixel_format);
  367. int width = CVPixelBufferGetWidth(pixbuf);
  368. int height = CVPixelBufferGetHeight(pixbuf);
  369. AVHWFramesContext *cached_frames;
  370. VTHWFrame *ref;
  371. int ret;
  372. if (!frame->buf[0] || frame->data[3]) {
  373. av_log(avctx, AV_LOG_ERROR, "videotoolbox: invalid state\n");
  374. av_frame_unref(frame);
  375. return AVERROR_EXTERNAL;
  376. }
  377. ref = (VTHWFrame *)frame->buf[0]->data;
  378. if (ref->pixbuf)
  379. CVPixelBufferRelease(ref->pixbuf);
  380. ref->pixbuf = vtctx->frame;
  381. vtctx->frame = NULL;
  382. // Old API code path.
  383. if (!vtctx->cached_hw_frames_ctx)
  384. return 0;
  385. cached_frames = (AVHWFramesContext*)vtctx->cached_hw_frames_ctx->data;
  386. if (cached_frames->sw_format != sw_format ||
  387. cached_frames->width != width ||
  388. cached_frames->height != height) {
  389. AVBufferRef *hw_frames_ctx = av_hwframe_ctx_alloc(cached_frames->device_ref);
  390. AVHWFramesContext *hw_frames;
  391. if (!hw_frames_ctx)
  392. return AVERROR(ENOMEM);
  393. hw_frames = (AVHWFramesContext*)hw_frames_ctx->data;
  394. hw_frames->format = cached_frames->format;
  395. hw_frames->sw_format = sw_format;
  396. hw_frames->width = width;
  397. hw_frames->height = height;
  398. ret = av_hwframe_ctx_init(hw_frames_ctx);
  399. if (ret < 0) {
  400. av_buffer_unref(&hw_frames_ctx);
  401. return ret;
  402. }
  403. av_buffer_unref(&vtctx->cached_hw_frames_ctx);
  404. vtctx->cached_hw_frames_ctx = hw_frames_ctx;
  405. }
  406. av_buffer_unref(&ref->hw_frames_ctx);
  407. ref->hw_frames_ctx = av_buffer_ref(vtctx->cached_hw_frames_ctx);
  408. if (!ref->hw_frames_ctx)
  409. return AVERROR(ENOMEM);
  410. return 0;
  411. }
  412. static void videotoolbox_write_mp4_descr_length(PutByteContext *pb, int length)
  413. {
  414. int i;
  415. uint8_t b;
  416. for (i = 3; i >= 0; i--) {
  417. b = (length >> (i * 7)) & 0x7F;
  418. if (i != 0)
  419. b |= 0x80;
  420. bytestream2_put_byteu(pb, b);
  421. }
  422. }
  423. static CFDataRef videotoolbox_esds_extradata_create(AVCodecContext *avctx)
  424. {
  425. CFDataRef data;
  426. uint8_t *rw_extradata;
  427. PutByteContext pb;
  428. int full_size = 3 + 5 + 13 + 5 + avctx->extradata_size + 3;
  429. // ES_DescrTag data + DecoderConfigDescrTag + data + DecSpecificInfoTag + size + SLConfigDescriptor
  430. int config_size = 13 + 5 + avctx->extradata_size;
  431. int s;
  432. if (!(rw_extradata = av_mallocz(full_size + VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING)))
  433. return NULL;
  434. bytestream2_init_writer(&pb, rw_extradata, full_size + VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING);
  435. bytestream2_put_byteu(&pb, 0); // version
  436. bytestream2_put_ne24(&pb, 0); // flags
  437. // elementary stream descriptor
  438. bytestream2_put_byteu(&pb, 0x03); // ES_DescrTag
  439. videotoolbox_write_mp4_descr_length(&pb, full_size);
  440. bytestream2_put_ne16(&pb, 0); // esid
  441. bytestream2_put_byteu(&pb, 0); // stream priority (0-32)
  442. // decoder configuration descriptor
  443. bytestream2_put_byteu(&pb, 0x04); // DecoderConfigDescrTag
  444. videotoolbox_write_mp4_descr_length(&pb, config_size);
  445. bytestream2_put_byteu(&pb, 32); // object type indication. 32 = AV_CODEC_ID_MPEG4
  446. bytestream2_put_byteu(&pb, 0x11); // stream type
  447. bytestream2_put_ne24(&pb, 0); // buffer size
  448. bytestream2_put_ne32(&pb, 0); // max bitrate
  449. bytestream2_put_ne32(&pb, 0); // avg bitrate
  450. // decoder specific descriptor
  451. bytestream2_put_byteu(&pb, 0x05); ///< DecSpecificInfoTag
  452. videotoolbox_write_mp4_descr_length(&pb, avctx->extradata_size);
  453. bytestream2_put_buffer(&pb, avctx->extradata, avctx->extradata_size);
  454. // SLConfigDescriptor
  455. bytestream2_put_byteu(&pb, 0x06); // SLConfigDescrTag
  456. bytestream2_put_byteu(&pb, 0x01); // length
  457. bytestream2_put_byteu(&pb, 0x02); //
  458. s = bytestream2_size_p(&pb);
  459. data = CFDataCreate(kCFAllocatorDefault, rw_extradata, s);
  460. av_freep(&rw_extradata);
  461. return data;
  462. }
  463. static CMSampleBufferRef videotoolbox_sample_buffer_create(CMFormatDescriptionRef fmt_desc,
  464. void *buffer,
  465. int size)
  466. {
  467. OSStatus status;
  468. CMBlockBufferRef block_buf;
  469. CMSampleBufferRef sample_buf;
  470. block_buf = NULL;
  471. sample_buf = NULL;
  472. status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,// structureAllocator
  473. buffer, // memoryBlock
  474. size, // blockLength
  475. kCFAllocatorNull, // blockAllocator
  476. NULL, // customBlockSource
  477. 0, // offsetToData
  478. size, // dataLength
  479. 0, // flags
  480. &block_buf);
  481. if (!status) {
  482. status = CMSampleBufferCreate(kCFAllocatorDefault, // allocator
  483. block_buf, // dataBuffer
  484. TRUE, // dataReady
  485. 0, // makeDataReadyCallback
  486. 0, // makeDataReadyRefcon
  487. fmt_desc, // formatDescription
  488. 1, // numSamples
  489. 0, // numSampleTimingEntries
  490. NULL, // sampleTimingArray
  491. 0, // numSampleSizeEntries
  492. NULL, // sampleSizeArray
  493. &sample_buf);
  494. }
  495. if (block_buf)
  496. CFRelease(block_buf);
  497. return sample_buf;
  498. }
  499. static void videotoolbox_decoder_callback(void *opaque,
  500. void *sourceFrameRefCon,
  501. OSStatus status,
  502. VTDecodeInfoFlags flags,
  503. CVImageBufferRef image_buffer,
  504. CMTime pts,
  505. CMTime duration)
  506. {
  507. AVCodecContext *avctx = opaque;
  508. VTContext *vtctx = avctx->internal->hwaccel_priv_data;
  509. if (vtctx->frame) {
  510. CVPixelBufferRelease(vtctx->frame);
  511. vtctx->frame = NULL;
  512. }
  513. if (!image_buffer) {
  514. av_log(NULL, AV_LOG_DEBUG, "vt decoder cb: output image buffer is null\n");
  515. return;
  516. }
  517. vtctx->frame = CVPixelBufferRetain(image_buffer);
  518. }
  519. static OSStatus videotoolbox_session_decode_frame(AVCodecContext *avctx)
  520. {
  521. OSStatus status;
  522. CMSampleBufferRef sample_buf;
  523. AVVideotoolboxContext *videotoolbox = videotoolbox_get_context(avctx);
  524. VTContext *vtctx = avctx->internal->hwaccel_priv_data;
  525. sample_buf = videotoolbox_sample_buffer_create(videotoolbox->cm_fmt_desc,
  526. vtctx->bitstream,
  527. vtctx->bitstream_size);
  528. if (!sample_buf)
  529. return -1;
  530. status = VTDecompressionSessionDecodeFrame(videotoolbox->session,
  531. sample_buf,
  532. 0, // decodeFlags
  533. NULL, // sourceFrameRefCon
  534. 0); // infoFlagsOut
  535. if (status == noErr)
  536. status = VTDecompressionSessionWaitForAsynchronousFrames(videotoolbox->session);
  537. CFRelease(sample_buf);
  538. return status;
  539. }
  540. static CMVideoFormatDescriptionRef videotoolbox_format_desc_create(CMVideoCodecType codec_type,
  541. CFDictionaryRef decoder_spec,
  542. int width,
  543. int height)
  544. {
  545. CMFormatDescriptionRef cm_fmt_desc;
  546. OSStatus status;
  547. status = CMVideoFormatDescriptionCreate(kCFAllocatorDefault,
  548. codec_type,
  549. width,
  550. height,
  551. decoder_spec, // Dictionary of extension
  552. &cm_fmt_desc);
  553. if (status)
  554. return NULL;
  555. return cm_fmt_desc;
  556. }
  557. static CFDictionaryRef videotoolbox_buffer_attributes_create(int width,
  558. int height,
  559. OSType pix_fmt)
  560. {
  561. CFMutableDictionaryRef buffer_attributes;
  562. CFMutableDictionaryRef io_surface_properties;
  563. CFNumberRef cv_pix_fmt;
  564. CFNumberRef w;
  565. CFNumberRef h;
  566. w = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width);
  567. h = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height);
  568. cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pix_fmt);
  569. buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
  570. 4,
  571. &kCFTypeDictionaryKeyCallBacks,
  572. &kCFTypeDictionaryValueCallBacks);
  573. io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault,
  574. 0,
  575. &kCFTypeDictionaryKeyCallBacks,
  576. &kCFTypeDictionaryValueCallBacks);
  577. if (pix_fmt)
  578. CFDictionarySetValue(buffer_attributes, kCVPixelBufferPixelFormatTypeKey, cv_pix_fmt);
  579. CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfacePropertiesKey, io_surface_properties);
  580. CFDictionarySetValue(buffer_attributes, kCVPixelBufferWidthKey, w);
  581. CFDictionarySetValue(buffer_attributes, kCVPixelBufferHeightKey, h);
  582. #if TARGET_OS_IPHONE
  583. CFDictionarySetValue(buffer_attributes, kCVPixelBufferOpenGLESCompatibilityKey, kCFBooleanTrue);
  584. #else
  585. CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfaceOpenGLTextureCompatibilityKey, kCFBooleanTrue);
  586. #endif
  587. CFRelease(io_surface_properties);
  588. CFRelease(cv_pix_fmt);
  589. CFRelease(w);
  590. CFRelease(h);
  591. return buffer_attributes;
  592. }
  593. static CFDictionaryRef videotoolbox_decoder_config_create(CMVideoCodecType codec_type,
  594. AVCodecContext *avctx)
  595. {
  596. CFMutableDictionaryRef config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
  597. 0,
  598. &kCFTypeDictionaryKeyCallBacks,
  599. &kCFTypeDictionaryValueCallBacks);
  600. CFDictionarySetValue(config_info,
  601. codec_type == kCMVideoCodecType_HEVC ?
  602. kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder :
  603. kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder,
  604. kCFBooleanTrue);
  605. CFMutableDictionaryRef avc_info;
  606. CFDataRef data = NULL;
  607. avc_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
  608. 1,
  609. &kCFTypeDictionaryKeyCallBacks,
  610. &kCFTypeDictionaryValueCallBacks);
  611. switch (codec_type) {
  612. case kCMVideoCodecType_MPEG4Video :
  613. if (avctx->extradata_size)
  614. data = videotoolbox_esds_extradata_create(avctx);
  615. if (data)
  616. CFDictionarySetValue(avc_info, CFSTR("esds"), data);
  617. break;
  618. case kCMVideoCodecType_H264 :
  619. data = ff_videotoolbox_avcc_extradata_create(avctx);
  620. if (data)
  621. CFDictionarySetValue(avc_info, CFSTR("avcC"), data);
  622. break;
  623. case kCMVideoCodecType_HEVC :
  624. data = ff_videotoolbox_hvcc_extradata_create(avctx);
  625. if (data)
  626. CFDictionarySetValue(avc_info, CFSTR("hvcC"), data);
  627. break;
  628. default:
  629. break;
  630. }
  631. CFDictionarySetValue(config_info,
  632. kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms,
  633. avc_info);
  634. if (data)
  635. CFRelease(data);
  636. CFRelease(avc_info);
  637. return config_info;
  638. }
  639. static int videotoolbox_start(AVCodecContext *avctx)
  640. {
  641. AVVideotoolboxContext *videotoolbox = videotoolbox_get_context(avctx);
  642. OSStatus status;
  643. VTDecompressionOutputCallbackRecord decoder_cb;
  644. CFDictionaryRef decoder_spec;
  645. CFDictionaryRef buf_attr;
  646. if (!videotoolbox) {
  647. av_log(avctx, AV_LOG_ERROR, "hwaccel context is not set\n");
  648. return -1;
  649. }
  650. switch( avctx->codec_id ) {
  651. case AV_CODEC_ID_H263 :
  652. videotoolbox->cm_codec_type = kCMVideoCodecType_H263;
  653. break;
  654. case AV_CODEC_ID_H264 :
  655. videotoolbox->cm_codec_type = kCMVideoCodecType_H264;
  656. break;
  657. case AV_CODEC_ID_HEVC :
  658. videotoolbox->cm_codec_type = kCMVideoCodecType_HEVC;
  659. break;
  660. case AV_CODEC_ID_MPEG1VIDEO :
  661. videotoolbox->cm_codec_type = kCMVideoCodecType_MPEG1Video;
  662. break;
  663. case AV_CODEC_ID_MPEG2VIDEO :
  664. videotoolbox->cm_codec_type = kCMVideoCodecType_MPEG2Video;
  665. break;
  666. case AV_CODEC_ID_MPEG4 :
  667. videotoolbox->cm_codec_type = kCMVideoCodecType_MPEG4Video;
  668. break;
  669. default :
  670. break;
  671. }
  672. decoder_spec = videotoolbox_decoder_config_create(videotoolbox->cm_codec_type, avctx);
  673. if (!decoder_spec) {
  674. av_log(avctx, AV_LOG_ERROR, "decoder specification creation failed\n");
  675. return -1;
  676. }
  677. videotoolbox->cm_fmt_desc = videotoolbox_format_desc_create(videotoolbox->cm_codec_type,
  678. decoder_spec,
  679. avctx->width,
  680. avctx->height);
  681. if (!videotoolbox->cm_fmt_desc) {
  682. if (decoder_spec)
  683. CFRelease(decoder_spec);
  684. av_log(avctx, AV_LOG_ERROR, "format description creation failed\n");
  685. return -1;
  686. }
  687. buf_attr = videotoolbox_buffer_attributes_create(avctx->width,
  688. avctx->height,
  689. videotoolbox->cv_pix_fmt_type);
  690. decoder_cb.decompressionOutputCallback = videotoolbox_decoder_callback;
  691. decoder_cb.decompressionOutputRefCon = avctx;
  692. status = VTDecompressionSessionCreate(NULL, // allocator
  693. videotoolbox->cm_fmt_desc, // videoFormatDescription
  694. decoder_spec, // videoDecoderSpecification
  695. buf_attr, // destinationImageBufferAttributes
  696. &decoder_cb, // outputCallback
  697. &videotoolbox->session); // decompressionSessionOut
  698. if (decoder_spec)
  699. CFRelease(decoder_spec);
  700. if (buf_attr)
  701. CFRelease(buf_attr);
  702. switch (status) {
  703. case kVTVideoDecoderNotAvailableNowErr:
  704. av_log(avctx, AV_LOG_VERBOSE, "VideoToolbox session not available.\n");
  705. return AVERROR(ENOSYS);
  706. case kVTVideoDecoderUnsupportedDataFormatErr:
  707. av_log(avctx, AV_LOG_VERBOSE, "VideoToolbox does not support this format.\n");
  708. return AVERROR(ENOSYS);
  709. case kVTCouldNotFindVideoDecoderErr:
  710. av_log(avctx, AV_LOG_VERBOSE, "VideoToolbox decoder for this format not found.\n");
  711. return AVERROR(ENOSYS);
  712. case kVTVideoDecoderMalfunctionErr:
  713. av_log(avctx, AV_LOG_VERBOSE, "VideoToolbox malfunction.\n");
  714. return AVERROR(EINVAL);
  715. case kVTVideoDecoderBadDataErr:
  716. av_log(avctx, AV_LOG_VERBOSE, "VideoToolbox reported invalid data.\n");
  717. return AVERROR_INVALIDDATA;
  718. case 0:
  719. return 0;
  720. default:
  721. av_log(avctx, AV_LOG_VERBOSE, "Unknown VideoToolbox session creation error %d\n", (int)status);
  722. return AVERROR_UNKNOWN;
  723. }
  724. }
  725. static void videotoolbox_stop(AVCodecContext *avctx)
  726. {
  727. AVVideotoolboxContext *videotoolbox = videotoolbox_get_context(avctx);
  728. if (!videotoolbox)
  729. return;
  730. if (videotoolbox->cm_fmt_desc) {
  731. CFRelease(videotoolbox->cm_fmt_desc);
  732. videotoolbox->cm_fmt_desc = NULL;
  733. }
  734. if (videotoolbox->session) {
  735. VTDecompressionSessionInvalidate(videotoolbox->session);
  736. CFRelease(videotoolbox->session);
  737. videotoolbox->session = NULL;
  738. }
  739. }
  740. static const char *videotoolbox_error_string(OSStatus status)
  741. {
  742. switch (status) {
  743. case kVTVideoDecoderBadDataErr:
  744. return "bad data";
  745. case kVTVideoDecoderMalfunctionErr:
  746. return "decoder malfunction";
  747. case kVTInvalidSessionErr:
  748. return "invalid session";
  749. }
  750. return "unknown";
  751. }
  752. static int videotoolbox_common_end_frame(AVCodecContext *avctx, AVFrame *frame)
  753. {
  754. OSStatus status;
  755. AVVideotoolboxContext *videotoolbox = videotoolbox_get_context(avctx);
  756. VTContext *vtctx = avctx->internal->hwaccel_priv_data;
  757. if (vtctx->reconfig_needed == true) {
  758. vtctx->reconfig_needed = false;
  759. av_log(avctx, AV_LOG_VERBOSE, "VideoToolbox decoder needs reconfig, restarting..\n");
  760. videotoolbox_stop(avctx);
  761. if (videotoolbox_start(avctx) != 0) {
  762. return AVERROR_EXTERNAL;
  763. }
  764. }
  765. if (!videotoolbox->session || !vtctx->bitstream || !vtctx->bitstream_size)
  766. return AVERROR_INVALIDDATA;
  767. status = videotoolbox_session_decode_frame(avctx);
  768. if (status != noErr) {
  769. if (status == kVTVideoDecoderMalfunctionErr || status == kVTInvalidSessionErr)
  770. vtctx->reconfig_needed = true;
  771. av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%s, %d)\n", videotoolbox_error_string(status), (int)status);
  772. return AVERROR_UNKNOWN;
  773. }
  774. if (!vtctx->frame) {
  775. vtctx->reconfig_needed = true;
  776. return AVERROR_UNKNOWN;
  777. }
  778. return videotoolbox_buffer_create(avctx, frame);
  779. }
  780. static int videotoolbox_h264_end_frame(AVCodecContext *avctx)
  781. {
  782. H264Context *h = avctx->priv_data;
  783. AVFrame *frame = h->cur_pic_ptr->f;
  784. VTContext *vtctx = avctx->internal->hwaccel_priv_data;
  785. int ret = videotoolbox_common_end_frame(avctx, frame);
  786. vtctx->bitstream_size = 0;
  787. return ret;
  788. }
  789. static int videotoolbox_hevc_start_frame(AVCodecContext *avctx,
  790. const uint8_t *buffer,
  791. uint32_t size)
  792. {
  793. return 0;
  794. }
  795. static int videotoolbox_hevc_decode_slice(AVCodecContext *avctx,
  796. const uint8_t *buffer,
  797. uint32_t size)
  798. {
  799. return videotoolbox_common_decode_slice(avctx, buffer, size);
  800. }
  801. static int videotoolbox_hevc_decode_params(AVCodecContext *avctx,
  802. int type,
  803. const uint8_t *buffer,
  804. uint32_t size)
  805. {
  806. return videotoolbox_common_decode_slice(avctx, buffer, size);
  807. }
  808. static int videotoolbox_hevc_end_frame(AVCodecContext *avctx)
  809. {
  810. HEVCContext *h = avctx->priv_data;
  811. AVFrame *frame = h->ref->frame;
  812. VTContext *vtctx = avctx->internal->hwaccel_priv_data;
  813. h->output_frame->crop_right = 0;
  814. h->output_frame->crop_left = 0;
  815. h->output_frame->crop_top = 0;
  816. h->output_frame->crop_bottom = 0;
  817. int ret = videotoolbox_common_end_frame(avctx, frame);
  818. vtctx->bitstream_size = 0;
  819. return ret;
  820. }
  821. static int videotoolbox_mpeg_start_frame(AVCodecContext *avctx,
  822. const uint8_t *buffer,
  823. uint32_t size)
  824. {
  825. VTContext *vtctx = avctx->internal->hwaccel_priv_data;
  826. return videotoolbox_buffer_copy(vtctx, buffer, size);
  827. }
  828. static int videotoolbox_mpeg_decode_slice(AVCodecContext *avctx,
  829. const uint8_t *buffer,
  830. uint32_t size)
  831. {
  832. return 0;
  833. }
  834. static int videotoolbox_mpeg_end_frame(AVCodecContext *avctx)
  835. {
  836. MpegEncContext *s = avctx->priv_data;
  837. AVFrame *frame = s->current_picture_ptr->f;
  838. return videotoolbox_common_end_frame(avctx, frame);
  839. }
  840. static int videotoolbox_uninit(AVCodecContext *avctx)
  841. {
  842. VTContext *vtctx = avctx->internal->hwaccel_priv_data;
  843. if (!vtctx)
  844. return 0;
  845. ff_videotoolbox_uninit(avctx);
  846. if (vtctx->vt_ctx)
  847. videotoolbox_stop(avctx);
  848. av_buffer_unref(&vtctx->cached_hw_frames_ctx);
  849. av_freep(&vtctx->vt_ctx);
  850. return 0;
  851. }
  852. static enum AVPixelFormat videotoolbox_best_pixel_format(AVCodecContext *avctx) {
  853. const AVPixFmtDescriptor *descriptor = av_pix_fmt_desc_get(avctx->pix_fmt);
  854. if (!descriptor)
  855. return AV_PIX_FMT_NV12; // same as av_videotoolbox_alloc_context()
  856. int depth = descriptor->comp[0].depth;
  857. if (depth > 8) {
  858. return AV_PIX_FMT_P010;
  859. }
  860. return AV_PIX_FMT_NV12;
  861. }
  862. static int videotoolbox_common_init(AVCodecContext *avctx)
  863. {
  864. VTContext *vtctx = avctx->internal->hwaccel_priv_data;
  865. AVHWFramesContext *hw_frames;
  866. int err;
  867. // Old API - do nothing.
  868. if (avctx->hwaccel_context)
  869. return 0;
  870. if (!avctx->hw_frames_ctx && !avctx->hw_device_ctx) {
  871. av_log(avctx, AV_LOG_ERROR,
  872. "Either hw_frames_ctx or hw_device_ctx must be set.\n");
  873. return AVERROR(EINVAL);
  874. }
  875. vtctx->vt_ctx = av_videotoolbox_alloc_context();
  876. if (!vtctx->vt_ctx) {
  877. err = AVERROR(ENOMEM);
  878. goto fail;
  879. }
  880. if (avctx->hw_frames_ctx) {
  881. hw_frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
  882. } else {
  883. avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx);
  884. if (!avctx->hw_frames_ctx) {
  885. err = AVERROR(ENOMEM);
  886. goto fail;
  887. }
  888. hw_frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
  889. hw_frames->format = AV_PIX_FMT_VIDEOTOOLBOX;
  890. hw_frames->sw_format = videotoolbox_best_pixel_format(avctx);
  891. hw_frames->width = avctx->width;
  892. hw_frames->height = avctx->height;
  893. err = av_hwframe_ctx_init(avctx->hw_frames_ctx);
  894. if (err < 0) {
  895. av_buffer_unref(&avctx->hw_frames_ctx);
  896. goto fail;
  897. }
  898. }
  899. vtctx->cached_hw_frames_ctx = av_buffer_ref(avctx->hw_frames_ctx);
  900. if (!vtctx->cached_hw_frames_ctx) {
  901. err = AVERROR(ENOMEM);
  902. goto fail;
  903. }
  904. bool full_range = avctx->color_range == AVCOL_RANGE_JPEG;
  905. vtctx->vt_ctx->cv_pix_fmt_type =
  906. av_map_videotoolbox_format_from_pixfmt2(hw_frames->sw_format, full_range);
  907. if (!vtctx->vt_ctx->cv_pix_fmt_type) {
  908. av_log(avctx, AV_LOG_ERROR, "Unknown sw_format.\n");
  909. err = AVERROR(EINVAL);
  910. goto fail;
  911. }
  912. err = videotoolbox_start(avctx);
  913. if (err < 0)
  914. goto fail;
  915. return 0;
  916. fail:
  917. videotoolbox_uninit(avctx);
  918. return err;
  919. }
  920. static int videotoolbox_frame_params(AVCodecContext *avctx,
  921. AVBufferRef *hw_frames_ctx)
  922. {
  923. AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data;
  924. frames_ctx->format = AV_PIX_FMT_VIDEOTOOLBOX;
  925. frames_ctx->width = avctx->coded_width;
  926. frames_ctx->height = avctx->coded_height;
  927. frames_ctx->sw_format = videotoolbox_best_pixel_format(avctx);
  928. return 0;
  929. }
  930. const AVHWAccel ff_h263_videotoolbox_hwaccel = {
  931. .name = "h263_videotoolbox",
  932. .type = AVMEDIA_TYPE_VIDEO,
  933. .id = AV_CODEC_ID_H263,
  934. .pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
  935. .alloc_frame = ff_videotoolbox_alloc_frame,
  936. .start_frame = videotoolbox_mpeg_start_frame,
  937. .decode_slice = videotoolbox_mpeg_decode_slice,
  938. .end_frame = videotoolbox_mpeg_end_frame,
  939. .frame_params = videotoolbox_frame_params,
  940. .init = videotoolbox_common_init,
  941. .uninit = videotoolbox_uninit,
  942. .priv_data_size = sizeof(VTContext),
  943. };
  944. const AVHWAccel ff_hevc_videotoolbox_hwaccel = {
  945. .name = "hevc_videotoolbox",
  946. .type = AVMEDIA_TYPE_VIDEO,
  947. .id = AV_CODEC_ID_HEVC,
  948. .pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
  949. .alloc_frame = ff_videotoolbox_alloc_frame,
  950. .start_frame = videotoolbox_hevc_start_frame,
  951. .decode_slice = videotoolbox_hevc_decode_slice,
  952. .decode_params = videotoolbox_hevc_decode_params,
  953. .end_frame = videotoolbox_hevc_end_frame,
  954. .frame_params = videotoolbox_frame_params,
  955. .init = videotoolbox_common_init,
  956. .uninit = videotoolbox_uninit,
  957. .priv_data_size = sizeof(VTContext),
  958. };
  959. const AVHWAccel ff_h264_videotoolbox_hwaccel = {
  960. .name = "h264_videotoolbox",
  961. .type = AVMEDIA_TYPE_VIDEO,
  962. .id = AV_CODEC_ID_H264,
  963. .pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
  964. .alloc_frame = ff_videotoolbox_alloc_frame,
  965. .start_frame = ff_videotoolbox_h264_start_frame,
  966. .decode_slice = ff_videotoolbox_h264_decode_slice,
  967. .decode_params = videotoolbox_h264_decode_params,
  968. .end_frame = videotoolbox_h264_end_frame,
  969. .frame_params = videotoolbox_frame_params,
  970. .init = videotoolbox_common_init,
  971. .uninit = videotoolbox_uninit,
  972. .priv_data_size = sizeof(VTContext),
  973. };
  974. const AVHWAccel ff_mpeg1_videotoolbox_hwaccel = {
  975. .name = "mpeg1_videotoolbox",
  976. .type = AVMEDIA_TYPE_VIDEO,
  977. .id = AV_CODEC_ID_MPEG1VIDEO,
  978. .pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
  979. .alloc_frame = ff_videotoolbox_alloc_frame,
  980. .start_frame = videotoolbox_mpeg_start_frame,
  981. .decode_slice = videotoolbox_mpeg_decode_slice,
  982. .end_frame = videotoolbox_mpeg_end_frame,
  983. .frame_params = videotoolbox_frame_params,
  984. .init = videotoolbox_common_init,
  985. .uninit = videotoolbox_uninit,
  986. .priv_data_size = sizeof(VTContext),
  987. };
  988. const AVHWAccel ff_mpeg2_videotoolbox_hwaccel = {
  989. .name = "mpeg2_videotoolbox",
  990. .type = AVMEDIA_TYPE_VIDEO,
  991. .id = AV_CODEC_ID_MPEG2VIDEO,
  992. .pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
  993. .alloc_frame = ff_videotoolbox_alloc_frame,
  994. .start_frame = videotoolbox_mpeg_start_frame,
  995. .decode_slice = videotoolbox_mpeg_decode_slice,
  996. .end_frame = videotoolbox_mpeg_end_frame,
  997. .frame_params = videotoolbox_frame_params,
  998. .init = videotoolbox_common_init,
  999. .uninit = videotoolbox_uninit,
  1000. .priv_data_size = sizeof(VTContext),
  1001. };
  1002. const AVHWAccel ff_mpeg4_videotoolbox_hwaccel = {
  1003. .name = "mpeg4_videotoolbox",
  1004. .type = AVMEDIA_TYPE_VIDEO,
  1005. .id = AV_CODEC_ID_MPEG4,
  1006. .pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
  1007. .alloc_frame = ff_videotoolbox_alloc_frame,
  1008. .start_frame = videotoolbox_mpeg_start_frame,
  1009. .decode_slice = videotoolbox_mpeg_decode_slice,
  1010. .end_frame = videotoolbox_mpeg_end_frame,
  1011. .frame_params = videotoolbox_frame_params,
  1012. .init = videotoolbox_common_init,
  1013. .uninit = videotoolbox_uninit,
  1014. .priv_data_size = sizeof(VTContext),
  1015. };
  1016. static AVVideotoolboxContext *av_videotoolbox_alloc_context_with_pix_fmt(enum AVPixelFormat pix_fmt,
  1017. bool full_range)
  1018. {
  1019. AVVideotoolboxContext *ret = av_mallocz(sizeof(*ret));
  1020. if (ret) {
  1021. ret->output_callback = videotoolbox_decoder_callback;
  1022. OSType cv_pix_fmt_type = av_map_videotoolbox_format_from_pixfmt2(pix_fmt, full_range);
  1023. if (cv_pix_fmt_type == 0) {
  1024. cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
  1025. }
  1026. ret->cv_pix_fmt_type = cv_pix_fmt_type;
  1027. }
  1028. return ret;
  1029. }
  1030. AVVideotoolboxContext *av_videotoolbox_alloc_context(void)
  1031. {
  1032. return av_videotoolbox_alloc_context_with_pix_fmt(AV_PIX_FMT_NONE, false);
  1033. }
  1034. int av_videotoolbox_default_init(AVCodecContext *avctx)
  1035. {
  1036. return av_videotoolbox_default_init2(avctx, NULL);
  1037. }
  1038. int av_videotoolbox_default_init2(AVCodecContext *avctx, AVVideotoolboxContext *vtctx)
  1039. {
  1040. enum AVPixelFormat pix_fmt = videotoolbox_best_pixel_format(avctx);
  1041. bool full_range = avctx->color_range == AVCOL_RANGE_JPEG;
  1042. avctx->hwaccel_context = vtctx ?: av_videotoolbox_alloc_context_with_pix_fmt(pix_fmt, full_range);
  1043. if (!avctx->hwaccel_context)
  1044. return AVERROR(ENOMEM);
  1045. return videotoolbox_start(avctx);
  1046. }
  1047. void av_videotoolbox_default_free(AVCodecContext *avctx)
  1048. {
  1049. videotoolbox_stop(avctx);
  1050. av_freep(&avctx->hwaccel_context);
  1051. }
  1052. #endif /* CONFIG_VIDEOTOOLBOX */