Subversion Repositories Kolibri OS

Rev

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