FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/riffenc.c
Date: 2025-06-23 20:06:14
Exec Total Coverage
Lines: 187 211 88.6%
Functions: 10 10 100.0%
Branches: 160 208 76.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 4373 int64_t ff_start_tag(AVIOContext *pb, const char *tag)
32 {
33 4373 ffio_wfourcc(pb, tag);
34 4373 avio_wl32(pb, -1);
35 4373 return avio_tell(pb);
36 }
37
38 4017 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 4017 times.
4017 av_assert0((start&1) == 0);
43
44 4017 pos = avio_tell(pb);
45
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4016 times.
4017 if (pos & 1)
46 1 avio_w8(pb, 0);
47 4017 avio_seek(pb, start - 4, SEEK_SET);
48 4017 avio_wl32(pb, (uint32_t)(pos - start));
49 4017 avio_seek(pb, FFALIGN(pos, 2), SEEK_SET);
50 4017 }
51
52 /* WAVEFORMATEX header */
53 /* returns the size or -1 on error */
54 489 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 489 int64_t hdrstart = avio_tell(pb);
60 int waveformatextensible;
61 uint8_t temp[256];
62 489 uint8_t *riff_extradata = temp;
63 489 uint8_t *riff_extradata_start = temp;
64
65
2/4
✓ Branch 0 taken 489 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 489 times.
489 if (!par->codec_tag || par->codec_tag > 0xffff)
66 return -1;
67
68
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 488 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
489 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 489 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 434 times.
✓ Branch 1 taken 53 times.
487 par->sample_rate > 48000 ||
83
6/8
✓ Branch 0 taken 488 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 434 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 434 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 429 times.
1417 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.
439 (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 431 times.
489 if (waveformatextensible)
87 58 avio_wl16(pb, 0xfffe);
88 else
89 431 avio_wl16(pb, par->codec_tag);
90
91 489 avio_wl16(pb, par->ch_layout.nb_channels);
92 489 avio_wl32(pb, par->sample_rate);
93
1/2
✓ Branch 0 taken 489 times.
✗ Branch 1 not taken.
489 if (par->codec_id == AV_CODEC_ID_ATRAC3 ||
94
1/2
✓ Branch 0 taken 489 times.
✗ Branch 1 not taken.
489 par->codec_id == AV_CODEC_ID_G723_1 ||
95
1/2
✓ Branch 0 taken 489 times.
✗ Branch 1 not taken.
489 par->codec_id == AV_CODEC_ID_G728 ||
96
2/2
✓ Branch 0 taken 483 times.
✓ Branch 1 taken 6 times.
489 par->codec_id == AV_CODEC_ID_MP2 ||
97
1/2
✓ Branch 0 taken 483 times.
✗ Branch 1 not taken.
483 par->codec_id == AV_CODEC_ID_MP3 ||
98
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 483 times.
483 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 474 times.
483 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 484 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
489 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 483 times.
489 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 483 times.
483 } 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 483 times.
483 } 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 483 times.
483 } 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 483 times.
483 } else if (par->codec_id == AV_CODEC_ID_G723_1) {
124 blkalign = 24;
125
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 5 times.
483 } else if (par->block_align != 0) { /* specified by the codec */
126 478 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 487 times.
✓ Branch 1 taken 2 times.
489 if (par->codec_id == AV_CODEC_ID_PCM_U8 ||
130
2/2
✓ Branch 0 taken 481 times.
✓ Branch 1 taken 6 times.
487 par->codec_id == AV_CODEC_ID_PCM_S24LE ||
131
2/2
✓ Branch 0 taken 479 times.
✓ Branch 1 taken 2 times.
481 par->codec_id == AV_CODEC_ID_PCM_S32LE ||
132
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 1 times.
479 par->codec_id == AV_CODEC_ID_PCM_F32LE ||
133
2/2
✓ Branch 0 taken 477 times.
✓ Branch 1 taken 1 times.
478 par->codec_id == AV_CODEC_ID_PCM_F64LE ||
134
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 25 times.
477 par->codec_id == AV_CODEC_ID_PCM_S16LE) {
135 464 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 489 avio_wl32(pb, bytespersec); /* bytes per second */
142 489 avio_wl16(pb, blkalign); /* block align */
143 489 avio_wl16(pb, bps); /* bits per sample */
144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 489 times.
489 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 483 times.
489 } 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 483 times.
483 } 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 483 times.
✗ Branch 1 not taken.
483 } else if (par->codec_id == AV_CODEC_ID_GSM_MS ||
172
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 481 times.
483 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 474 times.
481 } 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 431 times.
489 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 424 times.
✓ Branch 1 taken 7 times.
431 } else if ((flags & FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX) ||
200
3/4
✓ Branch 0 taken 404 times.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 404 times.
424 par->codec_tag != 0x0001 /* PCM */ ||
201 riff_extradata - riff_extradata_start) {
202 /* WAVEFORMATEX */
203 27 avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
204 } /* else PCMWAVEFORMAT */
205 489 avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
206 489 hdrsize = avio_tell(pb) - hdrstart;
207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 489 times.
489 if (hdrsize & 1) {
208 hdrsize++;
209 avio_w8(pb, 0);
210 }
211
212 489 return hdrsize;
213 }
214
215 /* BITMAPINFOHEADER header */
216 313 void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par,
217 int for_asf, int ignore_extradata, int rgb_frame_is_flipped)
218 {
219
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 227 times.
399 int flipped_extradata = (par->extradata_size >= 9 &&
220
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86 times.
86 !memcmp(par->extradata + par->extradata_size - 9, "BottomUp", 9));
221
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;
222 313 int extradata_size = par->extradata_size - 9*flipped_extradata;
223 313 enum AVPixelFormat pix_fmt = par->format;
224 int pal_avi;
225
226
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)
227 pix_fmt = AV_PIX_FMT_MONOWHITE;
228
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 &&
229
2/2
✓ Branch 0 taken 302 times.
✓ Branch 1 taken 4 times.
306 (pix_fmt == AV_PIX_FMT_PAL8 ||
230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 302 times.
302 pix_fmt == AV_PIX_FMT_MONOWHITE ||
231 pix_fmt == AV_PIX_FMT_MONOBLACK);
232
233 /* Size (not including the size of the color table or color masks) */
234
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));
235 313 avio_wl32(pb, par->width);
236 //We always store RGB TopDown
237
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);
238 /* planes */
239 313 avio_wl16(pb, 1);
240 /* depth */
241
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);
242 /* compression type */
243 // MSRLE compatibility with Media Player 3.1 and Windows 95
244
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);
245
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);
246 313 avio_wl32(pb, 0);
247 313 avio_wl32(pb, 0);
248 /* Number of color indices in the color table that are used.
249 * A value of 0 means 2^biBitCount indices, but this doesn't work
250 * with Windows Media Player and files containing xxpc chunks. */
251 // MSRLE on Windows 95 requires a zero here
252
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);
253 313 avio_wl32(pb, 0);
254
255
2/2
✓ Branch 0 taken 311 times.
✓ Branch 1 taken 2 times.
313 if (!ignore_extradata) {
256
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 209 times.
311 if (par->extradata_size) {
257 102 avio_write(pb, par->extradata, extradata_size);
258
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)
259 18 avio_w8(pb, 0);
260
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 201 times.
209 } else if (pal_avi) {
261 int i;
262
2/2
✓ Branch 0 taken 1032 times.
✓ Branch 1 taken 8 times.
1040 for (i = 0; i < 1 << par->bits_per_coded_sample; i++) {
263 /* Initialize 1 bpp palette to black & white */
264
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)
265 4 avio_wl32(pb, 0xffffff);
266
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)
267 avio_wl32(pb, 0xffffff);
268 else
269 1028 avio_wl32(pb, 0);
270 }
271 }
272 }
273 313 }
274
275 3300 void ff_parse_specific_params(AVStream *st, int *au_rate,
276 int *au_ssize, int *au_scale)
277 {
278 3300 AVCodecParameters *par = st->codecpar;
279 int gcd;
280 int audio_frame_size;
281
282 3300 audio_frame_size = av_get_audio_frame_duration2(par, 0);
283
2/2
✓ Branch 0 taken 3295 times.
✓ Branch 1 taken 5 times.
3300 if (!audio_frame_size)
284 3295 audio_frame_size = par->frame_size;
285
286 3300 *au_ssize = par->block_align;
287
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3295 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
3300 if (audio_frame_size && par->sample_rate) {
288 5 *au_scale = audio_frame_size;
289 5 *au_rate = par->sample_rate;
290
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 3280 times.
3295 } else if (par->codec_type == AVMEDIA_TYPE_VIDEO ||
291
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 par->codec_type == AVMEDIA_TYPE_DATA ||
292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
293 3280 *au_scale = st->time_base.num;
294 3280 *au_rate = st->time_base.den;
295 } else {
296
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 *au_scale = par->block_align ? par->block_align * 8 : 8;
297
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 *au_rate = par->bit_rate ? par->bit_rate :
298 8 * par->sample_rate;
299 }
300 3300 gcd = av_gcd(*au_scale, *au_rate);
301 3300 *au_scale /= gcd;
302 3300 *au_rate /= gcd;
303 3300 }
304
305 329 void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
306 {
307 329 size_t len = strlen(str);
308
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) {
309 329 len++;
310 329 ffio_wfourcc(pb, tag);
311 329 avio_wl32(pb, len);
312 329 avio_put_str(pb, str);
313
2/2
✓ Branch 0 taken 328 times.
✓ Branch 1 taken 1 times.
329 if (len & 1)
314 328 avio_w8(pb, 0);
315 }
316 329 }
317
318 static const char riff_tags[][5] = {
319 "IARL", "IART", "IAS1", "IAS2", "IAS3", "IAS4", "IAS5", "IAS6", "IAS7",
320 "IAS8", "IAS9", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
321 "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
322 "IPRT", "ITRK", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
323 { 0 }
324 };
325
326 781 static int riff_has_valid_tags(AVFormatContext *s)
327 {
328 int i;
329
330
2/2
✓ Branch 0 taken 26423 times.
✓ Branch 1 taken 452 times.
26875 for (i = 0; *riff_tags[i]; i++)
331
2/2
✓ Branch 1 taken 329 times.
✓ Branch 2 taken 26094 times.
26423 if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
332 329 return 1;
333
334 452 return 0;
335 }
336
337 781 void ff_riff_write_info(AVFormatContext *s)
338 {
339 781 AVIOContext *pb = s->pb;
340 int i;
341 int64_t list_pos;
342 781 AVDictionaryEntry *t = NULL;
343
344 781 ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
345
346 /* writing empty LIST is not nice and may cause problems */
347
2/2
✓ Branch 1 taken 452 times.
✓ Branch 2 taken 329 times.
781 if (!riff_has_valid_tags(s))
348 452 return;
349
350 329 list_pos = ff_start_tag(pb, "LIST");
351 329 ffio_wfourcc(pb, "INFO");
352
2/2
✓ Branch 0 taken 11844 times.
✓ Branch 1 taken 329 times.
12173 for (i = 0; *riff_tags[i]; i++)
353
2/2
✓ Branch 1 taken 329 times.
✓ Branch 2 taken 11515 times.
11844 if ((t = av_dict_get(s->metadata, riff_tags[i],
354 NULL, AV_DICT_MATCH_CASE)))
355 329 ff_riff_write_info_tag(s->pb, t->key, t->value);
356 329 ff_end_tag(pb, list_pos);
357 }
358
359 258 void ff_put_guid(AVIOContext *s, const ff_asf_guid *g)
360 {
361 av_assert0(sizeof(*g) == 16);
362 258 avio_write(s, *g, sizeof(*g));
363 258 }
364
365 4 const ff_asf_guid *ff_get_codec_guid(enum AVCodecID id, const AVCodecGuid *av_guid)
366 {
367 int i;
368
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 for (i = 0; av_guid[i].id != AV_CODEC_ID_NONE; i++) {
369
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
12 if (id == av_guid[i].id)
370 4 return &(av_guid[i].guid);
371 }
372 return NULL;
373 }
374