• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <math.h>
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/avutil.h"
33 #include "libavutil/internal.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     char tag[4];
48     unsigned int flags;
49     unsigned int pos;
50     unsigned int len;
51 } AVIIentry;
52 
53 #define AVI_INDEX_CLUSTER_SIZE 16384
54 #define AVI_MASTER_INDEX_PREFIX_SIZE    (8+2+1+1+4+8+4+4)
55 #define AVI_MASTER_INDEX_ENTRY_SIZE     16  /* bytes per entry */
56 #define AVI_MASTER_INDEX_SIZE_DEFAULT   256 /* number of entries */
57 
58 typedef struct AVIIndex {
59     int64_t     indx_start;
60     int64_t     audio_strm_offset;
61     int         entry;
62     int         ents_allocated;
63     int         master_odml_riff_id_base;
64     AVIIentry** cluster;
65 } AVIIndex;
66 
67 typedef struct AVIContext {
68     const AVClass *class;
69     AVPacket *empty_packet;
70     int64_t riff_start, movi_list, odml_list;
71     int64_t frames_hdr_all;
72     int riff_id;
73     int reserve_index_space;
74     int master_index_max_size;
75     int write_channel_mask;
76     int flipped_raw_rgb;
77 } AVIContext;
78 
79 typedef struct AVIStream {
80     int64_t frames_hdr_strm;
81     int64_t audio_strm_length;
82     int packet_count;
83     int entry;
84     int max_size;
85     int sample_requested;
86 
87     int64_t last_dts;
88 
89     AVIIndex indexes;
90 
91     int64_t strh_flags_offset;
92 
93     uint32_t palette[AVPALETTE_COUNT];
94     uint32_t old_palette[AVPALETTE_COUNT];
95     int64_t pal_offset;
96 } AVIStream;
97 
98 static int avi_write_packet_internal(AVFormatContext *s, AVPacket *pkt);
99 
avi_get_ientry(const AVIIndex * idx,int ent_id)100 static inline AVIIentry *avi_get_ientry(const AVIIndex *idx, int ent_id)
101 {
102     int cl = ent_id / AVI_INDEX_CLUSTER_SIZE;
103     int id = ent_id % AVI_INDEX_CLUSTER_SIZE;
104     return &idx->cluster[cl][id];
105 }
106 
avi_add_ientry(AVFormatContext * s,int stream_index,char * tag,unsigned int flags,unsigned int size)107 static int avi_add_ientry(AVFormatContext *s, int stream_index, char *tag,
108                           unsigned int flags, unsigned int size)
109 {
110     AVIContext *avi  = s->priv_data;
111     AVIOContext *pb  = s->pb;
112     AVIStream *avist = s->streams[stream_index]->priv_data;
113     AVIIndex *idx    = &avist->indexes;
114     int cl           = idx->entry / AVI_INDEX_CLUSTER_SIZE;
115     int id           = idx->entry % AVI_INDEX_CLUSTER_SIZE;
116 
117     if (idx->ents_allocated <= idx->entry) {
118         idx->cluster = av_realloc_f(idx->cluster, sizeof(void*), cl+1);
119         if (!idx->cluster) {
120             idx->ents_allocated = 0;
121             idx->entry          = 0;
122             return AVERROR(ENOMEM);
123         }
124         idx->cluster[cl] =
125             av_malloc(AVI_INDEX_CLUSTER_SIZE * sizeof(AVIIentry));
126         if (!idx->cluster[cl])
127             return AVERROR(ENOMEM);
128         idx->ents_allocated += AVI_INDEX_CLUSTER_SIZE;
129     }
130 
131     if (tag)
132         memcpy(idx->cluster[cl][id].tag, tag, 4);
133     else
134         memset(idx->cluster[cl][id].tag, 0, 4);
135     idx->cluster[cl][id].flags = flags;
136     idx->cluster[cl][id].pos   = avio_tell(pb) - avi->movi_list;
137     idx->cluster[cl][id].len   = size;
138     avist->max_size = FFMAX(avist->max_size, size);
139     idx->entry++;
140 
141     return 0;
142 }
143 
avi_init(struct AVFormatContext * s)144 static av_cold int avi_init(struct AVFormatContext *s)
145 {
146     AVIContext *avi = s->priv_data;
147 
148     if (avi->reserve_index_space > 0) {
149         avi->master_index_max_size = (avi->reserve_index_space - AVI_MASTER_INDEX_PREFIX_SIZE) / AVI_MASTER_INDEX_ENTRY_SIZE;
150         avi->master_index_max_size = FFMAX(avi->master_index_max_size, 16);
151     } else
152         avi->master_index_max_size = AVI_MASTER_INDEX_SIZE_DEFAULT;
153     av_log(s, AV_LOG_DEBUG, "reserve_index_space:%d master_index_max_size:%d\n",
154            avi->reserve_index_space, avi->master_index_max_size);
155 
156     return 1; /* stream initialization continues in avi_write_header */
157 }
158 
avi_start_new_riff(AVFormatContext * s,AVIOContext * pb,const char * riff_tag,const char * list_tag)159 static int64_t avi_start_new_riff(AVFormatContext *s, AVIOContext *pb,
160                                   const char *riff_tag, const char *list_tag)
161 {
162     AVIContext *avi = s->priv_data;
163     int64_t loff;
164     int i;
165 
166     avi->riff_id++;
167     for (i = 0; i < s->nb_streams; i++) {
168         AVIStream *avist = s->streams[i]->priv_data;
169         avist->indexes.audio_strm_offset = avist->audio_strm_length;
170         avist->indexes.entry = 0;
171     }
172 
173     avi->riff_start = ff_start_tag(pb, "RIFF");
174     ffio_wfourcc(pb, riff_tag);
175     loff = ff_start_tag(pb, "LIST");
176     ffio_wfourcc(pb, list_tag);
177     return loff;
178 }
179 
avi_stream2fourcc(char * tag,int index,enum AVMediaType type)180 static char *avi_stream2fourcc(char *tag, int index, enum AVMediaType type)
181 {
182     tag[0] = '0' + index / 10;
183     tag[1] = '0' + index % 10;
184     if (type == AVMEDIA_TYPE_VIDEO) {
185         tag[2] = 'd';
186         tag[3] = 'c';
187     } else if (type == AVMEDIA_TYPE_SUBTITLE) {
188         // note: this is not an official code
189         tag[2] = 's';
190         tag[3] = 'b';
191     } else {
192         tag[2] = 'w';
193         tag[3] = 'b';
194     }
195     tag[4] = '\0';
196     return tag;
197 }
198 
avi_write_counters(AVFormatContext * s,int riff_id)199 static int avi_write_counters(AVFormatContext *s, int riff_id)
200 {
201     AVIOContext *pb = s->pb;
202     AVIContext *avi = s->priv_data;
203     int n, au_byterate, au_ssize, au_scale, nb_frames = 0;
204     int64_t file_size;
205     AVCodecParameters *par;
206 
207     file_size = avio_tell(pb);
208     for (n = 0; n < s->nb_streams; n++) {
209         AVIStream *avist = s->streams[n]->priv_data;
210 
211         av_assert0(avist->frames_hdr_strm);
212         par = s->streams[n]->codecpar;
213         avio_seek(pb, avist->frames_hdr_strm, SEEK_SET);
214         ff_parse_specific_params(s->streams[n], &au_byterate, &au_ssize, &au_scale);
215         if (au_ssize == 0)
216             avio_wl32(pb, avist->packet_count);
217         else
218             avio_wl32(pb, avist->audio_strm_length / au_ssize);
219         if (par->codec_type == AVMEDIA_TYPE_VIDEO)
220             nb_frames = FFMAX(nb_frames, avist->packet_count);
221     }
222     if (riff_id == 1) {
223         av_assert0(avi->frames_hdr_all);
224         avio_seek(pb, avi->frames_hdr_all, SEEK_SET);
225         avio_wl32(pb, nb_frames);
226     }
227     avio_seek(pb, file_size, SEEK_SET);
228 
229     return 0;
230 }
231 
write_odml_master(AVFormatContext * s,int stream_index)232 static void write_odml_master(AVFormatContext *s, int stream_index)
233 {
234     AVIOContext *pb = s->pb;
235     AVIContext *avi = s->priv_data;
236     AVStream *st = s->streams[stream_index];
237     AVCodecParameters *par = st->codecpar;
238     AVIStream *avist = st->priv_data;
239     unsigned char tag[5];
240     int j;
241 
242     /* Starting to lay out AVI OpenDML master index.
243         * We want to make it JUNK entry for now, since we'd
244         * like to get away without making AVI an OpenDML one
245         * for compatibility reasons. */
246     avist->indexes.indx_start = ff_start_tag(pb, "JUNK");
247     avio_wl16(pb, 4);   /* wLongsPerEntry */
248     avio_w8(pb, 0);     /* bIndexSubType (0 == frame index) */
249     avio_w8(pb, 0);     /* bIndexType (0 == AVI_INDEX_OF_INDEXES) */
250     avio_wl32(pb, 0);   /* nEntriesInUse (will fill out later on) */
251     ffio_wfourcc(pb, avi_stream2fourcc(tag, stream_index, par->codec_type));
252                         /* dwChunkId */
253     avio_wl64(pb, 0);   /* dwReserved[3] */
254     avio_wl32(pb, 0);   /* Must be 0.    */
255     for (j = 0; j < avi->master_index_max_size * 2; j++)
256         avio_wl64(pb, 0);
257     ff_end_tag(pb, avist->indexes.indx_start);
258 }
259 
avi_write_header(AVFormatContext * s)260 static int avi_write_header(AVFormatContext *s)
261 {
262     AVIContext *avi = s->priv_data;
263     AVIOContext *pb = s->pb;
264     int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale;
265     int64_t max_stream_duration = 0;
266     AVCodecParameters *video_par;
267     AVStream *video_st = NULL;
268     int64_t list1, list2, strh, strf;
269     AVDictionaryEntry *t = NULL;
270     int padding;
271 
272     if (s->nb_streams > AVI_MAX_STREAM_COUNT) {
273         av_log(s, AV_LOG_ERROR, "AVI does not support "
274                ">"AV_STRINGIFY(AVI_MAX_STREAM_COUNT)" streams\n");
275         return AVERROR(EINVAL);
276     }
277 
278     avi->empty_packet = av_packet_alloc();
279     if (!avi->empty_packet)
280         return AVERROR(ENOMEM);
281 
282     for (n = 0; n < s->nb_streams; n++) {
283         s->streams[n]->priv_data = av_mallocz(sizeof(AVIStream));
284         if (!s->streams[n]->priv_data)
285             return AVERROR(ENOMEM);
286     }
287 
288     /* header list */
289     avi->riff_id = 0;
290     list1 = avi_start_new_riff(s, pb, "AVI ", "hdrl");
291 
292     /* avi header */
293     ffio_wfourcc(pb, "avih");
294     avio_wl32(pb, 14 * 4);
295     bitrate = 0;
296 
297     video_par = NULL;
298     for (n = 0; n < s->nb_streams; n++) {
299         AVCodecParameters *par = s->streams[n]->codecpar;
300         AVStream *st = s->streams[n];
301         bitrate = FFMIN(bitrate + par->bit_rate, INT32_MAX);
302         if (st->duration > 0) {
303             int64_t stream_duration = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
304             max_stream_duration = FFMAX(stream_duration, max_stream_duration);
305         }
306         if (par->codec_type == AVMEDIA_TYPE_VIDEO) {
307             video_par = par;
308             video_st = st;
309         }
310     }
311 
312     /* guess master index size based on bitrate and duration */
313     if (!avi->reserve_index_space) {
314         double duration_est, filesize_est;
315         if (s->duration > 0)
316             duration_est = (double)s->duration / AV_TIME_BASE;
317         else if (max_stream_duration > 0)
318             duration_est = (double)max_stream_duration / AV_TIME_BASE;
319         else
320             duration_est = 10 * 60 * 60; /* default to 10 hours */
321         filesize_est = duration_est * (bitrate / 8) * 1.10; /* add 10% safety margin for muxer+bitrate */
322         avi->master_index_max_size = FFMAX((int)ceil(filesize_est / AVI_MAX_RIFF_SIZE) + 1,
323                                            avi->master_index_max_size);
324         av_log(s, AV_LOG_DEBUG, "duration_est:%0.3f, filesize_est:%0.1fGiB, master_index_max_size:%d\n",
325                duration_est, filesize_est / (1024*1024*1024), avi->master_index_max_size);
326     }
327 
328     nb_frames = 0;
329 
330     // TODO: should be avg_frame_rate
331     if (video_st)
332         avio_wl32(pb, (uint32_t) (INT64_C(1000000) * video_st->time_base.num /
333                                   video_st->time_base.den));
334     else
335         avio_wl32(pb, 0);
336     avio_wl32(pb, bitrate / 8); /* XXX: not quite exact */
337     avio_wl32(pb, 0); /* padding */
338     if (!(pb->seekable & AVIO_SEEKABLE_NORMAL))
339         avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_ISINTERLEAVED);  /* flags */
340     else
341         avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_HASINDEX | AVIF_ISINTERLEAVED);  /* flags */
342     avi->frames_hdr_all = avio_tell(pb); /* remember this offset to fill later */
343     avio_wl32(pb, nb_frames); /* nb frames, filled later */
344     avio_wl32(pb, 0); /* initial frame */
345     avio_wl32(pb, s->nb_streams); /* nb streams */
346     avio_wl32(pb, 1024 * 1024); /* suggested buffer size */
347     if (video_par) {
348         avio_wl32(pb, video_par->width);
349         avio_wl32(pb, video_par->height);
350     } else {
351         avio_wl32(pb, 0);
352         avio_wl32(pb, 0);
353     }
354     avio_wl32(pb, 0); /* reserved */
355     avio_wl32(pb, 0); /* reserved */
356     avio_wl32(pb, 0); /* reserved */
357     avio_wl32(pb, 0); /* reserved */
358 
359     /* stream list */
360     for (i = 0; i < n; i++) {
361         AVStream *st = s->streams[i];
362         AVCodecParameters *par = st->codecpar;
363         AVIStream *avist = st->priv_data;
364         list2 = ff_start_tag(pb, "LIST");
365         ffio_wfourcc(pb, "strl");
366 
367         /* stream generic header */
368         strh = ff_start_tag(pb, "strh");
369         switch (par->codec_type) {
370         case AVMEDIA_TYPE_SUBTITLE:
371             // XSUB subtitles behave like video tracks, other subtitles
372             // are not (yet) supported.
373             if (par->codec_id != AV_CODEC_ID_XSUB) {
374                 avpriv_report_missing_feature(s, "Subtitle streams other than DivX XSUB");
375                 return AVERROR_PATCHWELCOME;
376             }
377         case AVMEDIA_TYPE_VIDEO:
378             ffio_wfourcc(pb, "vids");
379             break;
380         case AVMEDIA_TYPE_AUDIO:
381             ffio_wfourcc(pb, "auds");
382             break;
383 //      case AVMEDIA_TYPE_TEXT:
384 //          ffio_wfourcc(pb, "txts");
385 //          break;
386         case AVMEDIA_TYPE_DATA:
387             ffio_wfourcc(pb, "dats");
388             break;
389         }
390         if (par->codec_type == AVMEDIA_TYPE_VIDEO ||
391             par->codec_id == AV_CODEC_ID_XSUB)
392             avio_wl32(pb, par->codec_tag);
393         else
394             avio_wl32(pb, 1);
395         avist->strh_flags_offset = avio_tell(pb);
396         avio_wl32(pb, 0); /* flags */
397         avio_wl16(pb, 0); /* priority */
398         avio_wl16(pb, 0); /* language */
399         avio_wl32(pb, 0); /* initial frame */
400 
401         ff_parse_specific_params(st, &au_byterate, &au_ssize, &au_scale);
402 
403         if (   par->codec_type == AVMEDIA_TYPE_VIDEO
404             && par->codec_id != AV_CODEC_ID_XSUB
405             && au_byterate > 1000LL*au_scale) {
406             au_byterate = 600;
407             au_scale    = 1;
408         }
409         avpriv_set_pts_info(st, 64, au_scale, au_byterate);
410         if (par->codec_id == AV_CODEC_ID_XSUB)
411             au_scale = au_byterate = 0;
412 
413         avio_wl32(pb, au_scale); /* scale */
414         avio_wl32(pb, au_byterate); /* rate */
415 
416         avio_wl32(pb, 0); /* start */
417         /* remember this offset to fill later */
418         avist->frames_hdr_strm = avio_tell(pb);
419         if (!(pb->seekable & AVIO_SEEKABLE_NORMAL))
420             /* FIXME: this may be broken, but who cares */
421             avio_wl32(pb, AVI_MAX_RIFF_SIZE);
422         else
423             avio_wl32(pb, 0);  /* length, XXX: filled later */
424 
425         /* suggested buffer size, is set to largest chunk size in avi_write_trailer */
426         if (par->codec_type == AVMEDIA_TYPE_VIDEO)
427             avio_wl32(pb, 1024 * 1024);
428         else if (par->codec_type == AVMEDIA_TYPE_AUDIO)
429             avio_wl32(pb, 12 * 1024);
430         else
431             avio_wl32(pb, 0);
432         avio_wl32(pb, -1); /* quality */
433         avio_wl32(pb, au_ssize); /* sample size */
434         avio_wl32(pb, 0);
435         avio_wl16(pb, par->width);
436         avio_wl16(pb, par->height);
437         ff_end_tag(pb, strh);
438 
439         if (par->codec_type != AVMEDIA_TYPE_DATA) {
440             int ret, flags;
441             enum AVPixelFormat pix_fmt;
442 
443             strf = ff_start_tag(pb, "strf");
444             switch (par->codec_type) {
445             case AVMEDIA_TYPE_SUBTITLE:
446                 /* XSUB subtitles behave like video tracks, other subtitles
447                  * are not (yet) supported. */
448                 if (par->codec_id != AV_CODEC_ID_XSUB)
449                     break;
450             case AVMEDIA_TYPE_VIDEO:
451                 /* WMP expects RGB 5:5:5 rawvideo in avi to have bpp set to 16. */
452                 if (  !par->codec_tag
453                     && par->codec_id == AV_CODEC_ID_RAWVIDEO
454                     && par->format == AV_PIX_FMT_RGB555LE
455                     && par->bits_per_coded_sample == 15)
456                     par->bits_per_coded_sample = 16;
457                 avist->pal_offset = avio_tell(pb) + 40;
458                 ff_put_bmp_header(pb, par, 0, 0, avi->flipped_raw_rgb);
459                 pix_fmt = avpriv_find_pix_fmt(avpriv_pix_fmt_bps_avi,
460                                               par->bits_per_coded_sample);
461                 if (   !par->codec_tag
462                     && par->codec_id == AV_CODEC_ID_RAWVIDEO
463                     && par->format != pix_fmt
464                     && par->format != AV_PIX_FMT_NONE)
465                     av_log(s, AV_LOG_ERROR, "%s rawvideo cannot be written to avi, output file will be unreadable\n",
466                           av_get_pix_fmt_name(par->format));
467 
468                 if (par->format == AV_PIX_FMT_PAL8) {
469                     if (par->bits_per_coded_sample < 0 || par->bits_per_coded_sample > 8) {
470                         av_log(s, AV_LOG_ERROR, "PAL8 with %d bps is not allowed\n", par->bits_per_coded_sample);
471                         return AVERROR(EINVAL);
472                     }
473                 }
474 
475                 break;
476             case AVMEDIA_TYPE_AUDIO:
477                 flags = (avi->write_channel_mask == 0) ? FF_PUT_WAV_HEADER_SKIP_CHANNELMASK : 0;
478                 if ((ret = ff_put_wav_header(s, pb, par, flags)) < 0)
479                     return ret;
480                 break;
481             default:
482                 av_log(s, AV_LOG_ERROR,
483                     "Invalid or not supported codec type '%s' found in the input\n",
484                     (char *)av_x_if_null(av_get_media_type_string(par->codec_type), "?"));
485                 return AVERROR(EINVAL);
486             }
487             ff_end_tag(pb, strf);
488             if ((t = av_dict_get(st->metadata, "title", NULL, 0))) {
489                 ff_riff_write_info_tag(s->pb, "strn", t->value);
490                 t = NULL;
491             }
492             if (par->codec_id == AV_CODEC_ID_XSUB
493             && (t = av_dict_get(s->streams[i]->metadata, "language", NULL, 0))) {
494                 const char* langstr = ff_convert_lang_to(t->value, AV_LANG_ISO639_1);
495                 t = NULL;
496                 if (langstr) {
497                     char* str = av_asprintf("Subtitle - %s-xx;02", langstr);
498                     if (!str)
499                         return AVERROR(ENOMEM);
500                     ff_riff_write_info_tag(s->pb, "strn", str);
501                     av_free(str);
502                 }
503             }
504         }
505 
506         if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
507             write_odml_master(s, i);
508         }
509 
510         if (par->codec_type == AVMEDIA_TYPE_VIDEO   &&
511             st->sample_aspect_ratio.num > 0 &&
512             st->sample_aspect_ratio.den > 0) {
513             int vprp       = ff_start_tag(pb, "vprp");
514             AVRational dar = av_mul_q(st->sample_aspect_ratio,
515                                       (AVRational) { par->width,
516                                                      par->height });
517             int num, den, fields, i;
518             av_reduce(&num, &den, dar.num, dar.den, 0xFFFF);
519             if (par->field_order == AV_FIELD_TT || par->field_order == AV_FIELD_BB ||
520                 par->field_order == AV_FIELD_TB || par->field_order == AV_FIELD_BT) {
521                 fields = 2; // interlaced
522             } else {
523                 fields = 1; // progressive
524             }
525 
526             avio_wl32(pb, 0); // video format   = unknown
527             avio_wl32(pb, 0); // video standard = unknown
528             // TODO: should be avg_frame_rate
529             avio_wl32(pb, (2LL*st->time_base.den + st->time_base.num - 1) / (2LL * st->time_base.num));
530             avio_wl32(pb, par->width);
531             avio_wl32(pb, par->height);
532             avio_wl16(pb, den);
533             avio_wl16(pb, num);
534             avio_wl32(pb, par->width);
535             avio_wl32(pb, par->height);
536             avio_wl32(pb, fields); // fields per frame
537 
538             for (i = 0; i < fields; i++) {
539                 int start_line;
540                 // OpenDML v1.02 is not very specific on what value to use for
541                 // start_line when frame data is not coming from a capturing device,
542                 // so just use 0/1 depending on the field order for interlaced frames
543                 if (par->field_order == AV_FIELD_TT || par->field_order == AV_FIELD_TB) {
544                     start_line = (i == 0) ? 0 : 1;
545                 } else if (par->field_order == AV_FIELD_BB || par->field_order == AV_FIELD_BT) {
546                     start_line = (i == 0) ? 1 : 0;
547                 } else {
548                     start_line = 0;
549                 }
550 
551                 avio_wl32(pb, par->height / fields); // compressed bitmap height
552                 avio_wl32(pb, par->width);           // compressed bitmap width
553                 avio_wl32(pb, par->height / fields); // valid bitmap height
554                 avio_wl32(pb, par->width);           // valid bitmap width
555                 avio_wl32(pb, 0);                    // valid bitmap X offset
556                 avio_wl32(pb, 0);                    // valid bitmap Y offset
557                 avio_wl32(pb, 0);                    // valid X offset in T
558                 avio_wl32(pb, start_line);           // valid Y start line
559             }
560             ff_end_tag(pb, vprp);
561         }
562 
563         ff_end_tag(pb, list2);
564     }
565 
566     if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
567         /* AVI could become an OpenDML one, if it grows beyond 2Gb range */
568         avi->odml_list = ff_start_tag(pb, "JUNK");
569         ffio_wfourcc(pb, "odml");
570         ffio_wfourcc(pb, "dmlh");
571         avio_wl32(pb, 248);
572         for (i = 0; i < 248; i += 4)
573             avio_wl32(pb, 0);
574         ff_end_tag(pb, avi->odml_list);
575     }
576 
577     ff_end_tag(pb, list1);
578 
579     ff_riff_write_info(s);
580 
581 
582     padding = s->metadata_header_padding;
583     if (padding < 0)
584         padding = 1016;
585 
586     /* some padding for easier tag editing */
587     if (padding) {
588         list2 = ff_start_tag(pb, "JUNK");
589         for (i = padding; i > 0; i -= 4)
590             avio_wl32(pb, 0);
591         ff_end_tag(pb, list2);
592     }
593 
594     avi->movi_list = ff_start_tag(pb, "LIST");
595     ffio_wfourcc(pb, "movi");
596 
597     return 0;
598 }
599 
update_odml_entry(AVFormatContext * s,int stream_index,int64_t ix,int size)600 static void update_odml_entry(AVFormatContext *s, int stream_index, int64_t ix, int size)
601 {
602     AVIOContext *pb = s->pb;
603     AVIContext *avi = s->priv_data;
604     AVIStream *avist = s->streams[stream_index]->priv_data;
605     int64_t pos;
606     int au_byterate, au_ssize, au_scale;
607 
608     pos = avio_tell(pb);
609 
610     /* Updating one entry in the AVI OpenDML master index */
611     avio_seek(pb, avist->indexes.indx_start - 8, SEEK_SET);
612     ffio_wfourcc(pb, "indx");             /* enabling this entry */
613     avio_skip(pb, 8);
614     avio_wl32(pb, avi->riff_id - avist->indexes.master_odml_riff_id_base);          /* nEntriesInUse */
615     avio_skip(pb, 16 * (avi->riff_id - avist->indexes.master_odml_riff_id_base));
616     avio_wl64(pb, ix);                    /* qwOffset */
617     avio_wl32(pb, size);                  /* dwSize */
618     ff_parse_specific_params(s->streams[stream_index], &au_byterate, &au_ssize, &au_scale);
619     if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && au_ssize > 0) {
620         uint32_t audio_segm_size = (avist->audio_strm_length - avist->indexes.audio_strm_offset);
621         if ((audio_segm_size % au_ssize > 0) && !avist->sample_requested) {
622             avpriv_request_sample(s, "OpenDML index duration for audio packets with partial frames");
623             avist->sample_requested = 1;
624         }
625         avio_wl32(pb, audio_segm_size / au_ssize);  /* dwDuration (sample count) */
626     } else
627         avio_wl32(pb, avist->indexes.entry);  /* dwDuration (packet count) */
628 
629     avio_seek(pb, pos, SEEK_SET);
630 }
631 
avi_write_ix(AVFormatContext * s)632 static int avi_write_ix(AVFormatContext *s)
633 {
634     AVIOContext *pb = s->pb;
635     AVIContext *avi = s->priv_data;
636     char tag[5];
637     char ix_tag[] = "ix00";
638     int i, j;
639 
640     av_assert0(pb->seekable & AVIO_SEEKABLE_NORMAL);
641 
642     for (i = 0; i < s->nb_streams; i++) {
643         AVIStream *avist = s->streams[i]->priv_data;
644         if (avi->riff_id - avist->indexes.master_odml_riff_id_base == avi->master_index_max_size) {
645             int64_t pos;
646             int size = AVI_MASTER_INDEX_PREFIX_SIZE + AVI_MASTER_INDEX_ENTRY_SIZE * avi->master_index_max_size;
647 
648             pos = avio_tell(pb);
649             update_odml_entry(s, i, pos, size);
650             write_odml_master(s, i);
651             av_assert1(avio_tell(pb) - pos == size);
652             avist->indexes.master_odml_riff_id_base = avi->riff_id - 1;
653         }
654         av_assert0(avi->riff_id - avist->indexes.master_odml_riff_id_base < avi->master_index_max_size);
655     }
656 
657     for (i = 0; i < s->nb_streams; i++) {
658         AVIStream *avist = s->streams[i]->priv_data;
659         int64_t ix;
660 
661         avi_stream2fourcc(tag, i, s->streams[i]->codecpar->codec_type);
662         ix_tag[3] = '0' + i;
663 
664         /* Writing AVI OpenDML leaf index chunk */
665         ix = avio_tell(pb);
666         ffio_wfourcc(pb, ix_tag);      /* ix?? */
667         avio_wl32(pb, avist->indexes.entry * 8 + 24);
668         /* chunk size */
669         avio_wl16(pb, 2);           /* wLongsPerEntry */
670         avio_w8(pb, 0);             /* bIndexSubType (0 == frame index) */
671         avio_w8(pb, 1);             /* bIndexType (1 == AVI_INDEX_OF_CHUNKS) */
672         avio_wl32(pb, avist->indexes.entry);
673         /* nEntriesInUse */
674         ffio_wfourcc(pb, tag);         /* dwChunkId */
675         avio_wl64(pb, avi->movi_list); /* qwBaseOffset */
676         avio_wl32(pb, 0);              /* dwReserved_3 (must be 0) */
677 
678         for (j = 0; j < avist->indexes.entry; j++) {
679             AVIIentry *ie = avi_get_ientry(&avist->indexes, j);
680             avio_wl32(pb, ie->pos + 8);
681             avio_wl32(pb, ((uint32_t) ie->len & ~0x80000000) |
682                           (ie->flags & 0x10 ? 0 : 0x80000000));
683         }
684 
685         update_odml_entry(s, i, ix, avio_tell(pb) - ix);
686     }
687     return 0;
688 }
689 
avi_write_idx1(AVFormatContext * s)690 static int avi_write_idx1(AVFormatContext *s)
691 {
692     AVIOContext *pb = s->pb;
693     AVIContext *avi = s->priv_data;
694     int64_t idx_chunk;
695     int i;
696     char tag[5];
697 
698     if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
699         AVIStream *avist;
700         AVIIentry *ie = 0, *tie;
701         int empty, stream_id = -1;
702 
703         idx_chunk = ff_start_tag(pb, "idx1");
704         for (i = 0; i < s->nb_streams; i++) {
705             avist        = s->streams[i]->priv_data;
706             avist->entry = 0;
707         }
708 
709         do {
710             empty = 1;
711             for (i = 0; i < s->nb_streams; i++) {
712                 avist = s->streams[i]->priv_data;
713                 if (avist->indexes.entry <= avist->entry)
714                     continue;
715 
716                 tie = avi_get_ientry(&avist->indexes, avist->entry);
717                 if (empty || tie->pos < ie->pos) {
718                     ie        = tie;
719                     stream_id = i;
720                 }
721                 empty = 0;
722             }
723             if (!empty) {
724                 avist = s->streams[stream_id]->priv_data;
725                 if (*ie->tag)
726                     ffio_wfourcc(pb, ie->tag);
727                 else {
728                     avi_stream2fourcc(tag, stream_id,
729                                   s->streams[stream_id]->codecpar->codec_type);
730                     ffio_wfourcc(pb, tag);
731                 }
732                 avio_wl32(pb, ie->flags);
733                 avio_wl32(pb, ie->pos);
734                 avio_wl32(pb, ie->len);
735                 avist->entry++;
736             }
737         } while (!empty);
738         ff_end_tag(pb, idx_chunk);
739 
740         avi_write_counters(s, avi->riff_id);
741     }
742     return 0;
743 }
744 
write_skip_frames(AVFormatContext * s,int stream_index,int64_t dts)745 static int write_skip_frames(AVFormatContext *s, int stream_index, int64_t dts)
746 {
747     AVIContext *avi = s->priv_data;
748     AVIStream *avist    = s->streams[stream_index]->priv_data;
749     AVCodecParameters *par = s->streams[stream_index]->codecpar;
750 
751     ff_dlog(s, "dts:%s packet_count:%d stream_index:%d\n", av_ts2str(dts), avist->packet_count, stream_index);
752     while (par->block_align == 0 && dts != AV_NOPTS_VALUE &&
753            dts > avist->packet_count && par->codec_id != AV_CODEC_ID_XSUB && avist->packet_count) {
754 
755         if (dts - avist->packet_count > 60000) {
756             av_log(s, AV_LOG_ERROR, "Too large number of skipped frames %"PRId64" > 60000\n", dts - avist->packet_count);
757             return AVERROR(EINVAL);
758         }
759 
760         avi->empty_packet->stream_index = stream_index;
761         avi_write_packet_internal(s, avi->empty_packet);
762         ff_dlog(s, "dup dts:%s packet_count:%d\n", av_ts2str(dts), avist->packet_count);
763     }
764 
765     return 0;
766 }
767 
avi_write_packet(AVFormatContext * s,AVPacket * pkt)768 static int avi_write_packet(AVFormatContext *s, AVPacket *pkt)
769 {
770     const int stream_index = pkt->stream_index;
771     AVCodecParameters *par = s->streams[stream_index]->codecpar;
772     int ret;
773 
774     if (par->codec_id == AV_CODEC_ID_H264 && par->codec_tag == MKTAG('H','2','6','4') && pkt->size) {
775         ret = ff_check_h264_startcode(s, s->streams[stream_index], pkt);
776         if (ret < 0)
777             return ret;
778     }
779 
780     if ((ret = write_skip_frames(s, stream_index, pkt->dts)) < 0)
781         return ret;
782 
783     if (!pkt->size)
784         return avi_write_packet_internal(s, pkt); /* Passthrough */
785 
786     if (par->codec_type == AVMEDIA_TYPE_VIDEO) {
787         AVIStream *avist = s->streams[stream_index]->priv_data;
788         AVIOContext *pb  = s->pb;
789         AVPacket *opkt   = pkt;
790         int reshuffle_ret;
791         if (par->codec_id == AV_CODEC_ID_RAWVIDEO && par->codec_tag == 0) {
792             int64_t bpc = par->bits_per_coded_sample != 15 ? par->bits_per_coded_sample : 16;
793             int expected_stride = ((par->width * bpc + 31) >> 5)*4;
794             reshuffle_ret = ff_reshuffle_raw_rgb(s, &pkt, par, expected_stride);
795             if (reshuffle_ret < 0)
796                 return reshuffle_ret;
797         } else
798             reshuffle_ret = 0;
799         if (par->format == AV_PIX_FMT_PAL8) {
800             ret = ff_get_packet_palette(s, opkt, reshuffle_ret, avist->palette);
801             if (ret < 0)
802                 goto fail;
803             if (ret) {
804                 int pal_size = 1 << par->bits_per_coded_sample;
805                 int pc_tag, i;
806 
807                 av_assert0(par->bits_per_coded_sample >= 0 && par->bits_per_coded_sample <= 8);
808 
809                 if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && avist->pal_offset) {
810                     int64_t cur_offset = avio_tell(pb);
811                     avio_seek(pb, avist->pal_offset, SEEK_SET);
812                     for (i = 0; i < pal_size; i++) {
813                         uint32_t v = avist->palette[i];
814                         avio_wl32(pb, v & 0xffffff);
815                     }
816                     avio_seek(pb, cur_offset, SEEK_SET);
817                     memcpy(avist->old_palette, avist->palette, pal_size * 4);
818                     avist->pal_offset = 0;
819                 }
820                 if (memcmp(avist->palette, avist->old_palette, pal_size * 4)) {
821                     unsigned char tag[5];
822                     avi_stream2fourcc(tag, stream_index, par->codec_type);
823                     tag[2] = 'p'; tag[3] = 'c';
824                     if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) {
825                         if (avist->strh_flags_offset) {
826                             int64_t cur_offset = avio_tell(pb);
827                             avio_seek(pb, avist->strh_flags_offset, SEEK_SET);
828                             avio_wl32(pb, AVISF_VIDEO_PALCHANGES);
829                             avio_seek(pb, cur_offset, SEEK_SET);
830                             avist->strh_flags_offset = 0;
831                         }
832                         ret = avi_add_ientry(s, stream_index, tag, AVIIF_NO_TIME,
833                                        pal_size * 4 + 4);
834                         if (ret < 0)
835                             goto fail;
836                     }
837                     pc_tag = ff_start_tag(pb, tag);
838                     avio_w8(pb, 0);
839                     avio_w8(pb, pal_size & 0xFF);
840                     avio_wl16(pb, 0); // reserved
841                     for (i = 0; i < pal_size; i++) {
842                         uint32_t v = avist->palette[i];
843                         avio_wb32(pb, v<<8);
844                     }
845                     ff_end_tag(pb, pc_tag);
846                     memcpy(avist->old_palette, avist->palette, pal_size * 4);
847                 }
848             }
849         }
850         if (reshuffle_ret) {
851             ret = avi_write_packet_internal(s, pkt);
852 
853 fail:
854             if (reshuffle_ret)
855                 av_packet_free(&pkt);
856             return ret;
857         }
858     }
859 
860     return avi_write_packet_internal(s, pkt);
861 }
862 
avi_write_packet_internal(AVFormatContext * s,AVPacket * pkt)863 static int avi_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
864 {
865     unsigned char tag[5];
866     unsigned int flags = 0;
867     const int stream_index = pkt->stream_index;
868     int size               = pkt->size;
869     AVIContext *avi     = s->priv_data;
870     AVIOContext *pb     = s->pb;
871     AVIStream *avist    = s->streams[stream_index]->priv_data;
872     AVCodecParameters *par = s->streams[stream_index]->codecpar;
873 
874     if (pkt->dts != AV_NOPTS_VALUE)
875         avist->last_dts = pkt->dts + pkt->duration;
876 
877     avist->packet_count++;
878 
879     // Make sure to put an OpenDML chunk when the file size exceeds the limits
880     if ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
881         (avio_tell(pb) - avi->riff_start > AVI_MAX_RIFF_SIZE)) {
882         avi_write_ix(s);
883         ff_end_tag(pb, avi->movi_list);
884 
885         if (avi->riff_id == 1)
886             avi_write_idx1(s);
887 
888         ff_end_tag(pb, avi->riff_start);
889         avi->movi_list = avi_start_new_riff(s, pb, "AVIX", "movi");
890     }
891 
892     avi_stream2fourcc(tag, stream_index, par->codec_type);
893     if (pkt->flags & AV_PKT_FLAG_KEY)
894         flags = 0x10;
895     if (par->codec_type == AVMEDIA_TYPE_AUDIO)
896         avist->audio_strm_length += size;
897 
898     if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) {
899         int ret;
900         ret = avi_add_ientry(s, stream_index, NULL, flags, size);
901         if (ret < 0)
902             return ret;
903     }
904 
905     avio_write(pb, tag, 4);
906     avio_wl32(pb, size);
907     avio_write(pb, pkt->data, size);
908     if (size & 1)
909         avio_w8(pb, 0);
910 
911     return 0;
912 }
913 
avi_write_trailer(AVFormatContext * s)914 static int avi_write_trailer(AVFormatContext *s)
915 {
916     AVIContext *avi = s->priv_data;
917     AVIOContext *pb = s->pb;
918     int res = 0;
919     int i, n, nb_frames;
920     int64_t file_size;
921 
922     for (i = 0; i < s->nb_streams; i++) {
923         AVIStream *avist = s->streams[i]->priv_data;
924         write_skip_frames(s, i, avist->last_dts);
925     }
926 
927     if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
928         if (avi->riff_id == 1) {
929             ff_end_tag(pb, avi->movi_list);
930             res = avi_write_idx1(s);
931             ff_end_tag(pb, avi->riff_start);
932         } else {
933             avi_write_ix(s);
934             ff_end_tag(pb, avi->movi_list);
935             ff_end_tag(pb, avi->riff_start);
936 
937             file_size = avio_tell(pb);
938             avio_seek(pb, avi->odml_list - 8, SEEK_SET);
939             ffio_wfourcc(pb, "LIST"); /* Making this AVI OpenDML one */
940             avio_skip(pb, 16);
941 
942             for (n = nb_frames = 0; n < s->nb_streams; n++) {
943                 AVCodecParameters *par = s->streams[n]->codecpar;
944                 AVIStream *avist       = s->streams[n]->priv_data;
945 
946                 if (par->codec_type == AVMEDIA_TYPE_VIDEO) {
947                     if (nb_frames < avist->packet_count)
948                         nb_frames = avist->packet_count;
949                 } else {
950                     if (par->codec_id == AV_CODEC_ID_MP2 ||
951                         par->codec_id == AV_CODEC_ID_MP3)
952                         nb_frames += avist->packet_count;
953                 }
954             }
955             avio_wl32(pb, nb_frames);
956             avio_seek(pb, file_size, SEEK_SET);
957 
958             avi_write_counters(s, avi->riff_id);
959         }
960     }
961 
962     if (avi->riff_id >= avi->master_index_max_size) {
963         int index_space = AVI_MASTER_INDEX_PREFIX_SIZE +
964                           AVI_MASTER_INDEX_ENTRY_SIZE * avi->riff_id;
965         av_log(s, AV_LOG_WARNING, "Output file not strictly OpenDML compliant, "
966                "consider re-muxing with 'reserve_index_space' option value >= %d\n",
967                index_space);
968     }
969 
970     for (i = 0; i < s->nb_streams; i++) {
971         AVIStream *avist = s->streams[i]->priv_data;
972         if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
973             avio_seek(pb, avist->frames_hdr_strm + 4, SEEK_SET);
974             avio_wl32(pb, avist->max_size);
975         }
976     }
977 
978     return res;
979 }
980 
avi_deinit(AVFormatContext * s)981 static void avi_deinit(AVFormatContext *s)
982 {
983     AVIContext *avi = s->priv_data;
984 
985     av_packet_free(&avi->empty_packet);
986 
987     for (int i = 0; i < s->nb_streams; i++) {
988         AVIStream *avist = s->streams[i]->priv_data;
989         if (!avist)
990             continue;
991         for (int j = 0; j < avist->indexes.ents_allocated / AVI_INDEX_CLUSTER_SIZE; j++)
992             av_freep(&avist->indexes.cluster[j]);
993         av_freep(&avist->indexes.cluster);
994         avist->indexes.ents_allocated = avist->indexes.entry = 0;
995     }
996 }
997 
998 #define OFFSET(x) offsetof(AVIContext, x)
999 #define ENC AV_OPT_FLAG_ENCODING_PARAM
1000 static const AVOption options[] = {
1001     { "reserve_index_space", "reserve space (in bytes) at the beginning of the file for each stream index", OFFSET(reserve_index_space), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, ENC },
1002     { "write_channel_mask", "write channel mask into wave format header", OFFSET(write_channel_mask), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, ENC },
1003     { "flipped_raw_rgb", "Raw RGB bitmaps are stored bottom-up", OFFSET(flipped_raw_rgb), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC },
1004     { NULL },
1005 };
1006 
1007 static const AVClass avi_muxer_class = {
1008     .class_name = "AVI muxer",
1009     .item_name  = av_default_item_name,
1010     .option     = options,
1011     .version    = LIBAVUTIL_VERSION_INT,
1012 };
1013 
1014 AVOutputFormat ff_avi_muxer = {
1015     .name           = "avi",
1016     .long_name      = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),
1017     .mime_type      = "video/x-msvideo",
1018     .extensions     = "avi",
1019     .priv_data_size = sizeof(AVIContext),
1020     .audio_codec    = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_AC3,
1021     .video_codec    = AV_CODEC_ID_MPEG4,
1022     .init           = avi_init,
1023     .deinit         = avi_deinit,
1024     .write_header   = avi_write_header,
1025     .write_packet   = avi_write_packet,
1026     .write_trailer  = avi_write_trailer,
1027     .codec_tag      = ff_riff_codec_tags_list,
1028     .priv_class     = &avi_muxer_class,
1029 };
1030