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.

498 lines
16KB

  1. /*
  2. * VDA H.264 hardware acceleration
  3. *
  4. * copyright (c) 2011 Sebastien Zwickert
  5. *
  6. * This file is part of Libav.
  7. *
  8. * Libav 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. * Libav 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 Libav; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. #include <CoreFoundation/CFNumber.h>
  23. #include <CoreFoundation/CFData.h>
  24. #include <CoreFoundation/CFString.h>
  25. #include "libavutil/avutil.h"
  26. #include "h264dec.h"
  27. #include "internal.h"
  28. #include "vda.h"
  29. #include "vda_internal.h"
  30. typedef struct VDAContext {
  31. // The current bitstream buffer.
  32. uint8_t *bitstream;
  33. // The current size of the bitstream.
  34. int bitstream_size;
  35. // The reference size used for fast reallocation.
  36. int allocated_size;
  37. CVImageBufferRef frame;
  38. } VDAContext;
  39. /* Decoder callback that adds the VDA frame to the queue in display order. */
  40. static void vda_decoder_callback(void *vda_hw_ctx,
  41. CFDictionaryRef user_info,
  42. OSStatus status,
  43. uint32_t infoFlags,
  44. CVImageBufferRef image_buffer)
  45. {
  46. struct vda_context *vda_ctx = vda_hw_ctx;
  47. if (!image_buffer)
  48. return;
  49. if (vda_ctx->cv_pix_fmt_type != CVPixelBufferGetPixelFormatType(image_buffer))
  50. return;
  51. vda_ctx->cv_buffer = CVPixelBufferRetain(image_buffer);
  52. }
  53. static int vda_sync_decode(VDAContext *ctx, struct vda_context *vda_ctx)
  54. {
  55. OSStatus status;
  56. CFDataRef coded_frame;
  57. uint32_t flush_flags = 1 << 0; ///< kVDADecoderFlush_emitFrames
  58. coded_frame = CFDataCreate(kCFAllocatorDefault,
  59. ctx->bitstream,
  60. ctx->bitstream_size);
  61. status = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, NULL);
  62. if (kVDADecoderNoErr == status)
  63. status = VDADecoderFlush(vda_ctx->decoder, flush_flags);
  64. CFRelease(coded_frame);
  65. return status;
  66. }
  67. static int vda_old_h264_start_frame(AVCodecContext *avctx,
  68. av_unused const uint8_t *buffer,
  69. av_unused uint32_t size)
  70. {
  71. VDAContext *vda = avctx->internal->hwaccel_priv_data;
  72. struct vda_context *vda_ctx = avctx->hwaccel_context;
  73. if (!vda_ctx->decoder)
  74. return -1;
  75. vda->bitstream_size = 0;
  76. return 0;
  77. }
  78. static int vda_old_h264_decode_slice(AVCodecContext *avctx,
  79. const uint8_t *buffer,
  80. uint32_t size)
  81. {
  82. VDAContext *vda = avctx->internal->hwaccel_priv_data;
  83. struct vda_context *vda_ctx = avctx->hwaccel_context;
  84. void *tmp;
  85. if (!vda_ctx->decoder)
  86. return -1;
  87. tmp = av_fast_realloc(vda->bitstream,
  88. &vda->allocated_size,
  89. vda->bitstream_size + size + 4);
  90. if (!tmp)
  91. return AVERROR(ENOMEM);
  92. vda->bitstream = tmp;
  93. AV_WB32(vda->bitstream + vda->bitstream_size, size);
  94. memcpy(vda->bitstream + vda->bitstream_size + 4, buffer, size);
  95. vda->bitstream_size += size + 4;
  96. return 0;
  97. }
  98. static int vda_old_h264_end_frame(AVCodecContext *avctx)
  99. {
  100. H264Context *h = avctx->priv_data;
  101. VDAContext *vda = avctx->internal->hwaccel_priv_data;
  102. struct vda_context *vda_ctx = avctx->hwaccel_context;
  103. AVFrame *frame = h->cur_pic_ptr->f;
  104. int status;
  105. if (!vda_ctx->decoder || !vda->bitstream)
  106. return -1;
  107. status = vda_sync_decode(vda, vda_ctx);
  108. frame->data[3] = (void*)vda_ctx->cv_buffer;
  109. if (status)
  110. av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
  111. return status;
  112. }
  113. int ff_vda_create_decoder(struct vda_context *vda_ctx,
  114. uint8_t *extradata,
  115. int extradata_size)
  116. {
  117. OSStatus status = kVDADecoderNoErr;
  118. CFNumberRef height;
  119. CFNumberRef width;
  120. CFNumberRef format;
  121. CFDataRef avc_data;
  122. CFMutableDictionaryRef config_info;
  123. CFMutableDictionaryRef buffer_attributes;
  124. CFMutableDictionaryRef io_surface_properties;
  125. CFNumberRef cv_pix_fmt;
  126. /* Each VCL NAL in the bitstream sent to the decoder
  127. * is preceded by a 4 bytes length header.
  128. * Change the avcC atom header if needed, to signal headers of 4 bytes. */
  129. if (extradata_size >= 4 && (extradata[4] & 0x03) != 0x03) {
  130. uint8_t *rw_extradata;
  131. if (!(rw_extradata = av_malloc(extradata_size)))
  132. return AVERROR(ENOMEM);
  133. memcpy(rw_extradata, extradata, extradata_size);
  134. rw_extradata[4] |= 0x03;
  135. avc_data = CFDataCreate(kCFAllocatorDefault, rw_extradata, extradata_size);
  136. av_freep(&rw_extradata);
  137. } else {
  138. avc_data = CFDataCreate(kCFAllocatorDefault, extradata, extradata_size);
  139. }
  140. config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
  141. 4,
  142. &kCFTypeDictionaryKeyCallBacks,
  143. &kCFTypeDictionaryValueCallBacks);
  144. height = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->height);
  145. width = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->width);
  146. format = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->format);
  147. CFDictionarySetValue(config_info, kVDADecoderConfiguration_Height, height);
  148. CFDictionarySetValue(config_info, kVDADecoderConfiguration_Width, width);
  149. CFDictionarySetValue(config_info, kVDADecoderConfiguration_SourceFormat, format);
  150. CFDictionarySetValue(config_info, kVDADecoderConfiguration_avcCData, avc_data);
  151. buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
  152. 2,
  153. &kCFTypeDictionaryKeyCallBacks,
  154. &kCFTypeDictionaryValueCallBacks);
  155. io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault,
  156. 0,
  157. &kCFTypeDictionaryKeyCallBacks,
  158. &kCFTypeDictionaryValueCallBacks);
  159. cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault,
  160. kCFNumberSInt32Type,
  161. &vda_ctx->cv_pix_fmt_type);
  162. CFDictionarySetValue(buffer_attributes,
  163. kCVPixelBufferPixelFormatTypeKey,
  164. cv_pix_fmt);
  165. CFDictionarySetValue(buffer_attributes,
  166. kCVPixelBufferIOSurfacePropertiesKey,
  167. io_surface_properties);
  168. status = VDADecoderCreate(config_info,
  169. buffer_attributes,
  170. (VDADecoderOutputCallback *)vda_decoder_callback,
  171. vda_ctx,
  172. &vda_ctx->decoder);
  173. CFRelease(height);
  174. CFRelease(width);
  175. CFRelease(format);
  176. CFRelease(avc_data);
  177. CFRelease(config_info);
  178. CFRelease(io_surface_properties);
  179. CFRelease(cv_pix_fmt);
  180. CFRelease(buffer_attributes);
  181. return status;
  182. }
  183. int ff_vda_destroy_decoder(struct vda_context *vda_ctx)
  184. {
  185. OSStatus status = kVDADecoderNoErr;
  186. if (vda_ctx->decoder)
  187. status = VDADecoderDestroy(vda_ctx->decoder);
  188. return status;
  189. }
  190. static int vda_h264_uninit(AVCodecContext *avctx)
  191. {
  192. VDAContext *vda = avctx->internal->hwaccel_priv_data;
  193. av_freep(&vda->bitstream);
  194. if (vda->frame)
  195. CVPixelBufferRelease(vda->frame);
  196. return 0;
  197. }
  198. AVHWAccel ff_h264_vda_old_hwaccel = {
  199. .name = "h264_vda",
  200. .type = AVMEDIA_TYPE_VIDEO,
  201. .id = AV_CODEC_ID_H264,
  202. .pix_fmt = AV_PIX_FMT_VDA_VLD,
  203. .start_frame = vda_old_h264_start_frame,
  204. .decode_slice = vda_old_h264_decode_slice,
  205. .end_frame = vda_old_h264_end_frame,
  206. .uninit = vda_h264_uninit,
  207. .priv_data_size = sizeof(VDAContext),
  208. };
  209. void ff_vda_output_callback(void *opaque,
  210. CFDictionaryRef user_info,
  211. OSStatus status,
  212. uint32_t infoFlags,
  213. CVImageBufferRef image_buffer)
  214. {
  215. AVCodecContext *ctx = opaque;
  216. VDAContext *vda = ctx->internal->hwaccel_priv_data;
  217. if (vda->frame) {
  218. CVPixelBufferRelease(vda->frame);
  219. vda->frame = NULL;
  220. }
  221. if (!image_buffer)
  222. return;
  223. vda->frame = CVPixelBufferRetain(image_buffer);
  224. }
  225. static int vda_h264_start_frame(AVCodecContext *avctx,
  226. const uint8_t *buffer,
  227. uint32_t size)
  228. {
  229. VDAContext *vda = avctx->internal->hwaccel_priv_data;
  230. vda->bitstream_size = 0;
  231. return 0;
  232. }
  233. static int vda_h264_decode_slice(AVCodecContext *avctx,
  234. const uint8_t *buffer,
  235. uint32_t size)
  236. {
  237. VDAContext *vda = avctx->internal->hwaccel_priv_data;
  238. void *tmp;
  239. tmp = av_fast_realloc(vda->bitstream,
  240. &vda->allocated_size,
  241. vda->bitstream_size + size + 4);
  242. if (!tmp)
  243. return AVERROR(ENOMEM);
  244. vda->bitstream = tmp;
  245. AV_WB32(vda->bitstream + vda->bitstream_size, size);
  246. memcpy(vda->bitstream + vda->bitstream_size + 4, buffer, size);
  247. vda->bitstream_size += size + 4;
  248. return 0;
  249. }
  250. static void release_buffer(void *opaque, uint8_t *data)
  251. {
  252. CVImageBufferRef frame = (CVImageBufferRef)data;
  253. CVPixelBufferRelease(frame);
  254. }
  255. static int vda_h264_end_frame(AVCodecContext *avctx)
  256. {
  257. H264Context *h = avctx->priv_data;
  258. VDAContext *vda = avctx->internal->hwaccel_priv_data;
  259. AVVDAContext *vda_ctx = avctx->hwaccel_context;
  260. AVFrame *frame = h->cur_pic_ptr->f;
  261. uint32_t flush_flags = 1 << 0; ///< kVDADecoderFlush_emitFrames
  262. CFDataRef coded_frame;
  263. OSStatus status;
  264. if (!vda->bitstream_size)
  265. return AVERROR_INVALIDDATA;
  266. coded_frame = CFDataCreate(kCFAllocatorDefault,
  267. vda->bitstream,
  268. vda->bitstream_size);
  269. status = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, NULL);
  270. if (status == kVDADecoderNoErr)
  271. status = VDADecoderFlush(vda_ctx->decoder, flush_flags);
  272. CFRelease(coded_frame);
  273. if (!vda->frame)
  274. return AVERROR_UNKNOWN;
  275. if (status != kVDADecoderNoErr) {
  276. av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
  277. return AVERROR_UNKNOWN;
  278. }
  279. av_buffer_unref(&frame->buf[0]);
  280. frame->buf[0] = av_buffer_create((uint8_t*)vda->frame,
  281. sizeof(vda->frame),
  282. release_buffer, NULL,
  283. AV_BUFFER_FLAG_READONLY);
  284. if (!frame->buf[0])
  285. return AVERROR(ENOMEM);
  286. frame->data[3] = (uint8_t*)vda->frame;
  287. vda->frame = NULL;
  288. return 0;
  289. }
  290. int ff_vda_default_init(AVCodecContext *avctx)
  291. {
  292. AVVDAContext *vda_ctx = avctx->hwaccel_context;
  293. OSStatus status = kVDADecoderNoErr;
  294. CFNumberRef height;
  295. CFNumberRef width;
  296. CFNumberRef format;
  297. CFDataRef avc_data;
  298. CFMutableDictionaryRef config_info;
  299. CFMutableDictionaryRef buffer_attributes;
  300. CFMutableDictionaryRef io_surface_properties;
  301. CFNumberRef cv_pix_fmt;
  302. int32_t fmt = 'avc1', pix_fmt = vda_ctx->cv_pix_fmt_type;
  303. // kCVPixelFormatType_420YpCbCr8Planar;
  304. /* Each VCL NAL in the bitstream sent to the decoder
  305. * is preceded by a 4 bytes length header.
  306. * Change the avcC atom header if needed, to signal headers of 4 bytes. */
  307. if (avctx->extradata_size >= 4 && (avctx->extradata[4] & 0x03) != 0x03) {
  308. uint8_t *rw_extradata;
  309. if (!(rw_extradata = av_malloc(avctx->extradata_size)))
  310. return AVERROR(ENOMEM);
  311. memcpy(rw_extradata, avctx->extradata, avctx->extradata_size);
  312. rw_extradata[4] |= 0x03;
  313. avc_data = CFDataCreate(kCFAllocatorDefault, rw_extradata, avctx->extradata_size);
  314. av_freep(&rw_extradata);
  315. } else {
  316. avc_data = CFDataCreate(kCFAllocatorDefault,
  317. avctx->extradata, avctx->extradata_size);
  318. }
  319. config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
  320. 4,
  321. &kCFTypeDictionaryKeyCallBacks,
  322. &kCFTypeDictionaryValueCallBacks);
  323. height = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &avctx->height);
  324. width = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &avctx->width);
  325. format = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &fmt);
  326. CFDictionarySetValue(config_info, kVDADecoderConfiguration_Height, height);
  327. CFDictionarySetValue(config_info, kVDADecoderConfiguration_Width, width);
  328. CFDictionarySetValue(config_info, kVDADecoderConfiguration_avcCData, avc_data);
  329. CFDictionarySetValue(config_info, kVDADecoderConfiguration_SourceFormat, format);
  330. buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
  331. 2,
  332. &kCFTypeDictionaryKeyCallBacks,
  333. &kCFTypeDictionaryValueCallBacks);
  334. io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault,
  335. 0,
  336. &kCFTypeDictionaryKeyCallBacks,
  337. &kCFTypeDictionaryValueCallBacks);
  338. cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault,
  339. kCFNumberSInt32Type,
  340. &pix_fmt);
  341. CFDictionarySetValue(buffer_attributes,
  342. kCVPixelBufferPixelFormatTypeKey,
  343. cv_pix_fmt);
  344. CFDictionarySetValue(buffer_attributes,
  345. kCVPixelBufferIOSurfacePropertiesKey,
  346. io_surface_properties);
  347. status = VDADecoderCreate(config_info,
  348. buffer_attributes,
  349. (VDADecoderOutputCallback *)ff_vda_output_callback,
  350. avctx,
  351. &vda_ctx->decoder);
  352. CFRelease(format);
  353. CFRelease(height);
  354. CFRelease(width);
  355. CFRelease(avc_data);
  356. CFRelease(config_info);
  357. CFRelease(cv_pix_fmt);
  358. CFRelease(io_surface_properties);
  359. CFRelease(buffer_attributes);
  360. if (status != kVDADecoderNoErr) {
  361. av_log(avctx, AV_LOG_ERROR, "Cannot initialize VDA %d\n", status);
  362. }
  363. switch (status) {
  364. case kVDADecoderHardwareNotSupportedErr:
  365. case kVDADecoderFormatNotSupportedErr:
  366. return AVERROR(ENOSYS);
  367. case kVDADecoderConfigurationError:
  368. return AVERROR(EINVAL);
  369. case kVDADecoderDecoderFailedErr:
  370. return AVERROR_INVALIDDATA;
  371. case kVDADecoderNoErr:
  372. return 0;
  373. default:
  374. return AVERROR_UNKNOWN;
  375. }
  376. }
  377. static int vda_h264_alloc_frame(AVCodecContext *avctx, AVFrame *frame)
  378. {
  379. frame->width = avctx->width;
  380. frame->height = avctx->height;
  381. frame->format = avctx->pix_fmt;
  382. frame->buf[0] = av_buffer_alloc(1);
  383. if (!frame->buf[0])
  384. return AVERROR(ENOMEM);
  385. return 0;
  386. }
  387. AVHWAccel ff_h264_vda_hwaccel = {
  388. .name = "h264_vda",
  389. .type = AVMEDIA_TYPE_VIDEO,
  390. .id = AV_CODEC_ID_H264,
  391. .pix_fmt = AV_PIX_FMT_VDA,
  392. .alloc_frame = vda_h264_alloc_frame,
  393. .start_frame = vda_h264_start_frame,
  394. .decode_slice = vda_h264_decode_slice,
  395. .end_frame = vda_h264_end_frame,
  396. .uninit = vda_h264_uninit,
  397. .priv_data_size = sizeof(VDAContext),
  398. };