Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * FLV muxer
  3.  * Copyright (c) 2003 The FFmpeg Project
  4.  *
  5.  * This file is part of FFmpeg.
  6.  *
  7.  * FFmpeg is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * FFmpeg is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with FFmpeg; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20.  */
  21.  
  22. #include "libavutil/intreadwrite.h"
  23. #include "libavutil/dict.h"
  24. #include "libavutil/intfloat.h"
  25. #include "libavutil/avassert.h"
  26. #include "avc.h"
  27. #include "avformat.h"
  28. #include "flv.h"
  29. #include "internal.h"
  30. #include "metadata.h"
  31.  
  32.  
  33. static const AVCodecTag flv_video_codec_ids[] = {
  34.     { AV_CODEC_ID_FLV1,     FLV_CODECID_H263 },
  35.     { AV_CODEC_ID_H263,     FLV_CODECID_REALH263 },
  36.     { AV_CODEC_ID_MPEG4,    FLV_CODECID_MPEG4 },
  37.     { AV_CODEC_ID_FLASHSV,  FLV_CODECID_SCREEN },
  38.     { AV_CODEC_ID_FLASHSV2, FLV_CODECID_SCREEN2 },
  39.     { AV_CODEC_ID_VP6F,     FLV_CODECID_VP6 },
  40.     { AV_CODEC_ID_VP6,      FLV_CODECID_VP6 },
  41.     { AV_CODEC_ID_VP6A,     FLV_CODECID_VP6A },
  42.     { AV_CODEC_ID_H264,     FLV_CODECID_H264 },
  43.     { AV_CODEC_ID_NONE,     0 }
  44. };
  45.  
  46. static const AVCodecTag flv_audio_codec_ids[] = {
  47.     { AV_CODEC_ID_MP3,        FLV_CODECID_MP3        >> FLV_AUDIO_CODECID_OFFSET },
  48.     { AV_CODEC_ID_PCM_U8,     FLV_CODECID_PCM        >> FLV_AUDIO_CODECID_OFFSET },
  49.     { AV_CODEC_ID_PCM_S16BE,  FLV_CODECID_PCM        >> FLV_AUDIO_CODECID_OFFSET },
  50.     { AV_CODEC_ID_PCM_S16LE,  FLV_CODECID_PCM_LE     >> FLV_AUDIO_CODECID_OFFSET },
  51.     { AV_CODEC_ID_ADPCM_SWF,  FLV_CODECID_ADPCM      >> FLV_AUDIO_CODECID_OFFSET },
  52.     { AV_CODEC_ID_AAC,        FLV_CODECID_AAC        >> FLV_AUDIO_CODECID_OFFSET },
  53.     { AV_CODEC_ID_NELLYMOSER, FLV_CODECID_NELLYMOSER >> FLV_AUDIO_CODECID_OFFSET },
  54.     { AV_CODEC_ID_PCM_MULAW,  FLV_CODECID_PCM_MULAW  >> FLV_AUDIO_CODECID_OFFSET },
  55.     { AV_CODEC_ID_PCM_ALAW,   FLV_CODECID_PCM_ALAW   >> FLV_AUDIO_CODECID_OFFSET },
  56.     { AV_CODEC_ID_SPEEX,      FLV_CODECID_SPEEX      >> FLV_AUDIO_CODECID_OFFSET },
  57.     { AV_CODEC_ID_NONE,       0 }
  58. };
  59.  
  60. typedef struct FLVContext {
  61.     int     reserved;
  62.     int64_t duration_offset;
  63.     int64_t filesize_offset;
  64.     int64_t duration;
  65.     int64_t delay;      ///< first dts delay (needed for AVC & Speex)
  66.  
  67.     AVCodecContext *audio_enc;
  68.     AVCodecContext *video_enc;
  69.     double framerate;
  70.     AVCodecContext *data_enc;
  71. } FLVContext;
  72.  
  73. typedef struct FLVStreamContext {
  74.     int64_t last_ts;    ///< last timestamp for each stream
  75. } FLVStreamContext;
  76.  
  77. static int get_audio_flags(AVFormatContext *s, AVCodecContext *enc)
  78. {
  79.     int flags = (enc->bits_per_coded_sample == 16) ? FLV_SAMPLESSIZE_16BIT
  80.                                                    : FLV_SAMPLESSIZE_8BIT;
  81.  
  82.     if (enc->codec_id == AV_CODEC_ID_AAC) // specs force these parameters
  83.         return FLV_CODECID_AAC | FLV_SAMPLERATE_44100HZ |
  84.                FLV_SAMPLESSIZE_16BIT | FLV_STEREO;
  85.     else if (enc->codec_id == AV_CODEC_ID_SPEEX) {
  86.         if (enc->sample_rate != 16000) {
  87.             av_log(s, AV_LOG_ERROR,
  88.                    "FLV only supports wideband (16kHz) Speex audio\n");
  89.             return AVERROR(EINVAL);
  90.         }
  91.         if (enc->channels != 1) {
  92.             av_log(s, AV_LOG_ERROR, "FLV only supports mono Speex audio\n");
  93.             return AVERROR(EINVAL);
  94.         }
  95.         return FLV_CODECID_SPEEX | FLV_SAMPLERATE_11025HZ | FLV_SAMPLESSIZE_16BIT;
  96.     } else {
  97.         switch (enc->sample_rate) {
  98.         case 44100:
  99.             flags |= FLV_SAMPLERATE_44100HZ;
  100.             break;
  101.         case 22050:
  102.             flags |= FLV_SAMPLERATE_22050HZ;
  103.             break;
  104.         case 11025:
  105.             flags |= FLV_SAMPLERATE_11025HZ;
  106.             break;
  107.         case 16000: // nellymoser only
  108.         case  8000: // nellymoser only
  109.         case  5512: // not MP3
  110.             if (enc->codec_id != AV_CODEC_ID_MP3) {
  111.                 flags |= FLV_SAMPLERATE_SPECIAL;
  112.                 break;
  113.             }
  114.         default:
  115.             av_log(s, AV_LOG_ERROR,
  116.                    "FLV does not support sample rate %d, "
  117.                    "choose from (44100, 22050, 11025)\n", enc->sample_rate);
  118.             return AVERROR(EINVAL);
  119.         }
  120.     }
  121.  
  122.     if (enc->channels > 1)
  123.         flags |= FLV_STEREO;
  124.  
  125.     switch (enc->codec_id) {
  126.     case AV_CODEC_ID_MP3:
  127.         flags |= FLV_CODECID_MP3    | FLV_SAMPLESSIZE_16BIT;
  128.         break;
  129.     case AV_CODEC_ID_PCM_U8:
  130.         flags |= FLV_CODECID_PCM    | FLV_SAMPLESSIZE_8BIT;
  131.         break;
  132.     case AV_CODEC_ID_PCM_S16BE:
  133.         flags |= FLV_CODECID_PCM    | FLV_SAMPLESSIZE_16BIT;
  134.         break;
  135.     case AV_CODEC_ID_PCM_S16LE:
  136.         flags |= FLV_CODECID_PCM_LE | FLV_SAMPLESSIZE_16BIT;
  137.         break;
  138.     case AV_CODEC_ID_ADPCM_SWF:
  139.         flags |= FLV_CODECID_ADPCM  | FLV_SAMPLESSIZE_16BIT;
  140.         break;
  141.     case AV_CODEC_ID_NELLYMOSER:
  142.         if (enc->sample_rate == 8000)
  143.             flags |= FLV_CODECID_NELLYMOSER_8KHZ_MONO  | FLV_SAMPLESSIZE_16BIT;
  144.         else if (enc->sample_rate == 16000)
  145.             flags |= FLV_CODECID_NELLYMOSER_16KHZ_MONO | FLV_SAMPLESSIZE_16BIT;
  146.         else
  147.             flags |= FLV_CODECID_NELLYMOSER            | FLV_SAMPLESSIZE_16BIT;
  148.         break;
  149.     case AV_CODEC_ID_PCM_MULAW:
  150.         flags = FLV_CODECID_PCM_MULAW | FLV_SAMPLERATE_SPECIAL | FLV_SAMPLESSIZE_16BIT;
  151.         break;
  152.     case AV_CODEC_ID_PCM_ALAW:
  153.         flags = FLV_CODECID_PCM_ALAW  | FLV_SAMPLERATE_SPECIAL | FLV_SAMPLESSIZE_16BIT;
  154.         break;
  155.     case 0:
  156.         flags |= enc->codec_tag << 4;
  157.         break;
  158.     default:
  159.         av_log(s, AV_LOG_ERROR, "Audio codec '%s' not compatible with FLV\n",
  160.                avcodec_get_name(enc->codec_id));
  161.         return AVERROR(EINVAL);
  162.     }
  163.  
  164.     return flags;
  165. }
  166.  
  167. static void put_amf_string(AVIOContext *pb, const char *str)
  168. {
  169.     size_t len = strlen(str);
  170.     avio_wb16(pb, len);
  171.     avio_write(pb, str, len);
  172. }
  173.  
  174. static void put_avc_eos_tag(AVIOContext *pb, unsigned ts)
  175. {
  176.     avio_w8(pb, FLV_TAG_TYPE_VIDEO);
  177.     avio_wb24(pb, 5);               /* Tag Data Size */
  178.     avio_wb24(pb, ts);              /* lower 24 bits of timestamp in ms */
  179.     avio_w8(pb, (ts >> 24) & 0x7F); /* MSB of ts in ms */
  180.     avio_wb24(pb, 0);               /* StreamId = 0 */
  181.     avio_w8(pb, 23);                /* ub[4] FrameType = 1, ub[4] CodecId = 7 */
  182.     avio_w8(pb, 2);                 /* AVC end of sequence */
  183.     avio_wb24(pb, 0);               /* Always 0 for AVC EOS. */
  184.     avio_wb32(pb, 16);              /* Size of FLV tag */
  185. }
  186.  
  187. static void put_amf_double(AVIOContext *pb, double d)
  188. {
  189.     avio_w8(pb, AMF_DATA_TYPE_NUMBER);
  190.     avio_wb64(pb, av_double2int(d));
  191. }
  192.  
  193. static void put_amf_bool(AVIOContext *pb, int b)
  194. {
  195.     avio_w8(pb, AMF_DATA_TYPE_BOOL);
  196.     avio_w8(pb, !!b);
  197. }
  198.  
  199. static void write_metadata(AVFormatContext *s, unsigned int ts)
  200. {
  201.     AVIOContext *pb = s->pb;
  202.     FLVContext *flv = s->priv_data;
  203.     int metadata_count = 0;
  204.     int64_t metadata_size_pos, data_size, metadata_count_pos;
  205.     AVDictionaryEntry *tag = NULL;
  206.  
  207.     /* write meta_tag */
  208.     avio_w8(pb, 18);            // tag type META
  209.     metadata_size_pos = avio_tell(pb);
  210.     avio_wb24(pb, 0);           // size of data part (sum of all parts below)
  211.     avio_wb24(pb, ts);          // timestamp
  212.     avio_wb32(pb, 0);           // reserved
  213.  
  214.     /* now data of data_size size */
  215.  
  216.     /* first event name as a string */
  217.     avio_w8(pb, AMF_DATA_TYPE_STRING);
  218.     put_amf_string(pb, "onMetaData"); // 12 bytes
  219.  
  220.     /* mixed array (hash) with size and string/type/data tuples */
  221.     avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
  222.     metadata_count_pos = avio_tell(pb);
  223.     metadata_count = 4 * !!flv->video_enc +
  224.                      5 * !!flv->audio_enc +
  225.                      1 * !!flv->data_enc  +
  226.                      2; // +2 for duration and file size
  227.  
  228.     avio_wb32(pb, metadata_count);
  229.  
  230.     put_amf_string(pb, "duration");
  231.     flv->duration_offset = avio_tell(pb);
  232.  
  233.     // fill in the guessed duration, it'll be corrected later if incorrect
  234.     put_amf_double(pb, s->duration / AV_TIME_BASE);
  235.  
  236.     if (flv->video_enc) {
  237.         put_amf_string(pb, "width");
  238.         put_amf_double(pb, flv->video_enc->width);
  239.  
  240.         put_amf_string(pb, "height");
  241.         put_amf_double(pb, flv->video_enc->height);
  242.  
  243.         put_amf_string(pb, "videodatarate");
  244.         put_amf_double(pb, flv->video_enc->bit_rate / 1024.0);
  245.  
  246.         if (flv->framerate != 0.0) {
  247.             put_amf_string(pb, "framerate");
  248.             put_amf_double(pb, flv->framerate);
  249.             metadata_count++;
  250.         }
  251.  
  252.         put_amf_string(pb, "videocodecid");
  253.         put_amf_double(pb, flv->video_enc->codec_tag);
  254.     }
  255.  
  256.     if (flv->audio_enc) {
  257.         put_amf_string(pb, "audiodatarate");
  258.         put_amf_double(pb, flv->audio_enc->bit_rate / 1024.0);
  259.  
  260.         put_amf_string(pb, "audiosamplerate");
  261.         put_amf_double(pb, flv->audio_enc->sample_rate);
  262.  
  263.         put_amf_string(pb, "audiosamplesize");
  264.         put_amf_double(pb, flv->audio_enc->codec_id == AV_CODEC_ID_PCM_U8 ? 8 : 16);
  265.  
  266.         put_amf_string(pb, "stereo");
  267.         put_amf_bool(pb, flv->audio_enc->channels == 2);
  268.  
  269.         put_amf_string(pb, "audiocodecid");
  270.         put_amf_double(pb, flv->audio_enc->codec_tag);
  271.     }
  272.  
  273.     if (flv->data_enc) {
  274.         put_amf_string(pb, "datastream");
  275.         put_amf_double(pb, 0.0);
  276.     }
  277.  
  278.     while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
  279.         if(   !strcmp(tag->key, "width")
  280.             ||!strcmp(tag->key, "height")
  281.             ||!strcmp(tag->key, "videodatarate")
  282.             ||!strcmp(tag->key, "framerate")
  283.             ||!strcmp(tag->key, "videocodecid")
  284.             ||!strcmp(tag->key, "audiodatarate")
  285.             ||!strcmp(tag->key, "audiosamplerate")
  286.             ||!strcmp(tag->key, "audiosamplesize")
  287.             ||!strcmp(tag->key, "stereo")
  288.             ||!strcmp(tag->key, "audiocodecid")
  289.             ||!strcmp(tag->key, "duration")
  290.             ||!strcmp(tag->key, "onMetaData")
  291.             ||!strcmp(tag->key, "datasize")
  292.             ||!strcmp(tag->key, "lasttimestamp")
  293.             ||!strcmp(tag->key, "totalframes")
  294.             ||!strcmp(tag->key, "hasAudio")
  295.             ||!strcmp(tag->key, "hasVideo")
  296.             ||!strcmp(tag->key, "hasCuePoints")
  297.             ||!strcmp(tag->key, "hasMetadata")
  298.             ||!strcmp(tag->key, "hasKeyframes")
  299.         ){
  300.             av_log(s, AV_LOG_DEBUG, "Ignoring metadata for %s\n", tag->key);
  301.             continue;
  302.         }
  303.         put_amf_string(pb, tag->key);
  304.         avio_w8(pb, AMF_DATA_TYPE_STRING);
  305.         put_amf_string(pb, tag->value);
  306.         metadata_count++;
  307.     }
  308.  
  309.     put_amf_string(pb, "filesize");
  310.     flv->filesize_offset = avio_tell(pb);
  311.     put_amf_double(pb, 0); // delayed write
  312.  
  313.     put_amf_string(pb, "");
  314.     avio_w8(pb, AMF_END_OF_OBJECT);
  315.  
  316.     /* write total size of tag */
  317.     data_size = avio_tell(pb) - metadata_size_pos - 10;
  318.  
  319.     avio_seek(pb, metadata_count_pos, SEEK_SET);
  320.     avio_wb32(pb, metadata_count);
  321.  
  322.     avio_seek(pb, metadata_size_pos, SEEK_SET);
  323.     avio_wb24(pb, data_size);
  324.     avio_skip(pb, data_size + 10 - 3);
  325.     avio_wb32(pb, data_size + 11);
  326. }
  327.  
  328. static int unsupported_codec(AVFormatContext *s,
  329.                              const char* type, int codec_id)
  330. {
  331.     const AVCodecDescriptor *desc = avcodec_descriptor_get(codec_id);
  332.     av_log(s, AV_LOG_ERROR,
  333.            "%s codec %s not compatible with flv\n",
  334.             type,
  335.             desc ? desc->name : "unknown");
  336.     return AVERROR(ENOSYS);
  337. }
  338.  
  339. static int flv_write_header(AVFormatContext *s)
  340. {
  341.     int i;
  342.     AVIOContext *pb = s->pb;
  343.     FLVContext *flv = s->priv_data;
  344.     int64_t data_size;
  345.  
  346.     for (i = 0; i < s->nb_streams; i++) {
  347.         AVCodecContext *enc = s->streams[i]->codec;
  348.         FLVStreamContext *sc;
  349.         switch (enc->codec_type) {
  350.         case AVMEDIA_TYPE_VIDEO:
  351.             if (s->streams[i]->avg_frame_rate.den &&
  352.                 s->streams[i]->avg_frame_rate.num) {
  353.                 flv->framerate = av_q2d(s->streams[i]->avg_frame_rate);
  354.             }
  355.             if (flv->video_enc) {
  356.                 av_log(s, AV_LOG_ERROR,
  357.                        "at most one video stream is supported in flv\n");
  358.                 return AVERROR(EINVAL);
  359.             }
  360.             flv->video_enc = enc;
  361.             if (!ff_codec_get_tag(flv_video_codec_ids, enc->codec_id))
  362.                 return unsupported_codec(s, "Video", enc->codec_id);
  363.  
  364.             if (enc->codec_id == AV_CODEC_ID_MPEG4 ||
  365.                 enc->codec_id == AV_CODEC_ID_H263) {
  366.                 int error = s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL;
  367.                 av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING,
  368.                        "Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(enc->codec_id));
  369.  
  370.                 if (error) {
  371.                     av_log(s, AV_LOG_ERROR,
  372.                            "use vstrict=-1 / -strict -1 to use it anyway.\n");
  373.                     return AVERROR(EINVAL);
  374.                 }
  375.             } else if (enc->codec_id == AV_CODEC_ID_VP6) {
  376.                 av_log(s, AV_LOG_WARNING,
  377.                        "Muxing VP6 in flv will produce flipped video on playback.\n");
  378.             }
  379.             break;
  380.         case AVMEDIA_TYPE_AUDIO:
  381.             if (flv->audio_enc) {
  382.                 av_log(s, AV_LOG_ERROR,
  383.                        "at most one audio stream is supported in flv\n");
  384.                 return AVERROR(EINVAL);
  385.             }
  386.             flv->audio_enc = enc;
  387.             if (get_audio_flags(s, enc) < 0)
  388.                 return unsupported_codec(s, "Audio", enc->codec_id);
  389.             if (enc->codec_id == AV_CODEC_ID_PCM_S16BE)
  390.                 av_log(s, AV_LOG_WARNING,
  391.                        "16-bit big-endian audio in flv is valid but most likely unplayable (hardware dependent); use s16le\n");
  392.             break;
  393.         case AVMEDIA_TYPE_DATA:
  394.             if (enc->codec_id != AV_CODEC_ID_TEXT && enc->codec_id != AV_CODEC_ID_NONE)
  395.                 return unsupported_codec(s, "Data", enc->codec_id);
  396.             flv->data_enc = enc;
  397.             break;
  398.         case AVMEDIA_TYPE_SUBTITLE:
  399.             if (enc->codec_id != AV_CODEC_ID_TEXT) {
  400.                 av_log(s, AV_LOG_ERROR, "Subtitle codec '%s' for stream %d is not compatible with FLV\n",
  401.                        avcodec_get_name(enc->codec_id), i);
  402.                 return AVERROR_INVALIDDATA;
  403.             }
  404.             flv->data_enc = enc;
  405.             break;
  406.         default:
  407.             av_log(s, AV_LOG_ERROR, "Codec type '%s' for stream %d is not compatible with FLV\n",
  408.                    av_get_media_type_string(enc->codec_type), i);
  409.             return AVERROR(EINVAL);
  410.         }
  411.         avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */
  412.  
  413.         sc = av_mallocz(sizeof(FLVStreamContext));
  414.         if (!sc)
  415.             return AVERROR(ENOMEM);
  416.         s->streams[i]->priv_data = sc;
  417.         sc->last_ts = -1;
  418.     }
  419.  
  420.     flv->delay = AV_NOPTS_VALUE;
  421.  
  422.     avio_write(pb, "FLV", 3);
  423.     avio_w8(pb, 1);
  424.     avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!flv->audio_enc +
  425.                 FLV_HEADER_FLAG_HASVIDEO * !!flv->video_enc);
  426.     avio_wb32(pb, 9);
  427.     avio_wb32(pb, 0);
  428.  
  429.     for (i = 0; i < s->nb_streams; i++)
  430.         if (s->streams[i]->codec->codec_tag == 5) {
  431.             avio_w8(pb, 8);     // message type
  432.             avio_wb24(pb, 0);   // include flags
  433.             avio_wb24(pb, 0);   // time stamp
  434.             avio_wb32(pb, 0);   // reserved
  435.             avio_wb32(pb, 11);  // size
  436.             flv->reserved = 5;
  437.         }
  438.  
  439.     write_metadata(s, 0);
  440.  
  441.     for (i = 0; i < s->nb_streams; i++) {
  442.         AVCodecContext *enc = s->streams[i]->codec;
  443.         if (enc->codec_id == AV_CODEC_ID_AAC || enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) {
  444.             int64_t pos;
  445.             avio_w8(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ?
  446.                     FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO);
  447.             avio_wb24(pb, 0); // size patched later
  448.             avio_wb24(pb, 0); // ts
  449.             avio_w8(pb, 0);   // ts ext
  450.             avio_wb24(pb, 0); // streamid
  451.             pos = avio_tell(pb);
  452.             if (enc->codec_id == AV_CODEC_ID_AAC) {
  453.                 avio_w8(pb, get_audio_flags(s, enc));
  454.                 avio_w8(pb, 0); // AAC sequence header
  455.                 avio_write(pb, enc->extradata, enc->extradata_size);
  456.             } else {
  457.                 avio_w8(pb, enc->codec_tag | FLV_FRAME_KEY); // flags
  458.                 avio_w8(pb, 0); // AVC sequence header
  459.                 avio_wb24(pb, 0); // composition time
  460.                 ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size);
  461.             }
  462.             data_size = avio_tell(pb) - pos;
  463.             avio_seek(pb, -data_size - 10, SEEK_CUR);
  464.             avio_wb24(pb, data_size);
  465.             avio_skip(pb, data_size + 10 - 3);
  466.             avio_wb32(pb, data_size + 11); // previous tag size
  467.         }
  468.     }
  469.  
  470.     return 0;
  471. }
  472.  
  473. static int flv_write_trailer(AVFormatContext *s)
  474. {
  475.     int64_t file_size;
  476.  
  477.     AVIOContext *pb = s->pb;
  478.     FLVContext *flv = s->priv_data;
  479.     int i;
  480.  
  481.     /* Add EOS tag */
  482.     for (i = 0; i < s->nb_streams; i++) {
  483.         AVCodecContext *enc = s->streams[i]->codec;
  484.         FLVStreamContext *sc = s->streams[i]->priv_data;
  485.         if (enc->codec_type == AVMEDIA_TYPE_VIDEO &&
  486.                 (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4))
  487.             put_avc_eos_tag(pb, sc->last_ts);
  488.     }
  489.  
  490.     file_size = avio_tell(pb);
  491.  
  492.     /* update information */
  493.     if (avio_seek(pb, flv->duration_offset, SEEK_SET) < 0)
  494.         av_log(s, AV_LOG_WARNING, "Failed to update header with correct duration.\n");
  495.     else
  496.         put_amf_double(pb, flv->duration / (double)1000);
  497.     if (avio_seek(pb, flv->filesize_offset, SEEK_SET) < 0)
  498.         av_log(s, AV_LOG_WARNING, "Failed to update header with correct filesize.\n");
  499.     else
  500.         put_amf_double(pb, file_size);
  501.  
  502.     avio_seek(pb, file_size, SEEK_SET);
  503.     return 0;
  504. }
  505.  
  506. static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
  507. {
  508.     AVIOContext *pb      = s->pb;
  509.     AVCodecContext *enc  = s->streams[pkt->stream_index]->codec;
  510.     FLVContext *flv      = s->priv_data;
  511.     FLVStreamContext *sc = s->streams[pkt->stream_index]->priv_data;
  512.     unsigned ts;
  513.     int size = pkt->size;
  514.     uint8_t *data = NULL;
  515.     int flags = -1, flags_size, ret;
  516.  
  517.     if (enc->codec_id == AV_CODEC_ID_VP6F || enc->codec_id == AV_CODEC_ID_VP6A ||
  518.         enc->codec_id == AV_CODEC_ID_VP6  || enc->codec_id == AV_CODEC_ID_AAC)
  519.         flags_size = 2;
  520.     else if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4)
  521.         flags_size = 5;
  522.     else
  523.         flags_size = 1;
  524.  
  525.     if (flv->delay == AV_NOPTS_VALUE)
  526.         flv->delay = -pkt->dts;
  527.  
  528.     if (pkt->dts < -flv->delay) {
  529.         av_log(s, AV_LOG_WARNING,
  530.                "Packets are not in the proper order with respect to DTS\n");
  531.         return AVERROR(EINVAL);
  532.     }
  533.  
  534.     ts = pkt->dts + flv->delay; // add delay to force positive dts
  535.  
  536.     if (s->event_flags & AVSTREAM_EVENT_FLAG_METADATA_UPDATED) {
  537.         write_metadata(s, ts);
  538.         s->event_flags &= ~AVSTREAM_EVENT_FLAG_METADATA_UPDATED;
  539.     }
  540.  
  541.     switch (enc->codec_type) {
  542.     case AVMEDIA_TYPE_VIDEO:
  543.         avio_w8(pb, FLV_TAG_TYPE_VIDEO);
  544.  
  545.         flags = ff_codec_get_tag(flv_video_codec_ids, enc->codec_id);
  546.  
  547.         flags |= pkt->flags & AV_PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER;
  548.         break;
  549.     case AVMEDIA_TYPE_AUDIO:
  550.         flags = get_audio_flags(s, enc);
  551.  
  552.         av_assert0(size);
  553.  
  554.         avio_w8(pb, FLV_TAG_TYPE_AUDIO);
  555.         break;
  556.     case AVMEDIA_TYPE_SUBTITLE:
  557.     case AVMEDIA_TYPE_DATA:
  558.         avio_w8(pb, FLV_TAG_TYPE_META);
  559.         break;
  560.     default:
  561.         return AVERROR(EINVAL);
  562.     }
  563.  
  564.     if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) {
  565.         /* check if extradata looks like mp4 formatted */
  566.         if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1)
  567.             if ((ret = ff_avc_parse_nal_units_buf(pkt->data, &data, &size)) < 0)
  568.                 return ret;
  569.     } else if (enc->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
  570.                (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
  571.         if (!s->streams[pkt->stream_index]->nb_frames) {
  572.         av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
  573.                "use the audio bitstream filter 'aac_adtstoasc' to fix it "
  574.                "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
  575.         return AVERROR_INVALIDDATA;
  576.         }
  577.         av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
  578.     }
  579.  
  580.     /* check Speex packet duration */
  581.     if (enc->codec_id == AV_CODEC_ID_SPEEX && ts - sc->last_ts > 160)
  582.         av_log(s, AV_LOG_WARNING, "Warning: Speex stream has more than "
  583.                                   "8 frames per packet. Adobe Flash "
  584.                                   "Player cannot handle this!\n");
  585.  
  586.     if (sc->last_ts < ts)
  587.         sc->last_ts = ts;
  588.  
  589.     if (size + flags_size >= 1<<24) {
  590.         av_log(s, AV_LOG_ERROR, "Too large packet with size %u >= %u\n",
  591.                size + flags_size, 1<<24);
  592.         return AVERROR(EINVAL);
  593.     }
  594.  
  595.     avio_wb24(pb, size + flags_size);
  596.     avio_wb24(pb, ts & 0xFFFFFF);
  597.     avio_w8(pb, (ts >> 24) & 0x7F); // timestamps are 32 bits _signed_
  598.     avio_wb24(pb, flv->reserved);
  599.  
  600.     if (enc->codec_type == AVMEDIA_TYPE_DATA ||
  601.         enc->codec_type == AVMEDIA_TYPE_SUBTITLE ) {
  602.         int data_size;
  603.         int64_t metadata_size_pos = avio_tell(pb);
  604.         if (enc->codec_id == AV_CODEC_ID_TEXT) {
  605.             // legacy FFmpeg magic?
  606.             avio_w8(pb, AMF_DATA_TYPE_STRING);
  607.             put_amf_string(pb, "onTextData");
  608.             avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
  609.             avio_wb32(pb, 2);
  610.             put_amf_string(pb, "type");
  611.             avio_w8(pb, AMF_DATA_TYPE_STRING);
  612.             put_amf_string(pb, "Text");
  613.             put_amf_string(pb, "text");
  614.             avio_w8(pb, AMF_DATA_TYPE_STRING);
  615.             put_amf_string(pb, pkt->data);
  616.             put_amf_string(pb, "");
  617.             avio_w8(pb, AMF_END_OF_OBJECT);
  618.         } else {
  619.             // just pass the metadata through
  620.             avio_write(pb, data ? data : pkt->data, size);
  621.         }
  622.         /* write total size of tag */
  623.         data_size = avio_tell(pb) - metadata_size_pos;
  624.         avio_seek(pb, metadata_size_pos - 10, SEEK_SET);
  625.         avio_wb24(pb, data_size);
  626.         avio_seek(pb, data_size + 10 - 3, SEEK_CUR);
  627.         avio_wb32(pb, data_size + 11);
  628.     } else {
  629.         av_assert1(flags>=0);
  630.         avio_w8(pb,flags);
  631.         if (enc->codec_id == AV_CODEC_ID_VP6)
  632.             avio_w8(pb,0);
  633.         if (enc->codec_id == AV_CODEC_ID_VP6F || enc->codec_id == AV_CODEC_ID_VP6A) {
  634.             if (enc->extradata_size)
  635.                 avio_w8(pb, enc->extradata[0]);
  636.             else
  637.                 avio_w8(pb, ((FFALIGN(enc->width,  16) - enc->width) << 4) |
  638.                              (FFALIGN(enc->height, 16) - enc->height));
  639.         } else if (enc->codec_id == AV_CODEC_ID_AAC)
  640.             avio_w8(pb, 1); // AAC raw
  641.         else if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) {
  642.             avio_w8(pb, 1); // AVC NALU
  643.             avio_wb24(pb, pkt->pts - pkt->dts);
  644.         }
  645.  
  646.         avio_write(pb, data ? data : pkt->data, size);
  647.  
  648.         avio_wb32(pb, size + flags_size + 11); // previous tag size
  649.         flv->duration = FFMAX(flv->duration,
  650.                               pkt->pts + flv->delay + pkt->duration);
  651.     }
  652.  
  653.     av_free(data);
  654.  
  655.     return pb->error;
  656. }
  657.  
  658. AVOutputFormat ff_flv_muxer = {
  659.     .name           = "flv",
  660.     .long_name      = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),
  661.     .mime_type      = "video/x-flv",
  662.     .extensions     = "flv",
  663.     .priv_data_size = sizeof(FLVContext),
  664.     .audio_codec    = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_ADPCM_SWF,
  665.     .video_codec    = AV_CODEC_ID_FLV1,
  666.     .write_header   = flv_write_header,
  667.     .write_packet   = flv_write_packet,
  668.     .write_trailer  = flv_write_trailer,
  669.     .codec_tag      = (const AVCodecTag* const []) {
  670.                           flv_video_codec_ids, flv_audio_codec_ids, 0
  671.                       },
  672.     .flags          = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |
  673.                       AVFMT_TS_NONSTRICT,
  674. };
  675.