Coverage Report

Created: 2026-09-14 08:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/bsf/apv_metadata.c
Line
Count
Source
1
/*
2
 * This file is part of FFmpeg.
3
 *
4
 * FFmpeg is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2.1 of the License, or (at your option) any later version.
8
 *
9
 * FFmpeg is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with FFmpeg; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
 */
18
19
#include "libavutil/common.h"
20
#include "libavutil/opt.h"
21
22
#include "libavcodec/bsf.h"
23
#include "libavcodec/bsf_internal.h"
24
#include "libavcodec/cbs.h"
25
#include "libavcodec/cbs_bsf.h"
26
#include "libavcodec/cbs_apv.h"
27
28
typedef struct APVMetadataContext {
29
    CBSBSFContext common;
30
31
    int color_primaries;
32
    int transfer_characteristics;
33
    int matrix_coefficients;
34
    int full_range_flag;
35
} APVMetadataContext;
36
37
38
static int apv_metadata_update_frame_header(AVBSFContext *bsf,
39
                                            APVRawFrameHeader *hdr)
40
235
{
41
235
    APVMetadataContext *ctx = bsf->priv_data;
42
43
235
    if (ctx->color_primaries >= 0          ||
44
235
        ctx->transfer_characteristics >= 0 ||
45
235
        ctx->matrix_coefficients >= 0      ||
46
235
        ctx->full_range_flag >= 0) {
47
0
        hdr->color_description_present_flag = 1;
48
49
0
        if (ctx->color_primaries >= 0)
50
0
            hdr->color_primaries = ctx->color_primaries;
51
0
        if (ctx->transfer_characteristics >= 0)
52
0
            hdr->transfer_characteristics = ctx->transfer_characteristics;
53
0
        if (ctx->matrix_coefficients >= 0)
54
0
            hdr->matrix_coefficients = ctx->matrix_coefficients;
55
0
        if (ctx->full_range_flag >= 0)
56
0
            hdr->full_range_flag = ctx->full_range_flag;
57
0
    }
58
59
235
    return 0;
60
235
}
61
62
static int apv_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt,
63
                                        CodedBitstreamFragment *frag)
64
7.10k
{
65
7.10k
    int err, i;
66
67
45.1k
    for (i = 0; i < frag->nb_units; i++) {
68
38.0k
        if (frag->units[i].type == APV_PBU_PRIMARY_FRAME) {
69
235
            APVRawFrame *pbu = frag->units[i].content;
70
235
            err = apv_metadata_update_frame_header(bsf, &pbu->frame_header);
71
235
            if (err < 0)
72
0
                return err;
73
235
        }
74
38.0k
    }
75
76
7.10k
    return 0;
77
7.10k
}
78
79
static const CBSBSFType apv_metadata_type = {
80
    .codec_id        = AV_CODEC_ID_APV,
81
    .fragment_name   = "access unit",
82
    .unit_name       = "PBU",
83
    .update_fragment = &apv_metadata_update_fragment,
84
};
85
86
static int apv_metadata_init(AVBSFContext *bsf)
87
1.01k
{
88
1.01k
    return ff_cbs_bsf_generic_init(bsf, &apv_metadata_type);
89
1.01k
}
90
91
#define OFFSET(x) offsetof(APVMetadataContext, x)
92
#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM)
93
static const AVOption apv_metadata_options[] = {
94
    { "color_primaries", "Set color primaries (section 5.3.5)",
95
        OFFSET(color_primaries), AV_OPT_TYPE_INT,
96
        { .i64 = -1 }, -1, 255, FLAGS },
97
    { "transfer_characteristics", "Set transfer characteristics (section 5.3.5)",
98
        OFFSET(transfer_characteristics), AV_OPT_TYPE_INT,
99
        { .i64 = -1 }, -1, 255, FLAGS },
100
    { "matrix_coefficients", "Set matrix coefficients (section 5.3.5)",
101
        OFFSET(matrix_coefficients), AV_OPT_TYPE_INT,
102
        { .i64 = -1 }, -1, 255, FLAGS },
103
104
    { "full_range_flag", "Set full range flag flag (section 5.3.5)",
105
        OFFSET(full_range_flag), AV_OPT_TYPE_INT,
106
        { .i64 = -1 }, -1, 1, FLAGS, .unit = "cr" },
107
    { "tv", "TV (limited) range", 0, AV_OPT_TYPE_CONST,
108
        { .i64 = 0 }, .flags = FLAGS, .unit = "cr" },
109
    { "pc", "PC (full) range",    0, AV_OPT_TYPE_CONST,
110
        { .i64 = 1 }, .flags = FLAGS, .unit = "cr" },
111
112
    { NULL }
113
};
114
115
static const AVClass apv_metadata_class = {
116
    .class_name = "apv_metadata_bsf",
117
    .item_name  = av_default_item_name,
118
    .option     = apv_metadata_options,
119
    .version    = LIBAVUTIL_VERSION_INT,
120
};
121
122
static const enum AVCodecID apv_metadata_codec_ids[] = {
123
    AV_CODEC_ID_APV, AV_CODEC_ID_NONE,
124
};
125
126
const FFBitStreamFilter ff_apv_metadata_bsf = {
127
    .p.name         = "apv_metadata",
128
    .p.codec_ids    = apv_metadata_codec_ids,
129
    .p.priv_class   = &apv_metadata_class,
130
    .priv_data_size = sizeof(APVMetadataContext),
131
    .init           = &apv_metadata_init,
132
    .close          = &ff_cbs_bsf_generic_close,
133
    .filter         = &ff_cbs_bsf_generic_filter,
134
};