FFmpeg
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 &&
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) {
171  av_log(s, AV_LOG_ERROR,
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) {
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 {
433  av_log(s, AV_LOG_ERROR,
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) {
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 */
Definition: wavenc.c:57
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
Definition: ffmpeg.c:702
void avio_wb64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:453
#define NULL
Definition: coverity.c:32
void avio_wl16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:459
Bytestream IO Context.
Definition: avio.h:161
const uint8_t ff_w64_guid_wave[16]
Definition: w64.c:28
Buffered I/O operations.
int16_t * peak_maxpos
Definition: wavenc.c:73
void ff_end_tag(AVIOContext *pb, int64_t start)
Definition: riffenc.c:38
int64_t ff_start_tag(AVIOContext *pb, const char *tag)
Definition: riffenc.c:31
#define RF64_ALWAYS
Definition: wavenc.c:51
AVOption.
Definition: opt.h:248
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:134
int ff_put_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int flags)
Write WAVEFORMAT header structure.
Definition: riffenc.c:54
int64_t minpts
Definition: wavenc.c:71
const uint8_t ff_w64_guid_fact[16]
Definition: w64.c:38
const char * desc
Definition: libsvtav1.c:79
int peak_format
Definition: wavenc.c:83
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
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:4869
int write_peak
Definition: wavenc.c:80
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:60
int num
Numerator.
Definition: rational.h:59
int size
Definition: packet.h:364
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:253
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
const char * key
static AVPacket pkt
int64_t ds64
Definition: wavenc.c:70
AVCodec.
Definition: codec.h:190
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:87
#define AVFMT_TS_NONSTRICT
Format does not require strictly increasing timestamps, but they must still be monotonic.
Definition: avformat.h:472
This struct describes the properties of an encoded stream.
Definition: codec_par.h:52
int64_t fact_pos
Definition: wavenc.c:69
int peak_block_pos
Definition: wavenc.c:84
Format I/O context.
Definition: avformat.h:1351
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
Public dictionary API.
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:379
uint8_t
#define av_cold
Definition: attributes.h:88
#define av_malloc(s)
AVOptions.
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:92
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:381
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
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1419
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
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1482
uint8_t * data
Definition: packet.h:363
uint32_t tag
Definition: movenc.c:1532
PeakFormat
Definition: wavenc.c:61
int64_t data
Definition: wavenc.c:68
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:557
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:225
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:58
#define AVFMT_FLAG_BITEXACT
When muxing, try to avoid writing any random/volatile data to the output.
Definition: avformat.h:1499
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
void avio_wl64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:447
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
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:1566
AVDictionary * metadata
Metadata that applies to the whole file.
Definition: avformat.h:1591
PeakType
Definition: wavenc.c:55
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:153
unsigned int pos
Definition: spdifenc.c:410
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 local see the OFFSET() macro
const char * name
Name of the codec implementation.
Definition: codec.h:197
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:506
AVOutputFormat ff_wav_muxer
#define FFMAX(a, b)
Definition: common.h:94
int16_t * peak_maxneg
Definition: wavenc.c:73
AVOutputFormat ff_w64_muxer
int write_bext
Definition: wavenc.c:79
int peak_block_size
Definition: wavenc.c:82
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1407
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:260
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
void ffio_fill(AVIOContext *s, int b, int count)
Definition: aviobuf.c:211
#define FFMIN(a, b)
Definition: common.h:96
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:98
const uint8_t ff_w64_guid_data[16]
Definition: w64.c:42
const char * name
Definition: avformat.h:500
internal header for RIFF based (de)muxers do NOT include this in end user applications ...
const uint8_t ff_w64_guid_riff[16]
Definition: w64.c:23
#define s(width, name)
Definition: cbs_vp9.c:257
int avio_put_str(AVIOContext *s, const char *str)
Write a NULL-terminated string.
Definition: aviobuf.c:395
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:39
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:40
#define AV_LOG_INFO
Standard information.
Definition: log.h:205
#define RF64_AUTO
Definition: wavenc.c:49
AVIOContext * pb
I/O context.
Definition: avformat.h:1393
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
int64_t maxpts
Definition: wavenc.c:72
#define ENC
Definition: caca.c:203
uint32_t peak_num_frames
Definition: wavenc.c:74
void ff_riff_write_info(AVFormatContext *s)
Write all recognized RIFF tags from s->metadata.
Definition: riffenc.c:328
Describe the class of an AVClass context structure.
Definition: log.h:67
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:101
#define RF64_NEVER
Definition: wavenc.c:50
const char * name
Name of the codec described by this descriptor.
Definition: codec_desc.h:46
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:931
This struct describes the properties of a single codec described by an AVCodecID. ...
Definition: codec_desc.h:38
int rf64
Definition: wavenc.c:81
#define flags(name, subs,...)
Definition: cbs_av1.c:560
const uint8_t ff_w64_guid_fmt[16]
Definition: w64.c:33
int sample_rate
Audio only.
Definition: codec_par.h:170
Main libavformat public API header.
const OptionDef options[]
Definition: ffmpeg_opt.c:3393
common internal and external API header
uint32_t peak_outbuf_size
Definition: wavenc.c:75
uint32_t peak_outbuf_bytes
Definition: wavenc.c:76
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
uint8_t * peak_output
Definition: wavenc.c:77
#define localtime_r
Definition: time_internal.h:46
int den
Denominator.
Definition: rational.h:60
char * value
Definition: dict.h:87
int len
int peak_bps
Definition: wavenc.c:86
void * priv_data
Format private data.
Definition: avformat.h:1379
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:346
#define PEAK_BUFFER_SIZE
Definition: wavenc.c:53
const AVCodecDescriptor * avcodec_descriptor_get(enum AVCodecID id)
Definition: codec_desc.c:3429
int channels
Audio only.
Definition: codec_par.h:166
#define av_freep(p)
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1023
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:64
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:905
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
This structure stores compressed data.
Definition: packet.h:340
int peak_ppv
Definition: wavenc.c:85
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:356
int i
Definition: input.c:407
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
int last_duration
Definition: wavenc.c:78
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:190