X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fvpcc.c;h=79514483af4be4dd2ab8e0e7638159c0c4242ca1;hb=26f02c51ce9797e392f956a268c373b353b21178;hp=df08de59a6a520949fa65ecd7422a3c879af491f;hpb=4961ddfd3563a075bdea7d729361adc95370d967;p=ffmpeg diff --git a/libavformat/vpcc.c b/libavformat/vpcc.c index df08de59a6a..79514483af4 100644 --- a/libavformat/vpcc.c +++ b/libavformat/vpcc.c @@ -67,11 +67,58 @@ static int get_vpx_video_full_range_flag(enum AVColorRange color_range) return color_range == AVCOL_RANGE_JPEG; } -int ff_isom_write_vpcc(AVFormatContext *s, AVIOContext *pb, - AVCodecParameters *par) +// Find approximate VP9 level based on the Luma's Sample rate and Picture size. +static int get_vp9_level(AVCodecParameters *par, AVRational *frame_rate) { + int picture_size = par->width * par->height; + int64_t sample_rate; + + // All decisions will be based on picture_size, if frame rate is missing/invalid + if (!frame_rate || !frame_rate->den) + sample_rate = 0; + else + sample_rate = ((int64_t)picture_size * frame_rate->num) / frame_rate->den; + + if (picture_size <= 0) { + return 0; + } else if (sample_rate <= 829440 && picture_size <= 36864) { + return 0x10; + } else if (sample_rate <= 2764800 && picture_size <= 73728) { + return 0x11; + } else if (sample_rate <= 4608000 && picture_size <= 122880) { + return 0x20; + } else if (sample_rate <= 9216000 && picture_size <= 245760) { + return 0x21; + } else if (sample_rate <= 20736000 && picture_size <= 552960) { + return 0x30; + } else if (sample_rate <= 36864000 && picture_size <= 983040) { + return 0x31; + } else if (sample_rate <= 83558400 && picture_size <= 2228224) { + return 0x40; + } else if (sample_rate <= 160432128 && picture_size <= 2228224) { + return 0x41; + } else if (sample_rate <= 311951360 && picture_size <= 8912896) { + return 0x50; + } else if (sample_rate <= 588251136 && picture_size <= 8912896) { + return 0x51; + } else if (sample_rate <= 1176502272 && picture_size <= 8912896) { + return 0x52; + } else if (sample_rate <= 1176502272 && picture_size <= 35651584) { + return 0x60; + } else if (sample_rate <= 2353004544 && picture_size <= 35651584) { + return 0x61; + } else if (sample_rate <= 4706009088 && picture_size <= 35651584) { + return 0x62; + } else { + return 0; + } +} + +int ff_isom_get_vpcc_features(AVFormatContext *s, AVCodecParameters *par, + AVRational *frame_rate, VPCC *vpcc) { int profile = par->profile; - int level = par->level == FF_LEVEL_UNKNOWN ? 0 : par->level; + int level = par->level == FF_LEVEL_UNKNOWN ? + get_vp9_level(par, frame_rate) : par->level; int bit_depth = get_bit_depth(s, par->format); int vpx_chroma_subsampling = get_vpx_chroma_subsampling(s, par->format, par->chroma_location); @@ -90,9 +137,28 @@ int ff_isom_write_vpcc(AVFormatContext *s, AVIOContext *pb, } } - avio_w8(pb, profile); - avio_w8(pb, level); - avio_w8(pb, (bit_depth << 4) | (vpx_chroma_subsampling << 1) | vpx_video_full_range_flag); + vpcc->profile = profile; + vpcc->level = level; + vpcc->bitdepth = bit_depth; + vpcc->chroma_subsampling = vpx_chroma_subsampling; + vpcc->full_range_flag = vpx_video_full_range_flag; + + return 0; +} + +int ff_isom_write_vpcc(AVFormatContext *s, AVIOContext *pb, + AVCodecParameters *par) +{ + VPCC vpcc; + int ret; + + ret = ff_isom_get_vpcc_features(s, par, NULL, &vpcc); + if (ret < 0) + return ret; + + avio_w8(pb, vpcc.profile); + avio_w8(pb, vpcc.level); + avio_w8(pb, (vpcc.bitdepth << 4) | (vpcc.chroma_subsampling << 1) | vpcc.full_range_flag); avio_w8(pb, par->color_primaries); avio_w8(pb, par->color_trc); avio_w8(pb, par->color_space);