FFmpeg  4.3
wavenc.c
Go to the documentation of this file.
1 /*
2  * WAV muxer
3  * Copyright (c) 2001, 2002 Fabrice Bellard
4  *
5  * Sony Wave64 muxer
6  * Copyright (c) 2012 Paul B Mahol
7  *
8  * WAV muxer RF64 support
9  * Copyright (c) 2013 Daniel Verkamp <daniel@drv.nu>
10  *
11  * EBU Tech 3285 - Supplement 3 - Peak Envelope Chunk encoder
12  * Copyright (c) 2014 Georg Lippitsch <georg.lippitsch@gmx.at>
13  *
14  * This file is part of FFmpeg.
15  *
16  * FFmpeg is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  *
21  * FFmpeg is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24  * Lesser General Public License for more details.
25  *
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with FFmpeg; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30 
31 #include <stdint.h>
32 #include <string.h>
33 
34 #include "libavutil/avstring.h"
35 #include "libavutil/dict.h"
36 #include "libavutil/common.h"
37 #include "libavutil/intreadwrite.h"
38 #include "libavutil/mathematics.h"
39 #include "libavutil/opt.h"
40 #include "libavutil/time.h"
42 
43 #include "avformat.h"
44 #include "avio.h"
45 #include "avio_internal.h"
46 #include "internal.h"
47 #include "riff.h"
48 
49 #define RF64_AUTO (-1)
50 #define RF64_NEVER 0
51 #define RF64_ALWAYS 1
52 
53 #define PEAK_BUFFER_SIZE 1024
54 
55 typedef enum {
56  PEAK_OFF = 0,
59 } PeakType;
60 
61 typedef enum {
64 } PeakFormat;
65 
66 typedef struct WAVMuxContext {
67  const AVClass *class;
68  int64_t data;
69  int64_t fact_pos;
70  int64_t ds64;
71  int64_t minpts;
72  int64_t maxpts;
74  uint32_t peak_num_frames;
75  uint32_t peak_outbuf_size;
81  int rf64;
85  int peak_ppv;
86  int peak_bps;
88 
89 #if CONFIG_WAV_MUXER
90 static inline void bwf_write_bext_string(AVFormatContext *s, const char *key, int maxlen)
91 {
93  size_t len = 0;
94 
95  if (tag = av_dict_get(s->metadata, key, NULL, 0)) {
96  len = strlen(tag->value);
97  len = FFMIN(len, maxlen);
98  avio_write(s->pb, tag->value, len);
99  }
100 
101  ffio_fill(s->pb, 0, maxlen - len);
102 }
103 
104 static void bwf_write_bext_chunk(AVFormatContext *s)
105 {
106  AVDictionaryEntry *tmp_tag;
107  uint64_t time_reference = 0;
108  int64_t bext = ff_start_tag(s->pb, "bext");
109 
110  bwf_write_bext_string(s, "description", 256);
111  bwf_write_bext_string(s, "originator", 32);
112  bwf_write_bext_string(s, "originator_reference", 32);
113  bwf_write_bext_string(s, "origination_date", 10);
114  bwf_write_bext_string(s, "origination_time", 8);
115 
116  if (tmp_tag = av_dict_get(s->metadata, "time_reference", NULL, 0))
117  time_reference = strtoll(tmp_tag->value, NULL, 10);
118  avio_wl64(s->pb, time_reference);
119  avio_wl16(s->pb, 1); // set version to 1
120 
121  if ((tmp_tag = av_dict_get(s->metadata, "umid", NULL, 0)) && strlen(tmp_tag->value) > 2) {
122  unsigned char umidpart_str[17] = {0};
123  int64_t i;
124  uint64_t umidpart;
125  size_t len = strlen(tmp_tag->value+2);
126 
127  for (i = 0; i < len/16; i++) {
128  memcpy(umidpart_str, tmp_tag->value + 2 + (i*16), 16);
129  umidpart = strtoll(umidpart_str, NULL, 16);
130  avio_wb64(s->pb, umidpart);
131  }
132  ffio_fill(s->pb, 0, 64 - i*8);
133  } else
134  ffio_fill(s->pb, 0, 64); // zero UMID
135 
136  ffio_fill(s->pb, 0, 190); // Reserved
137 
138  if (tmp_tag = av_dict_get(s->metadata, "coding_history", NULL, 0))
139  avio_put_str(s->pb, tmp_tag->value);
140 
141  ff_end_tag(s->pb, bext);
142 }
143 
144 static av_cold void wav_deinit(AVFormatContext *s)
145 {
146  WAVMuxContext *wav = s->priv_data;
147 
148  av_freep(&wav->peak_maxpos);
149  av_freep(&wav->peak_maxneg);
150  av_freep(&wav->peak_output);
151 }
152 
153 static av_cold int peak_init_writer(AVFormatContext *s)
154 {
155  WAVMuxContext *wav = s->priv_data;
156  AVCodecParameters *par = s->streams[0]->codecpar;
157 
158  if (par->codec_id != AV_CODEC_ID_PCM_S8 &&
160  par->codec_id != AV_CODEC_ID_PCM_U8 &&
162  AVCodec *codec = avcodec_find_decoder(s->streams[0]->codecpar->codec_id);
163  av_log(s, AV_LOG_ERROR, "%s codec not supported for Peak Chunk\n",
164  codec ? codec->name : "NONE");
165  return -1;
166  }
167 
168  wav->peak_bps = av_get_bits_per_sample(par->codec_id) / 8;
169 
170  if (wav->peak_bps == 1 && wav->peak_format == PEAK_FORMAT_UINT16) {
172  "Writing 16 bit peak for 8 bit audio does not make sense\n");
173  return AVERROR(EINVAL);
174  }
175 
176  wav->peak_maxpos = av_mallocz_array(par->channels, sizeof(*wav->peak_maxpos));
177  wav->peak_maxneg = av_mallocz_array(par->channels, sizeof(*wav->peak_maxneg));
179  if (!wav->peak_maxpos || !wav->peak_maxneg || !wav->peak_output)
180  goto nomem;
181 
183 
184  return 0;
185 
186 nomem:
187  av_log(s, AV_LOG_ERROR, "Out of memory\n");
188  return AVERROR(ENOMEM);
189 }
190 
191 static void peak_write_frame(AVFormatContext *s)
192 {
193  WAVMuxContext *wav = s->priv_data;
194  AVCodecParameters *par = s->streams[0]->codecpar;
195  int c;
196 
197  if (!wav->peak_output)
198  return;
199 
200  for (c = 0; c < par->channels; c++) {
201  wav->peak_maxneg[c] = -wav->peak_maxneg[c];
202 
203  if (wav->peak_bps == 2 && wav->peak_format == PEAK_FORMAT_UINT8) {
204  wav->peak_maxpos[c] = wav->peak_maxpos[c] / 256;
205  wav->peak_maxneg[c] = wav->peak_maxneg[c] / 256;
206  }
207 
208  if (wav->peak_ppv == 1)
209  wav->peak_maxpos[c] =
210  FFMAX(wav->peak_maxpos[c], wav->peak_maxneg[c]);
211 
212  if (wav->peak_outbuf_size - wav->peak_outbuf_bytes <
213  wav->peak_format * wav->peak_ppv) {
215  wav->peak_output = av_realloc(wav->peak_output,
216  wav->peak_outbuf_size);
217  if (!wav->peak_output) {
218  av_log(s, AV_LOG_ERROR, "No memory for peak data\n");
219  return;
220  }
221  }
222 
223  if (wav->peak_format == PEAK_FORMAT_UINT8) {
224  wav->peak_output[wav->peak_outbuf_bytes++] =
225  wav->peak_maxpos[c];
226  if (wav->peak_ppv == 2) {
227  wav->peak_output[wav->peak_outbuf_bytes++] =
228  wav->peak_maxneg[c];
229  }
230  } else {
232  wav->peak_maxpos[c]);
233  wav->peak_outbuf_bytes += 2;
234  if (wav->peak_ppv == 2) {
236  wav->peak_maxneg[c]);
237  wav->peak_outbuf_bytes += 2;
238  }
239  }
240  wav->peak_maxpos[c] = 0;
241  wav->peak_maxneg[c] = 0;
242  }
243  wav->peak_num_frames++;
244 }
245 
246 static int peak_write_chunk(AVFormatContext *s)
247 {
248  WAVMuxContext *wav = s->priv_data;
249  AVIOContext *pb = s->pb;
250  AVCodecParameters *par = s->streams[0]->codecpar;
251  int64_t peak = ff_start_tag(s->pb, "levl");
252  int64_t now0;
253  time_t now_secs;
254  char timestamp[28];
255 
256  /* Peak frame of incomplete block at end */
257  if (wav->peak_block_pos)
258  peak_write_frame(s);
259 
260  memset(timestamp, 0, sizeof(timestamp));
261  if (!(s->flags & AVFMT_FLAG_BITEXACT)) {
262  struct tm tmpbuf;
263  av_log(s, AV_LOG_INFO, "Writing local time and date to Peak Envelope Chunk\n");
264  now0 = av_gettime();
265  now_secs = now0 / 1000000;
266  if (strftime(timestamp, sizeof(timestamp), "%Y:%m:%d:%H:%M:%S:", localtime_r(&now_secs, &tmpbuf))) {
267  av_strlcatf(timestamp, sizeof(timestamp), "%03d", (int)((now0 / 1000) % 1000));
268  } else {
269  av_log(s, AV_LOG_ERROR, "Failed to write timestamp\n");
270  return -1;
271  }
272  }
273 
274  avio_wl32(pb, 1); /* version */
275  avio_wl32(pb, wav->peak_format); /* 8 or 16 bit */
276  avio_wl32(pb, wav->peak_ppv); /* positive and negative */
277  avio_wl32(pb, wav->peak_block_size); /* frames per value */
278  avio_wl32(pb, par->channels); /* number of channels */
279  avio_wl32(pb, wav->peak_num_frames); /* number of peak frames */
280  avio_wl32(pb, -1); /* audio sample frame position (not implemented) */
281  avio_wl32(pb, 128); /* equal to size of header */
282  avio_write(pb, timestamp, 28); /* ASCII time stamp */
283  ffio_fill(pb, 0, 60);
284 
285  avio_write(pb, wav->peak_output, wav->peak_outbuf_bytes);
286 
287  ff_end_tag(pb, peak);
288 
289  if (!wav->data)
290  wav->data = peak;
291 
292  return 0;
293 }
294 
295 static int wav_write_header(AVFormatContext *s)
296 {
297  WAVMuxContext *wav = s->priv_data;
298  AVIOContext *pb = s->pb;
299  int64_t fmt;
300 
301  if (s->nb_streams != 1) {
302  av_log(s, AV_LOG_ERROR, "WAVE files have exactly one stream\n");
303  return AVERROR(EINVAL);
304  }
305 
306  if (wav->rf64 == RF64_ALWAYS) {
307  ffio_wfourcc(pb, "RF64");
308  avio_wl32(pb, -1); /* RF64 chunk size: use size in ds64 */
309  } else {
310  ffio_wfourcc(pb, "RIFF");
311  avio_wl32(pb, -1); /* file length */
312  }
313 
314  ffio_wfourcc(pb, "WAVE");
315 
316  if (wav->rf64 != RF64_NEVER) {
317  /* write empty ds64 chunk or JUNK chunk to reserve space for ds64 */
318  ffio_wfourcc(pb, wav->rf64 == RF64_ALWAYS ? "ds64" : "JUNK");
319  avio_wl32(pb, 28); /* chunk size */
320  wav->ds64 = avio_tell(pb);
321  ffio_fill(pb, 0, 28);
322  }
323 
324  if (wav->write_peak != PEAK_ONLY) {
325  /* format header */
326  fmt = ff_start_tag(pb, "fmt ");
327  if (ff_put_wav_header(s, pb, s->streams[0]->codecpar, 0) < 0) {
328  const AVCodecDescriptor *desc = avcodec_descriptor_get(s->streams[0]->codecpar->codec_id);
329  av_log(s, AV_LOG_ERROR, "%s codec not supported in WAVE format\n",
330  desc ? desc->name : "unknown");
331  return AVERROR(ENOSYS);
332  }
333  ff_end_tag(pb, fmt);
334  }
335 
336  if (s->streams[0]->codecpar->codec_tag != 0x01 /* hence for all other than PCM */
337  && (s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
338  wav->fact_pos = ff_start_tag(pb, "fact");
339  avio_wl32(pb, 0);
340  ff_end_tag(pb, wav->fact_pos);
341  }
342 
343  if (wav->write_bext)
344  bwf_write_bext_chunk(s);
345 
346  if (wav->write_peak) {
347  int ret;
348  if ((ret = peak_init_writer(s)) < 0)
349  return ret;
350  }
351 
352  avpriv_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codecpar->sample_rate);
353  wav->maxpts = wav->last_duration = 0;
354  wav->minpts = INT64_MAX;
355 
356  if (wav->write_peak != PEAK_ONLY) {
357  /* info header */
359 
360  /* data header */
361  wav->data = ff_start_tag(pb, "data");
362  }
363 
364  return 0;
365 }
366 
367 static int wav_write_packet(AVFormatContext *s, AVPacket *pkt)
368 {
369  AVIOContext *pb = s->pb;
370  WAVMuxContext *wav = s->priv_data;
371 
372  if (wav->write_peak != PEAK_ONLY)
373  avio_write(pb, pkt->data, pkt->size);
374 
375  if (wav->write_peak) {
376  int c = 0;
377  int i;
378  for (i = 0; i < pkt->size; i += wav->peak_bps) {
379  if (wav->peak_bps == 1) {
380  wav->peak_maxpos[c] = FFMAX(wav->peak_maxpos[c], *(int8_t*)(pkt->data + i));
381  wav->peak_maxneg[c] = FFMIN(wav->peak_maxneg[c], *(int8_t*)(pkt->data + i));
382  } else {
383  wav->peak_maxpos[c] = FFMAX(wav->peak_maxpos[c], (int16_t)AV_RL16(pkt->data + i));
384  wav->peak_maxneg[c] = FFMIN(wav->peak_maxneg[c], (int16_t)AV_RL16(pkt->data + i));
385  }
386  if (++c == s->streams[0]->codecpar->channels) {
387  c = 0;
388  if (++wav->peak_block_pos == wav->peak_block_size) {
389  peak_write_frame(s);
390  wav->peak_block_pos = 0;
391  }
392  }
393  }
394  }
395 
396  if(pkt->pts != AV_NOPTS_VALUE) {
397  wav->minpts = FFMIN(wav->minpts, pkt->pts);
398  wav->maxpts = FFMAX(wav->maxpts, pkt->pts);
399  wav->last_duration = pkt->duration;
400  } else
401  av_log(s, AV_LOG_ERROR, "wav_write_packet: NOPTS\n");
402  return 0;
403 }
404 
405 static int wav_write_trailer(AVFormatContext *s)
406 {
407  AVIOContext *pb = s->pb;
408  WAVMuxContext *wav = s->priv_data;
409  int64_t file_size, data_size;
410  int64_t number_of_samples = 0;
411  int rf64 = 0;
412  int ret = 0;
413 
414  if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) {
415  if (wav->write_peak != PEAK_ONLY && avio_tell(pb) - wav->data < UINT32_MAX) {
416  ff_end_tag(pb, wav->data);
417  }
418 
419  if (wav->write_peak && wav->peak_output) {
420  ret = peak_write_chunk(s);
421  }
422 
423  /* update file size */
424  file_size = avio_tell(pb);
425  data_size = file_size - wav->data;
426  if (wav->rf64 == RF64_ALWAYS || (wav->rf64 == RF64_AUTO && file_size - 8 > UINT32_MAX)) {
427  rf64 = 1;
428  } else if (file_size - 8 <= UINT32_MAX) {
429  avio_seek(pb, 4, SEEK_SET);
430  avio_wl32(pb, (uint32_t)(file_size - 8));
431  avio_seek(pb, file_size, SEEK_SET);
432  } else {
434  "Filesize %"PRId64" invalid for wav, output file will be broken\n",
435  file_size);
436  }
437  number_of_samples = av_rescale_q(wav->maxpts - wav->minpts + wav->last_duration,
438  s->streams[0]->time_base,
439  av_make_q(1, s->streams[0]->codecpar->sample_rate));
440 
441  if(s->streams[0]->codecpar->codec_tag != 0x01) {
442  /* Update num_samps in fact chunk */
443  avio_seek(pb, wav->fact_pos, SEEK_SET);
444  if (rf64 || (wav->rf64 == RF64_AUTO && number_of_samples > UINT32_MAX)) {
445  rf64 = 1;
446  avio_wl32(pb, -1);
447  } else {
448  avio_wl32(pb, number_of_samples);
449  avio_seek(pb, file_size, SEEK_SET);
450  }
451  }
452 
453  if (rf64) {
454  /* overwrite RIFF with RF64 */
455  avio_seek(pb, 0, SEEK_SET);
456  ffio_wfourcc(pb, "RF64");
457  avio_wl32(pb, -1);
458 
459  /* write ds64 chunk (overwrite JUNK if rf64 == RF64_AUTO) */
460  avio_seek(pb, wav->ds64 - 8, SEEK_SET);
461  ffio_wfourcc(pb, "ds64");
462  avio_wl32(pb, 28); /* ds64 chunk size */
463  avio_wl64(pb, file_size - 8); /* RF64 chunk size */
464  avio_wl64(pb, data_size); /* data chunk size */
465  avio_wl64(pb, number_of_samples); /* fact chunk number of samples */
466  avio_wl32(pb, 0); /* number of table entries for non-'data' chunks */
467 
468  /* write -1 in data chunk size */
469  avio_seek(pb, wav->data - 4, SEEK_SET);
470  avio_wl32(pb, -1);
471 
472  avio_seek(pb, file_size, SEEK_SET);
473  }
474  }
475 
476  return ret;
477 }
478 
479 #define OFFSET(x) offsetof(WAVMuxContext, x)
480 #define ENC AV_OPT_FLAG_ENCODING_PARAM
481 static const AVOption options[] = {
482  { "write_bext", "Write BEXT chunk.", OFFSET(write_bext), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC },
483  { "write_peak", "Write Peak Envelope chunk.", OFFSET(write_peak), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, ENC, "peak" },
484  { "off", "Do not write peak chunk.", 0, AV_OPT_TYPE_CONST, { .i64 = PEAK_OFF }, 0, 0, ENC, "peak" },
485  { "on", "Append peak chunk after wav data.", 0, AV_OPT_TYPE_CONST, { .i64 = PEAK_ON }, 0, 0, ENC, "peak" },
486  { "only", "Write only peak chunk, omit wav data.", 0, AV_OPT_TYPE_CONST, { .i64 = PEAK_ONLY }, 0, 0, ENC, "peak" },
487  { "rf64", "Use RF64 header rather than RIFF for large files.", OFFSET(rf64), AV_OPT_TYPE_INT, { .i64 = RF64_NEVER },-1, 1, ENC, "rf64" },
488  { "auto", "Write RF64 header if file grows large enough.", 0, AV_OPT_TYPE_CONST, { .i64 = RF64_AUTO }, 0, 0, ENC, "rf64" },
489  { "always", "Always write RF64 header regardless of file size.", 0, AV_OPT_TYPE_CONST, { .i64 = RF64_ALWAYS }, 0, 0, ENC, "rf64" },
490  { "never", "Never write RF64 header regardless of file size.", 0, AV_OPT_TYPE_CONST, { .i64 = RF64_NEVER }, 0, 0, ENC, "rf64" },
491  { "peak_block_size", "Number of audio samples used to generate each peak frame.", OFFSET(peak_block_size), AV_OPT_TYPE_INT, { .i64 = 256 }, 0, 65536, ENC },
492  { "peak_format", "The format of the peak envelope data (1: uint8, 2: uint16).", OFFSET(peak_format), AV_OPT_TYPE_INT, { .i64 = PEAK_FORMAT_UINT16 }, PEAK_FORMAT_UINT8, PEAK_FORMAT_UINT16, ENC },
493  { "peak_ppv", "Number of peak points per peak value (1 or 2).", OFFSET(peak_ppv), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, 2, ENC },
494  { NULL },
495 };
496 
497 static const AVClass wav_muxer_class = {
498  .class_name = "WAV muxer",
499  .item_name = av_default_item_name,
500  .option = options,
501  .version = LIBAVUTIL_VERSION_INT,
502 };
503 
505  .name = "wav",
506  .long_name = NULL_IF_CONFIG_SMALL("WAV / WAVE (Waveform Audio)"),
507  .mime_type = "audio/x-wav",
508  .extensions = "wav",
509  .priv_data_size = sizeof(WAVMuxContext),
510  .audio_codec = AV_CODEC_ID_PCM_S16LE,
511  .video_codec = AV_CODEC_ID_NONE,
512  .write_header = wav_write_header,
513  .write_packet = wav_write_packet,
514  .write_trailer = wav_write_trailer,
515  .deinit = wav_deinit,
517  .codec_tag = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
518  .priv_class = &wav_muxer_class,
519 };
520 #endif /* CONFIG_WAV_MUXER */
521 
522 #if CONFIG_W64_MUXER
523 #include "w64.h"
524 
525 static void start_guid(AVIOContext *pb, const uint8_t *guid, int64_t *pos)
526 {
527  *pos = avio_tell(pb);
528 
529  avio_write(pb, guid, 16);
530  avio_wl64(pb, INT64_MAX);
531 }
532 
533 static void end_guid(AVIOContext *pb, int64_t start)
534 {
535  int64_t end, pos = avio_tell(pb);
536 
537  end = FFALIGN(pos, 8);
538  ffio_fill(pb, 0, end - pos);
539  avio_seek(pb, start + 16, SEEK_SET);
540  avio_wl64(pb, end - start);
541  avio_seek(pb, end, SEEK_SET);
542 }
543 
544 static int w64_write_header(AVFormatContext *s)
545 {
546  WAVMuxContext *wav = s->priv_data;
547  AVIOContext *pb = s->pb;
548  int64_t start;
549  int ret;
550 
552  avio_wl64(pb, -1);
554  start_guid(pb, ff_w64_guid_fmt, &start);
555  if ((ret = ff_put_wav_header(s, pb, s->streams[0]->codecpar, 0)) < 0) {
556  AVCodec *codec = avcodec_find_decoder(s->streams[0]->codecpar->codec_id);
557  av_log(s, AV_LOG_ERROR, "%s codec not supported\n",
558  codec ? codec->name : "NONE");
559  return ret;
560  }
561  end_guid(pb, start);
562 
563  if (s->streams[0]->codecpar->codec_tag != 0x01 /* hence for all other than PCM */
564  && (s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
565  start_guid(pb, ff_w64_guid_fact, &wav->fact_pos);
566  avio_wl64(pb, 0);
567  end_guid(pb, wav->fact_pos);
568  }
569 
570  start_guid(pb, ff_w64_guid_data, &wav->data);
571 
572  return 0;
573 }
574 
575 static int w64_write_trailer(AVFormatContext *s)
576 {
577  AVIOContext *pb = s->pb;
578  WAVMuxContext *wav = s->priv_data;
579  int64_t file_size;
580 
581  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
582  end_guid(pb, wav->data);
583 
584  file_size = avio_tell(pb);
585  avio_seek(pb, 16, SEEK_SET);
586  avio_wl64(pb, file_size);
587 
588  if (s->streams[0]->codecpar->codec_tag != 0x01) {
589  int64_t number_of_samples;
590 
591  number_of_samples = av_rescale(wav->maxpts - wav->minpts + wav->last_duration,
592  s->streams[0]->codecpar->sample_rate * (int64_t)s->streams[0]->time_base.num,
593  s->streams[0]->time_base.den);
594  avio_seek(pb, wav->fact_pos + 24, SEEK_SET);
595  avio_wl64(pb, number_of_samples);
596  }
597 
598  avio_seek(pb, file_size, SEEK_SET);
599  }
600 
601  return 0;
602 }
603 
605  .name = "w64",
606  .long_name = NULL_IF_CONFIG_SMALL("Sony Wave64"),
607  .extensions = "w64",
608  .priv_data_size = sizeof(WAVMuxContext),
609  .audio_codec = AV_CODEC_ID_PCM_S16LE,
610  .video_codec = AV_CODEC_ID_NONE,
611  .write_header = w64_write_header,
612  .write_packet = wav_write_packet,
613  .write_trailer = w64_write_trailer,
615  .codec_tag = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
616 };
617 #endif /* CONFIG_W64_MUXER */
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:301
AVCodec
AVCodec.
Definition: codec.h:190
WAVMuxContext::peak_output
uint8_t * peak_output
Definition: wavenc.c:77
AVOutputFormat::name
const char * name
Definition: avformat.h:491
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
WAVMuxContext::peak_maxneg
int16_t * peak_maxneg
Definition: wavenc.c:73
ffio_wfourcc
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:58
PEAK_BUFFER_SIZE
#define PEAK_BUFFER_SIZE
Definition: wavenc.c:53
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:52
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:135
WAVMuxContext::maxpts
int64_t maxpts
Definition: wavenc.c:72
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
AVPacket::data
uint8_t * data
Definition: packet.h:355
AVOption
AVOption.
Definition: opt.h:246
PeakFormat
PeakFormat
Definition: wavenc.c:61
av_mallocz_array
void * av_mallocz_array(size_t nmemb, size_t size)
Allocate a memory block for an array with av_mallocz().
Definition: mem.c:192
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:506
avio_wl64
void avio_wl64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:435
ff_wav_muxer
AVOutputFormat ff_wav_muxer
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:373
mathematics.h
WAVMuxContext::peak_outbuf_bytes
uint32_t peak_outbuf_bytes
Definition: wavenc.c:76
WAVMuxContext::fact_pos
int64_t fact_pos
Definition: wavenc.c:69
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:101
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
PEAK_ONLY
@ PEAK_ONLY
Definition: wavenc.c:58
avio_wl16
void avio_wl16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:447
AVCodecParameters::channels
int channels
Audio only.
Definition: codec_par.h:166
WAVMuxContext::peak_bps
int peak_bps
Definition: wavenc.c:86
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:557
RF64_AUTO
#define RF64_AUTO
Definition: wavenc.c:49
ENC
#define ENC
Definition: caca.c:203
PEAK_FORMAT_UINT16
@ PEAK_FORMAT_UINT16
Definition: wavenc.c:63
ff_start_tag
int64_t ff_start_tag(AVIOContext *pb, const char *tag)
Definition: riffenc.c:31
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:305
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
av_cold
#define av_cold
Definition: attributes.h:90
AVCodecTag
Definition: internal.h:42
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:40
AVCodecDescriptor
This struct describes the properties of a single codec described by an AVCodecID.
Definition: codec_desc.h:38
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
RF64_NEVER
#define RF64_NEVER
Definition: wavenc.c:50
WAVMuxContext::peak_outbuf_size
uint32_t peak_outbuf_size
Definition: wavenc.c:75
PEAK_FORMAT_UINT8
@ PEAK_FORMAT_UINT8
Definition: wavenc.c:62
PEAK_ON
@ PEAK_ON
Definition: wavenc.c:57
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
AV_RL16
#define AV_RL16
Definition: intreadwrite.h:42
RF64_ALWAYS
#define RF64_ALWAYS
Definition: wavenc.c:51
key
const char * key
Definition: hwcontext_opencl.c:168
WAVMuxContext::data
int64_t data
Definition: wavenc.c:68
time_internal.h
WAVMuxContext::rf64
int rf64
Definition: wavenc.c:81
AVFormatContext
Format I/O context.
Definition: avformat.h:1335
internal.h
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
PEAK_OFF
@ PEAK_OFF
Definition: wavenc.c:56
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
WAVMuxContext::last_duration
int last_duration
Definition: wavenc.c:78
NULL
#define NULL
Definition: coverity.c:32
ff_put_wav_header
int ff_put_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int flags)
Write WAVEFORMAT header structure.
Definition: riffenc.c:54
write_trailer
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:98
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
time.h
WAVMuxContext::peak_block_pos
int peak_block_pos
Definition: wavenc.c:84
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
ff_w64_guid_fmt
const uint8_t ff_w64_guid_fmt[16]
Definition: w64.c:33
options
const OptionDef options[]
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:1552
desc
const char * desc
Definition: nvenc.c:79
AVIOContext
Bytestream IO Context.
Definition: avio.h:161
AVPacket::size
int size
Definition: packet.h:356
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:186
WAVMuxContext::write_bext
int write_bext
Definition: wavenc.c:79
PeakType
PeakType
Definition: wavenc.c:55
AVIOContext::seekable
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:260
localtime_r
#define localtime_r
Definition: time_internal.h:46
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:4938
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
avio.h
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
WAVMuxContext::minpts
int64_t minpts
Definition: wavenc.c:71
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:213
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
avio_wl32
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:367
WAVMuxContext
Definition: wavenc.c:66
ff_end_tag
void ff_end_tag(AVIOContext *pb, int64_t start)
Definition: riffenc.c:38
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
WAVMuxContext::write_peak
int write_peak
Definition: wavenc.c:80
write_packet
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
Definition: ffmpeg.c:701
WAVMuxContext::peak_block_size
int peak_block_size
Definition: wavenc.c:82
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:47
AVOutputFormat
Definition: avformat.h:490
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:348
avio_internal.h
ff_w64_guid_wave
const uint8_t ff_w64_guid_wave[16]
Definition: w64.c:28
common.h
ff_w64_muxer
AVOutputFormat ff_w64_muxer
uint8_t
uint8_t
Definition: audio_convert.c:194
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:197
WAVMuxContext::peak_maxpos
int16_t * peak_maxpos
Definition: wavenc.c:73
ff_w64_guid_fact
const uint8_t ff_w64_guid_fact[16]
Definition: w64.c:38
len
int len
Definition: vorbis_enc_data.h:452
av_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
AVFMT_TS_NONSTRICT
#define AVFMT_TS_NONSTRICT
Format does not require strictly increasing timestamps, but they must still be monotonic.
Definition: avformat.h:472
WAVMuxContext::peak_ppv
int peak_ppv
Definition: wavenc.c:85
tag
uint32_t tag
Definition: movenc.c:1532
ret
ret
Definition: filter_design.txt:187
AVFMT_FLAG_BITEXACT
#define AVFMT_FLAG_BITEXACT
When muxing, try to avoid writing any random/volatile data to the output.
Definition: avformat.h:1483
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:241
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
avcodec_find_decoder
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:919
pos
unsigned int pos
Definition: spdifenc.c:410
avformat.h
dict.h
OFFSET
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option keep it simple and lowercase description are in without and describe what they for example set the foo of the bar offset is the offset of the field in your see the OFFSET() macro
w64.h
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:40
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
ff_riff_write_info
void ff_riff_write_info(AVFormatContext *s)
Write all recognized RIFF tags from s->metadata.
Definition: riffenc.c:327
WAVMuxContext::peak_format
int peak_format
Definition: wavenc.c:83
WAVMuxContext::ds64
int64_t ds64
Definition: wavenc.c:70
avio_wb64
void avio_wb64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:441
av_gettime
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:39
ff_w64_guid_data
const uint8_t ff_w64_guid_data[16]
Definition: w64.c:42
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:306
ff_w64_guid_riff
const uint8_t ff_w64_guid_riff[16]
Definition: w64.c:23
AVDictionaryEntry
Definition: dict.h:81
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:48
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:60
AVPacket
This structure stores compressed data.
Definition: packet.h:332
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:240
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
riff.h
AV_CODEC_ID_PCM_U16LE
@ AV_CODEC_ID_PCM_U16LE
Definition: codec_id.h:303
ffio_fill
void ffio_fill(AVIOContext *s, int b, int count)
Definition: aviobuf.c:199
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:564
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
avcodec_descriptor_get
const AVCodecDescriptor * avcodec_descriptor_get(enum AVCodecID id)
Definition: codec_desc.c:3394
AVDictionaryEntry::value
char * value
Definition: dict.h:83
avstring.h
write_header
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:346
avio_put_str
int avio_put_str(AVIOContext *s, const char *str)
Write a NULL-terminated string.
Definition: aviobuf.c:383
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:232
WAVMuxContext::peak_num_frames
uint32_t peak_num_frames
Definition: wavenc.c:74