FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/riffenc.c
Date: 2025-03-08 20:38:41
Exec Total Coverage
Lines: 186 210 88.6%
Functions: 10 10 100.0%
Branches: 159 206 77.2%

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 4333 int64_t ff_start_tag(AVIOContext *pb, const char *tag)
32 {
33 4333 ffio_wfourcc(pb, tag);
34 4333 avio_wl32(pb, -1);
35 4333 return avio_tell(pb);
36 }
37
38 3977 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 3977 times.
3977 av_assert0((start&1) == 0);
43
44 3977 pos = avio_tell(pb);
45
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3976 times.
3977 if (pos & 1)
46 1 avio_w8(pb, 0);
47 3977 avio_seek(pb, start - 4, SEEK_SET);
48 3977 avio_wl32(pb, (uint32_t)(pos - start));
49 3977 avio_seek(pb, FFALIGN(pos, 2), SEEK_SET);
50 3977 }
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
2/2
✓ Branch 0 taken 483 times.
✓ Branch 1 taken 6 times.
489 par->codec_id == AV_CODEC_ID_MP2 ||
96
1/2
✓ Branch 0 taken 483 times.
✗ Branch 1 not taken.
483 par->codec_id == AV_CODEC_ID_MP3 ||
97
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 483 times.
483 par->codec_id == AV_CODEC_ID_GSM_MS) {
98 6 bps = 0;
99 } else {
100
2/2
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 474 times.
483 if (!(bps = av_get_bits_per_sample(par->codec_id))) {
101
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if (par->bits_per_coded_sample)
102 5 bps = par->bits_per_coded_sample;
103 else
104 4 bps = 16; // default to 16
105 }
106 }
107
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) {
108 av_log(s, AV_LOG_WARNING,
109 "requested bits_per_coded_sample (%d) "
110 "and actually stored (%d) differ\n",
111 par->bits_per_coded_sample, bps);
112 }
113
114
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 483 times.
489 if (par->codec_id == AV_CODEC_ID_MP2) {
115 6 blkalign = (144 * par->bit_rate - 1)/par->sample_rate + 1;
116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 483 times.
483 } else if (par->codec_id == AV_CODEC_ID_MP3) {
117 blkalign = 576 * (par->sample_rate <= (24000 + 32000)/2 ? 1 : 2);
118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 483 times.
483 } else if (par->codec_id == AV_CODEC_ID_AC3) {
119 blkalign = 3840; /* maximum bytes per frame */
120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 483 times.
483 } else if (par->codec_id == AV_CODEC_ID_AAC) {
121 blkalign = 768 * par->ch_layout.nb_channels; /* maximum bytes per frame */
122
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 483 times.
483 } else if (par->codec_id == AV_CODEC_ID_G723_1) {
123 blkalign = 24;
124
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 5 times.
483 } else if (par->block_align != 0) { /* specified by the codec */
125 478 blkalign = par->block_align;
126 } else
127 5 blkalign = bps * par->ch_layout.nb_channels / av_gcd(8, bps);
128
2/2
✓ Branch 0 taken 487 times.
✓ Branch 1 taken 2 times.
489 if (par->codec_id == AV_CODEC_ID_PCM_U8 ||
129
2/2
✓ Branch 0 taken 481 times.
✓ Branch 1 taken 6 times.
487 par->codec_id == AV_CODEC_ID_PCM_S24LE ||
130
2/2
✓ Branch 0 taken 479 times.
✓ Branch 1 taken 2 times.
481 par->codec_id == AV_CODEC_ID_PCM_S32LE ||
131
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 1 times.
479 par->codec_id == AV_CODEC_ID_PCM_F32LE ||
132
2/2
✓ Branch 0 taken 477 times.
✓ Branch 1 taken 1 times.
478 par->codec_id == AV_CODEC_ID_PCM_F64LE ||
133
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 25 times.
477 par->codec_id == AV_CODEC_ID_PCM_S16LE) {
134 464 bytespersec = par->sample_rate * blkalign;
135
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 } else if (par->codec_id == AV_CODEC_ID_G723_1) {
136 bytespersec = 800;
137 } else {
138 25 bytespersec = par->bit_rate / 8;
139 }
140 489 avio_wl32(pb, bytespersec); /* bytes per second */
141 489 avio_wl16(pb, blkalign); /* block align */
142 489 avio_wl16(pb, bps); /* bits per sample */
143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 489 times.
489 if (par->codec_id == AV_CODEC_ID_MP3) {
144 bytestream_put_le16(&riff_extradata, 1); /* wID */
145 bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */
146 bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
147 bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */
148 bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
149
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 483 times.
489 } else if (par->codec_id == AV_CODEC_ID_MP2) {
150 /* fwHeadLayer */
151 6 bytestream_put_le16(&riff_extradata, 2);
152 /* dwHeadBitrate */
153 6 bytestream_put_le32(&riff_extradata, par->bit_rate);
154 /* fwHeadMode */
155
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);
156 /* fwHeadModeExt */
157 6 bytestream_put_le16(&riff_extradata, 0);
158 /* wHeadEmphasis */
159 6 bytestream_put_le16(&riff_extradata, 1);
160 /* fwHeadFlags */
161 6 bytestream_put_le16(&riff_extradata, 16);
162 /* dwPTSLow */
163 6 bytestream_put_le32(&riff_extradata, 0);
164 /* dwPTSHigh */
165 6 bytestream_put_le32(&riff_extradata, 0);
166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 483 times.
483 } else if (par->codec_id == AV_CODEC_ID_G723_1) {
167 bytestream_put_le32(&riff_extradata, 0x9ace0002); /* extradata needed for msacm g723.1 codec */
168 bytestream_put_le32(&riff_extradata, 0xaea2f732);
169 bytestream_put_le16(&riff_extradata, 0xacde);
170
1/2
✓ Branch 0 taken 483 times.
✗ Branch 1 not taken.
483 } else if (par->codec_id == AV_CODEC_ID_GSM_MS ||
171
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 481 times.
483 par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
172 /* wSamplesPerBlock */
173 2 bytestream_put_le16(&riff_extradata, frame_size);
174
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 474 times.
481 } else if (par->extradata_size) {
175 7 riff_extradata_start = par->extradata;
176 7 riff_extradata = par->extradata + par->extradata_size;
177 }
178 /* write WAVEFORMATEXTENSIBLE extensions */
179
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 431 times.
489 if (waveformatextensible) {
180
1/2
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
116 int write_channel_mask = !(flags & FF_PUT_WAV_HEADER_SKIP_CHANNELMASK) &&
181
1/2
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
58 (s->strict_std_compliance < FF_COMPLIANCE_NORMAL ||
182
1/2
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
58 par->ch_layout.u.mask < 0x40000);
183 /* 22 is WAVEFORMATEXTENSIBLE size */
184 58 avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
185 /* ValidBitsPerSample || SamplesPerBlock || Reserved */
186 58 avio_wl16(pb, bps);
187 /* dwChannelMask */
188
1/2
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
58 avio_wl32(pb, write_channel_mask ? par->ch_layout.u.mask : 0);
189 /* GUID + next 3 */
190
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) {
191 ff_put_guid(pb, ff_get_codec_guid(par->codec_id, ff_codec_wav_guids));
192 } else {
193 58 avio_wl32(pb, par->codec_tag);
194 58 avio_wl32(pb, 0x00100000);
195 58 avio_wl32(pb, 0xAA000080);
196 58 avio_wl32(pb, 0x719B3800);
197 }
198
2/2
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 7 times.
431 } else if ((flags & FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX) ||
199
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 */ ||
200 riff_extradata - riff_extradata_start) {
201 /* WAVEFORMATEX */
202 27 avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
203 } /* else PCMWAVEFORMAT */
204 489 avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
205 489 hdrsize = avio_tell(pb) - hdrstart;
206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 489 times.
489 if (hdrsize & 1) {
207 hdrsize++;
208 avio_w8(pb, 0);
209 }
210
211 489 return hdrsize;
212 }
213
214 /* BITMAPINFOHEADER header */
215 309 void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par,
216 int for_asf, int ignore_extradata, int rgb_frame_is_flipped)
217 {
218
2/2
✓ Branch 0 taken 82 times.
✓ Branch 1 taken 227 times.
391 int flipped_extradata = (par->extradata_size >= 9 &&
219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 82 times.
82 !memcmp(par->extradata + par->extradata_size - 9, "BottomUp", 9));
220
2/4
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 309 times.
309 int keep_height = flipped_extradata || rgb_frame_is_flipped;
221 309 int extradata_size = par->extradata_size - 9*flipped_extradata;
222 309 enum AVPixelFormat pix_fmt = par->format;
223 int pal_avi;
224
225
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 309 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
309 if (pix_fmt == AV_PIX_FMT_NONE && par->bits_per_coded_sample == 1)
226 pix_fmt = AV_PIX_FMT_MONOWHITE;
227
4/4
✓ Branch 0 taken 307 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 302 times.
✓ Branch 3 taken 5 times.
611 pal_avi = !for_asf &&
228
2/2
✓ Branch 0 taken 298 times.
✓ Branch 1 taken 4 times.
302 (pix_fmt == AV_PIX_FMT_PAL8 ||
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 298 times.
298 pix_fmt == AV_PIX_FMT_MONOWHITE ||
230 pix_fmt == AV_PIX_FMT_MONOBLACK);
231
232 /* Size (not including the size of the color table or color masks) */
233
4/4
✓ Branch 0 taken 307 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 298 times.
✓ Branch 3 taken 9 times.
309 avio_wl32(pb, 40 + (ignore_extradata || pal_avi ? 0 : extradata_size));
234 309 avio_wl32(pb, par->width);
235 //We always store RGB TopDown
236
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 295 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
309 avio_wl32(pb, par->codec_tag || keep_height ? par->height : -par->height);
237 /* planes */
238 309 avio_wl16(pb, 1);
239 /* depth */
240
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 232 times.
309 avio_wl16(pb, par->bits_per_coded_sample ? par->bits_per_coded_sample : 24);
241 /* compression type */
242 // MSRLE compatibility with Media Player 3.1 and Windows 95
243
2/2
✓ Branch 0 taken 305 times.
✓ Branch 1 taken 4 times.
309 avio_wl32(pb, par->codec_id == AV_CODEC_ID_MSRLE ? 1 : par->codec_tag);
244
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 232 times.
309 avio_wl32(pb, (par->width * par->height * (par->bits_per_coded_sample ? par->bits_per_coded_sample : 24)+7) / 8);
245 309 avio_wl32(pb, 0);
246 309 avio_wl32(pb, 0);
247 /* Number of color indices in the color table that are used.
248 * A value of 0 means 2^biBitCount indices, but this doesn't work
249 * with Windows Media Player and files containing xxpc chunks. */
250 // MSRLE on Windows 95 requires a zero here
251
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 300 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 4 times.
309 avio_wl32(pb, pal_avi && par->codec_id != AV_CODEC_ID_MSRLE ? 1 << par->bits_per_coded_sample : 0);
252 309 avio_wl32(pb, 0);
253
254
2/2
✓ Branch 0 taken 307 times.
✓ Branch 1 taken 2 times.
309 if (!ignore_extradata) {
255
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 209 times.
307 if (par->extradata_size) {
256 98 avio_write(pb, par->extradata, extradata_size);
257
3/4
✓ Branch 0 taken 98 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 80 times.
98 if (!for_asf && extradata_size & 1)
258 18 avio_w8(pb, 0);
259
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 201 times.
209 } else if (pal_avi) {
260 int i;
261
2/2
✓ Branch 0 taken 1032 times.
✓ Branch 1 taken 8 times.
1040 for (i = 0; i < 1 << par->bits_per_coded_sample; i++) {
262 /* Initialize 1 bpp palette to black & white */
263
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)
264 4 avio_wl32(pb, 0xffffff);
265
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)
266 avio_wl32(pb, 0xffffff);
267 else
268 1028 avio_wl32(pb, 0);
269 }
270 }
271 }
272 309 }
273
274 3276 void ff_parse_specific_params(AVStream *st, int *au_rate,
275 int *au_ssize, int *au_scale)
276 {
277 3276 AVCodecParameters *par = st->codecpar;
278 int gcd;
279 int audio_frame_size;
280
281 3276 audio_frame_size = av_get_audio_frame_duration2(par, 0);
282
2/2
✓ Branch 0 taken 3271 times.
✓ Branch 1 taken 5 times.
3276 if (!audio_frame_size)
283 3271 audio_frame_size = par->frame_size;
284
285 3276 *au_ssize = par->block_align;
286
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3271 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
3276 if (audio_frame_size && par->sample_rate) {
287 5 *au_scale = audio_frame_size;
288 5 *au_rate = par->sample_rate;
289
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 3256 times.
3271 } else if (par->codec_type == AVMEDIA_TYPE_VIDEO ||
290
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 par->codec_type == AVMEDIA_TYPE_DATA ||
291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
292 3256 *au_scale = st->time_base.num;
293 3256 *au_rate = st->time_base.den;
294 } else {
295
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 *au_scale = par->block_align ? par->block_align * 8 : 8;
296
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 *au_rate = par->bit_rate ? par->bit_rate :
297 8 * par->sample_rate;
298 }
299 3276 gcd = av_gcd(*au_scale, *au_rate);
300 3276 *au_scale /= gcd;
301 3276 *au_rate /= gcd;
302 3276 }
303
304 329 void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
305 {
306 329 size_t len = strlen(str);
307
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) {
308 329 len++;
309 329 ffio_wfourcc(pb, tag);
310 329 avio_wl32(pb, len);
311 329 avio_put_str(pb, str);
312
2/2
✓ Branch 0 taken 328 times.
✓ Branch 1 taken 1 times.
329 if (len & 1)
313 328 avio_w8(pb, 0);
314 }
315 329 }
316
317 static const char riff_tags[][5] = {
318 "IARL", "IART", "IAS1", "IAS2", "IAS3", "IAS4", "IAS5", "IAS6", "IAS7",
319 "IAS8", "IAS9", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
320 "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
321 "IPRT", "ITRK", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
322 { 0 }
323 };
324
325 777 static int riff_has_valid_tags(AVFormatContext *s)
326 {
327 int i;
328
329
2/2
✓ Branch 0 taken 26279 times.
✓ Branch 1 taken 448 times.
26727 for (i = 0; *riff_tags[i]; i++)
330
2/2
✓ Branch 1 taken 329 times.
✓ Branch 2 taken 25950 times.
26279 if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
331 329 return 1;
332
333 448 return 0;
334 }
335
336 777 void ff_riff_write_info(AVFormatContext *s)
337 {
338 777 AVIOContext *pb = s->pb;
339 int i;
340 int64_t list_pos;
341 777 AVDictionaryEntry *t = NULL;
342
343 777 ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
344
345 /* writing empty LIST is not nice and may cause problems */
346
2/2
✓ Branch 1 taken 448 times.
✓ Branch 2 taken 329 times.
777 if (!riff_has_valid_tags(s))
347 448 return;
348
349 329 list_pos = ff_start_tag(pb, "LIST");
350 329 ffio_wfourcc(pb, "INFO");
351
2/2
✓ Branch 0 taken 11844 times.
✓ Branch 1 taken 329 times.
12173 for (i = 0; *riff_tags[i]; i++)
352
2/2
✓ Branch 1 taken 329 times.
✓ Branch 2 taken 11515 times.
11844 if ((t = av_dict_get(s->metadata, riff_tags[i],
353 NULL, AV_DICT_MATCH_CASE)))
354 329 ff_riff_write_info_tag(s->pb, t->key, t->value);
355 329 ff_end_tag(pb, list_pos);
356 }
357
358 258 void ff_put_guid(AVIOContext *s, const ff_asf_guid *g)
359 {
360 av_assert0(sizeof(*g) == 16);
361 258 avio_write(s, *g, sizeof(*g));
362 258 }
363
364 4 const ff_asf_guid *ff_get_codec_guid(enum AVCodecID id, const AVCodecGuid *av_guid)
365 {
366 int i;
367
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 for (i = 0; av_guid[i].id != AV_CODEC_ID_NONE; i++) {
368
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
12 if (id == av_guid[i].id)
369 4 return &(av_guid[i].guid);
370 }
371 return NULL;
372 }
373