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.

390 lines
13KB

  1. /*
  2. * Copyright (c) 2010, Google, Inc.
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * FFmpeg is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * FFmpeg is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with FFmpeg; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. /**
  21. * @file
  22. * VP8/9 decoder support via libvpx
  23. */
  24. #define VPX_CODEC_DISABLE_COMPAT 1
  25. #include <vpx/vpx_decoder.h>
  26. #include <vpx/vpx_frame_buffer.h>
  27. #include <vpx/vp8dx.h>
  28. #include "libavutil/common.h"
  29. #include "libavutil/imgutils.h"
  30. #include "libavutil/intreadwrite.h"
  31. #include "avcodec.h"
  32. #include "internal.h"
  33. #include "libvpx.h"
  34. #include "profiles.h"
  35. typedef struct VPxDecoderContext {
  36. struct vpx_codec_ctx decoder;
  37. struct vpx_codec_ctx decoder_alpha;
  38. AVBufferPool *pool;
  39. size_t pool_size;
  40. int has_alpha_channel;
  41. } VPxContext;
  42. static int get_frame_buffer(void *priv, size_t min_size, vpx_codec_frame_buffer_t *fb)
  43. {
  44. VPxContext *ctx = priv;
  45. AVBufferRef *buf;
  46. if (min_size > ctx->pool_size) {
  47. av_buffer_pool_uninit(&ctx->pool);
  48. /* According to the libvpx docs the buffer must be zeroed out. */
  49. ctx->pool = av_buffer_pool_init(min_size, av_buffer_allocz);
  50. if (!ctx->pool) {
  51. ctx->pool_size = 0;
  52. return AVERROR(ENOMEM);
  53. }
  54. ctx->pool_size = min_size;
  55. }
  56. buf = av_buffer_pool_get(ctx->pool);
  57. if (!buf)
  58. return AVERROR(ENOMEM);
  59. fb->priv = buf;
  60. fb->size = ctx->pool_size;
  61. fb->data = buf->data;
  62. return 0;
  63. }
  64. static int release_frame_buffer(void *priv, vpx_codec_frame_buffer_t *fb)
  65. {
  66. AVBufferRef *buf = fb->priv;
  67. av_buffer_unref(&buf);
  68. return 0;
  69. }
  70. static av_cold int vpx_init(AVCodecContext *avctx,
  71. struct vpx_codec_ctx* decoder,
  72. const struct vpx_codec_iface *iface)
  73. {
  74. struct vpx_codec_dec_cfg deccfg = {
  75. .threads = FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), 16)
  76. };
  77. av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str());
  78. av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config());
  79. if (vpx_codec_dec_init(decoder, iface, &deccfg, 0) != VPX_CODEC_OK) {
  80. const char *error = vpx_codec_error(decoder);
  81. av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder: %s\n",
  82. error);
  83. return AVERROR(EINVAL);
  84. }
  85. if (avctx->codec_id == AV_CODEC_ID_VP9)
  86. vpx_codec_set_frame_buffer_functions(decoder, get_frame_buffer, release_frame_buffer, avctx->priv_data);
  87. return 0;
  88. }
  89. // returns 0 on success, AVERROR_INVALIDDATA otherwise
  90. static int set_pix_fmt(AVCodecContext *avctx, struct vpx_image *img,
  91. int has_alpha_channel)
  92. {
  93. static const enum AVColorSpace colorspaces[8] = {
  94. AVCOL_SPC_UNSPECIFIED, AVCOL_SPC_BT470BG, AVCOL_SPC_BT709, AVCOL_SPC_SMPTE170M,
  95. AVCOL_SPC_SMPTE240M, AVCOL_SPC_BT2020_NCL, AVCOL_SPC_RESERVED, AVCOL_SPC_RGB,
  96. };
  97. #if VPX_IMAGE_ABI_VERSION >= 4
  98. static const enum AVColorRange color_ranges[] = {
  99. AVCOL_RANGE_MPEG, AVCOL_RANGE_JPEG
  100. };
  101. avctx->color_range = color_ranges[img->range];
  102. #endif
  103. avctx->colorspace = colorspaces[img->cs];
  104. if (avctx->codec_id == AV_CODEC_ID_VP8 && img->fmt != VPX_IMG_FMT_I420)
  105. return AVERROR_INVALIDDATA;
  106. switch (img->fmt) {
  107. case VPX_IMG_FMT_I420:
  108. if (avctx->codec_id == AV_CODEC_ID_VP9)
  109. avctx->profile = FF_PROFILE_VP9_0;
  110. avctx->pix_fmt =
  111. has_alpha_channel ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P;
  112. return 0;
  113. #if CONFIG_LIBVPX_VP9_DECODER
  114. case VPX_IMG_FMT_I422:
  115. avctx->profile = FF_PROFILE_VP9_1;
  116. avctx->pix_fmt = AV_PIX_FMT_YUV422P;
  117. return 0;
  118. case VPX_IMG_FMT_I440:
  119. avctx->profile = FF_PROFILE_VP9_1;
  120. avctx->pix_fmt = AV_PIX_FMT_YUV440P;
  121. return 0;
  122. case VPX_IMG_FMT_I444:
  123. avctx->profile = FF_PROFILE_VP9_1;
  124. avctx->pix_fmt = avctx->colorspace == AVCOL_SPC_RGB ?
  125. AV_PIX_FMT_GBRP : AV_PIX_FMT_YUV444P;
  126. return 0;
  127. case VPX_IMG_FMT_I42016:
  128. avctx->profile = FF_PROFILE_VP9_2;
  129. if (img->bit_depth == 10) {
  130. avctx->pix_fmt = AV_PIX_FMT_YUV420P10;
  131. return 0;
  132. } else if (img->bit_depth == 12) {
  133. avctx->pix_fmt = AV_PIX_FMT_YUV420P12;
  134. return 0;
  135. } else {
  136. return AVERROR_INVALIDDATA;
  137. }
  138. case VPX_IMG_FMT_I42216:
  139. avctx->profile = FF_PROFILE_VP9_3;
  140. if (img->bit_depth == 10) {
  141. avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
  142. return 0;
  143. } else if (img->bit_depth == 12) {
  144. avctx->pix_fmt = AV_PIX_FMT_YUV422P12;
  145. return 0;
  146. } else {
  147. return AVERROR_INVALIDDATA;
  148. }
  149. case VPX_IMG_FMT_I44016:
  150. avctx->profile = FF_PROFILE_VP9_3;
  151. if (img->bit_depth == 10) {
  152. avctx->pix_fmt = AV_PIX_FMT_YUV440P10;
  153. return 0;
  154. } else if (img->bit_depth == 12) {
  155. avctx->pix_fmt = AV_PIX_FMT_YUV440P12;
  156. return 0;
  157. } else {
  158. return AVERROR_INVALIDDATA;
  159. }
  160. case VPX_IMG_FMT_I44416:
  161. avctx->profile = FF_PROFILE_VP9_3;
  162. if (img->bit_depth == 10) {
  163. avctx->pix_fmt = avctx->colorspace == AVCOL_SPC_RGB ?
  164. AV_PIX_FMT_GBRP10 : AV_PIX_FMT_YUV444P10;
  165. return 0;
  166. } else if (img->bit_depth == 12) {
  167. avctx->pix_fmt = avctx->colorspace == AVCOL_SPC_RGB ?
  168. AV_PIX_FMT_GBRP12 : AV_PIX_FMT_YUV444P12;
  169. return 0;
  170. } else {
  171. return AVERROR_INVALIDDATA;
  172. }
  173. #endif
  174. default:
  175. return AVERROR_INVALIDDATA;
  176. }
  177. }
  178. static int decode_frame(AVCodecContext *avctx, vpx_codec_ctx_t *decoder,
  179. uint8_t *data, uint32_t data_sz)
  180. {
  181. if (vpx_codec_decode(decoder, data, data_sz, NULL, 0) != VPX_CODEC_OK) {
  182. const char *error = vpx_codec_error(decoder);
  183. const char *detail = vpx_codec_error_detail(decoder);
  184. av_log(avctx, AV_LOG_ERROR, "Failed to decode frame: %s\n", error);
  185. if (detail) {
  186. av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n",
  187. detail);
  188. }
  189. return AVERROR_INVALIDDATA;
  190. }
  191. return 0;
  192. }
  193. static int vpx_decode(AVCodecContext *avctx,
  194. void *data, int *got_frame, AVPacket *avpkt)
  195. {
  196. VPxContext *ctx = avctx->priv_data;
  197. AVFrame *picture = data;
  198. const void *iter = NULL;
  199. const void *iter_alpha = NULL;
  200. struct vpx_image *img, *img_alpha;
  201. int ret;
  202. uint8_t *side_data = NULL;
  203. int side_data_size = 0;
  204. ret = decode_frame(avctx, &ctx->decoder, avpkt->data, avpkt->size);
  205. if (ret)
  206. return ret;
  207. side_data = av_packet_get_side_data(avpkt,
  208. AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
  209. &side_data_size);
  210. if (side_data_size >= 8) {
  211. const uint64_t additional_id = AV_RB64(side_data);
  212. side_data += 8;
  213. side_data_size -= 8;
  214. if (additional_id == 1) { // 1 stands for alpha channel data.
  215. if (!ctx->has_alpha_channel) {
  216. ctx->has_alpha_channel = 1;
  217. ret = vpx_init(avctx,
  218. &ctx->decoder_alpha,
  219. #if CONFIG_LIBVPX_VP8_DECODER && CONFIG_LIBVPX_VP9_DECODER
  220. (avctx->codec_id == AV_CODEC_ID_VP8) ?
  221. &vpx_codec_vp8_dx_algo : &vpx_codec_vp9_dx_algo
  222. #elif CONFIG_LIBVPX_VP8_DECODER
  223. &vpx_codec_vp8_dx_algo
  224. #else
  225. &vpx_codec_vp9_dx_algo
  226. #endif
  227. );
  228. if (ret)
  229. return ret;
  230. }
  231. ret = decode_frame(avctx, &ctx->decoder_alpha, side_data,
  232. side_data_size);
  233. if (ret)
  234. return ret;
  235. }
  236. }
  237. if ((img = vpx_codec_get_frame(&ctx->decoder, &iter)) &&
  238. (!ctx->has_alpha_channel ||
  239. (img_alpha = vpx_codec_get_frame(&ctx->decoder_alpha, &iter_alpha)))) {
  240. uint8_t *planes[4];
  241. int linesizes[4];
  242. if (img->d_w > img->w || img->d_h > img->h) {
  243. av_log(avctx, AV_LOG_ERROR, "Display dimensions %dx%d exceed storage %dx%d\n",
  244. img->d_w, img->d_h, img->w, img->h);
  245. return AVERROR_EXTERNAL;
  246. }
  247. if ((ret = set_pix_fmt(avctx, img, ctx->has_alpha_channel)) < 0) {
  248. av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d) / bit_depth (%d)\n",
  249. img->fmt, img->bit_depth);
  250. return ret;
  251. }
  252. if ((int) img->d_w != avctx->width || (int) img->d_h != avctx->height) {
  253. av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n",
  254. avctx->width, avctx->height, img->d_w, img->d_h);
  255. ret = ff_set_dimensions(avctx, img->d_w, img->d_h);
  256. if (ret < 0)
  257. return ret;
  258. }
  259. if (ctx->has_alpha_channel &&
  260. (img->d_w != img_alpha->d_w ||
  261. img->d_h != img_alpha->d_h ||
  262. img->bit_depth != img_alpha->bit_depth)) {
  263. av_log(avctx, AV_LOG_ERROR,
  264. "Video dimensions %dx%d@%dbpc differ from alpha dimensions %dx%d@%dbpc\n",
  265. img->d_w, img->d_h, img->bit_depth,
  266. img_alpha->d_w, img_alpha->d_h, img_alpha->bit_depth);
  267. return AVERROR_INVALIDDATA;
  268. }
  269. planes[0] = img->planes[VPX_PLANE_Y];
  270. planes[1] = img->planes[VPX_PLANE_U];
  271. planes[2] = img->planes[VPX_PLANE_V];
  272. planes[3] =
  273. ctx->has_alpha_channel ? img_alpha->planes[VPX_PLANE_Y] : NULL;
  274. linesizes[0] = img->stride[VPX_PLANE_Y];
  275. linesizes[1] = img->stride[VPX_PLANE_U];
  276. linesizes[2] = img->stride[VPX_PLANE_V];
  277. linesizes[3] =
  278. ctx->has_alpha_channel ? img_alpha->stride[VPX_PLANE_Y] : 0;
  279. if (img->fb_priv && (!ctx->has_alpha_channel || img_alpha->fb_priv)) {
  280. ret = ff_decode_frame_props(avctx, picture);
  281. if (ret < 0)
  282. return ret;
  283. picture->buf[0] = av_buffer_ref(img->fb_priv);
  284. if (!picture->buf[0])
  285. return AVERROR(ENOMEM);
  286. if (ctx->has_alpha_channel) {
  287. picture->buf[1] = av_buffer_ref(img_alpha->fb_priv);
  288. if (!picture->buf[1]) {
  289. av_frame_unref(picture);
  290. return AVERROR(ENOMEM);
  291. }
  292. }
  293. for (int i = 0; i < 4; i++) {
  294. picture->data[i] = planes[i];
  295. picture->linesize[i] = linesizes[i];
  296. }
  297. } else {
  298. if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
  299. return ret;
  300. av_image_copy(picture->data, picture->linesize, (const uint8_t**)planes,
  301. linesizes, avctx->pix_fmt, img->d_w, img->d_h);
  302. }
  303. *got_frame = 1;
  304. }
  305. return avpkt->size;
  306. }
  307. static av_cold int vpx_free(AVCodecContext *avctx)
  308. {
  309. VPxContext *ctx = avctx->priv_data;
  310. vpx_codec_destroy(&ctx->decoder);
  311. if (ctx->has_alpha_channel)
  312. vpx_codec_destroy(&ctx->decoder_alpha);
  313. av_buffer_pool_uninit(&ctx->pool);
  314. return 0;
  315. }
  316. #if CONFIG_LIBVPX_VP8_DECODER
  317. static av_cold int vp8_init(AVCodecContext *avctx)
  318. {
  319. VPxContext *ctx = avctx->priv_data;
  320. return vpx_init(avctx, &ctx->decoder, &vpx_codec_vp8_dx_algo);
  321. }
  322. AVCodec ff_libvpx_vp8_decoder = {
  323. .name = "libvpx",
  324. .long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"),
  325. .type = AVMEDIA_TYPE_VIDEO,
  326. .id = AV_CODEC_ID_VP8,
  327. .priv_data_size = sizeof(VPxContext),
  328. .init = vp8_init,
  329. .close = vpx_free,
  330. .decode = vpx_decode,
  331. .capabilities = AV_CODEC_CAP_AUTO_THREADS | AV_CODEC_CAP_DR1,
  332. .wrapper_name = "libvpx",
  333. };
  334. #endif /* CONFIG_LIBVPX_VP8_DECODER */
  335. #if CONFIG_LIBVPX_VP9_DECODER
  336. static av_cold int vp9_init(AVCodecContext *avctx)
  337. {
  338. VPxContext *ctx = avctx->priv_data;
  339. return vpx_init(avctx, &ctx->decoder, &vpx_codec_vp9_dx_algo);
  340. }
  341. AVCodec ff_libvpx_vp9_decoder = {
  342. .name = "libvpx-vp9",
  343. .long_name = NULL_IF_CONFIG_SMALL("libvpx VP9"),
  344. .type = AVMEDIA_TYPE_VIDEO,
  345. .id = AV_CODEC_ID_VP9,
  346. .priv_data_size = sizeof(VPxContext),
  347. .init = vp9_init,
  348. .close = vpx_free,
  349. .decode = vpx_decode,
  350. .capabilities = AV_CODEC_CAP_AUTO_THREADS,
  351. .init_static_data = ff_vp9_init_static,
  352. .profiles = NULL_IF_CONFIG_SMALL(ff_vp9_profiles),
  353. .wrapper_name = "libvpx",
  354. };
  355. #endif /* CONFIG_LIBVPX_VP9_DECODER */