]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/flvenc.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavformat / flvenc.c
index 3caa6ded99d12195fb0d482872bbb07a032b2f52..610c3fc7207732e466c5f4a0ee6374929422ab98 100644 (file)
@@ -1,41 +1,44 @@
 /*
  * FLV muxer
- * Copyright (c) 2003 The Libav Project
+ * Copyright (c) 2003 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
 #include "libavutil/intfloat.h"
+#include "libavutil/avassert.h"
 #include "avc.h"
 #include "avformat.h"
 #include "flv.h"
 #include "internal.h"
 #include "metadata.h"
 
-#undef NDEBUG
-#include <assert.h>
 
 static const AVCodecTag flv_video_codec_ids[] = {
     { CODEC_ID_FLV1,     FLV_CODECID_H263 },
+    { CODEC_ID_H263,     FLV_CODECID_REALH263 },
+    { CODEC_ID_MPEG4,    FLV_CODECID_MPEG4 },
     { CODEC_ID_FLASHSV,  FLV_CODECID_SCREEN },
     { CODEC_ID_FLASHSV2, FLV_CODECID_SCREEN2 },
     { CODEC_ID_VP6F,     FLV_CODECID_VP6 },
     { CODEC_ID_VP6,      FLV_CODECID_VP6 },
+    { CODEC_ID_VP6A,     FLV_CODECID_VP6A },
     { CODEC_ID_H264,     FLV_CODECID_H264 },
     { CODEC_ID_NONE,     0 }
 };
@@ -48,6 +51,8 @@ static const AVCodecTag flv_audio_codec_ids[] = {
     { CODEC_ID_ADPCM_SWF,  FLV_CODECID_ADPCM      >> FLV_AUDIO_CODECID_OFFSET },
     { CODEC_ID_AAC,        FLV_CODECID_AAC        >> FLV_AUDIO_CODECID_OFFSET },
     { CODEC_ID_NELLYMOSER, FLV_CODECID_NELLYMOSER >> FLV_AUDIO_CODECID_OFFSET },
+    { CODEC_ID_PCM_MULAW,  FLV_CODECID_PCM_MULAW  >> FLV_AUDIO_CODECID_OFFSET },
+    { CODEC_ID_PCM_ALAW,   FLV_CODECID_PCM_ALAW   >> FLV_AUDIO_CODECID_OFFSET },
     { CODEC_ID_SPEEX,      FLV_CODECID_SPEEX      >> FLV_AUDIO_CODECID_OFFSET },
     { CODEC_ID_NONE,       0 }
 };
@@ -136,6 +141,12 @@ static int get_audio_flags(AVFormatContext *s, AVCodecContext *enc)
         else
             flags |= FLV_CODECID_NELLYMOSER            | FLV_SAMPLESSIZE_16BIT;
         break;
+    case CODEC_ID_PCM_MULAW:
+        flags = FLV_CODECID_PCM_MULAW | FLV_SAMPLERATE_SPECIAL | FLV_SAMPLESSIZE_16BIT;
+        break;
+    case CODEC_ID_PCM_ALAW:
+        flags = FLV_CODECID_PCM_ALAW  | FLV_SAMPLERATE_SPECIAL | FLV_SAMPLESSIZE_16BIT;
+        break;
     case 0:
         flags |= enc->codec_tag << 4;
         break;
@@ -319,6 +330,22 @@ static int flv_write_header(AVFormatContext *s)
     }
 
     while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
+        if(   !strcmp(tag->key, "width")
+            ||!strcmp(tag->key, "height")
+            ||!strcmp(tag->key, "videodatarate")
+            ||!strcmp(tag->key, "framerate")
+            ||!strcmp(tag->key, "videocodecid")
+            ||!strcmp(tag->key, "audiodatarate")
+            ||!strcmp(tag->key, "audiosamplerate")
+            ||!strcmp(tag->key, "audiosamplesize")
+            ||!strcmp(tag->key, "stereo")
+            ||!strcmp(tag->key, "audiocodecid")
+            ||!strcmp(tag->key, "duration")
+            ||!strcmp(tag->key, "onMetaData")
+        ){
+            av_log(s, AV_LOG_DEBUG, "ignoring metadata for %s\n", tag->key);
+            continue;
+        }
         put_amf_string(pb, tag->key);
         avio_w8(pb, AMF_DATA_TYPE_STRING);
         put_amf_string(pb, tag->value);
@@ -345,7 +372,7 @@ static int flv_write_header(AVFormatContext *s)
 
     for (i = 0; i < s->nb_streams; i++) {
         AVCodecContext *enc = s->streams[i]->codec;
-        if (enc->codec_id == CODEC_ID_AAC || enc->codec_id == CODEC_ID_H264) {
+        if (enc->codec_id == CODEC_ID_AAC || enc->codec_id == CODEC_ID_H264 || enc->codec_id == CODEC_ID_MPEG4) {
             int64_t pos;
             avio_w8(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ?
                     FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO);
@@ -388,7 +415,7 @@ static int flv_write_trailer(AVFormatContext *s)
         AVCodecContext *enc = s->streams[i]->codec;
         FLVStreamContext *sc = s->streams[i]->priv_data;
         if (enc->codec_type == AVMEDIA_TYPE_VIDEO &&
-            enc->codec_id == CODEC_ID_H264)
+                (enc->codec_id == CODEC_ID_H264 || enc->codec_id == CODEC_ID_MPEG4))
             put_avc_eos_tag(pb, sc->last_ts);
     }
 
@@ -419,9 +446,9 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
     //        enc->codec_type, timestamp, size);
 
     if (enc->codec_id == CODEC_ID_VP6 || enc->codec_id == CODEC_ID_VP6F ||
-        enc->codec_id == CODEC_ID_AAC)
+        enc->codec_id == CODEC_ID_VP6A || enc->codec_id == CODEC_ID_AAC)
         flags_size = 2;
-    else if (enc->codec_id == CODEC_ID_H264)
+    else if (enc->codec_id == CODEC_ID_H264 || enc->codec_id == CODEC_ID_MPEG4)
         flags_size = 5;
     else
         flags_size = 1;
@@ -433,8 +460,8 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
         flags = enc->codec_tag;
         if (flags == 0) {
             av_log(s, AV_LOG_ERROR,
-                   "video codec %X not compatible with flv\n",
-                   enc->codec_id);
+                   "video codec %s not compatible with flv\n",
+                   avcodec_get_name(enc->codec_id));
             return -1;
         }
 
@@ -443,7 +470,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
     case AVMEDIA_TYPE_AUDIO:
         flags = get_audio_flags(s, enc);
 
-        assert(size);
+        av_assert0(size);
 
         avio_w8(pb, FLV_TAG_TYPE_AUDIO);
         break;
@@ -454,11 +481,16 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
         return AVERROR(EINVAL);
     }
 
-    if (enc->codec_id == CODEC_ID_H264)
-        /* check if extradata looks like MP4 */
+    if (enc->codec_id == CODEC_ID_H264 || enc->codec_id == CODEC_ID_MPEG4) {
+        /* check if extradata looks like mp4 formated */
         if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1)
             if (ff_avc_parse_nal_units_buf(pkt->data, &data, &size) < 0)
                 return -1;
+    } else if (enc->codec_id == CODEC_ID_AAC && pkt->size > 2 &&
+               (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
+        av_log(s, AV_LOG_ERROR, "malformated aac bitstream, use -absf aac_adtstoasc\n");
+        return -1;
+    }
 
     if (flv->delay == AV_NOPTS_VALUE)
         flv->delay = -pkt->dts;
@@ -509,14 +541,14 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
     } else {
         avio_w8(pb,flags);
         if (enc->codec_id == CODEC_ID_VP6)
-            avio_w8(pb, 0);
-        if (enc->codec_id == CODEC_ID_VP6F)
+            avio_w8(pb,0);
+        if (enc->codec_id == CODEC_ID_VP6F || enc->codec_id == CODEC_ID_VP6A)
             avio_w8(pb, enc->extradata_size ? enc->extradata[0] : 0);
         else if (enc->codec_id == CODEC_ID_AAC)
-            avio_w8(pb, 1); // AAC raw
-        else if (enc->codec_id == CODEC_ID_H264) {
-            avio_w8(pb, 1); // AVC NALU
-            avio_wb24(pb, pkt->pts - pkt->dts);
+            avio_w8(pb,1); // AAC raw
+        else if (enc->codec_id == CODEC_ID_H264 || enc->codec_id == CODEC_ID_MPEG4) {
+            avio_w8(pb,1); // AVC NALU
+            avio_wb24(pb,pkt->pts - pkt->dts);
         }
 
         avio_write(pb, data ? data : pkt->data, size);
@@ -538,11 +570,7 @@ AVOutputFormat ff_flv_muxer = {
     .mime_type      = "video/x-flv",
     .extensions     = "flv",
     .priv_data_size = sizeof(FLVContext),
-#if CONFIG_LIBMP3LAME
-    .audio_codec    = CODEC_ID_MP3,
-#else // CONFIG_LIBMP3LAME
-    .audio_codec    = CODEC_ID_ADPCM_SWF,
-#endif // CONFIG_LIBMP3LAME
+    .audio_codec    = CONFIG_LIBMP3LAME ? CODEC_ID_MP3 : CODEC_ID_ADPCM_SWF,
     .video_codec    = CODEC_ID_FLV1,
     .write_header   = flv_write_header,
     .write_packet   = flv_write_packet,