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

Generated by: LCOV version 1.12