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.

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