FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/tests/mpegaudiodecheader.c
Date: 2026-09-21 03:55:38
Exec Total Coverage
Lines: 51 58 87.9%
Functions: 3 3 100.0%
Branches: 22 30 73.3%

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 /**
20 * Walks the MPEG audio frames of a file, checks that every frame header
21 * encodes back to its original bits, and prints each distinct header.
22 */
23
24 #include <inttypes.h>
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <string.h>
28
29 #include "libavutil/file.h"
30 #include "libavutil/mem.h"
31 #include "libavutil/intreadwrite.h"
32
33 #include "libavcodec/mpegaudiodecheader.h"
34
35 #define PADDING_BIT (1U << 9)
36
37 7 static size_t id3v2_size(const uint8_t *buf, size_t size)
38 {
39
3/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 3 times.
7 if (size < 10 || memcmp(buf, "ID3", 3))
40 4 return 0;
41
42
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 return 10 + (buf[5] & 0x10 ? 10 : 0) +
43 3 ((buf[6] & 0x7f) << 21 | (buf[7] & 0x7f) << 14 |
44 3 (buf[8] & 0x7f) << 7 | (buf[9] & 0x7f));
45 }
46
47 30 static void print_header(size_t offset, unsigned frames, uint32_t bits,
48 const MPADecodeHeader2 *header)
49 {
50 30 printf("offset=%zu frames=%u header=%08"PRIX32" layer=%d sample_rate=%d "
51 "bit_rate=%d crc=%d mode=%d mode_ext=%d copyright=%d original=%d "
52 "emphasis=%d private_bit=%d\n",
53 30 offset, frames, bits, header->layer, header->sample_rate,
54 30 header->bit_rate, header->error_protection, header->mode,
55 30 header->mode_ext, header->copyright, header->original,
56 30 header->emphasis, header->private_bit);
57 30 }
58
59 7 int main(int argc, char *argv[])
60 {
61 7 MPADecodeHeader2 run_header, *header = NULL;
62 uint8_t *buf;
63 7 size_t size, pos, run_offset = 0;
64 7 uint32_t run_bits = 0;
65 7 unsigned run_frames = 0, total_frames = 0;
66 7 int ret = 1;
67
68
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (argc != 2) {
69 fprintf(stderr, "Usage: %s <file>\n", argv[0]);
70 return 1;
71 }
72
73
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 if (av_file_map(argv[1], &buf, &size, 0, NULL) < 0) {
74 fprintf(stderr, "Failed to open '%s'\n", argv[1]);
75 return 1;
76 }
77
78 7 pos = id3v2_size(buf, size);
79
2/2
✓ Branch 0 taken 996 times.
✓ Branch 1 taken 7 times.
1003 while (pos + 4 <= size) {
80 996 uint32_t bits = AV_RB32(buf + pos);
81 uint32_t encoded;
82 int decoded;
83
84
2/2
✓ Branch 1 taken 340 times.
✓ Branch 2 taken 656 times.
996 if (ff_mpa_check_header(bits) < 0) {
85 340 pos++;
86 340 continue;
87 }
88
89
2/2
✓ Branch 0 taken 649 times.
✓ Branch 1 taken 7 times.
656 if (header)
90 649 memset(header, 0, sizeof(*header));
91
92 656 decoded = avpriv_mpegaudio_decode_header2(&header, bits);
93
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 656 times.
656 if (decoded < 0)
94 goto end;
95
96 656 encoded = ff_mpa_encode_header(header);
97
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 656 times.
656 if (encoded != bits) {
98 printf("offset=%zu header=%08"PRIX32" encoded back as %08"PRIX32"\n",
99 pos, bits, encoded);
100 goto end;
101 }
102
103
4/4
✓ Branch 0 taken 649 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 626 times.
656 if (run_frames && (bits & ~PADDING_BIT) != (run_bits & ~PADDING_BIT)) {
104 23 print_header(run_offset, run_frames, run_bits, &run_header);
105 23 run_frames = 0;
106 }
107
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 626 times.
656 if (!run_frames) {
108 30 run_offset = pos;
109 30 run_bits = bits;
110 30 run_header = *header;
111 }
112 656 run_frames++;
113 656 total_frames++;
114
115
1/2
✓ Branch 0 taken 656 times.
✗ Branch 1 not taken.
656 pos += decoded == 0 ? header->frame_size : 1;
116 }
117
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (run_frames)
118 7 print_header(run_offset, run_frames, run_bits, &run_header);
119
120 7 printf("frames=%u\n", total_frames);
121 7 ret = !total_frames;
122
123 7 end:
124 7 av_freep(&header);
125 7 av_file_unmap(buf, size);
126 7 return ret;
127 }
128