Coverage Report

Created: 2025-11-16 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavformat/dovi_isom.c
Line
Count
Source
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
#include "libavutil/mem.h"
26
27
#include "libavcodec/put_bits.h"
28
29
#include "avformat.h"
30
#include "dovi_isom.h"
31
32
int ff_isom_parse_dvcc_dvvc(void *logctx, AVStream *st,
33
                            const uint8_t *buf_ptr, uint64_t size)
34
751
{
35
751
    uint32_t buf;
36
751
    AVDOVIDecoderConfigurationRecord *dovi;
37
751
    size_t dovi_size;
38
39
751
    if (size > (1 << 30) || size < 4)
40
0
        return AVERROR_INVALIDDATA;
41
42
751
    dovi = av_dovi_alloc(&dovi_size);
43
751
    if (!dovi)
44
0
        return AVERROR(ENOMEM);
45
46
751
    dovi->dv_version_major = *buf_ptr++;    // 8 bits
47
751
    dovi->dv_version_minor = *buf_ptr++;    // 8 bits
48
49
751
    buf = *buf_ptr++ << 8;
50
751
    buf |= *buf_ptr++;
51
52
751
    dovi->dv_profile        = (buf >> 9) & 0x7f;    // 7 bits
53
751
    dovi->dv_level          = (buf >> 3) & 0x3f;    // 6 bits
54
751
    dovi->rpu_present_flag  = (buf >> 2) & 0x01;    // 1 bit
55
751
    dovi->el_present_flag   = (buf >> 1) & 0x01;    // 1 bit
56
751
    dovi->bl_present_flag   =  buf       & 0x01;    // 1 bit
57
58
    // Has enough remaining data
59
751
    if (size >= 5) {
60
751
        uint8_t buf = *buf_ptr++;
61
751
        dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
62
751
        dovi->dv_md_compression = (buf >> 2) & 0x03; // 2 bits
63
751
    } else {
64
        // 0 stands for None
65
        // Dolby Vision V1.2.93 profiles and levels
66
0
        dovi->dv_bl_signal_compatibility_id = 0;
67
0
        dovi->dv_md_compression = AV_DOVI_COMPRESSION_NONE;
68
0
    }
69
70
751
    if (!av_packet_side_data_add(&st->codecpar->coded_side_data, &st->codecpar->nb_coded_side_data,
71
751
                                 AV_PKT_DATA_DOVI_CONF, (uint8_t *)dovi, dovi_size, 0)) {
72
0
        av_free(dovi);
73
0
        return AVERROR(ENOMEM);
74
0
    }
75
76
751
    av_log(logctx, AV_LOG_TRACE, "DOVI in dvcC/dvvC/dvwC box, version: %d.%d, profile: %d, level: %d, "
77
751
           "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d, compression: %d\n",
78
751
           dovi->dv_version_major, dovi->dv_version_minor,
79
751
           dovi->dv_profile, dovi->dv_level,
80
751
           dovi->rpu_present_flag,
81
751
           dovi->el_present_flag,
82
751
           dovi->bl_present_flag,
83
751
           dovi->dv_bl_signal_compatibility_id,
84
751
           dovi->dv_md_compression);
85
86
751
    return 0;
87
751
}
88
89
void ff_isom_put_dvcc_dvvc(void *logctx, uint8_t out[ISOM_DVCC_DVVC_SIZE],
90
                           const AVDOVIDecoderConfigurationRecord *dovi)
91
0
{
92
0
    PutBitContext pb;
93
94
0
    init_put_bits(&pb, out, ISOM_DVCC_DVVC_SIZE);
95
96
0
    put_bits(&pb, 8, dovi->dv_version_major);
97
0
    put_bits(&pb, 8, dovi->dv_version_minor);
98
0
    put_bits(&pb, 7, dovi->dv_profile & 0x7f);
99
0
    put_bits(&pb, 6, dovi->dv_level & 0x3f);
100
0
    put_bits(&pb, 1, !!dovi->rpu_present_flag);
101
0
    put_bits(&pb, 1, !!dovi->el_present_flag);
102
0
    put_bits(&pb, 1, !!dovi->bl_present_flag);
103
0
    put_bits(&pb, 4, dovi->dv_bl_signal_compatibility_id & 0x0f);
104
0
    put_bits(&pb, 2, dovi->dv_md_compression & 0x03);
105
106
0
    put_bits(&pb, 26, 0); /* reserved */
107
0
    put_bits32(&pb, 0); /* reserved */
108
0
    put_bits32(&pb, 0); /* reserved */
109
0
    put_bits32(&pb, 0); /* reserved */
110
0
    put_bits32(&pb, 0); /* reserved */
111
112
0
    flush_put_bits(&pb);
113
114
0
    av_log(logctx, AV_LOG_DEBUG,
115
0
           "DOVI in %s box, version: %d.%d, profile: %d, level: %d, "
116
0
           "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d, "
117
0
           "compression: %d\n",
118
0
           dovi->dv_profile > 10 ? "dvwC" : (dovi->dv_profile > 7 ? "dvvC" : "dvcC"),
119
0
           dovi->dv_version_major, dovi->dv_version_minor,
120
0
           dovi->dv_profile, dovi->dv_level,
121
0
           dovi->rpu_present_flag,
122
0
           dovi->el_present_flag,
123
0
           dovi->bl_present_flag,
124
0
           dovi->dv_bl_signal_compatibility_id,
125
0
           dovi->dv_md_compression);
126
0
}