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.

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