• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * DOVI ISO Media common code
3  *
4  * Copyright (c) 2020 Vacing Fang <vacingfang@tencent.com>
5  * Copyright (c) 2021 quietvoid
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "libavutil/dovi_meta.h"
25 
26 #include "libavcodec/put_bits.h"
27 
28 #include "avformat.h"
29 #include "dovi_isom.h"
30 
ff_isom_parse_dvcc_dvvc(AVFormatContext * s,AVStream * st,const uint8_t * buf_ptr,uint64_t size)31 int ff_isom_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const uint8_t *buf_ptr, uint64_t size)
32 {
33     uint32_t buf;
34     AVDOVIDecoderConfigurationRecord *dovi;
35     size_t dovi_size;
36     int ret;
37 
38     if (size > (1 << 30) || size < 4)
39         return AVERROR_INVALIDDATA;
40 
41     dovi = av_dovi_alloc(&dovi_size);
42     if (!dovi)
43         return AVERROR(ENOMEM);
44 
45     dovi->dv_version_major = *buf_ptr++;    // 8 bits
46     dovi->dv_version_minor = *buf_ptr++;    // 8 bits
47 
48     buf = *buf_ptr++ << 8;
49     buf |= *buf_ptr++;
50 
51     dovi->dv_profile        = (buf >> 9) & 0x7f;    // 7 bits
52     dovi->dv_level          = (buf >> 3) & 0x3f;    // 6 bits
53     dovi->rpu_present_flag  = (buf >> 2) & 0x01;    // 1 bit
54     dovi->el_present_flag   = (buf >> 1) & 0x01;    // 1 bit
55     dovi->bl_present_flag   =  buf       & 0x01;    // 1 bit
56 
57     // Has enough remaining data
58     if (size >= 5) {
59         dovi->dv_bl_signal_compatibility_id = ((*buf_ptr++) >> 4) & 0x0f; // 4 bits
60     } else {
61         // 0 stands for None
62         // Dolby Vision V1.2.93 profiles and levels
63         dovi->dv_bl_signal_compatibility_id = 0;
64     }
65 
66     ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
67                                   (uint8_t *)dovi, dovi_size);
68     if (ret < 0) {
69         av_free(dovi);
70         return ret;
71     }
72 
73     av_log(s, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, profile: %d, level: %d, "
74            "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
75            dovi->dv_version_major, dovi->dv_version_minor,
76            dovi->dv_profile, dovi->dv_level,
77            dovi->rpu_present_flag,
78            dovi->el_present_flag,
79            dovi->bl_present_flag,
80            dovi->dv_bl_signal_compatibility_id);
81 
82     return 0;
83 }
84 
ff_isom_put_dvcc_dvvc(AVFormatContext * s,uint8_t out[ISOM_DVCC_DVVC_SIZE],AVDOVIDecoderConfigurationRecord * dovi)85 void ff_isom_put_dvcc_dvvc(AVFormatContext *s, uint8_t out[ISOM_DVCC_DVVC_SIZE],
86                            AVDOVIDecoderConfigurationRecord *dovi)
87 {
88     PutBitContext pb;
89 
90     init_put_bits(&pb, out, ISOM_DVCC_DVVC_SIZE);
91 
92     put_bits(&pb, 8, dovi->dv_version_major);
93     put_bits(&pb, 8, dovi->dv_version_minor);
94     put_bits(&pb, 7, dovi->dv_profile & 0x7f);
95     put_bits(&pb, 6, dovi->dv_level & 0x3f);
96     put_bits(&pb, 1, !!dovi->rpu_present_flag);
97     put_bits(&pb, 1, !!dovi->el_present_flag);
98     put_bits(&pb, 1, !!dovi->bl_present_flag);
99     put_bits(&pb, 4, dovi->dv_bl_signal_compatibility_id & 0x0f);
100 
101     put_bits(&pb, 28, 0); /* reserved */
102     put_bits32(&pb, 0); /* reserved */
103     put_bits32(&pb, 0); /* reserved */
104     put_bits32(&pb, 0); /* reserved */
105     put_bits32(&pb, 0); /* reserved */
106 
107     flush_put_bits(&pb);
108 
109     av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, "
110            "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
111            dovi->dv_profile > 10 ? "dvwC" : (dovi->dv_profile > 7 ? "dvvC" : "dvcC"),
112            dovi->dv_version_major, dovi->dv_version_minor,
113            dovi->dv_profile, dovi->dv_level,
114            dovi->rpu_present_flag,
115            dovi->el_present_flag,
116            dovi->bl_present_flag,
117            dovi->dv_bl_signal_compatibility_id);
118 }
119