FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/riffenc.c
Date: 2026-10-14 08:57:35
Exec Total Coverage
Lines: 193 227 85.0%
Functions: 10 10 100.0%
Branches: 167 220 75.9%

Line Branch Exec Source
1 /*
2 * RIFF muxing functions
3 * Copyright (c) 2000 Fabrice Bellard
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "libavutil/channel_layout.h"
23 #include "libavutil/dict.h"
24 #include "libavutil/log.h"
25 #include "libavutil/mathematics.h"
26 #include "libavcodec/bytestream.h"
27 #include "avformat.h"
28 #include "avio_internal.h"
29 #include "riff.h"
30
31 4467 int64_t ff_start_tag(AVIOContext *pb, const char *tag)
32 {
33 4467 ffio_wfourcc(pb, tag);
34 4467 avio_wl32(pb, -1);
35 4467 return avio_tell(pb);
36 }
37
38 4102 void ff_end_tag(AVIOContext *pb, int64_t start)
39 {
40 int64_t pos;
41
42
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4102 times.
4102 av_assert0((start&1) == 0);
43
44 4102 pos = avio_tell(pb);
45
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4101 times.
4102 if (pos & 1)
46 1 avio_w8(pb, 0);
47 4102 avio_seek(pb, start - 4, SEEK_SET);
48 4102 avio_wl32(pb, (uint32_t)(pos - start));
49 4102 avio_seek(pb, FFALIGN(pos, 2), SEEK_SET);
50 4102 }
51
52 /* WAVEFORMATEX header */
53 /* returns the size or -1 on error */
54 527 int ff_put_wav_header(AVFormatContext *s, AVIOContext *pb,
55 AVCodecParameters *par, int flags)
56 {
57 int bps, blkalign, bytespersec, frame_size;
58 int hdrsize;
59 527 int64_t hdrstart = avio_tell(pb);
60 int waveformatextensible;
61 uint8_t temp[256];
62 527 uint8_t *riff_extradata = temp;
63 527 uint8_t *riff_extradata_start = temp;
64
65
2/4
✓ Branch 0 taken 527 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 527 times.
527 if (!par->codec_tag || par->codec_tag > 0xffff)
66 ✗ return -1;
67
68
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 526 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
527 if (par->codec_id == AV_CODEC_ID_ADPCM_SWF && par->block_align == 0) {
69 ✗ av_log(s, AV_LOG_ERROR, "%s can only be written to WAVE with a constant frame size\n",
70 avcodec_get_name(par->codec_id));
71 ✗ return AVERROR(EINVAL);
72 }
73
74 /* We use the known constant frame size for the codec if known, otherwise
75 * fall back on using AVCodecParameters.frame_size, which is not as reliable
76 * for indicating packet duration. */
77 527 frame_size = av_get_audio_frame_duration2(par, par->block_align);
78
79
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 357 times.
519 waveformatextensible = (par->ch_layout.order == AV_CHANNEL_ORDER_NATIVE &&
80
2/2
✓ Branch 1 taken 160 times.
✓ Branch 2 taken 2 times.
681 av_channel_layout_compare(&par->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_MONO) &&
81 162 av_channel_layout_compare(&par->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO)) ||
82
2/2
✓ Branch 0 taken 472 times.
✓ Branch 1 taken 53 times.
525 par->sample_rate > 48000 ||
83
6/8
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 472 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 472 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7 times.
✓ Branch 7 taken 465 times.
1533 par->codec_id == AV_CODEC_ID_EAC3 || par->codec_id == AV_CODEC_ID_DFPWM ||
84
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 2 times.
479 (av_get_bits_per_sample(par->codec_id) > 16 && par->codec_tag != 0x0003);
85
86
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 467 times.
527 if (waveformatextensible)
87 60 avio_wl16(pb, 0xfffe);
88 else
89 467 avio_wl16(pb, par->codec_tag);
90
91 527 avio_wl16(pb, par->ch_layout.nb_channels);
92 527 avio_wl32(pb, par->sample_rate);
93
1/2
✓ Branch 0 taken 527 times.
✗ Branch 1 not taken.
527 if (par->codec_id == AV_CODEC_ID_ATRAC3 ||
94
1/2
✓ Branch 0 taken 527 times.
✗ Branch 1 not taken.
527 par->codec_id == AV_CODEC_ID_G723_1 ||
95
1/2
✓ Branch 0 taken 527 times.
✗ Branch 1 not taken.
527 par->codec_id == AV_CODEC_ID_G728 ||
96
2/2
✓ Branch 0 taken 521 times.
✓ Branch 1 taken 6 times.
527 par->codec_id == AV_CODEC_ID_MP2 ||
97
1/2
✓ Branch 0 taken 521 times.
✗ Branch 1 not taken.
521 par->codec_id == AV_CODEC_ID_MP3 ||
98
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 521 times.
521 par->codec_id == AV_CODEC_ID_GSM_MS) {
99 6 bps = 0;
100 } else {
101
2/2
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 510 times.
521 if (!(bps = av_get_bits_per_sample(par->codec_id))) {
102
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6 times.
11 if (par->bits_per_coded_sample)
103 5 bps = par->bits_per_coded_sample;
104 else
105 6 bps = 16; // default to 16
106 }
107 }
108
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 520 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
527 if (bps != par->bits_per_coded_sample && par->bits_per_coded_sample) {
109 ✗ av_log(s, AV_LOG_WARNING,
110 "requested bits_per_coded_sample (%d) "
111 "and actually stored (%d) differ\n",
112 par->bits_per_coded_sample, bps);
113 }
114
115
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 521 times.
527 if (par->codec_id == AV_CODEC_ID_MP2) {
116 6 blkalign = (144 * par->bit_rate - 1)/par->sample_rate + 1;
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 521 times.
521 } else if (par->codec_id == AV_CODEC_ID_MP3) {
118 ✗ blkalign = 576 * (par->sample_rate <= (24000 + 32000)/2 ? 1 : 2);
119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 521 times.
521 } else if (par->codec_id == AV_CODEC_ID_AC3) {
120 ✗ blkalign = 3840; /* maximum bytes per frame */
121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 521 times.
521 } else if (par->codec_id == AV_CODEC_ID_AAC) {
122 ✗ blkalign = 768 * par->ch_layout.nb_channels; /* maximum bytes per frame */
123
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 521 times.
521 } else if (par->codec_id == AV_CODEC_ID_G723_1) {
124 ✗ blkalign = 24;
125
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 5 times.
521 } else if (par->block_align != 0) { /* specified by the codec */
126 516 blkalign = par->block_align;
127 } else
128 5 blkalign = bps * par->ch_layout.nb_channels / av_gcd(8, bps);
129
2/2
✓ Branch 0 taken 523 times.
✓ Branch 1 taken 4 times.
527 if (par->codec_id == AV_CODEC_ID_PCM_U8 ||
130
2/2
✓ Branch 0 taken 515 times.
✓ Branch 1 taken 8 times.
523 par->codec_id == AV_CODEC_ID_PCM_S24LE ||
131
2/2
✓ Branch 0 taken 513 times.
✓ Branch 1 taken 2 times.
515 par->codec_id == AV_CODEC_ID_PCM_S32LE ||
132
2/2
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 1 times.
513 par->codec_id == AV_CODEC_ID_PCM_F32LE ||
133
2/2
✓ Branch 0 taken 511 times.
✓ Branch 1 taken 1 times.
512 par->codec_id == AV_CODEC_ID_PCM_F64LE ||
134
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 33 times.
511 par->codec_id == AV_CODEC_ID_PCM_S16LE) {
135 494 bytespersec = par->sample_rate * blkalign;
136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
33 } else if (par->codec_id == AV_CODEC_ID_G723_1) {
137 ✗ bytespersec = 800;
138
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 3 times.
33 } else if (par->codec_id == AV_CODEC_ID_ADPCM_MS ||
139
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 27 times.
30 par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
140
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (frame_size <= 0) {
141 ✗ av_log(s, AV_LOG_ERROR, "Invalid block_align or bps for %s\n",
142 avcodec_get_name(par->codec_id));
143 ✗ return AVERROR(EINVAL);
144 }
145 6 bytespersec = (int64_t)par->sample_rate * blkalign / frame_size;
146 } else {
147 27 bytespersec = par->bit_rate / 8;
148 }
149 527 avio_wl32(pb, bytespersec); /* bytes per second */
150 527 avio_wl16(pb, blkalign); /* block align */
151 527 avio_wl16(pb, bps); /* bits per sample */
152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 527 times.
527 if (par->codec_id == AV_CODEC_ID_MP3) {
153 ✗ bytestream_put_le16(&riff_extradata, 1); /* wID */
154 ✗ bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */
155 ✗ bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
156 ✗ bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */
157 ✗ bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
158
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 521 times.
527 } else if (par->codec_id == AV_CODEC_ID_MP2) {
159 /* fwHeadLayer */
160 6 bytestream_put_le16(&riff_extradata, 2);
161 /* dwHeadBitrate */
162 6 bytestream_put_le32(&riff_extradata, par->bit_rate);
163 /* fwHeadMode */
164
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 bytestream_put_le16(&riff_extradata, par->ch_layout.nb_channels == 2 ? 1 : 8);
165 /* fwHeadModeExt */
166 6 bytestream_put_le16(&riff_extradata, 0);
167 /* wHeadEmphasis */
168 6 bytestream_put_le16(&riff_extradata, 1);
169 /* fwHeadFlags */
170 6 bytestream_put_le16(&riff_extradata, 16);
171 /* dwPTSLow */
172 6 bytestream_put_le32(&riff_extradata, 0);
173 /* dwPTSHigh */
174 6 bytestream_put_le32(&riff_extradata, 0);
175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 521 times.
521 } else if (par->codec_id == AV_CODEC_ID_G723_1) {
176 ✗ bytestream_put_le32(&riff_extradata, 0x9ace0002); /* extradata needed for msacm g723.1 codec */
177 ✗ bytestream_put_le32(&riff_extradata, 0xaea2f732);
178 ✗ bytestream_put_le16(&riff_extradata, 0xacde);
179
1/2
✓ Branch 0 taken 521 times.
✗ Branch 1 not taken.
521 } else if (par->codec_id == AV_CODEC_ID_GSM_MS ||
180
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 518 times.
521 par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
181 /* wSamplesPerBlock */
182 3 bytestream_put_le16(&riff_extradata, frame_size);
183
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 508 times.
518 } else if (par->extradata_size) {
184 10 riff_extradata_start = par->extradata;
185 10 riff_extradata = par->extradata + par->extradata_size;
186 }
187 /* write WAVEFORMATEXTENSIBLE extensions */
188
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 467 times.
527 if (waveformatextensible) {
189
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
120 int write_channel_mask = !(flags & FF_PUT_WAV_HEADER_SKIP_CHANNELMASK) &&
190
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 (s->strict_std_compliance < FF_COMPLIANCE_NORMAL ||
191
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 par->ch_layout.u.mask < 0x40000);
192 /* 22 is WAVEFORMATEXTENSIBLE size */
193 60 avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
194 /* ValidBitsPerSample || SamplesPerBlock || Reserved */
195 60 avio_wl16(pb, bps);
196 /* dwChannelMask */
197
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 avio_wl32(pb, write_channel_mask ? par->ch_layout.u.mask : 0);
198 /* GUID + next 3 */
199
2/4
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 60 times.
60 if (par->codec_id == AV_CODEC_ID_EAC3 || par->codec_id == AV_CODEC_ID_DFPWM) {
200 ✗ ff_put_guid(pb, ff_get_codec_guid(par->codec_id, ff_codec_wav_guids));
201 } else {
202 60 avio_wl32(pb, par->codec_tag);
203 60 avio_wl32(pb, 0x00100000);
204 60 avio_wl32(pb, 0xAA000080);
205 60 avio_wl32(pb, 0x719B3800);
206 }
207
2/2
✓ Branch 0 taken 458 times.
✓ Branch 1 taken 9 times.
467 } else if ((flags & FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX) ||
208
3/4
✓ Branch 0 taken 432 times.
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 432 times.
458 par->codec_tag != 0x0001 /* PCM */ ||
209 riff_extradata - riff_extradata_start) {
210 /* WAVEFORMATEX */
211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
35 if (par->codec_tag == 0x1610) {
212 /* HEAACWAVEFORMAT */
213 ✗ avio_wl16(pb, par->extradata_size + 12); /* cbSize */
214 ✗ avio_wl16(pb, !par->extradata_size); // wPayloadType, 0 = Raw, 1 = ADTS
215 ✗ avio_wl16(pb, 0xFE); // wAudioProfileLevelIndication, 0xFE = unspecified
216 ✗ avio_wl16(pb, 0); // wStructType, 0 = AudioSpecificConfig()
217 ✗ avio_wl16(pb, 0); // wReserved1
218 ✗ avio_wl32(pb, 0); // dwReserved2
219
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
35 } else if (par->codec_tag == 0xFF && !par->extradata_size) {
220 ✗ av_log(s, AV_LOG_ERROR, "ADTS is only supported with codec tag 0x1610\n");
221 ✗ return AVERROR(EINVAL);
222 } else
223 35 avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
224 } /* else PCMWAVEFORMAT */
225 527 avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
226 527 hdrsize = avio_tell(pb) - hdrstart;
227
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 527 times.
527 if (hdrsize & 1) {
228 ✗ hdrsize++;
229 ✗ avio_w8(pb, 0);
230 }
231
232 527 return hdrsize;
233 }
234
235 /* BITMAPINFOHEADER header */
236 314 void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par,
237 int for_asf, int ignore_extradata, int rgb_frame_is_flipped)
238 {
239
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 228 times.
400 int flipped_extradata = (par->extradata_size >= 9 &&
240
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86 times.
86 !memcmp(par->extradata + par->extradata_size - 9, "BottomUp", 9));
241
2/4
✓ Branch 0 taken 314 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 314 times.
314 int keep_height = flipped_extradata || rgb_frame_is_flipped;
242 314 int extradata_size = par->extradata_size - 9*flipped_extradata;
243 314 enum AVPixelFormat pix_fmt = par->format;
244 int pal_avi;
245
246
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 314 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
314 if (pix_fmt == AV_PIX_FMT_NONE && par->bits_per_coded_sample == 1)
247 ✗ pix_fmt = AV_PIX_FMT_MONOWHITE;
248
4/4
✓ Branch 0 taken 312 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 307 times.
✓ Branch 3 taken 5 times.
621 pal_avi = !for_asf &&
249
2/2
✓ Branch 0 taken 303 times.
✓ Branch 1 taken 4 times.
307 (pix_fmt == AV_PIX_FMT_PAL8 ||
250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 303 times.
303 pix_fmt == AV_PIX_FMT_MONOWHITE ||
251 pix_fmt == AV_PIX_FMT_MONOBLACK);
252
253 /* Size (not including the size of the color table or color masks) */
254
4/4
✓ Branch 0 taken 312 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 303 times.
✓ Branch 3 taken 9 times.
314 avio_wl32(pb, 40 + (ignore_extradata || pal_avi ? 0 : extradata_size));
255 314 avio_wl32(pb, par->width);
256 //We always store RGB TopDown
257
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 300 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
314 avio_wl32(pb, par->codec_tag || keep_height ? par->height : -par->height);
258 /* planes */
259 314 avio_wl16(pb, 1);
260 /* depth */
261
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 237 times.
314 avio_wl16(pb, par->bits_per_coded_sample ? par->bits_per_coded_sample : 24);
262 /* compression type */
263 // MSRLE compatibility with Media Player 3.1 and Windows 95
264
2/2
✓ Branch 0 taken 310 times.
✓ Branch 1 taken 4 times.
314 avio_wl32(pb, par->codec_id == AV_CODEC_ID_MSRLE ? 1 : par->codec_tag);
265
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 237 times.
314 avio_wl32(pb, (par->width * par->height * (par->bits_per_coded_sample ? par->bits_per_coded_sample : 24)+7) / 8);
266 314 avio_wl32(pb, 0);
267 314 avio_wl32(pb, 0);
268 /* Number of color indices in the color table that are used.
269 * A value of 0 means 2^biBitCount indices, but this doesn't work
270 * with Windows Media Player and files containing xxpc chunks. */
271 // MSRLE on Windows 95 requires a zero here
272
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 305 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 4 times.
314 avio_wl32(pb, pal_avi && par->codec_id != AV_CODEC_ID_MSRLE ? 1 << par->bits_per_coded_sample : 0);
273 314 avio_wl32(pb, 0);
274
275
2/2
✓ Branch 0 taken 312 times.
✓ Branch 1 taken 2 times.
314 if (!ignore_extradata) {
276
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 210 times.
312 if (par->extradata_size) {
277 102 avio_write(pb, par->extradata, extradata_size);
278
3/4
✓ Branch 0 taken 102 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 84 times.
102 if (!for_asf && extradata_size & 1)
279 18 avio_w8(pb, 0);
280
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 202 times.
210 } else if (pal_avi) {
281 int i;
282
2/2
✓ Branch 0 taken 1032 times.
✓ Branch 1 taken 8 times.
1040 for (i = 0; i < 1 << par->bits_per_coded_sample; i++) {
283 /* Initialize 1 bpp palette to black & white */
284
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1024 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
1032 if (i == 0 && pix_fmt == AV_PIX_FMT_MONOWHITE)
285 4 avio_wl32(pb, 0xffffff);
286
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1020 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
1028 else if (i == 1 && pix_fmt == AV_PIX_FMT_MONOBLACK)
287 ✗ avio_wl32(pb, 0xffffff);
288 else
289 1028 avio_wl32(pb, 0);
290 }
291 }
292 }
293 314 }
294
295 3424 void ff_parse_specific_params(AVStream *st, int *au_rate,
296 int *au_ssize, int *au_scale)
297 {
298 3424 AVCodecParameters *par = st->codecpar;
299 int gcd;
300 int audio_frame_size;
301
302 3424 audio_frame_size = av_get_audio_frame_duration2(par, 0);
303
2/2
✓ Branch 0 taken 3419 times.
✓ Branch 1 taken 5 times.
3424 if (!audio_frame_size)
304 3419 audio_frame_size = par->frame_size;
305
306 3424 *au_ssize = par->block_align;
307
3/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 3408 times.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
3424 if (audio_frame_size && par->sample_rate) {
308 16 *au_scale = audio_frame_size;
309 16 *au_rate = par->sample_rate;
310
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 3393 times.
3408 } else if (par->codec_type == AVMEDIA_TYPE_VIDEO ||
311
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 par->codec_type == AVMEDIA_TYPE_DATA ||
312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
313 3393 *au_scale = st->time_base.num;
314 3393 *au_rate = st->time_base.den;
315 } else {
316
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 *au_scale = par->block_align ? par->block_align * 8 : 8;
317
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 *au_rate = par->bit_rate ? par->bit_rate :
318 ✗ 8 * par->sample_rate;
319 }
320 3424 gcd = av_gcd(*au_scale, *au_rate);
321 3424 *au_scale /= gcd;
322 3424 *au_rate /= gcd;
323 3424 }
324
325 343 void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
326 {
327 343 size_t len = strlen(str);
328
2/4
✓ Branch 0 taken 343 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 343 times.
✗ Branch 3 not taken.
343 if (len > 0 && len < UINT32_MAX) {
329 343 len++;
330 343 ffio_wfourcc(pb, tag);
331 343 avio_wl32(pb, len);
332 343 avio_put_str(pb, str);
333
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 330 times.
343 if (len & 1)
334 13 avio_w8(pb, 0);
335 }
336 343 }
337
338 static const char riff_tags[][5] = {
339 "IARL", "IART", "IAS1", "IAS2", "IAS3", "IAS4", "IAS5", "IAS6", "IAS7",
340 "IAS8", "IAS9", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
341 "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
342 "IPRT", "ITRK", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
343 { 0 }
344 };
345
346 818 static int riff_has_valid_tags(AVFormatContext *s)
347 {
348 int i;
349
350
2/2
✓ Branch 0 taken 27684 times.
✓ Branch 1 taken 483 times.
28167 for (i = 0; *riff_tags[i]; i++)
351
2/2
✓ Branch 1 taken 335 times.
✓ Branch 2 taken 27349 times.
27684 if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
352 335 return 1;
353
354 483 return 0;
355 }
356
357 818 void ff_riff_write_info(AVFormatContext *s)
358 {
359 818 AVIOContext *pb = s->pb;
360 int i;
361 int64_t list_pos;
362 818 AVDictionaryEntry *t = NULL;
363
364 818 ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
365
366 /* writing empty LIST is not nice and may cause problems */
367
2/2
✓ Branch 1 taken 483 times.
✓ Branch 2 taken 335 times.
818 if (!riff_has_valid_tags(s))
368 483 return;
369
370 335 list_pos = ff_start_tag(pb, "LIST");
371 335 ffio_wfourcc(pb, "INFO");
372
2/2
✓ Branch 0 taken 12060 times.
✓ Branch 1 taken 335 times.
12395 for (i = 0; *riff_tags[i]; i++)
373
2/2
✓ Branch 1 taken 343 times.
✓ Branch 2 taken 11717 times.
12060 if ((t = av_dict_get(s->metadata, riff_tags[i],
374 NULL, AV_DICT_MATCH_CASE)))
375 343 ff_riff_write_info_tag(s->pb, t->key, t->value);
376 335 ff_end_tag(pb, list_pos);
377 }
378
379 286 void ff_put_guid(AVIOContext *s, const ff_asf_guid *g)
380 {
381 av_assert0(sizeof(*g) == 16);
382 286 avio_write(s, *g, sizeof(*g));
383 286 }
384
385 4 const ff_asf_guid *ff_get_codec_guid(enum AVCodecID id, const AVCodecGuid *av_guid)
386 {
387 int i;
388
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 for (i = 0; av_guid[i].id != AV_CODEC_ID_NONE; i++) {
389
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
12 if (id == av_guid[i].id)
390 4 return &(av_guid[i].guid);
391 }
392 ✗ return NULL;
393 }
394