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.

340 lines
11KB

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