FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/riffenc.c
Date: 2026-04-24 19:58:39
Exec Total Coverage
Lines: 189 221 85.5%
Functions: 10 10 100.0%
Branches: 162 214 75.7%

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 4387 int64_t ff_start_tag(AVIOContext *pb, const char *tag)
32 {
33 4387 ffio_wfourcc(pb, tag);
34 4387 avio_wl32(pb, -1);
35 4387 return avio_tell(pb);
36 }
37
38 4031 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 4031 times.
4031 av_assert0((start&1) == 0);
43
44 4031 pos = avio_tell(pb);
45
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4030 times.
4031 if (pos & 1)
46 1 avio_w8(pb, 0);
47 4031 avio_seek(pb, start - 4, SEEK_SET);
48 4031 avio_wl32(pb, (uint32_t)(pos - start));
49 4031 avio_seek(pb, FFALIGN(pos, 2), SEEK_SET);
50 4031 }
51
52 /* WAVEFORMATEX header */
53 /* returns the size or -1 on error */
54 496 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 496 int64_t hdrstart = avio_tell(pb);
60 int waveformatextensible;
61 uint8_t temp[256];
62 496 uint8_t *riff_extradata = temp;
63 496 uint8_t *riff_extradata_start = temp;
64
65
2/4
✓ Branch 0 taken 496 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 496 times.
496 if (!par->codec_tag || par->codec_tag > 0xffff)
66 return -1;
67
68
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 495 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
496 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 496 frame_size = av_get_audio_frame_duration2(par, par->block_align);
78
79
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 352 times.
488 waveformatextensible = (par->ch_layout.order == AV_CHANNEL_ORDER_NATIVE &&
80
2/2
✓ Branch 1 taken 134 times.
✓ Branch 2 taken 2 times.
624 av_channel_layout_compare(&par->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_MONO) &&
81 136 av_channel_layout_compare(&par->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO)) ||
82
2/2
✓ Branch 0 taken 441 times.
✓ Branch 1 taken 53 times.
494 par->sample_rate > 48000 ||
83
6/8
✓ Branch 0 taken 488 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 441 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 441 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 436 times.
1438 par->codec_id == AV_CODEC_ID_EAC3 || par->codec_id == AV_CODEC_ID_DFPWM ||
84
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 2 times.
446 (av_get_bits_per_sample(par->codec_id) > 16 && par->codec_tag != 0x0003);
85
86
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 438 times.
496 if (waveformatextensible)
87 58 avio_wl16(pb, 0xfffe);
88 else
89 438 avio_wl16(pb, par->codec_tag);
90
91 496 avio_wl16(pb, par->ch_layout.nb_channels);
92 496 avio_wl32(pb, par->sample_rate);
93
1/2
✓ Branch 0 taken 496 times.
✗ Branch 1 not taken.
496 if (par->codec_id == AV_CODEC_ID_ATRAC3 ||
94
1/2
✓ Branch 0 taken 496 times.
✗ Branch 1 not taken.
496 par->codec_id == AV_CODEC_ID_G723_1 ||
95
1/2
✓ Branch 0 taken 496 times.
✗ Branch 1 not taken.
496 par->codec_id == AV_CODEC_ID_G728 ||
96
2/2
✓ Branch 0 taken 490 times.
✓ Branch 1 taken 6 times.
496 par->codec_id == AV_CODEC_ID_MP2 ||
97
1/2
✓ Branch 0 taken 490 times.
✗ Branch 1 not taken.
490 par->codec_id == AV_CODEC_ID_MP3 ||
98
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 490 times.
490 par->codec_id == AV_CODEC_ID_GSM_MS) {
99 6 bps = 0;
100 } else {
101
2/2
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 481 times.
490 if (!(bps = av_get_bits_per_sample(par->codec_id))) {
102
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if (par->bits_per_coded_sample)
103 5 bps = par->bits_per_coded_sample;
104 else
105 4 bps = 16; // default to 16
106 }
107 }
108
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 491 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
496 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 490 times.
496 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 490 times.
490 } 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 490 times.
490 } 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 490 times.
490 } 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 490 times.
490 } else if (par->codec_id == AV_CODEC_ID_G723_1) {
124 blkalign = 24;
125
2/2
✓ Branch 0 taken 485 times.
✓ Branch 1 taken 5 times.
490 } else if (par->block_align != 0) { /* specified by the codec */
126 485 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 494 times.
✓ Branch 1 taken 2 times.
496 if (par->codec_id == AV_CODEC_ID_PCM_U8 ||
130
2/2
✓ Branch 0 taken 488 times.
✓ Branch 1 taken 6 times.
494 par->codec_id == AV_CODEC_ID_PCM_S24LE ||
131
2/2
✓ Branch 0 taken 486 times.
✓ Branch 1 taken 2 times.
488 par->codec_id == AV_CODEC_ID_PCM_S32LE ||
132
2/2
✓ Branch 0 taken 485 times.
✓ Branch 1 taken 1 times.
486 par->codec_id == AV_CODEC_ID_PCM_F32LE ||
133
2/2
✓ Branch 0 taken 484 times.
✓ Branch 1 taken 1 times.
485 par->codec_id == AV_CODEC_ID_PCM_F64LE ||
134
2/2
✓ Branch 0 taken 459 times.
✓ Branch 1 taken 25 times.
484 par->codec_id == AV_CODEC_ID_PCM_S16LE) {
135 471 bytespersec = par->sample_rate * blkalign;
136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 } else if (par->codec_id == AV_CODEC_ID_G723_1) {
137 bytespersec = 800;
138 } else {
139 25 bytespersec = par->bit_rate / 8;
140 }
141 496 avio_wl32(pb, bytespersec); /* bytes per second */
142 496 avio_wl16(pb, blkalign); /* block align */
143 496 avio_wl16(pb, bps); /* bits per sample */
144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 496 times.
496 if (par->codec_id == AV_CODEC_ID_MP3) {
145 bytestream_put_le16(&riff_extradata, 1); /* wID */
146 bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */
147 bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
148 bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */
149 bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
150
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 490 times.
496 } else if (par->codec_id == AV_CODEC_ID_MP2) {
151 /* fwHeadLayer */
152 6 bytestream_put_le16(&riff_extradata, 2);
153 /* dwHeadBitrate */
154 6 bytestream_put_le32(&riff_extradata, par->bit_rate);
155 /* fwHeadMode */
156
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);
157 /* fwHeadModeExt */
158 6 bytestream_put_le16(&riff_extradata, 0);
159 /* wHeadEmphasis */
160 6 bytestream_put_le16(&riff_extradata, 1);
161 /* fwHeadFlags */
162 6 bytestream_put_le16(&riff_extradata, 16);
163 /* dwPTSLow */
164 6 bytestream_put_le32(&riff_extradata, 0);
165 /* dwPTSHigh */
166 6 bytestream_put_le32(&riff_extradata, 0);
167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 490 times.
490 } else if (par->codec_id == AV_CODEC_ID_G723_1) {
168 bytestream_put_le32(&riff_extradata, 0x9ace0002); /* extradata needed for msacm g723.1 codec */
169 bytestream_put_le32(&riff_extradata, 0xaea2f732);
170 bytestream_put_le16(&riff_extradata, 0xacde);
171
1/2
✓ Branch 0 taken 490 times.
✗ Branch 1 not taken.
490 } else if (par->codec_id == AV_CODEC_ID_GSM_MS ||
172
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 488 times.
490 par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
173 /* wSamplesPerBlock */
174 2 bytestream_put_le16(&riff_extradata, frame_size);
175
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 481 times.
488 } else if (par->extradata_size) {
176 7 riff_extradata_start = par->extradata;
177 7 riff_extradata = par->extradata + par->extradata_size;
178 }
179 /* write WAVEFORMATEXTENSIBLE extensions */
180
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 438 times.
496 if (waveformatextensible) {
181
1/2
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
116 int write_channel_mask = !(flags & FF_PUT_WAV_HEADER_SKIP_CHANNELMASK) &&
182
1/2
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
58 (s->strict_std_compliance < FF_COMPLIANCE_NORMAL ||
183
1/2
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
58 par->ch_layout.u.mask < 0x40000);
184 /* 22 is WAVEFORMATEXTENSIBLE size */
185 58 avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
186 /* ValidBitsPerSample || SamplesPerBlock || Reserved */
187 58 avio_wl16(pb, bps);
188 /* dwChannelMask */
189
1/2
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
58 avio_wl32(pb, write_channel_mask ? par->ch_layout.u.mask : 0);
190 /* GUID + next 3 */
191
2/4
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 58 times.
58 if (par->codec_id == AV_CODEC_ID_EAC3 || par->codec_id == AV_CODEC_ID_DFPWM) {
192 ff_put_guid(pb, ff_get_codec_guid(par->codec_id, ff_codec_wav_guids));
193 } else {
194 58 avio_wl32(pb, par->codec_tag);
195 58 avio_wl32(pb, 0x00100000);
196 58 avio_wl32(pb, 0xAA000080);
197 58 avio_wl32(pb, 0x719B3800);
198 }
199
2/2
✓ Branch 0 taken 431 times.
✓ Branch 1 taken 7 times.
438 } else if ((flags & FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX) ||
200
3/4
✓ Branch 0 taken 411 times.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 411 times.
431 par->codec_tag != 0x0001 /* PCM */ ||
201 riff_extradata - riff_extradata_start) {
202 /* WAVEFORMATEX */
203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if (par->codec_tag == 0x1610) {
204 /* HEAACWAVEFORMAT */
205 avio_wl16(pb, par->extradata_size + 12); /* cbSize */
206 avio_wl16(pb, !par->extradata_size); // wPayloadType, 0 = Raw, 1 = ADTS
207 avio_wl16(pb, 0xFE); // wAudioProfileLevelIndication, 0xFE = unspecified
208 avio_wl16(pb, 0); // wStructType, 0 = AudioSpecificConfig()
209 avio_wl16(pb, 0); // wReserved1
210 avio_wl32(pb, 0); // dwReserved2
211
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
27 } else if (par->codec_tag == 0xFF && !par->extradata_size) {
212 av_log(s, AV_LOG_ERROR, "ADTS is only supported with codec tag 0x1610\n");
213 return AVERROR(EINVAL);
214 } else
215 27 avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
216 } /* else PCMWAVEFORMAT */
217 496 avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
218 496 hdrsize = avio_tell(pb) - hdrstart;
219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 496 times.
496 if (hdrsize & 1) {
220 hdrsize++;
221 avio_w8(pb, 0);
222 }
223
224 496 return hdrsize;
225 }
226
227 /* BITMAPINFOHEADER header */
228 313 void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par,
229 int for_asf, int ignore_extradata, int rgb_frame_is_flipped)
230 {
231
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 227 times.
399 int flipped_extradata = (par->extradata_size >= 9 &&
232
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86 times.
86 !memcmp(par->extradata + par->extradata_size - 9, "BottomUp", 9));
233
2/4
✓ Branch 0 taken 313 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 313 times.
313 int keep_height = flipped_extradata || rgb_frame_is_flipped;
234 313 int extradata_size = par->extradata_size - 9*flipped_extradata;
235 313 enum AVPixelFormat pix_fmt = par->format;
236 int pal_avi;
237
238
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 313 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
313 if (pix_fmt == AV_PIX_FMT_NONE && par->bits_per_coded_sample == 1)
239 pix_fmt = AV_PIX_FMT_MONOWHITE;
240
4/4
✓ Branch 0 taken 311 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 306 times.
✓ Branch 3 taken 5 times.
619 pal_avi = !for_asf &&
241
2/2
✓ Branch 0 taken 302 times.
✓ Branch 1 taken 4 times.
306 (pix_fmt == AV_PIX_FMT_PAL8 ||
242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 302 times.
302 pix_fmt == AV_PIX_FMT_MONOWHITE ||
243 pix_fmt == AV_PIX_FMT_MONOBLACK);
244
245 /* Size (not including the size of the color table or color masks) */
246
4/4
✓ Branch 0 taken 311 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 302 times.
✓ Branch 3 taken 9 times.
313 avio_wl32(pb, 40 + (ignore_extradata || pal_avi ? 0 : extradata_size));
247 313 avio_wl32(pb, par->width);
248 //We always store RGB TopDown
249
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 299 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
313 avio_wl32(pb, par->codec_tag || keep_height ? par->height : -par->height);
250 /* planes */
251 313 avio_wl16(pb, 1);
252 /* depth */
253
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 236 times.
313 avio_wl16(pb, par->bits_per_coded_sample ? par->bits_per_coded_sample : 24);
254 /* compression type */
255 // MSRLE compatibility with Media Player 3.1 and Windows 95
256
2/2
✓ Branch 0 taken 309 times.
✓ Branch 1 taken 4 times.
313 avio_wl32(pb, par->codec_id == AV_CODEC_ID_MSRLE ? 1 : par->codec_tag);
257
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 236 times.
313 avio_wl32(pb, (par->width * par->height * (par->bits_per_coded_sample ? par->bits_per_coded_sample : 24)+7) / 8);
258 313 avio_wl32(pb, 0);
259 313 avio_wl32(pb, 0);
260 /* Number of color indices in the color table that are used.
261 * A value of 0 means 2^biBitCount indices, but this doesn't work
262 * with Windows Media Player and files containing xxpc chunks. */
263 // MSRLE on Windows 95 requires a zero here
264
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 304 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 4 times.
313 avio_wl32(pb, pal_avi && par->codec_id != AV_CODEC_ID_MSRLE ? 1 << par->bits_per_coded_sample : 0);
265 313 avio_wl32(pb, 0);
266
267
2/2
✓ Branch 0 taken 311 times.
✓ Branch 1 taken 2 times.
313 if (!ignore_extradata) {
268
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 209 times.
311 if (par->extradata_size) {
269 102 avio_write(pb, par->extradata, extradata_size);
270
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)
271 18 avio_w8(pb, 0);
272
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 201 times.
209 } else if (pal_avi) {
273 int i;
274
2/2
✓ Branch 0 taken 1032 times.
✓ Branch 1 taken 8 times.
1040 for (i = 0; i < 1 << par->bits_per_coded_sample; i++) {
275 /* Initialize 1 bpp palette to black & white */
276
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)
277 4 avio_wl32(pb, 0xffffff);
278
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)
279 avio_wl32(pb, 0xffffff);
280 else
281 1028 avio_wl32(pb, 0);
282 }
283 }
284 }
285 313 }
286
287 3400 void ff_parse_specific_params(AVStream *st, int *au_rate,
288 int *au_ssize, int *au_scale)
289 {
290 3400 AVCodecParameters *par = st->codecpar;
291 int gcd;
292 int audio_frame_size;
293
294 3400 audio_frame_size = av_get_audio_frame_duration2(par, 0);
295
2/2
✓ Branch 0 taken 3395 times.
✓ Branch 1 taken 5 times.
3400 if (!audio_frame_size)
296 3395 audio_frame_size = par->frame_size;
297
298 3400 *au_ssize = par->block_align;
299
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3395 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
3400 if (audio_frame_size && par->sample_rate) {
300 5 *au_scale = audio_frame_size;
301 5 *au_rate = par->sample_rate;
302
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 3380 times.
3395 } else if (par->codec_type == AVMEDIA_TYPE_VIDEO ||
303
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 par->codec_type == AVMEDIA_TYPE_DATA ||
304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
305 3380 *au_scale = st->time_base.num;
306 3380 *au_rate = st->time_base.den;
307 } else {
308
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 *au_scale = par->block_align ? par->block_align * 8 : 8;
309
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 *au_rate = par->bit_rate ? par->bit_rate :
310 8 * par->sample_rate;
311 }
312 3400 gcd = av_gcd(*au_scale, *au_rate);
313 3400 *au_scale /= gcd;
314 3400 *au_rate /= gcd;
315 3400 }
316
317 329 void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
318 {
319 329 size_t len = strlen(str);
320
2/4
✓ Branch 0 taken 329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 329 times.
✗ Branch 3 not taken.
329 if (len > 0 && len < UINT32_MAX) {
321 329 len++;
322 329 ffio_wfourcc(pb, tag);
323 329 avio_wl32(pb, len);
324 329 avio_put_str(pb, str);
325
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 322 times.
329 if (len & 1)
326 7 avio_w8(pb, 0);
327 }
328 329 }
329
330 static const char riff_tags[][5] = {
331 "IARL", "IART", "IAS1", "IAS2", "IAS3", "IAS4", "IAS5", "IAS6", "IAS7",
332 "IAS8", "IAS9", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
333 "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
334 "IPRT", "ITRK", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
335 { 0 }
336 };
337
338 788 static int riff_has_valid_tags(AVFormatContext *s)
339 {
340 int i;
341
342
2/2
✓ Branch 0 taken 26675 times.
✓ Branch 1 taken 459 times.
27134 for (i = 0; *riff_tags[i]; i++)
343
2/2
✓ Branch 1 taken 329 times.
✓ Branch 2 taken 26346 times.
26675 if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
344 329 return 1;
345
346 459 return 0;
347 }
348
349 788 void ff_riff_write_info(AVFormatContext *s)
350 {
351 788 AVIOContext *pb = s->pb;
352 int i;
353 int64_t list_pos;
354 788 AVDictionaryEntry *t = NULL;
355
356 788 ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
357
358 /* writing empty LIST is not nice and may cause problems */
359
2/2
✓ Branch 1 taken 459 times.
✓ Branch 2 taken 329 times.
788 if (!riff_has_valid_tags(s))
360 459 return;
361
362 329 list_pos = ff_start_tag(pb, "LIST");
363 329 ffio_wfourcc(pb, "INFO");
364
2/2
✓ Branch 0 taken 11844 times.
✓ Branch 1 taken 329 times.
12173 for (i = 0; *riff_tags[i]; i++)
365
2/2
✓ Branch 1 taken 329 times.
✓ Branch 2 taken 11515 times.
11844 if ((t = av_dict_get(s->metadata, riff_tags[i],
366 NULL, AV_DICT_MATCH_CASE)))
367 329 ff_riff_write_info_tag(s->pb, t->key, t->value);
368 329 ff_end_tag(pb, list_pos);
369 }
370
371 258 void ff_put_guid(AVIOContext *s, const ff_asf_guid *g)
372 {
373 av_assert0(sizeof(*g) == 16);
374 258 avio_write(s, *g, sizeof(*g));
375 258 }
376
377 4 const ff_asf_guid *ff_get_codec_guid(enum AVCodecID id, const AVCodecGuid *av_guid)
378 {
379 int i;
380
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 for (i = 0; av_guid[i].id != AV_CODEC_ID_NONE; i++) {
381
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
12 if (id == av_guid[i].id)
382 4 return &(av_guid[i].guid);
383 }
384 return NULL;
385 }
386