]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/vpcc.c
avformat/hlsenc: rename option from use_localtime to strftime
[ffmpeg] / libavformat / vpcc.c
index df08de59a6a520949fa65ecd7422a3c879af491f..79514483af4be4dd2ab8e0e7638159c0c4242ca1 100644 (file)
@@ -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);