]> git.sesse.net Git - ffmpeg/blob - libavformat/avienc.c
Merge commit '3ef98937f512184f80d3bd30015f5ec83dc11eb0'
[ffmpeg] / libavformat / avienc.c
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 "mpegts.h"
30 #include "libavformat/avlanguage.h"
31 #include "libavutil/avstring.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/dict.h"
35 #include "libavutil/avassert.h"
36 #include "libavutil/timestamp.h"
37 #include "libavutil/opt.h"
38 #include "libavutil/pixdesc.h"
39 #include "libavcodec/raw.h"
40
41 /*
42  * TODO:
43  *  - fill all fields if non streamed (nb_frames for example)
44  */
45
46 typedef struct AVIIentry {
47     unsigned int flags, pos, len;
48 } AVIIentry;
49
50 #define AVI_INDEX_CLUSTER_SIZE 16384
51
52 typedef struct AVIIndex {
53     int64_t     indx_start;
54     int64_t     audio_strm_offset;
55     int         entry;
56     int         ents_allocated;
57     int         master_odml_riff_id_base;
58     AVIIentry** cluster;
59 } AVIIndex;
60
61 typedef struct AVIContext {
62     const AVClass *class;
63     int64_t riff_start, movi_list, odml_list;
64     int64_t frames_hdr_all;
65     int riff_id;
66     int write_channel_mask;
67 } AVIContext;
68
69 typedef struct AVIStream {
70     int64_t frames_hdr_strm;
71     int64_t audio_strm_length;
72     int packet_count;
73     int entry;
74     int max_size;
75     int sample_requested;
76
77     int64_t pal_offset;
78     int hdr_pal_done;
79
80     int64_t last_dts;
81
82     AVIIndex indexes;
83 } AVIStream;
84
85 static int avi_write_packet_internal(AVFormatContext *s, AVPacket *pkt);
86
87 static inline AVIIentry *avi_get_ientry(const AVIIndex *idx, int ent_id)
88 {
89     int cl = ent_id / AVI_INDEX_CLUSTER_SIZE;
90     int id = ent_id % AVI_INDEX_CLUSTER_SIZE;
91     return &idx->cluster[cl][id];
92 }
93
94 static int64_t avi_start_new_riff(AVFormatContext *s, AVIOContext *pb,
95                                   const char *riff_tag, const char *list_tag)
96 {
97     AVIContext *avi = s->priv_data;
98     int64_t loff;
99     int i;
100
101     avi->riff_id++;
102     for (i = 0; i < s->nb_streams; i++) {
103         AVIStream *avist = s->streams[i]->priv_data;
104         avist->indexes.audio_strm_offset = avist->audio_strm_length;
105         avist->indexes.entry = 0;
106     }
107
108     avi->riff_start = ff_start_tag(pb, "RIFF");
109     ffio_wfourcc(pb, riff_tag);
110     loff = ff_start_tag(pb, "LIST");
111     ffio_wfourcc(pb, list_tag);
112     return loff;
113 }
114
115 static char *avi_stream2fourcc(char *tag, int index, enum AVMediaType type)
116 {
117     tag[0] = '0' + index / 10;
118     tag[1] = '0' + index % 10;
119     if (type == AVMEDIA_TYPE_VIDEO) {
120         tag[2] = 'd';
121         tag[3] = 'c';
122     } else if (type == AVMEDIA_TYPE_SUBTITLE) {
123         // note: this is not an official code
124         tag[2] = 's';
125         tag[3] = 'b';
126     } else {
127         tag[2] = 'w';
128         tag[3] = 'b';
129     }
130     tag[4] = '\0';
131     return tag;
132 }
133
134 static int avi_write_counters(AVFormatContext *s, int riff_id)
135 {
136     AVIOContext *pb = s->pb;
137     AVIContext *avi = s->priv_data;
138     int n, au_byterate, au_ssize, au_scale, nb_frames = 0;
139     int64_t file_size;
140     AVCodecContext *stream;
141
142     file_size = avio_tell(pb);
143     for (n = 0; n < s->nb_streams; n++) {
144         AVIStream *avist = s->streams[n]->priv_data;
145
146         av_assert0(avist->frames_hdr_strm);
147         stream = s->streams[n]->codec;
148         avio_seek(pb, avist->frames_hdr_strm, SEEK_SET);
149         ff_parse_specific_params(s->streams[n], &au_byterate, &au_ssize, &au_scale);
150         if (au_ssize == 0)
151             avio_wl32(pb, avist->packet_count);
152         else
153             avio_wl32(pb, avist->audio_strm_length / au_ssize);
154         if (stream->codec_type == AVMEDIA_TYPE_VIDEO)
155             nb_frames = FFMAX(nb_frames, avist->packet_count);
156     }
157     if (riff_id == 1) {
158         av_assert0(avi->frames_hdr_all);
159         avio_seek(pb, avi->frames_hdr_all, SEEK_SET);
160         avio_wl32(pb, nb_frames);
161     }
162     avio_seek(pb, file_size, SEEK_SET);
163
164     return 0;
165 }
166
167 static void write_odml_master(AVFormatContext *s, int stream_index)
168 {
169     AVIOContext *pb = s->pb;
170     AVStream *st = s->streams[stream_index];
171     AVCodecContext *enc = st->codec;
172     AVIStream *avist = st->priv_data;
173     unsigned char tag[5];
174     int j;
175
176     /* Starting to lay out AVI OpenDML master index.
177         * We want to make it JUNK entry for now, since we'd
178         * like to get away without making AVI an OpenDML one
179         * for compatibility reasons. */
180     avist->indexes.indx_start = ff_start_tag(pb, "JUNK");
181     avio_wl16(pb, 4);   /* wLongsPerEntry */
182     avio_w8(pb, 0);     /* bIndexSubType (0 == frame index) */
183     avio_w8(pb, 0);     /* bIndexType (0 == AVI_INDEX_OF_INDEXES) */
184     avio_wl32(pb, 0);   /* nEntriesInUse (will fill out later on) */
185     ffio_wfourcc(pb, avi_stream2fourcc(tag, stream_index, enc->codec_type));
186                         /* dwChunkId */
187     avio_wl64(pb, 0);   /* dwReserved[3] */
188     avio_wl32(pb, 0);   /* Must be 0.    */
189     for (j = 0; j < AVI_MASTER_INDEX_SIZE * 2; j++)
190         avio_wl64(pb, 0);
191     ff_end_tag(pb, avist->indexes.indx_start);
192 }
193
194 static int avi_write_header(AVFormatContext *s)
195 {
196     AVIContext *avi = s->priv_data;
197     AVIOContext *pb = s->pb;
198     int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale;
199     AVCodecContext *video_enc;
200     AVStream *video_st = NULL;
201     int64_t list1, list2, strh, strf;
202     AVDictionaryEntry *t = NULL;
203     int padding;
204
205     if (s->nb_streams > AVI_MAX_STREAM_COUNT) {
206         av_log(s, AV_LOG_ERROR, "AVI does not support >%d streams\n",
207                AVI_MAX_STREAM_COUNT);
208         return AVERROR(EINVAL);
209     }
210
211     for (n = 0; n < s->nb_streams; n++) {
212         s->streams[n]->priv_data = av_mallocz(sizeof(AVIStream));
213         if (!s->streams[n]->priv_data)
214             return AVERROR(ENOMEM);
215     }
216
217     /* header list */
218     avi->riff_id = 0;
219     list1 = avi_start_new_riff(s, pb, "AVI ", "hdrl");
220
221     /* avi header */
222     ffio_wfourcc(pb, "avih");
223     avio_wl32(pb, 14 * 4);
224     bitrate = 0;
225
226     video_enc = NULL;
227     for (n = 0; n < s->nb_streams; n++) {
228         AVCodecContext *codec = s->streams[n]->codec;
229         bitrate += codec->bit_rate;
230         if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
231             video_enc = codec;
232             video_st = s->streams[n];
233         }
234     }
235
236     nb_frames = 0;
237
238     // TODO: should be avg_frame_rate
239     if (video_st)
240         avio_wl32(pb, (uint32_t) (INT64_C(1000000) * video_st->time_base.num /
241                                   video_st->time_base.den));
242     else
243         avio_wl32(pb, 0);
244     avio_wl32(pb, bitrate / 8); /* XXX: not quite exact */
245     avio_wl32(pb, 0); /* padding */
246     if (!pb->seekable)
247         avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_ISINTERLEAVED);  /* flags */
248     else
249         avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_HASINDEX | AVIF_ISINTERLEAVED);  /* flags */
250     avi->frames_hdr_all = avio_tell(pb); /* remember this offset to fill later */
251     avio_wl32(pb, nb_frames); /* nb frames, filled later */
252     avio_wl32(pb, 0); /* initial frame */
253     avio_wl32(pb, s->nb_streams); /* nb streams */
254     avio_wl32(pb, 1024 * 1024); /* suggested buffer size */
255     if (video_enc) {
256         avio_wl32(pb, video_enc->width);
257         avio_wl32(pb, video_enc->height);
258     } else {
259         avio_wl32(pb, 0);
260         avio_wl32(pb, 0);
261     }
262     avio_wl32(pb, 0); /* reserved */
263     avio_wl32(pb, 0); /* reserved */
264     avio_wl32(pb, 0); /* reserved */
265     avio_wl32(pb, 0); /* reserved */
266
267     /* stream list */
268     for (i = 0; i < n; i++) {
269         AVStream *st = s->streams[i];
270         AVCodecContext *enc = st->codec;
271         AVIStream *avist = st->priv_data;
272         list2 = ff_start_tag(pb, "LIST");
273         ffio_wfourcc(pb, "strl");
274
275         /* stream generic header */
276         strh = ff_start_tag(pb, "strh");
277         switch (enc->codec_type) {
278         case AVMEDIA_TYPE_SUBTITLE:
279             // XSUB subtitles behave like video tracks, other subtitles
280             // are not (yet) supported.
281             if (enc->codec_id != AV_CODEC_ID_XSUB) {
282                 av_log(s, AV_LOG_ERROR,
283                        "Subtitle streams other than DivX XSUB are not supported by the AVI muxer.\n");
284                 return AVERROR_PATCHWELCOME;
285             }
286         case AVMEDIA_TYPE_VIDEO:
287             ffio_wfourcc(pb, "vids");
288             break;
289         case AVMEDIA_TYPE_AUDIO:
290             ffio_wfourcc(pb, "auds");
291             break;
292 //      case AVMEDIA_TYPE_TEXT:
293 //          ffio_wfourcc(pb, "txts");
294 //          break;
295         case AVMEDIA_TYPE_DATA:
296             ffio_wfourcc(pb, "dats");
297             break;
298         }
299         if (enc->codec_type == AVMEDIA_TYPE_VIDEO ||
300             enc->codec_id == AV_CODEC_ID_XSUB)
301             avio_wl32(pb, enc->codec_tag);
302         else
303             avio_wl32(pb, 1);
304         avio_wl32(pb, 0); /* flags */
305         avio_wl16(pb, 0); /* priority */
306         avio_wl16(pb, 0); /* language */
307         avio_wl32(pb, 0); /* initial frame */
308
309         ff_parse_specific_params(st, &au_byterate, &au_ssize, &au_scale);
310
311         if (   enc->codec_type == AVMEDIA_TYPE_VIDEO
312             && enc->codec_id != AV_CODEC_ID_XSUB
313             && au_byterate > 1000LL*au_scale) {
314             au_byterate = 600;
315             au_scale    = 1;
316         }
317         avpriv_set_pts_info(st, 64, au_scale, au_byterate);
318         if (enc->codec_id == AV_CODEC_ID_XSUB)
319             au_scale = au_byterate = 0;
320
321         avio_wl32(pb, au_scale); /* scale */
322         avio_wl32(pb, au_byterate); /* rate */
323
324         avio_wl32(pb, 0); /* start */
325         /* remember this offset to fill later */
326         avist->frames_hdr_strm = avio_tell(pb);
327         if (!pb->seekable)
328             /* FIXME: this may be broken, but who cares */
329             avio_wl32(pb, AVI_MAX_RIFF_SIZE);
330         else
331             avio_wl32(pb, 0);  /* length, XXX: filled later */
332
333         /* suggested buffer size, is set to largest chunk size in avi_write_trailer */
334         if (enc->codec_type == AVMEDIA_TYPE_VIDEO)
335             avio_wl32(pb, 1024 * 1024);
336         else if (enc->codec_type == AVMEDIA_TYPE_AUDIO)
337             avio_wl32(pb, 12 * 1024);
338         else
339             avio_wl32(pb, 0);
340         avio_wl32(pb, -1); /* quality */
341         avio_wl32(pb, au_ssize); /* sample size */
342         avio_wl32(pb, 0);
343         avio_wl16(pb, enc->width);
344         avio_wl16(pb, enc->height);
345         ff_end_tag(pb, strh);
346
347         if (enc->codec_type != AVMEDIA_TYPE_DATA) {
348             int ret, flags;
349             enum AVPixelFormat pix_fmt;
350
351             strf = ff_start_tag(pb, "strf");
352             switch (enc->codec_type) {
353             case AVMEDIA_TYPE_SUBTITLE:
354                 /* XSUB subtitles behave like video tracks, other subtitles
355                  * are not (yet) supported. */
356                 if (enc->codec_id != AV_CODEC_ID_XSUB)
357                     break;
358             case AVMEDIA_TYPE_VIDEO:
359                 /* WMP expects RGB 5:5:5 rawvideo in avi to have bpp set to 16. */
360                 if (  !enc->codec_tag
361                     && enc->codec_id == AV_CODEC_ID_RAWVIDEO
362                     && enc->pix_fmt == AV_PIX_FMT_RGB555LE
363                     && enc->bits_per_coded_sample == 15)
364                     enc->bits_per_coded_sample = 16;
365                 avist->pal_offset = avio_tell(pb) + 40;
366                 ff_put_bmp_header(pb, enc, ff_codec_bmp_tags, 0, 0);
367                 pix_fmt = avpriv_find_pix_fmt(avpriv_pix_fmt_bps_avi,
368                                               enc->bits_per_coded_sample);
369                 if (   !enc->codec_tag
370                     && enc->codec_id == AV_CODEC_ID_RAWVIDEO
371                     && enc->pix_fmt != pix_fmt
372                     && enc->pix_fmt != AV_PIX_FMT_NONE)
373                     av_log(s, AV_LOG_ERROR, "%s rawvideo cannot be written to avi, output file will be unreadable\n",
374                           av_get_pix_fmt_name(enc->pix_fmt));
375                 break;
376             case AVMEDIA_TYPE_AUDIO:
377                 flags = (avi->write_channel_mask == 0) ? FF_PUT_WAV_HEADER_SKIP_CHANNELMASK : 0;
378                 if ((ret = ff_put_wav_header(pb, enc, flags)) < 0)
379                     return ret;
380                 break;
381             default:
382                 av_log(s, AV_LOG_ERROR,
383                     "Invalid or not supported codec type '%s' found in the input\n",
384                     (char *)av_x_if_null(av_get_media_type_string(enc->codec_type), "?"));
385                 return AVERROR(EINVAL);
386             }
387             ff_end_tag(pb, strf);
388             if ((t = av_dict_get(st->metadata, "title", NULL, 0))) {
389                 ff_riff_write_info_tag(s->pb, "strn", t->value);
390                 t = NULL;
391             }
392             if (enc->codec_id == AV_CODEC_ID_XSUB
393             && (t = av_dict_get(s->streams[i]->metadata, "language", NULL, 0))) {
394                 const char* langstr = av_convert_lang_to(t->value, AV_LANG_ISO639_1);
395                 t = NULL;
396                 if (langstr) {
397                     char* str = av_asprintf("Subtitle - %s-xx;02", langstr);
398                     if (!str)
399                         return AVERROR(ENOMEM);
400                     ff_riff_write_info_tag(s->pb, "strn", str);
401                     av_free(str);
402                 }
403             }
404         }
405
406         if (pb->seekable) {
407             write_odml_master(s, i);
408         }
409
410         if (enc->codec_type == AVMEDIA_TYPE_VIDEO   &&
411             st->sample_aspect_ratio.num > 0 &&
412             st->sample_aspect_ratio.den > 0) {
413             int vprp       = ff_start_tag(pb, "vprp");
414             AVRational dar = av_mul_q(st->sample_aspect_ratio,
415                                       (AVRational) { enc->width,
416                                                      enc->height });
417             int num, den;
418             av_reduce(&num, &den, dar.num, dar.den, 0xFFFF);
419
420             avio_wl32(pb, 0); // video format   = unknown
421             avio_wl32(pb, 0); // video standard = unknown
422             // TODO: should be avg_frame_rate
423             avio_wl32(pb, (2LL*st->time_base.den + st->time_base.num - 1) / (2LL * st->time_base.num));
424             avio_wl32(pb, enc->width);
425             avio_wl32(pb, enc->height);
426             avio_wl16(pb, den);
427             avio_wl16(pb, num);
428             avio_wl32(pb, enc->width);
429             avio_wl32(pb, enc->height);
430             avio_wl32(pb, 1); // progressive FIXME
431
432             avio_wl32(pb, enc->height);
433             avio_wl32(pb, enc->width);
434             avio_wl32(pb, enc->height);
435             avio_wl32(pb, enc->width);
436             avio_wl32(pb, 0);
437             avio_wl32(pb, 0);
438
439             avio_wl32(pb, 0);
440             avio_wl32(pb, 0);
441             ff_end_tag(pb, vprp);
442         }
443
444         ff_end_tag(pb, list2);
445     }
446
447     if (pb->seekable) {
448         /* AVI could become an OpenDML one, if it grows beyond 2Gb range */
449         avi->odml_list = ff_start_tag(pb, "JUNK");
450         ffio_wfourcc(pb, "odml");
451         ffio_wfourcc(pb, "dmlh");
452         avio_wl32(pb, 248);
453         for (i = 0; i < 248; i += 4)
454             avio_wl32(pb, 0);
455         ff_end_tag(pb, avi->odml_list);
456     }
457
458     ff_end_tag(pb, list1);
459
460     ff_riff_write_info(s);
461
462
463     padding = s->metadata_header_padding;
464     if (padding < 0)
465         padding = 1016;
466
467     /* some padding for easier tag editing */
468     if (padding) {
469         list2 = ff_start_tag(pb, "JUNK");
470         for (i = padding; i > 0; i -= 4)
471             avio_wl32(pb, 0);
472         ff_end_tag(pb, list2);
473     }
474
475     avi->movi_list = ff_start_tag(pb, "LIST");
476     ffio_wfourcc(pb, "movi");
477
478     avio_flush(pb);
479
480     return 0;
481 }
482
483 static void update_odml_entry(AVFormatContext *s, int stream_index, int64_t ix, int size)
484 {
485     AVIOContext *pb = s->pb;
486     AVIContext *avi = s->priv_data;
487     AVIStream *avist = s->streams[stream_index]->priv_data;
488     int64_t pos;
489     int au_byterate, au_ssize, au_scale;
490
491     avio_flush(pb);
492     pos = avio_tell(pb);
493
494     /* Updating one entry in the AVI OpenDML master index */
495     avio_seek(pb, avist->indexes.indx_start - 8, SEEK_SET);
496     ffio_wfourcc(pb, "indx");             /* enabling this entry */
497     avio_skip(pb, 8);
498     avio_wl32(pb, avi->riff_id - avist->indexes.master_odml_riff_id_base);          /* nEntriesInUse */
499     avio_skip(pb, 16 * (avi->riff_id - avist->indexes.master_odml_riff_id_base));
500     avio_wl64(pb, ix);                    /* qwOffset */
501     avio_wl32(pb, size);                  /* dwSize */
502     ff_parse_specific_params(s->streams[stream_index], &au_byterate, &au_ssize, &au_scale);
503     if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO && au_ssize > 0) {
504         uint32_t audio_segm_size = (avist->audio_strm_length - avist->indexes.audio_strm_offset);
505         if ((audio_segm_size % au_ssize > 0) && !avist->sample_requested) {
506             avpriv_request_sample(s, "OpenDML index duration for audio packets with partial frames");
507             avist->sample_requested = 1;
508         }
509         avio_wl32(pb, audio_segm_size / au_ssize);  /* dwDuration (sample count) */
510     } else
511         avio_wl32(pb, avist->indexes.entry);  /* dwDuration (packet count) */
512
513     avio_seek(pb, pos, SEEK_SET);
514 }
515
516 static int avi_write_ix(AVFormatContext *s)
517 {
518     AVIOContext *pb = s->pb;
519     AVIContext *avi = s->priv_data;
520     char tag[5];
521     char ix_tag[] = "ix00";
522     int i, j;
523
524     av_assert0(pb->seekable);
525
526     for (i = 0; i < s->nb_streams; i++) {
527         AVIStream *avist = s->streams[i]->priv_data;
528         if (avi->riff_id - avist->indexes.master_odml_riff_id_base == AVI_MASTER_INDEX_SIZE) {
529             int64_t pos;
530             int size = 8+2+1+1+4+8+4+4+16*AVI_MASTER_INDEX_SIZE;
531
532             pos = avio_tell(pb);
533             update_odml_entry(s, i, pos, size);
534             write_odml_master(s, i);
535             av_assert1(avio_tell(pb) - pos == size);
536             avist->indexes.master_odml_riff_id_base = avi->riff_id - 1;
537         }
538         av_assert0(avi->riff_id - avist->indexes.master_odml_riff_id_base < AVI_MASTER_INDEX_SIZE);
539     }
540
541     for (i = 0; i < s->nb_streams; i++) {
542         AVIStream *avist = s->streams[i]->priv_data;
543         int64_t ix;
544
545         avi_stream2fourcc(tag, i, s->streams[i]->codec->codec_type);
546         ix_tag[3] = '0' + i;
547
548         /* Writing AVI OpenDML leaf index chunk */
549         ix = avio_tell(pb);
550         ffio_wfourcc(pb, ix_tag);      /* ix?? */
551         avio_wl32(pb, avist->indexes.entry * 8 + 24);
552         /* chunk size */
553         avio_wl16(pb, 2);           /* wLongsPerEntry */
554         avio_w8(pb, 0);             /* bIndexSubType (0 == frame index) */
555         avio_w8(pb, 1);             /* bIndexType (1 == AVI_INDEX_OF_CHUNKS) */
556         avio_wl32(pb, avist->indexes.entry);
557         /* nEntriesInUse */
558         ffio_wfourcc(pb, tag);         /* dwChunkId */
559         avio_wl64(pb, avi->movi_list); /* qwBaseOffset */
560         avio_wl32(pb, 0);              /* dwReserved_3 (must be 0) */
561
562         for (j = 0; j < avist->indexes.entry; j++) {
563             AVIIentry *ie = avi_get_ientry(&avist->indexes, j);
564             avio_wl32(pb, ie->pos + 8);
565             avio_wl32(pb, ((uint32_t) ie->len & ~0x80000000) |
566                           (ie->flags & 0x10 ? 0 : 0x80000000));
567         }
568
569         update_odml_entry(s, i, ix, avio_tell(pb) - ix);
570     }
571     return 0;
572 }
573
574 static int avi_write_idx1(AVFormatContext *s)
575 {
576     AVIOContext *pb = s->pb;
577     AVIContext *avi = s->priv_data;
578     int64_t idx_chunk;
579     int i;
580     char tag[5];
581
582     if (pb->seekable) {
583         AVIStream *avist;
584         AVIIentry *ie = 0, *tie;
585         int empty, stream_id = -1;
586
587         idx_chunk = ff_start_tag(pb, "idx1");
588         for (i = 0; i < s->nb_streams; i++) {
589             avist        = s->streams[i]->priv_data;
590             avist->entry = 0;
591         }
592
593         do {
594             empty = 1;
595             for (i = 0; i < s->nb_streams; i++) {
596                 avist = s->streams[i]->priv_data;
597                 if (avist->indexes.entry <= avist->entry)
598                     continue;
599
600                 tie = avi_get_ientry(&avist->indexes, avist->entry);
601                 if (empty || tie->pos < ie->pos) {
602                     ie        = tie;
603                     stream_id = i;
604                 }
605                 empty = 0;
606             }
607             if (!empty) {
608                 avist = s->streams[stream_id]->priv_data;
609                 avi_stream2fourcc(tag, stream_id,
610                                   s->streams[stream_id]->codec->codec_type);
611                 ffio_wfourcc(pb, tag);
612                 avio_wl32(pb, ie->flags);
613                 avio_wl32(pb, ie->pos);
614                 avio_wl32(pb, ie->len);
615                 avist->entry++;
616             }
617         } while (!empty);
618         ff_end_tag(pb, idx_chunk);
619
620         avi_write_counters(s, avi->riff_id);
621     }
622     return 0;
623 }
624
625 static int write_skip_frames(AVFormatContext *s, int stream_index, int64_t dts)
626 {
627     AVIStream *avist    = s->streams[stream_index]->priv_data;
628     AVCodecContext *enc = s->streams[stream_index]->codec;
629
630     ff_dlog(s, "dts:%s packet_count:%d stream_index:%d\n", av_ts2str(dts), avist->packet_count, stream_index);
631     while (enc->block_align == 0 && dts != AV_NOPTS_VALUE &&
632            dts > avist->packet_count && enc->codec_id != AV_CODEC_ID_XSUB && avist->packet_count) {
633         AVPacket empty_packet;
634
635         if (dts - avist->packet_count > 60000) {
636             av_log(s, AV_LOG_ERROR, "Too large number of skipped frames %"PRId64" > 60000\n", dts - avist->packet_count);
637             return AVERROR(EINVAL);
638         }
639
640         av_init_packet(&empty_packet);
641         empty_packet.size         = 0;
642         empty_packet.data         = NULL;
643         empty_packet.stream_index = stream_index;
644         avi_write_packet_internal(s, &empty_packet);
645         ff_dlog(s, "dup dts:%s packet_count:%d\n", av_ts2str(dts), avist->packet_count);
646     }
647
648     return 0;
649 }
650
651 static int avi_write_packet(AVFormatContext *s, AVPacket *pkt)
652 {
653     unsigned char tag[5];
654     const int stream_index = pkt->stream_index;
655     const uint8_t *data    = pkt->data;
656     int size               = pkt->size;
657     AVIOContext *pb     = s->pb;
658     AVCodecContext *enc = s->streams[stream_index]->codec;
659     AVIStream *avist    = s->streams[stream_index]->priv_data;
660     int ret;
661
662     if (enc->codec_id == AV_CODEC_ID_H264 && enc->codec_tag == MKTAG('H','2','6','4') && pkt->size) {
663         ret = ff_check_h264_startcode(s, s->streams[stream_index], pkt);
664         if (ret < 0)
665             return ret;
666     }
667
668     if ((ret = write_skip_frames(s, stream_index, pkt->dts)) < 0)
669         return ret;
670
671     if (enc->codec_id == AV_CODEC_ID_RAWVIDEO && enc->codec_tag == 0) {
672         int64_t bpc = enc->bits_per_coded_sample != 15 ? enc->bits_per_coded_sample : 16;
673         int expected_stride = ((enc->width * bpc + 31) >> 5)*4;
674
675         ret = ff_reshuffle_raw_rgb(s, &pkt, enc, expected_stride);
676         if (ret < 0)
677             return ret;
678         if (ret) {
679             if (ret == CONTAINS_PAL) {
680                 int pc_tag, i;
681                 int pal_size = 1 << enc->bits_per_coded_sample;
682                 if (!avist->hdr_pal_done) {
683                     int64_t cur_offset = avio_tell(pb);
684                     avio_seek(pb, avist->pal_offset, SEEK_SET);
685                     for (i = 0; i < pal_size; i++) {
686                         uint32_t v = AV_RL32(data + size - 4*pal_size + 4*i);
687                         avio_wl32(pb, v & 0xffffff);
688                     }
689                     avio_seek(pb, cur_offset, SEEK_SET);
690                     avist->hdr_pal_done++;
691                 }
692                 avi_stream2fourcc(tag, stream_index, enc->codec_type);
693                 tag[2] = 'p'; tag[3] = 'c';
694                 pc_tag = ff_start_tag(pb, tag);
695                 avio_w8(pb, 0);
696                 avio_w8(pb, pal_size & 0xFF);
697                 avio_wl16(pb, 0); // reserved
698                 for (i = 0; i < pal_size; i++) {
699                     uint32_t v = AV_RL32(data + size - 4*pal_size + 4*i);
700                     avio_wb32(pb, v<<8);
701                 }
702                 ff_end_tag(pb, pc_tag);
703             }
704             ret = avi_write_packet_internal(s, pkt);
705             av_packet_free(&pkt);
706             return ret;
707         }
708     }
709
710     return avi_write_packet_internal(s, pkt);
711 }
712
713 static int avi_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
714 {
715     unsigned char tag[5];
716     unsigned int flags = 0;
717     const int stream_index = pkt->stream_index;
718     int size               = pkt->size;
719     AVIContext *avi     = s->priv_data;
720     AVIOContext *pb     = s->pb;
721     AVIStream *avist    = s->streams[stream_index]->priv_data;
722     AVCodecContext *enc = s->streams[stream_index]->codec;
723
724     if (pkt->dts != AV_NOPTS_VALUE)
725         avist->last_dts = pkt->dts + pkt->duration;
726
727     avist->packet_count++;
728
729     // Make sure to put an OpenDML chunk when the file size exceeds the limits
730     if (pb->seekable &&
731         (avio_tell(pb) - avi->riff_start > AVI_MAX_RIFF_SIZE)) {
732         avi_write_ix(s);
733         ff_end_tag(pb, avi->movi_list);
734
735         if (avi->riff_id == 1)
736             avi_write_idx1(s);
737
738         ff_end_tag(pb, avi->riff_start);
739         avi->movi_list = avi_start_new_riff(s, pb, "AVIX", "movi");
740     }
741
742     avi_stream2fourcc(tag, stream_index, enc->codec_type);
743     if (pkt->flags & AV_PKT_FLAG_KEY)
744         flags = 0x10;
745     if (enc->codec_type == AVMEDIA_TYPE_AUDIO)
746         avist->audio_strm_length += size;
747
748     if (s->pb->seekable) {
749         AVIIndex *idx = &avist->indexes;
750         int cl = idx->entry / AVI_INDEX_CLUSTER_SIZE;
751         int id = idx->entry % AVI_INDEX_CLUSTER_SIZE;
752         if (idx->ents_allocated <= idx->entry) {
753             idx->cluster = av_realloc_f(idx->cluster, sizeof(void*), cl+1);
754             if (!idx->cluster) {
755                 idx->ents_allocated = 0;
756                 idx->entry          = 0;
757                 return AVERROR(ENOMEM);
758             }
759             idx->cluster[cl] =
760                 av_malloc(AVI_INDEX_CLUSTER_SIZE * sizeof(AVIIentry));
761             if (!idx->cluster[cl])
762                 return AVERROR(ENOMEM);
763             idx->ents_allocated += AVI_INDEX_CLUSTER_SIZE;
764         }
765
766         idx->cluster[cl][id].flags = flags;
767         idx->cluster[cl][id].pos   = avio_tell(pb) - avi->movi_list;
768         idx->cluster[cl][id].len   = size;
769         avist->max_size = FFMAX(avist->max_size, size);
770         idx->entry++;
771     }
772
773     avio_write(pb, tag, 4);
774     avio_wl32(pb, size);
775     avio_write(pb, pkt->data, size);
776     if (size & 1)
777         avio_w8(pb, 0);
778
779     return 0;
780 }
781
782 static int avi_write_trailer(AVFormatContext *s)
783 {
784     AVIContext *avi = s->priv_data;
785     AVIOContext *pb = s->pb;
786     int res = 0;
787     int i, j, n, nb_frames;
788     int64_t file_size;
789
790     for (i = 0; i < s->nb_streams; i++) {
791         AVIStream *avist = s->streams[i]->priv_data;
792         write_skip_frames(s, i, avist->last_dts);
793     }
794
795     if (pb->seekable) {
796         if (avi->riff_id == 1) {
797             ff_end_tag(pb, avi->movi_list);
798             res = avi_write_idx1(s);
799             ff_end_tag(pb, avi->riff_start);
800         } else {
801             avi_write_ix(s);
802             ff_end_tag(pb, avi->movi_list);
803             ff_end_tag(pb, avi->riff_start);
804
805             file_size = avio_tell(pb);
806             avio_seek(pb, avi->odml_list - 8, SEEK_SET);
807             ffio_wfourcc(pb, "LIST"); /* Making this AVI OpenDML one */
808             avio_skip(pb, 16);
809
810             for (n = nb_frames = 0; n < s->nb_streams; n++) {
811                 AVCodecContext *stream = s->streams[n]->codec;
812                 AVIStream *avist       = s->streams[n]->priv_data;
813
814                 if (stream->codec_type == AVMEDIA_TYPE_VIDEO) {
815                     if (nb_frames < avist->packet_count)
816                         nb_frames = avist->packet_count;
817                 } else {
818                     if (stream->codec_id == AV_CODEC_ID_MP2 ||
819                         stream->codec_id == AV_CODEC_ID_MP3)
820                         nb_frames += avist->packet_count;
821                 }
822             }
823             avio_wl32(pb, nb_frames);
824             avio_seek(pb, file_size, SEEK_SET);
825
826             avi_write_counters(s, avi->riff_id);
827         }
828     }
829
830     for (i = 0; i < s->nb_streams; i++) {
831         AVIStream *avist = s->streams[i]->priv_data;
832         for (j = 0; j < avist->indexes.ents_allocated / AVI_INDEX_CLUSTER_SIZE; j++)
833             av_freep(&avist->indexes.cluster[j]);
834         av_freep(&avist->indexes.cluster);
835         avist->indexes.ents_allocated = avist->indexes.entry = 0;
836         if (pb->seekable) {
837             avio_seek(pb, avist->frames_hdr_strm + 4, SEEK_SET);
838             avio_wl32(pb, avist->max_size);
839         }
840     }
841
842     return res;
843 }
844
845 #define OFFSET(x) offsetof(AVIContext, x)
846 #define ENC AV_OPT_FLAG_ENCODING_PARAM
847 static const AVOption options[] = {
848     { "write_channel_mask", "write channel mask into wave format header", OFFSET(write_channel_mask), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, ENC },
849     { NULL },
850 };
851
852 static const AVClass avi_muxer_class = {
853     .class_name = "AVI muxer",
854     .item_name  = av_default_item_name,
855     .option     = options,
856     .version    = LIBAVUTIL_VERSION_INT,
857 };
858
859 AVOutputFormat ff_avi_muxer = {
860     .name           = "avi",
861     .long_name      = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),
862     .mime_type      = "video/x-msvideo",
863     .extensions     = "avi",
864     .priv_data_size = sizeof(AVIContext),
865     .audio_codec    = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_AC3,
866     .video_codec    = AV_CODEC_ID_MPEG4,
867     .write_header   = avi_write_header,
868     .write_packet   = avi_write_packet,
869     .write_trailer  = avi_write_trailer,
870     .codec_tag      = (const AVCodecTag * const []) {
871         ff_codec_bmp_tags, ff_codec_wav_tags, 0
872     },
873     .priv_class     = &avi_muxer_class,
874 };