]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/flvenc.c
print at debug level the score at which codec probing succedeed
[ffmpeg] / libavformat / flvenc.c
index a0fbd53d2d4d5b86839b0c8a535d0c66c3a69795..f616889a34f01eac9e8a4d325c6d7a7f9553a3fe 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * FLV muxer
- * Copyright (c) 2003 The FFmpeg Project.
+ * Copyright (c) 2003 The FFmpeg Project
  *
  * This file is part of FFmpeg.
  *
@@ -48,14 +48,14 @@ static const AVCodecTag flv_audio_codec_ids[] = {
 
 typedef struct FLVContext {
     int reserved;
-    offset_t duration_offset;
-    offset_t filesize_offset;
+    int64_t duration_offset;
+    int64_t filesize_offset;
     int64_t duration;
     int delay; ///< first dts delay for AVC
 } FLVContext;
 
 static int get_audio_flags(AVCodecContext *enc){
-    int flags = (enc->bits_per_sample == 16) ? FLV_SAMPLESSIZE_16BIT : FLV_SAMPLESSIZE_8BIT;
+    int flags = (enc->bits_per_coded_sample == 16) ? FLV_SAMPLESSIZE_16BIT : FLV_SAMPLESSIZE_8BIT;
 
     if (enc->codec_id == CODEC_ID_AAC) // specs force these parameters
         return FLV_CODECID_AAC | FLV_SAMPLERATE_44100HZ | FLV_SAMPLESSIZE_16BIT | FLV_STEREO;
@@ -103,7 +103,11 @@ static int get_audio_flags(AVCodecContext *enc){
         flags |= FLV_CODECID_ADPCM | FLV_SAMPLESSIZE_16BIT;
         break;
     case CODEC_ID_NELLYMOSER:
-        flags |= FLV_CODECID_NELLYMOSER | FLV_SAMPLESSIZE_16BIT;
+        if (enc->sample_rate == 8000) {
+            flags |= FLV_CODECID_NELLYMOSER_8KHZ_MONO | FLV_SAMPLESSIZE_16BIT;
+        } else {
+            flags |= FLV_CODECID_NELLYMOSER | FLV_SAMPLESSIZE_16BIT;
+        }
         break;
     case 0:
         flags |= enc->codec_tag<<4;
@@ -196,7 +200,7 @@ static int flv_write_header(AVFormatContext *s)
 
     /* mixed array (hash) with size and string/type/data tuples */
     put_byte(pb, AMF_DATA_TYPE_MIXEDARRAY);
-    put_be32(pb, 5*!!video_enc + 4*!!audio_enc + 2); // +2 for duration and file size
+    put_be32(pb, 5*!!video_enc + 5*!!audio_enc + 2); // +2 for duration and file size
 
     put_amf_string(pb, "duration");
     flv->duration_offset= url_ftell(pb);
@@ -210,7 +214,7 @@ static int flv_write_header(AVFormatContext *s)
         put_amf_double(pb, video_enc->height);
 
         put_amf_string(pb, "videodatarate");
-        put_amf_double(pb, s->bit_rate / 1024.0);
+        put_amf_double(pb, video_enc->bit_rate / 1024.0);
 
         put_amf_string(pb, "framerate");
         put_amf_double(pb, framerate);
@@ -220,6 +224,9 @@ static int flv_write_header(AVFormatContext *s)
     }
 
     if(audio_enc){
+        put_amf_string(pb, "audiodatarate");
+        put_amf_double(pb, audio_enc->bit_rate / 1024.0);
+
         put_amf_string(pb, "audiosamplerate");
         put_amf_double(pb, audio_enc->sample_rate);
 
@@ -250,7 +257,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) {
-            offset_t pos;
+            int64_t pos;
             put_byte(pb, enc->codec_type == CODEC_TYPE_VIDEO ?
                      FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO);
             put_be24(pb, 0); // size patched later
@@ -305,6 +312,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
     FLVContext *flv = s->priv_data;
     unsigned ts;
     int size= pkt->size;
+    uint8_t *data= NULL;
     int flags, flags_size;
 
 //    av_log(s, AV_LOG_DEBUG, "type:%d pts: %"PRId64" size:%d\n", enc->codec_type, timestamp, size);
@@ -337,19 +345,19 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
     }
 
     if (enc->codec_id == CODEC_ID_H264) {
-        if (ff_avc_parse_nal_units(pkt->data, &pkt->data, &pkt->size) < 0)
-            return -1;
-        assert(pkt->size);
-        size = pkt->size;
-        /* cast needed to get negative value */
-        if (!flv->delay && (int32_t)pkt->dts < 0)
-            flv->delay = -(int32_t)pkt->dts;
+        /* 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;
+        }
+        if (!flv->delay && pkt->dts < 0)
+            flv->delay = -pkt->dts;
     }
 
     ts = pkt->dts + flv->delay; // add delay to force positive dts
     put_be24(pb,size + flags_size);
     put_be24(pb,ts);
-    put_byte(pb,ts >> 24);
+    put_byte(pb,(ts >> 24) & 0x7F); // timestamps are 32bits _signed_
     put_be24(pb,flv->reserved);
     put_byte(pb,flags);
     if (enc->codec_id == CODEC_ID_VP6)
@@ -360,23 +368,28 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
         put_byte(pb,1); // AAC raw
     else if (enc->codec_id == CODEC_ID_H264) {
         put_byte(pb,1); // AVC NALU
-        put_be24(pb,pkt->pts - (int32_t)pkt->dts);
+        put_be24(pb,pkt->pts - pkt->dts);
     }
-    put_buffer(pb, pkt->data, size);
+
+    put_buffer(pb, data ? data : pkt->data, size);
+
     put_be32(pb,size+flags_size+11); // previous tag size
     flv->duration = FFMAX(flv->duration, pkt->pts + flv->delay + pkt->duration);
 
     put_flush_packet(pb);
+
+    av_free(data);
+
     return 0;
 }
 
 AVOutputFormat flv_muxer = {
     "flv",
-    "flv format",
+    NULL_IF_CONFIG_SMALL("FLV format"),
     "video/x-flv",
     "flv",
     sizeof(FLVContext),
-#ifdef CONFIG_LIBMP3LAME
+#if CONFIG_LIBMP3LAME
     CODEC_ID_MP3,
 #else // CONFIG_LIBMP3LAME
     CODEC_ID_ADPCM_SWF,
@@ -385,6 +398,6 @@ AVOutputFormat flv_muxer = {
     flv_write_header,
     flv_write_packet,
     flv_write_trailer,
-    .codec_tag= (const AVCodecTag*[]){flv_video_codec_ids, flv_audio_codec_ids, 0},
-    .flags= AVFMT_GLOBALHEADER,
+    .codec_tag= (const AVCodecTag* const []){flv_video_codec_ids, flv_audio_codec_ids, 0},
+    .flags= AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
 };