00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "avformat.h"
00022 #include "flv.h"
00023 #include "riff.h"
00024 #include "avc.h"
00025
00026 #undef NDEBUG
00027 #include <assert.h>
00028
00029 static const AVCodecTag flv_video_codec_ids[] = {
00030 {CODEC_ID_FLV1, FLV_CODECID_H263 },
00031 {CODEC_ID_FLASHSV, FLV_CODECID_SCREEN},
00032 {CODEC_ID_FLASHSV2, FLV_CODECID_SCREEN2},
00033 {CODEC_ID_VP6F, FLV_CODECID_VP6 },
00034 {CODEC_ID_VP6, FLV_CODECID_VP6 },
00035 {CODEC_ID_H264, FLV_CODECID_H264 },
00036 {CODEC_ID_NONE, 0}
00037 };
00038
00039 static const AVCodecTag flv_audio_codec_ids[] = {
00040 {CODEC_ID_MP3, FLV_CODECID_MP3 >> FLV_AUDIO_CODECID_OFFSET},
00041 {CODEC_ID_PCM_U8, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET},
00042 {CODEC_ID_PCM_S16BE, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET},
00043 {CODEC_ID_PCM_S16LE, FLV_CODECID_PCM_LE >> FLV_AUDIO_CODECID_OFFSET},
00044 {CODEC_ID_ADPCM_SWF, FLV_CODECID_ADPCM >> FLV_AUDIO_CODECID_OFFSET},
00045 {CODEC_ID_AAC, FLV_CODECID_AAC >> FLV_AUDIO_CODECID_OFFSET},
00046 {CODEC_ID_NELLYMOSER, FLV_CODECID_NELLYMOSER >> FLV_AUDIO_CODECID_OFFSET},
00047 {CODEC_ID_SPEEX, FLV_CODECID_SPEEX >> FLV_AUDIO_CODECID_OFFSET},
00048 {CODEC_ID_NONE, 0}
00049 };
00050
00051 typedef struct FLVContext {
00052 int reserved;
00053 int64_t duration_offset;
00054 int64_t filesize_offset;
00055 int64_t duration;
00056 int delay;
00057 } FLVContext;
00058
00059 static int get_audio_flags(AVCodecContext *enc){
00060 int flags = (enc->bits_per_coded_sample == 16) ? FLV_SAMPLESSIZE_16BIT : FLV_SAMPLESSIZE_8BIT;
00061
00062 if (enc->codec_id == CODEC_ID_AAC)
00063 return FLV_CODECID_AAC | FLV_SAMPLERATE_44100HZ | FLV_SAMPLESSIZE_16BIT | FLV_STEREO;
00064 else if (enc->codec_id == CODEC_ID_SPEEX) {
00065 if (enc->sample_rate != 16000) {
00066 av_log(enc, AV_LOG_ERROR, "flv only supports wideband (16kHz) Speex audio\n");
00067 return -1;
00068 }
00069 if (enc->channels != 1) {
00070 av_log(enc, AV_LOG_ERROR, "flv only supports mono Speex audio\n");
00071 return -1;
00072 }
00073 if (enc->frame_size / 320 > 8) {
00074 av_log(enc, AV_LOG_WARNING, "Warning: Speex stream has more than "
00075 "8 frames per packet. Adobe Flash "
00076 "Player cannot handle this!\n");
00077 }
00078 return FLV_CODECID_SPEEX | FLV_SAMPLERATE_11025HZ | FLV_SAMPLESSIZE_16BIT;
00079 } else {
00080 switch (enc->sample_rate) {
00081 case 44100:
00082 flags |= FLV_SAMPLERATE_44100HZ;
00083 break;
00084 case 22050:
00085 flags |= FLV_SAMPLERATE_22050HZ;
00086 break;
00087 case 11025:
00088 flags |= FLV_SAMPLERATE_11025HZ;
00089 break;
00090 case 8000:
00091 case 5512:
00092 if(enc->codec_id != CODEC_ID_MP3){
00093 flags |= FLV_SAMPLERATE_SPECIAL;
00094 break;
00095 }
00096 default:
00097 av_log(enc, AV_LOG_ERROR, "flv does not support that sample rate, choose from (44100, 22050, 11025).\n");
00098 return -1;
00099 }
00100 }
00101
00102 if (enc->channels > 1) {
00103 flags |= FLV_STEREO;
00104 }
00105
00106 switch(enc->codec_id){
00107 case CODEC_ID_MP3:
00108 flags |= FLV_CODECID_MP3 | FLV_SAMPLESSIZE_16BIT;
00109 break;
00110 case CODEC_ID_PCM_U8:
00111 flags |= FLV_CODECID_PCM | FLV_SAMPLESSIZE_8BIT;
00112 break;
00113 case CODEC_ID_PCM_S16BE:
00114 flags |= FLV_CODECID_PCM | FLV_SAMPLESSIZE_16BIT;
00115 break;
00116 case CODEC_ID_PCM_S16LE:
00117 flags |= FLV_CODECID_PCM_LE | FLV_SAMPLESSIZE_16BIT;
00118 break;
00119 case CODEC_ID_ADPCM_SWF:
00120 flags |= FLV_CODECID_ADPCM | FLV_SAMPLESSIZE_16BIT;
00121 break;
00122 case CODEC_ID_NELLYMOSER:
00123 if (enc->sample_rate == 8000) {
00124 flags |= FLV_CODECID_NELLYMOSER_8KHZ_MONO | FLV_SAMPLESSIZE_16BIT;
00125 } else {
00126 flags |= FLV_CODECID_NELLYMOSER | FLV_SAMPLESSIZE_16BIT;
00127 }
00128 break;
00129 case 0:
00130 flags |= enc->codec_tag<<4;
00131 break;
00132 default:
00133 av_log(enc, AV_LOG_ERROR, "codec not compatible with flv\n");
00134 return -1;
00135 }
00136
00137 return flags;
00138 }
00139
00140 static void put_amf_string(ByteIOContext *pb, const char *str)
00141 {
00142 size_t len = strlen(str);
00143 put_be16(pb, len);
00144 put_buffer(pb, str, len);
00145 }
00146
00147 static void put_amf_double(ByteIOContext *pb, double d)
00148 {
00149 put_byte(pb, AMF_DATA_TYPE_NUMBER);
00150 put_be64(pb, av_dbl2int(d));
00151 }
00152
00153 static void put_amf_bool(ByteIOContext *pb, int b) {
00154 put_byte(pb, AMF_DATA_TYPE_BOOL);
00155 put_byte(pb, !!b);
00156 }
00157
00158 static int flv_write_header(AVFormatContext *s)
00159 {
00160 ByteIOContext *pb = s->pb;
00161 FLVContext *flv = s->priv_data;
00162 AVCodecContext *audio_enc = NULL, *video_enc = NULL;
00163 int i;
00164 double framerate = 0.0;
00165 int64_t metadata_size_pos, data_size;
00166
00167 for(i=0; i<s->nb_streams; i++){
00168 AVCodecContext *enc = s->streams[i]->codec;
00169 if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
00170 if (s->streams[i]->r_frame_rate.den && s->streams[i]->r_frame_rate.num) {
00171 framerate = av_q2d(s->streams[i]->r_frame_rate);
00172 } else {
00173 framerate = 1/av_q2d(s->streams[i]->codec->time_base);
00174 }
00175 video_enc = enc;
00176 if(enc->codec_tag == 0) {
00177 av_log(enc, AV_LOG_ERROR, "video codec not compatible with flv\n");
00178 return -1;
00179 }
00180 } else {
00181 audio_enc = enc;
00182 if(get_audio_flags(enc)<0)
00183 return -1;
00184 }
00185 av_set_pts_info(s->streams[i], 32, 1, 1000);
00186 }
00187 put_tag(pb,"FLV");
00188 put_byte(pb,1);
00189 put_byte(pb, FLV_HEADER_FLAG_HASAUDIO * !!audio_enc
00190 + FLV_HEADER_FLAG_HASVIDEO * !!video_enc);
00191 put_be32(pb,9);
00192 put_be32(pb,0);
00193
00194 for(i=0; i<s->nb_streams; i++){
00195 if(s->streams[i]->codec->codec_tag == 5){
00196 put_byte(pb,8);
00197 put_be24(pb,0);
00198 put_be24(pb,0);
00199 put_be32(pb,0);
00200 put_be32(pb,11);
00201 flv->reserved=5;
00202 }
00203 }
00204
00205
00206 put_byte(pb, 18);
00207 metadata_size_pos= url_ftell(pb);
00208 put_be24(pb, 0);
00209 put_be24(pb, 0);
00210 put_be32(pb, 0);
00211
00212
00213
00214
00215 put_byte(pb, AMF_DATA_TYPE_STRING);
00216 put_amf_string(pb, "onMetaData");
00217
00218
00219 put_byte(pb, AMF_DATA_TYPE_MIXEDARRAY);
00220 put_be32(pb, 5*!!video_enc + 5*!!audio_enc + 2);
00221
00222 put_amf_string(pb, "duration");
00223 flv->duration_offset= url_ftell(pb);
00224 put_amf_double(pb, s->duration / AV_TIME_BASE);
00225
00226 if(video_enc){
00227 put_amf_string(pb, "width");
00228 put_amf_double(pb, video_enc->width);
00229
00230 put_amf_string(pb, "height");
00231 put_amf_double(pb, video_enc->height);
00232
00233 put_amf_string(pb, "videodatarate");
00234 put_amf_double(pb, video_enc->bit_rate / 1024.0);
00235
00236 put_amf_string(pb, "framerate");
00237 put_amf_double(pb, framerate);
00238
00239 put_amf_string(pb, "videocodecid");
00240 put_amf_double(pb, video_enc->codec_tag);
00241 }
00242
00243 if(audio_enc){
00244 put_amf_string(pb, "audiodatarate");
00245 put_amf_double(pb, audio_enc->bit_rate / 1024.0);
00246
00247 put_amf_string(pb, "audiosamplerate");
00248 put_amf_double(pb, audio_enc->sample_rate);
00249
00250 put_amf_string(pb, "audiosamplesize");
00251 put_amf_double(pb, audio_enc->codec_id == CODEC_ID_PCM_U8 ? 8 : 16);
00252
00253 put_amf_string(pb, "stereo");
00254 put_amf_bool(pb, audio_enc->channels == 2);
00255
00256 put_amf_string(pb, "audiocodecid");
00257 put_amf_double(pb, audio_enc->codec_tag);
00258 }
00259
00260 put_amf_string(pb, "filesize");
00261 flv->filesize_offset= url_ftell(pb);
00262 put_amf_double(pb, 0);
00263
00264 put_amf_string(pb, "");
00265 put_byte(pb, AMF_END_OF_OBJECT);
00266
00267
00268 data_size= url_ftell(pb) - metadata_size_pos - 10;
00269 url_fseek(pb, metadata_size_pos, SEEK_SET);
00270 put_be24(pb, data_size);
00271 url_fseek(pb, data_size + 10 - 3, SEEK_CUR);
00272 put_be32(pb, data_size + 11);
00273
00274 for (i = 0; i < s->nb_streams; i++) {
00275 AVCodecContext *enc = s->streams[i]->codec;
00276 if (enc->codec_id == CODEC_ID_AAC || enc->codec_id == CODEC_ID_H264) {
00277 int64_t pos;
00278 put_byte(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ?
00279 FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO);
00280 put_be24(pb, 0);
00281 put_be24(pb, 0);
00282 put_byte(pb, 0);
00283 put_be24(pb, 0);
00284 pos = url_ftell(pb);
00285 if (enc->codec_id == CODEC_ID_AAC) {
00286 put_byte(pb, get_audio_flags(enc));
00287 put_byte(pb, 0);
00288 put_buffer(pb, enc->extradata, enc->extradata_size);
00289 } else {
00290 put_byte(pb, enc->codec_tag | FLV_FRAME_KEY);
00291 put_byte(pb, 0);
00292 put_be24(pb, 0);
00293 ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size);
00294 }
00295 data_size = url_ftell(pb) - pos;
00296 url_fseek(pb, -data_size - 10, SEEK_CUR);
00297 put_be24(pb, data_size);
00298 url_fseek(pb, data_size + 10 - 3, SEEK_CUR);
00299 put_be32(pb, data_size + 11);
00300 }
00301 }
00302
00303 return 0;
00304 }
00305
00306 static int flv_write_trailer(AVFormatContext *s)
00307 {
00308 int64_t file_size;
00309
00310 ByteIOContext *pb = s->pb;
00311 FLVContext *flv = s->priv_data;
00312
00313 file_size = url_ftell(pb);
00314
00315
00316 url_fseek(pb, flv->duration_offset, SEEK_SET);
00317 put_amf_double(pb, flv->duration / (double)1000);
00318 url_fseek(pb, flv->filesize_offset, SEEK_SET);
00319 put_amf_double(pb, file_size);
00320
00321 url_fseek(pb, file_size, SEEK_SET);
00322 return 0;
00323 }
00324
00325 static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
00326 {
00327 ByteIOContext *pb = s->pb;
00328 AVCodecContext *enc = s->streams[pkt->stream_index]->codec;
00329 FLVContext *flv = s->priv_data;
00330 unsigned ts;
00331 int size= pkt->size;
00332 uint8_t *data= NULL;
00333 int flags, flags_size;
00334
00335
00336
00337 if(enc->codec_id == CODEC_ID_VP6 || enc->codec_id == CODEC_ID_VP6F ||
00338 enc->codec_id == CODEC_ID_AAC)
00339 flags_size= 2;
00340 else if(enc->codec_id == CODEC_ID_H264)
00341 flags_size= 5;
00342 else
00343 flags_size= 1;
00344
00345 if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
00346 put_byte(pb, FLV_TAG_TYPE_VIDEO);
00347
00348 flags = enc->codec_tag;
00349 if(flags == 0) {
00350 av_log(enc, AV_LOG_ERROR, "video codec %X not compatible with flv\n",enc->codec_id);
00351 return -1;
00352 }
00353
00354 flags |= pkt->flags & AV_PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER;
00355 } else {
00356 assert(enc->codec_type == AVMEDIA_TYPE_AUDIO);
00357 flags = get_audio_flags(enc);
00358
00359 assert(size);
00360
00361 put_byte(pb, FLV_TAG_TYPE_AUDIO);
00362 }
00363
00364 if (enc->codec_id == CODEC_ID_H264) {
00365
00366 if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1) {
00367 if (ff_avc_parse_nal_units_buf(pkt->data, &data, &size) < 0)
00368 return -1;
00369 }
00370 if (!flv->delay && pkt->dts < 0)
00371 flv->delay = -pkt->dts;
00372 }
00373
00374 ts = pkt->dts + flv->delay;
00375 put_be24(pb,size + flags_size);
00376 put_be24(pb,ts);
00377 put_byte(pb,(ts >> 24) & 0x7F);
00378 put_be24(pb,flv->reserved);
00379 put_byte(pb,flags);
00380 if (enc->codec_id == CODEC_ID_VP6)
00381 put_byte(pb,0);
00382 if (enc->codec_id == CODEC_ID_VP6F)
00383 put_byte(pb, enc->extradata_size ? enc->extradata[0] : 0);
00384 else if (enc->codec_id == CODEC_ID_AAC)
00385 put_byte(pb,1);
00386 else if (enc->codec_id == CODEC_ID_H264) {
00387 put_byte(pb,1);
00388 put_be24(pb,pkt->pts - pkt->dts);
00389 }
00390
00391 put_buffer(pb, data ? data : pkt->data, size);
00392
00393 put_be32(pb,size+flags_size+11);
00394 flv->duration = FFMAX(flv->duration, pkt->pts + flv->delay + pkt->duration);
00395
00396 put_flush_packet(pb);
00397
00398 av_free(data);
00399
00400 return 0;
00401 }
00402
00403 AVOutputFormat flv_muxer = {
00404 "flv",
00405 NULL_IF_CONFIG_SMALL("FLV format"),
00406 "video/x-flv",
00407 "flv",
00408 sizeof(FLVContext),
00409 #if CONFIG_LIBMP3LAME
00410 CODEC_ID_MP3,
00411 #else
00412 CODEC_ID_ADPCM_SWF,
00413 #endif
00414 CODEC_ID_FLV1,
00415 flv_write_header,
00416 flv_write_packet,
00417 flv_write_trailer,
00418 .codec_tag= (const AVCodecTag* const []){flv_video_codec_ids, flv_audio_codec_ids, 0},
00419 .flags= AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
00420 };