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.

1161 lines
39KB

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