Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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