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/** 22 * @file 23 * AV1 decoder support via libaom 24 */ 25 26#include <aom/aom_decoder.h> 27#include <aom/aomdx.h> 28 29#include "libavutil/common.h" 30#include "libavutil/cpu.h" 31#include "libavutil/imgutils.h" 32 33#include "avcodec.h" 34#include "codec_internal.h" 35#include "internal.h" 36#include "profiles.h" 37 38typedef struct AV1DecodeContext { 39 struct aom_codec_ctx decoder; 40} AV1DecodeContext; 41 42static av_cold int aom_init(AVCodecContext *avctx, 43 const struct aom_codec_iface *iface) 44{ 45 AV1DecodeContext *ctx = avctx->priv_data; 46 struct aom_codec_dec_cfg deccfg = { 47 .threads = FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), 16) 48 }; 49 50 av_log(avctx, AV_LOG_INFO, "%s\n", aom_codec_version_str()); 51 av_log(avctx, AV_LOG_VERBOSE, "%s\n", aom_codec_build_config()); 52 53 if (aom_codec_dec_init(&ctx->decoder, iface, &deccfg, 0) != AOM_CODEC_OK) { 54 const char *error = aom_codec_error(&ctx->decoder); 55 av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder: %s\n", 56 error); 57 return AVERROR(EINVAL); 58 } 59 60 return 0; 61} 62 63static void image_copy_16_to_8(AVFrame *pic, struct aom_image *img) 64{ 65 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format); 66 int i; 67 68 for (i = 0; i < desc->nb_components; i++) { 69 int w = img->d_w; 70 int h = img->d_h; 71 int x, y; 72 73 if (i) { 74 w = (w + img->x_chroma_shift) >> img->x_chroma_shift; 75 h = (h + img->y_chroma_shift) >> img->y_chroma_shift; 76 } 77 78 for (y = 0; y < h; y++) { 79 uint16_t *src = (uint16_t *)(img->planes[i] + y * img->stride[i]); 80 uint8_t *dst = pic->data[i] + y * pic->linesize[i]; 81 for (x = 0; x < w; x++) 82 *dst++ = *src++; 83 } 84 } 85} 86 87// returns 0 on success, AVERROR_INVALIDDATA otherwise 88static int set_pix_fmt(AVCodecContext *avctx, struct aom_image *img) 89{ 90 static const enum AVColorRange color_ranges[] = { 91 AVCOL_RANGE_MPEG, AVCOL_RANGE_JPEG 92 }; 93 avctx->color_range = color_ranges[img->range]; 94 avctx->color_primaries = img->cp; 95 avctx->colorspace = img->mc; 96 avctx->color_trc = img->tc; 97 98 switch (img->fmt) { 99 case AOM_IMG_FMT_I420: 100 case AOM_IMG_FMT_I42016: 101 if (img->bit_depth == 8) { 102 avctx->pix_fmt = img->monochrome ? 103 AV_PIX_FMT_GRAY8 : AV_PIX_FMT_YUV420P; 104 avctx->profile = FF_PROFILE_AV1_MAIN; 105 return 0; 106 } else if (img->bit_depth == 10) { 107 avctx->pix_fmt = img->monochrome ? 108 AV_PIX_FMT_GRAY10 : AV_PIX_FMT_YUV420P10; 109 avctx->profile = FF_PROFILE_AV1_MAIN; 110 return 0; 111 } else if (img->bit_depth == 12) { 112 avctx->pix_fmt = img->monochrome ? 113 AV_PIX_FMT_GRAY12 : AV_PIX_FMT_YUV420P12; 114 avctx->profile = FF_PROFILE_AV1_PROFESSIONAL; 115 return 0; 116 } else { 117 return AVERROR_INVALIDDATA; 118 } 119 case AOM_IMG_FMT_I422: 120 case AOM_IMG_FMT_I42216: 121 if (img->bit_depth == 8) { 122 avctx->pix_fmt = AV_PIX_FMT_YUV422P; 123 avctx->profile = FF_PROFILE_AV1_PROFESSIONAL; 124 return 0; 125 } else if (img->bit_depth == 10) { 126 avctx->pix_fmt = AV_PIX_FMT_YUV422P10; 127 avctx->profile = FF_PROFILE_AV1_PROFESSIONAL; 128 return 0; 129 } else if (img->bit_depth == 12) { 130 avctx->pix_fmt = AV_PIX_FMT_YUV422P12; 131 avctx->profile = FF_PROFILE_AV1_PROFESSIONAL; 132 return 0; 133 } else { 134 return AVERROR_INVALIDDATA; 135 } 136 case AOM_IMG_FMT_I444: 137 case AOM_IMG_FMT_I44416: 138 if (img->bit_depth == 8) { 139 avctx->pix_fmt = AV_PIX_FMT_YUV444P; 140 avctx->profile = FF_PROFILE_AV1_HIGH; 141 return 0; 142 } else if (img->bit_depth == 10) { 143 avctx->pix_fmt = AV_PIX_FMT_YUV444P10; 144 avctx->profile = FF_PROFILE_AV1_HIGH; 145 return 0; 146 } else if (img->bit_depth == 12) { 147 avctx->pix_fmt = AV_PIX_FMT_YUV444P12; 148 avctx->profile = FF_PROFILE_AV1_PROFESSIONAL; 149 return 0; 150 } else { 151 return AVERROR_INVALIDDATA; 152 } 153 154 default: 155 return AVERROR_INVALIDDATA; 156 } 157} 158 159static int aom_decode(AVCodecContext *avctx, AVFrame *picture, 160 int *got_frame, AVPacket *avpkt) 161{ 162 AV1DecodeContext *ctx = avctx->priv_data; 163 const void *iter = NULL; 164 struct aom_image *img; 165 int ret; 166 167 if (aom_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL) != 168 AOM_CODEC_OK) { 169 const char *error = aom_codec_error(&ctx->decoder); 170 const char *detail = aom_codec_error_detail(&ctx->decoder); 171 172 av_log(avctx, AV_LOG_ERROR, "Failed to decode frame: %s\n", error); 173 if (detail) 174 av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n", 175 detail); 176 return AVERROR_INVALIDDATA; 177 } 178 179 if ((img = aom_codec_get_frame(&ctx->decoder, &iter))) { 180 if (img->d_w > img->w || img->d_h > img->h) { 181 av_log(avctx, AV_LOG_ERROR, "Display dimensions %dx%d exceed storage %dx%d\n", 182 img->d_w, img->d_h, img->w, img->h); 183 return AVERROR_EXTERNAL; 184 } 185 186 if ((ret = set_pix_fmt(avctx, img)) < 0) { 187 av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d) / bit_depth (%d)\n", 188 img->fmt, img->bit_depth); 189 return ret; 190 } 191 192 if ((int)img->d_w != avctx->width || (int)img->d_h != avctx->height) { 193 av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n", 194 avctx->width, avctx->height, img->d_w, img->d_h); 195 ret = ff_set_dimensions(avctx, img->d_w, img->d_h); 196 if (ret < 0) 197 return ret; 198 } 199 if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) 200 return ret; 201 202#ifdef AOM_CTRL_AOMD_GET_FRAME_FLAGS 203 { 204 aom_codec_frame_flags_t flags; 205 ret = aom_codec_control(&ctx->decoder, AOMD_GET_FRAME_FLAGS, &flags); 206 if (ret == AOM_CODEC_OK) { 207 picture->key_frame = !!(flags & AOM_FRAME_IS_KEY); 208 if (flags & (AOM_FRAME_IS_KEY | AOM_FRAME_IS_INTRAONLY)) 209 picture->pict_type = AV_PICTURE_TYPE_I; 210 else if (flags & AOM_FRAME_IS_SWITCH) 211 picture->pict_type = AV_PICTURE_TYPE_SP; 212 else 213 picture->pict_type = AV_PICTURE_TYPE_P; 214 } 215 } 216#endif 217 218 av_reduce(&picture->sample_aspect_ratio.num, 219 &picture->sample_aspect_ratio.den, 220 picture->height * img->r_w, 221 picture->width * img->r_h, 222 INT_MAX); 223 ff_set_sar(avctx, picture->sample_aspect_ratio); 224 225 if ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) && img->bit_depth == 8) 226 image_copy_16_to_8(picture, img); 227 else { 228 const uint8_t *planes[4] = { img->planes[0], img->planes[1], img->planes[2] }; 229 const int stride[4] = { img->stride[0], img->stride[1], img->stride[2] }; 230 231 av_image_copy(picture->data, picture->linesize, planes, 232 stride, avctx->pix_fmt, img->d_w, img->d_h); 233 } 234 *got_frame = 1; 235 } 236 return avpkt->size; 237} 238 239static av_cold int aom_free(AVCodecContext *avctx) 240{ 241 AV1DecodeContext *ctx = avctx->priv_data; 242 aom_codec_destroy(&ctx->decoder); 243 return 0; 244} 245 246static av_cold int av1_init(AVCodecContext *avctx) 247{ 248 return aom_init(avctx, aom_codec_av1_dx()); 249} 250 251const FFCodec ff_libaom_av1_decoder = { 252 .p.name = "libaom-av1", 253 .p.long_name = NULL_IF_CONFIG_SMALL("libaom AV1"), 254 .p.type = AVMEDIA_TYPE_VIDEO, 255 .p.id = AV_CODEC_ID_AV1, 256 .priv_data_size = sizeof(AV1DecodeContext), 257 .init = av1_init, 258 .close = aom_free, 259 FF_CODEC_DECODE_CB(aom_decode), 260 .p.capabilities = AV_CODEC_CAP_OTHER_THREADS | AV_CODEC_CAP_DR1, 261 .caps_internal = FF_CODEC_CAP_AUTO_THREADS, 262 .p.profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles), 263 .p.wrapper_name = "libaom", 264}; 265