LCOV - code coverage report
Current view: top level - libavformat - avienc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 439 583 75.3 %
Date: 2017-12-16 13:57:32 Functions: 13 15 86.7 %

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

Generated by: LCOV version 1.13