FFmpeg coverage


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