avienc.c
Go to the documentation of this file.
1 /*
2  * AVI muxer
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 //#define DEBUG
23 
24 #include "avformat.h"
25 #include "internal.h"
26 #include "avi.h"
27 #include "avio_internal.h"
28 #include "riff.h"
29 #include "libavutil/intreadwrite.h"
30 #include "libavutil/dict.h"
31 #include "libavutil/avassert.h"
32 #include "libavutil/timestamp.h"
33 
34 /*
35  * TODO:
36  * - fill all fields if non streamed (nb_frames for example)
37  */
38 
39 typedef struct AVIIentry {
40  unsigned int flags, pos, len;
41 } AVIIentry;
42 
43 #define AVI_INDEX_CLUSTER_SIZE 16384
44 
45 typedef struct AVIIndex {
46  int64_t indx_start;
47  int entry;
50 } AVIIndex;
51 
52 typedef struct {
53  int64_t riff_start, movi_list, odml_list;
54  int64_t frames_hdr_all;
55  int riff_id;
56 } AVIContext;
57 
58 typedef struct {
59  int64_t frames_hdr_strm;
62  int entry;
63 
65 } AVIStream ;
66 
67 static inline AVIIentry* avi_get_ientry(AVIIndex* idx, int ent_id)
68 {
69  int cl = ent_id / AVI_INDEX_CLUSTER_SIZE;
70  int id = ent_id % AVI_INDEX_CLUSTER_SIZE;
71  return &idx->cluster[cl][id];
72 }
73 
75  const char* riff_tag, const char* list_tag)
76 {
77  AVIContext *avi= s->priv_data;
78  int64_t loff;
79  int i;
80 
81  avi->riff_id++;
82  for (i=0; i<s->nb_streams; i++){
83  AVIStream *avist= s->streams[i]->priv_data;
84  avist->indexes.entry = 0;
85  }
86 
87  avi->riff_start = ff_start_tag(pb, "RIFF");
88  ffio_wfourcc(pb, riff_tag);
89  loff = ff_start_tag(pb, "LIST");
90  ffio_wfourcc(pb, list_tag);
91  return loff;
92 }
93 
94 static char* avi_stream2fourcc(char* tag, int index, enum AVMediaType type)
95 {
96  tag[0] = '0' + index/10;
97  tag[1] = '0' + index%10;
98  if (type == AVMEDIA_TYPE_VIDEO) {
99  tag[2] = 'd';
100  tag[3] = 'c';
101  } else if (type == AVMEDIA_TYPE_SUBTITLE) {
102  // note: this is not an official code
103  tag[2] = 's';
104  tag[3] = 'b';
105  } else {
106  tag[2] = 'w';
107  tag[3] = 'b';
108  }
109  tag[4] = '\0';
110  return tag;
111 }
112 
113 static int avi_write_counters(AVFormatContext* s, int riff_id)
114 {
115  AVIOContext *pb = s->pb;
116  AVIContext *avi = s->priv_data;
117  int n, au_byterate, au_ssize, au_scale, nb_frames = 0;
118  int64_t file_size;
119  AVCodecContext* stream;
120 
121  file_size = avio_tell(pb);
122  for(n = 0; n < s->nb_streams; n++) {
123  AVIStream *avist= s->streams[n]->priv_data;
124 
125  av_assert0(avist->frames_hdr_strm);
126  stream = s->streams[n]->codec;
127  avio_seek(pb, avist->frames_hdr_strm, SEEK_SET);
128  ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale);
129  if(au_ssize == 0) {
130  avio_wl32(pb, avist->packet_count);
131  } else {
132  avio_wl32(pb, avist->audio_strm_length / au_ssize);
133  }
134  if(stream->codec_type == AVMEDIA_TYPE_VIDEO)
135  nb_frames = FFMAX(nb_frames, avist->packet_count);
136  }
137  if(riff_id == 1) {
139  avio_seek(pb, avi->frames_hdr_all, SEEK_SET);
140  avio_wl32(pb, nb_frames);
141  }
142  avio_seek(pb, file_size, SEEK_SET);
143 
144  return 0;
145 }
146 
148 {
149  AVIContext *avi = s->priv_data;
150  AVIOContext *pb = s->pb;
151  int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale;
152  AVCodecContext *stream, *video_enc;
153  int64_t list1, list2, strh, strf;
155 
156  if (s->nb_streams > AVI_MAX_STREAM_COUNT) {
157  av_log(s, AV_LOG_ERROR, "AVI does not support >%d streams\n",
159  return AVERROR(EINVAL);
160  }
161 
162  for(n=0;n<s->nb_streams;n++) {
163  s->streams[n]->priv_data= av_mallocz(sizeof(AVIStream));
164  if(!s->streams[n]->priv_data)
165  return AVERROR(ENOMEM);
166  }
167 
168  /* header list */
169  avi->riff_id = 0;
170  list1 = avi_start_new_riff(s, pb, "AVI ", "hdrl");
171 
172  /* avi header */
173  ffio_wfourcc(pb, "avih");
174  avio_wl32(pb, 14 * 4);
175  bitrate = 0;
176 
177  video_enc = NULL;
178  for(n=0;n<s->nb_streams;n++) {
179  stream = s->streams[n]->codec;
180  bitrate += stream->bit_rate;
181  if (stream->codec_type == AVMEDIA_TYPE_VIDEO)
182  video_enc = stream;
183  }
184 
185  nb_frames = 0;
186 
187  if(video_enc){
188  avio_wl32(pb, (uint32_t)(INT64_C(1000000) * video_enc->time_base.num / video_enc->time_base.den));
189  } else {
190  avio_wl32(pb, 0);
191  }
192  avio_wl32(pb, bitrate / 8); /* XXX: not quite exact */
193  avio_wl32(pb, 0); /* padding */
194  if (!pb->seekable)
195  avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_ISINTERLEAVED); /* flags */
196  else
198  avi->frames_hdr_all = avio_tell(pb); /* remember this offset to fill later */
199  avio_wl32(pb, nb_frames); /* nb frames, filled later */
200  avio_wl32(pb, 0); /* initial frame */
201  avio_wl32(pb, s->nb_streams); /* nb streams */
202  avio_wl32(pb, 1024 * 1024); /* suggested buffer size */
203  if(video_enc){
204  avio_wl32(pb, video_enc->width);
205  avio_wl32(pb, video_enc->height);
206  } else {
207  avio_wl32(pb, 0);
208  avio_wl32(pb, 0);
209  }
210  avio_wl32(pb, 0); /* reserved */
211  avio_wl32(pb, 0); /* reserved */
212  avio_wl32(pb, 0); /* reserved */
213  avio_wl32(pb, 0); /* reserved */
214 
215  /* stream list */
216  for(i=0;i<n;i++) {
217  AVIStream *avist= s->streams[i]->priv_data;
218  list2 = ff_start_tag(pb, "LIST");
219  ffio_wfourcc(pb, "strl");
220 
221  stream = s->streams[i]->codec;
222 
223  /* stream generic header */
224  strh = ff_start_tag(pb, "strh");
225  switch(stream->codec_type) {
227  // XSUB subtitles behave like video tracks, other subtitles
228  // are not (yet) supported.
229  if (stream->codec_id != AV_CODEC_ID_XSUB) {
230  av_log(s, AV_LOG_ERROR, "Subtitle streams other than DivX XSUB are not supported by the AVI muxer.\n");
231  return AVERROR_PATCHWELCOME;
232  }
233  case AVMEDIA_TYPE_VIDEO: ffio_wfourcc(pb, "vids"); break;
234  case AVMEDIA_TYPE_AUDIO: ffio_wfourcc(pb, "auds"); break;
235 // case AVMEDIA_TYPE_TEXT : ffio_wfourcc(pb, "txts"); break;
236  case AVMEDIA_TYPE_DATA : ffio_wfourcc(pb, "dats"); break;
237  }
238  if(stream->codec_type == AVMEDIA_TYPE_VIDEO ||
239  stream->codec_id == AV_CODEC_ID_XSUB)
240  avio_wl32(pb, stream->codec_tag);
241  else
242  avio_wl32(pb, 1);
243  avio_wl32(pb, 0); /* flags */
244  avio_wl16(pb, 0); /* priority */
245  avio_wl16(pb, 0); /* language */
246  avio_wl32(pb, 0); /* initial frame */
247 
248  ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale);
249 
250  if ( stream->codec_type == AVMEDIA_TYPE_VIDEO
251  && stream->codec_id != AV_CODEC_ID_XSUB
252  && au_byterate > 1000LL*au_scale) {
253  au_byterate = 600;
254  au_scale = 1;
255  }
256  avpriv_set_pts_info(s->streams[i], 64, au_scale, au_byterate);
257  if(stream->codec_id == AV_CODEC_ID_XSUB)
258  au_scale = au_byterate = 0;
259 
260  avio_wl32(pb, au_scale); /* scale */
261  avio_wl32(pb, au_byterate); /* rate */
262 
263  avio_wl32(pb, 0); /* start */
264  avist->frames_hdr_strm = avio_tell(pb); /* remember this offset to fill later */
265  if (!pb->seekable)
266  avio_wl32(pb, AVI_MAX_RIFF_SIZE); /* FIXME: this may be broken, but who cares */
267  else
268  avio_wl32(pb, 0); /* length, XXX: filled later */
269 
270  /* suggested buffer size */ //FIXME set at the end to largest chunk
271  if(stream->codec_type == AVMEDIA_TYPE_VIDEO)
272  avio_wl32(pb, 1024 * 1024);
273  else if(stream->codec_type == AVMEDIA_TYPE_AUDIO)
274  avio_wl32(pb, 12 * 1024);
275  else
276  avio_wl32(pb, 0);
277  avio_wl32(pb, -1); /* quality */
278  avio_wl32(pb, au_ssize); /* sample size */
279  avio_wl32(pb, 0);
280  avio_wl16(pb, stream->width);
281  avio_wl16(pb, stream->height);
282  ff_end_tag(pb, strh);
283 
284  if(stream->codec_type != AVMEDIA_TYPE_DATA){
285  int ret;
286 
287  strf = ff_start_tag(pb, "strf");
288  switch(stream->codec_type) {
290  // XSUB subtitles behave like video tracks, other subtitles
291  // are not (yet) supported.
292  if (stream->codec_id != AV_CODEC_ID_XSUB) break;
293  case AVMEDIA_TYPE_VIDEO:
294  ff_put_bmp_header(pb, stream, ff_codec_bmp_tags, 0);
295  break;
296  case AVMEDIA_TYPE_AUDIO:
297  if ((ret = ff_put_wav_header(pb, stream)) < 0) {
298  return ret;
299  }
300  break;
301  default:
302  av_log(s, AV_LOG_ERROR,
303  "Invalid or not supported codec type '%s' found in the input\n",
304  (char *)av_x_if_null(av_get_media_type_string(stream->codec_type), "?"));
305  return AVERROR(EINVAL);
306  }
307  ff_end_tag(pb, strf);
308  if ((t = av_dict_get(s->streams[i]->metadata, "title", NULL, 0))) {
309  ff_riff_write_info_tag(s->pb, "strn", t->value);
310  t = NULL;
311  }
312  }
313 
314  if (pb->seekable) {
315  unsigned char tag[5];
316  int j;
317 
318  /* Starting to lay out AVI OpenDML master index.
319  * We want to make it JUNK entry for now, since we'd
320  * like to get away without making AVI an OpenDML one
321  * for compatibility reasons.
322  */
323  avist->indexes.entry = avist->indexes.ents_allocated = 0;
324  avist->indexes.indx_start = ff_start_tag(pb, "JUNK");
325  avio_wl16(pb, 4); /* wLongsPerEntry */
326  avio_w8(pb, 0); /* bIndexSubType (0 == frame index) */
327  avio_w8(pb, 0); /* bIndexType (0 == AVI_INDEX_OF_INDEXES) */
328  avio_wl32(pb, 0); /* nEntriesInUse (will fill out later on) */
329  ffio_wfourcc(pb, avi_stream2fourcc(tag, i, stream->codec_type));
330  /* dwChunkId */
331  avio_wl64(pb, 0); /* dwReserved[3]
332  avio_wl32(pb, 0); Must be 0. */
333  for (j=0; j < AVI_MASTER_INDEX_SIZE * 2; j++)
334  avio_wl64(pb, 0);
335  ff_end_tag(pb, avist->indexes.indx_start);
336  }
337 
338  if( stream->codec_type == AVMEDIA_TYPE_VIDEO
339  && s->streams[i]->sample_aspect_ratio.num>0
340  && s->streams[i]->sample_aspect_ratio.den>0){
341  int vprp= ff_start_tag(pb, "vprp");
343  (AVRational){stream->width, stream->height});
344  int num, den;
345  av_reduce(&num, &den, dar.num, dar.den, 0xFFFF);
346 
347  avio_wl32(pb, 0); //video format = unknown
348  avio_wl32(pb, 0); //video standard= unknown
349  avio_wl32(pb, lrintf(1.0/av_q2d(stream->time_base)));
350  avio_wl32(pb, stream->width );
351  avio_wl32(pb, stream->height);
352  avio_wl16(pb, den);
353  avio_wl16(pb, num);
354  avio_wl32(pb, stream->width );
355  avio_wl32(pb, stream->height);
356  avio_wl32(pb, 1); //progressive FIXME
357 
358  avio_wl32(pb, stream->height);
359  avio_wl32(pb, stream->width );
360  avio_wl32(pb, stream->height);
361  avio_wl32(pb, stream->width );
362  avio_wl32(pb, 0);
363  avio_wl32(pb, 0);
364 
365  avio_wl32(pb, 0);
366  avio_wl32(pb, 0);
367  ff_end_tag(pb, vprp);
368  }
369 
370  ff_end_tag(pb, list2);
371  }
372 
373  if (pb->seekable) {
374  /* AVI could become an OpenDML one, if it grows beyond 2Gb range */
375  avi->odml_list = ff_start_tag(pb, "JUNK");
376  ffio_wfourcc(pb, "odml");
377  ffio_wfourcc(pb, "dmlh");
378  avio_wl32(pb, 248);
379  for (i = 0; i < 248; i+= 4)
380  avio_wl32(pb, 0);
381  ff_end_tag(pb, avi->odml_list);
382  }
383 
384  ff_end_tag(pb, list1);
385 
387 
388  /* some padding for easier tag editing */
389  list2 = ff_start_tag(pb, "JUNK");
390  for (i = 0; i < 1016; i += 4)
391  avio_wl32(pb, 0);
392  ff_end_tag(pb, list2);
393 
394  avi->movi_list = ff_start_tag(pb, "LIST");
395  ffio_wfourcc(pb, "movi");
396 
397  avio_flush(pb);
398 
399  return 0;
400 }
401 
403 {
404  AVIOContext *pb = s->pb;
405  AVIContext *avi = s->priv_data;
406  char tag[5];
407  char ix_tag[] = "ix00";
408  int i, j;
409 
410  av_assert0(pb->seekable);
411 
412  if (avi->riff_id > AVI_MASTER_INDEX_SIZE) {
413  av_log(s, AV_LOG_ERROR, "Invalid riff index %d > %d\n",
415  return AVERROR(EINVAL);
416  }
417 
418  for (i=0;i<s->nb_streams;i++) {
419  AVIStream *avist= s->streams[i]->priv_data;
420  int64_t ix, pos;
421 
422  avi_stream2fourcc(tag, i, s->streams[i]->codec->codec_type);
423  ix_tag[3] = '0' + i;
424 
425  /* Writing AVI OpenDML leaf index chunk */
426  ix = avio_tell(pb);
427  ffio_wfourcc(pb, ix_tag); /* ix?? */
428  avio_wl32(pb, avist->indexes.entry * 8 + 24);
429  /* chunk size */
430  avio_wl16(pb, 2); /* wLongsPerEntry */
431  avio_w8(pb, 0); /* bIndexSubType (0 == frame index) */
432  avio_w8(pb, 1); /* bIndexType (1 == AVI_INDEX_OF_CHUNKS) */
433  avio_wl32(pb, avist->indexes.entry);
434  /* nEntriesInUse */
435  ffio_wfourcc(pb, tag); /* dwChunkId */
436  avio_wl64(pb, avi->movi_list);/* qwBaseOffset */
437  avio_wl32(pb, 0); /* dwReserved_3 (must be 0) */
438 
439  for (j=0; j<avist->indexes.entry; j++) {
440  AVIIentry* ie = avi_get_ientry(&avist->indexes, j);
441  avio_wl32(pb, ie->pos + 8);
442  avio_wl32(pb, ((uint32_t)ie->len & ~0x80000000) |
443  (ie->flags & 0x10 ? 0 : 0x80000000));
444  }
445  avio_flush(pb);
446  pos = avio_tell(pb);
447 
448  /* Updating one entry in the AVI OpenDML master index */
449  avio_seek(pb, avist->indexes.indx_start - 8, SEEK_SET);
450  ffio_wfourcc(pb, "indx"); /* enabling this entry */
451  avio_skip(pb, 8);
452  avio_wl32(pb, avi->riff_id); /* nEntriesInUse */
453  avio_skip(pb, 16*avi->riff_id);
454  avio_wl64(pb, ix); /* qwOffset */
455  avio_wl32(pb, pos - ix); /* dwSize */
456  avio_wl32(pb, avist->indexes.entry); /* dwDuration */
457 
458  avio_seek(pb, pos, SEEK_SET);
459  }
460  return 0;
461 }
462 
464 {
465  AVIOContext *pb = s->pb;
466  AVIContext *avi = s->priv_data;
467  int64_t idx_chunk;
468  int i;
469  char tag[5];
470 
471  if (pb->seekable) {
472  AVIStream *avist;
473  AVIIentry* ie = 0, *tie;
474  int empty, stream_id = -1;
475 
476  idx_chunk = ff_start_tag(pb, "idx1");
477  for(i=0; i<s->nb_streams; i++){
478  avist= s->streams[i]->priv_data;
479  avist->entry=0;
480  }
481 
482  do {
483  empty = 1;
484  for (i=0; i<s->nb_streams; i++) {
485  avist= s->streams[i]->priv_data;
486  if (avist->indexes.entry <= avist->entry)
487  continue;
488 
489  tie = avi_get_ientry(&avist->indexes, avist->entry);
490  if (empty || tie->pos < ie->pos) {
491  ie = tie;
492  stream_id = i;
493  }
494  empty = 0;
495  }
496  if (!empty) {
497  avist= s->streams[stream_id]->priv_data;
498  avi_stream2fourcc(tag, stream_id,
499  s->streams[stream_id]->codec->codec_type);
500  ffio_wfourcc(pb, tag);
501  avio_wl32(pb, ie->flags);
502  avio_wl32(pb, ie->pos);
503  avio_wl32(pb, ie->len);
504  avist->entry++;
505  }
506  } while (!empty);
507  ff_end_tag(pb, idx_chunk);
508 
509  avi_write_counters(s, avi->riff_id);
510  }
511  return 0;
512 }
513 
515 {
516  AVIContext *avi = s->priv_data;
517  AVIOContext *pb = s->pb;
518  unsigned char tag[5];
519  unsigned int flags=0;
520  const int stream_index= pkt->stream_index;
521  AVIStream *avist= s->streams[stream_index]->priv_data;
522  AVCodecContext *enc= s->streams[stream_index]->codec;
523  int size= pkt->size;
524 
525  av_dlog(s, "dts:%s packet_count:%d stream_index:%d\n", av_ts2str(pkt->dts), avist->packet_count, stream_index);
526  while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count && enc->codec_id != AV_CODEC_ID_XSUB){
527  AVPacket empty_packet;
528 
529  if(pkt->dts - avist->packet_count > 60000){
530  av_log(s, AV_LOG_ERROR, "Too large number of skipped frames %"PRId64" > 60000\n", pkt->dts - avist->packet_count);
531  return AVERROR(EINVAL);
532  }
533 
534  av_init_packet(&empty_packet);
535  empty_packet.size= 0;
536  empty_packet.data= NULL;
537  empty_packet.stream_index= stream_index;
538  avi_write_packet(s, &empty_packet);
539  av_dlog(s, "dup dts:%s packet_count:%d\n", av_ts2str(pkt->dts), avist->packet_count);
540  }
541  avist->packet_count++;
542 
543  // Make sure to put an OpenDML chunk when the file size exceeds the limits
544  if (pb->seekable &&
545  (avio_tell(pb) - avi->riff_start > AVI_MAX_RIFF_SIZE)) {
546 
547  avi_write_ix(s);
548  ff_end_tag(pb, avi->movi_list);
549 
550  if (avi->riff_id == 1)
551  avi_write_idx1(s);
552 
553  ff_end_tag(pb, avi->riff_start);
554  avi->movi_list = avi_start_new_riff(s, pb, "AVIX", "movi");
555  }
556 
557  avi_stream2fourcc(tag, stream_index, enc->codec_type);
558  if(pkt->flags&AV_PKT_FLAG_KEY)
559  flags = 0x10;
560  if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
561  avist->audio_strm_length += size;
562  }
563 
564  if (s->pb->seekable) {
565  AVIIndex* idx = &avist->indexes;
566  int cl = idx->entry / AVI_INDEX_CLUSTER_SIZE;
567  int id = idx->entry % AVI_INDEX_CLUSTER_SIZE;
568  if (idx->ents_allocated <= idx->entry) {
569  idx->cluster = av_realloc_f(idx->cluster, sizeof(void*), cl+1);
570  if (!idx->cluster)
571  return AVERROR(ENOMEM);
573  if (!idx->cluster[cl])
574  return AVERROR(ENOMEM);
576  }
577 
578  idx->cluster[cl][id].flags = flags;
579  idx->cluster[cl][id].pos = avio_tell(pb) - avi->movi_list;
580  idx->cluster[cl][id].len = size;
581  idx->entry++;
582  }
583 
584  avio_write(pb, tag, 4);
585  avio_wl32(pb, size);
586  avio_write(pb, pkt->data, size);
587  if (size & 1)
588  avio_w8(pb, 0);
589 
590  return 0;
591 }
592 
594 {
595  AVIContext *avi = s->priv_data;
596  AVIOContext *pb = s->pb;
597  int res = 0;
598  int i, j, n, nb_frames;
599  int64_t file_size;
600 
601  if (pb->seekable){
602  if (avi->riff_id == 1) {
603  ff_end_tag(pb, avi->movi_list);
604  res = avi_write_idx1(s);
605  ff_end_tag(pb, avi->riff_start);
606  } else {
607  avi_write_ix(s);
608  ff_end_tag(pb, avi->movi_list);
609  ff_end_tag(pb, avi->riff_start);
610 
611  file_size = avio_tell(pb);
612  avio_seek(pb, avi->odml_list - 8, SEEK_SET);
613  ffio_wfourcc(pb, "LIST"); /* Making this AVI OpenDML one */
614  avio_skip(pb, 16);
615 
616  for (n=nb_frames=0;n<s->nb_streams;n++) {
617  AVCodecContext *stream = s->streams[n]->codec;
618  AVIStream *avist= s->streams[n]->priv_data;
619 
620  if (stream->codec_type == AVMEDIA_TYPE_VIDEO) {
621  if (nb_frames < avist->packet_count)
622  nb_frames = avist->packet_count;
623  } else {
624  if (stream->codec_id == AV_CODEC_ID_MP2 || stream->codec_id == AV_CODEC_ID_MP3) {
625  nb_frames += avist->packet_count;
626  }
627  }
628  }
629  avio_wl32(pb, nb_frames);
630  avio_seek(pb, file_size, SEEK_SET);
631 
632  avi_write_counters(s, avi->riff_id);
633  }
634  }
635 
636  for (i=0; i<s->nb_streams; i++) {
637  AVIStream *avist= s->streams[i]->priv_data;
638  for (j=0; j<avist->indexes.ents_allocated/AVI_INDEX_CLUSTER_SIZE; j++)
639  av_free(avist->indexes.cluster[j]);
640  av_freep(&avist->indexes.cluster);
641  avist->indexes.ents_allocated = avist->indexes.entry = 0;
642  }
643 
644  return res;
645 }
646 
648  .name = "avi",
649  .long_name = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),
650  .mime_type = "video/x-msvideo",
651  .extensions = "avi",
652  .priv_data_size = sizeof(AVIContext),
654  .video_codec = AV_CODEC_ID_MPEG4,
658  .codec_tag = (const AVCodecTag* const []){
660  },
661  .flags = AVFMT_VARIABLE_FPS,
662 };
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
void avio_wl16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:367
const char * s
Definition: avisynth_c.h:668
#define CONFIG_LIBMP3LAME
Definition: config.h:321
Bytestream IO Context.
Definition: avio.h:68
void ff_end_tag(AVIOContext *pb, int64_t start)
int64_t ff_start_tag(AVIOContext *pb, const char *tag)
enum AVCodecID id
Definition: mxfenc.c:89
void * av_realloc_f(void *ptr, size_t nelem, size_t elsize)
Allocate or reallocate a block of memory.
Definition: mem.c:168
unsigned int pos
Definition: avienc.c:40
void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ssize, int *au_scale)
int ents_allocated
Definition: avienc.c:48
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.
#define AVI_MAX_RIFF_SIZE
Definition: avi.h:31
static int write_packet(AVFormatContext *s, AVPacket *pkt)
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:709
int num
numerator
Definition: rational.h:44
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:199
#define AVI_MASTER_INDEX_SIZE
Definition: avi.h:32
static char * avi_stream2fourcc(char *tag, int index, enum AVMediaType type)
Definition: avienc.c:94
void * priv_data
Definition: avformat.h:663
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:256
av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
AVDictionaryEntry * av_dict_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:39
AVOutputFormat ff_avi_muxer
Definition: avienc.c:647
int64_t frames_hdr_strm
Definition: avienc.c:59
int block_align
number of bytes per packet if constant and known or 0 Used by some WAV based audio codecs...
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
Format I/O context.
Definition: avformat.h:944
int64_t odml_list
Definition: avienc.c:53
#define AVIF_ISINTERLEAVED
Definition: avi.h:26
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
Public dictionary API.
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:291
Opaque data information usually continuous.
Definition: avutil.h:145
timestamp utils, mostly useful for debugging/logging purposes
static AVPacket pkt
Definition: demuxing.c:56
int64_t movi_list
Definition: avidec.c:66
AVStream ** streams
Definition: avformat.h:992
static double av_q2d(AVRational a)
Convert rational to double.
Definition: rational.h:69
struct AVIIndex AVIIndex
uint8_t * data
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
int64_t riff_start
Definition: avienc.c:53
uint32_t tag
Definition: movenc.c:894
#define lrintf(x)
Definition: libm_mips.h:70
static int64_t avi_start_new_riff(AVFormatContext *s, AVIOContext *pb, const char *riff_tag, const char *list_tag)
Definition: avienc.c:74
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:248
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:173
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:50
static int write_trailer(AVFormatContext *s)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
void avio_wl64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:355
static void * av_x_if_null(const void *p, const void *x)
Return x default pointer in case p is NULL.
Definition: avutil.h:250
#define AVI_MAX_STREAM_COUNT
Definition: avi.h:33
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
static int avi_write_idx1(AVFormatContext *s)
Definition: avienc.c:463
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
Write a single RIFF info tag.
preferred ID for decoding MPEG audio layer 1, 2 or 3
simple assert() macros that are a bit more flexible than ISO C assert().
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
unsigned int flags
Definition: avienc.c:40
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:334
#define FFMAX(a, b)
Definition: common.h:56
int size
int flags
A combination of AV_PKT_FLAG values.
int packet_count
Definition: avienc.c:61
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:662
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:36
unsigned int len
Definition: avienc.c:40
unsigned int nb_streams
A list of all streams in the file.
Definition: avformat.h:991
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:117
int bit_rate
the average bitrate
int void avio_flush(AVIOContext *s)
Force flushing of buffered data to the output s.
Definition: aviobuf.c:193
const AVCodecTag ff_codec_bmp_tags[]
Definition: riff.c:35
ret
Definition: avfilter.c:821
int width
picture width / height.
t
Definition: genspecsines3.m:6
const char * name
Definition: avformat.h:378
internal header for RIFF based (de)muxers do NOT include this in end user applications ...
static int avi_write_trailer(AVFormatContext *s)
Definition: avienc.c:593
AVDictionary * metadata
Definition: avformat.h:711
int64_t indx_start
Definition: avienc.c:46
int64_t audio_strm_length
Definition: avienc.c:60
static int avi_write_header(AVFormatContext *s)
Definition: avienc.c:147
#define AVIF_HASINDEX
Definition: avi.h:24
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
static int avi_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: avienc.c:514
NULL
Definition: eval.c:55
struct AVIStream AVIStream
enum AVMediaType codec_type
enum AVCodecID codec_id
AVIOContext * pb
I/O context.
Definition: avformat.h:977
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:151
main external API structure.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> (&#39;D&#39;<<24) + (&#39;C&#39;<<16) + (&#39;B&#39;<<8) + &#39;A&#39;).
void ff_riff_write_info(AVFormatContext *s)
Write all recognized RIFF tags from s->metadata.
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
#define AVI_INDEX_CLUSTER_SIZE
Definition: avienc.c:43
int index
Definition: gxfenc.c:89
synthesis window for stochastic i
rational number numerator/denominator
Definition: rational.h:43
AVMediaType
Definition: avutil.h:141
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
#define type
void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *tags, int for_asf)
AVIIentry ** cluster
Definition: avienc.c:49
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Main libavformat public API header.
int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
void av_init_packet(AVPacket *pkt)
Initialize optional fields of a packet with default values.
Definition: avpacket.c:56
int den
denominator
Definition: rational.h:45
static AVIIentry * avi_get_ientry(AVIIndex *idx, int ent_id)
Definition: avienc.c:67
#define AVFMT_VARIABLE_FPS
Format allows variable fps.
Definition: avformat.h:355
char * value
Definition: dict.h:82
struct AVIIentry AVIIentry
#define av_ts2str(ts)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: timestamp.h:50
int64_t frames_hdr_all
Definition: avienc.c:54
void * priv_data
Format private data.
Definition: avformat.h:964
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:470
int entry
Definition: avienc.c:62
AVIIndex indexes
Definition: avienc.c:64
static int avi_write_counters(AVFormatContext *s, int riff_id)
Definition: avienc.c:113
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
#define AVIF_TRUSTCKTYPE
Definition: avi.h:27
int entry
Definition: avienc.c:47
This structure stores compressed data.
static int avi_write_ix(AVFormatContext *s)
Definition: avienc.c:402
int riff_id
Definition: avienc.c:55
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:190