FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/apv_parser.c
Date: 2025-11-03 14:06:37
Exec Total Coverage
Lines: 56 62 90.3%
Functions: 4 4 100.0%
Branches: 11 20 55.0%

Line Branch Exec 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/avassert.h"
20 #include "libavutil/buffer.h"
21
22 #include "avcodec.h"
23 #include "apv.h"
24 #include "cbs.h"
25 #include "cbs_apv.h"
26 #include "parser_internal.h"
27
28 typedef struct APVParseContext {
29 CodedBitstreamContext *cbc;
30 CodedBitstreamFragment au;
31 } APVParseContext;
32
33 static const enum AVPixelFormat apv_format_table[5][5] = {
34 { AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_GRAY16 },
35 { 0 }, // 4:2:0 is not valid.
36 { AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_YUV422P16 },
37 { AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV444P12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_YUV444P16 },
38 { AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_YUVA444P16 },
39 };
40
41 24 static void dummy_free(void *opaque, uint8_t *data)
42 {
43
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 av_assert0(opaque == data);
44 24 }
45
46 24 static int parse(AVCodecParserContext *s,
47 AVCodecContext *avctx,
48 const uint8_t **poutbuf, int *poutbuf_size,
49 const uint8_t *buf, int buf_size)
50 {
51 24 APVParseContext *p = s->priv_data;
52 24 CodedBitstreamFragment *au = &p->au;
53 24 AVBufferRef *ref = NULL;
54 int ret;
55
56 24 *poutbuf = buf;
57 24 *poutbuf_size = buf_size;
58
59 24 ref = av_buffer_create((uint8_t *)buf, buf_size, dummy_free,
60 (void *)buf, AV_BUFFER_FLAG_READONLY);
61
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (!ref)
62 return buf_size;
63
64 24 p->cbc->log_ctx = avctx;
65
66 24 ret = ff_cbs_read(p->cbc, au, ref, buf, buf_size);
67
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (ret < 0) {
68 av_log(avctx, AV_LOG_ERROR, "Failed to parse access unit.\n");
69 goto end;
70 }
71
72 24 s->key_frame = 1;
73 24 s->pict_type = AV_PICTURE_TYPE_I;
74 24 s->field_order = AV_FIELD_UNKNOWN;
75 24 s->picture_structure = AV_PICTURE_STRUCTURE_FRAME;
76
77
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 6 times.
24 for (int i = 0; i < au->nb_units; i++) {
78 18 const CodedBitstreamUnit *pbu = &au->units[i];
79
80
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 switch (pbu->type) {
81 18 case APV_PBU_PRIMARY_FRAME: {
82 18 const APVRawFrame *frame = pbu->content;
83 18 const APVRawFrameHeader *header = &frame->frame_header;
84 18 const APVRawFrameInfo *info = &header->frame_info;
85 18 int bit_depth = info->bit_depth_minus8 + 8;
86
87
3/6
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
18 if (bit_depth < 8 || bit_depth > 16 || bit_depth % 2)
88 break;
89
90 18 s->width = info->frame_width;
91 18 s->height = info->frame_height;
92 18 s->format = apv_format_table[info->chroma_format_idc][bit_depth - 4 >> 2];
93 18 avctx->profile = info->profile_idc;
94 18 avctx->level = info->level_idc;
95 18 avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
96 18 avctx->color_primaries = header->color_primaries;
97 18 avctx->color_trc = header->transfer_characteristics;
98 18 avctx->colorspace = header->matrix_coefficients;
99 36 avctx->color_range = header->full_range_flag ? AVCOL_RANGE_JPEG
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 : AVCOL_RANGE_MPEG;
101 18 goto end;
102 }
103 default:
104 break;
105 }
106 }
107
108 6 end:
109 24 ff_cbs_fragment_reset(au);
110 av_assert1(av_buffer_get_ref_count(ref) == 1);
111 24 av_buffer_unref(&ref);
112 24 p->cbc->log_ctx = NULL;
113
114 24 return buf_size;
115 }
116
117 static const CodedBitstreamUnitType decompose_unit_types[] = {
118 APV_PBU_PRIMARY_FRAME,
119 };
120
121 6 static av_cold int init(AVCodecParserContext *s)
122 {
123 6 APVParseContext *p = s->priv_data;
124 int ret;
125
126 6 ret = ff_cbs_init(&p->cbc, AV_CODEC_ID_APV, NULL);
127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ret < 0)
128 return ret;
129
130 6 p->cbc->decompose_unit_types = decompose_unit_types;
131 6 p->cbc->nb_decompose_unit_types = FF_ARRAY_ELEMS(decompose_unit_types);
132
133 6 return 0;
134 }
135
136 6 static av_cold void close(AVCodecParserContext *s)
137 {
138 6 APVParseContext *p = s->priv_data;
139
140 6 ff_cbs_fragment_free(&p->au);
141 6 ff_cbs_close(&p->cbc);
142 6 }
143
144 const FFCodecParser ff_apv_parser = {
145 PARSER_CODEC_LIST(AV_CODEC_ID_APV),
146 .priv_data_size = sizeof(APVParseContext),
147 .init = init,
148 .parse = parse,
149 .close = close,
150 };
151