Libav 0.7.1
|
00001 /* 00002 * FLV muxer 00003 * Copyright (c) 2003 The Libav Project 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 #include "avformat.h" 00022 #include "flv.h" 00023 #include "internal.h" 00024 #include "avc.h" 00025 #include "metadata.h" 00026 #include "libavutil/dict.h" 00027 00028 #undef NDEBUG 00029 #include <assert.h> 00030 00031 static const AVCodecTag flv_video_codec_ids[] = { 00032 {CODEC_ID_FLV1, FLV_CODECID_H263 }, 00033 {CODEC_ID_FLASHSV, FLV_CODECID_SCREEN}, 00034 {CODEC_ID_FLASHSV2, FLV_CODECID_SCREEN2}, 00035 {CODEC_ID_VP6F, FLV_CODECID_VP6 }, 00036 {CODEC_ID_VP6, FLV_CODECID_VP6 }, 00037 {CODEC_ID_H264, FLV_CODECID_H264 }, 00038 {CODEC_ID_NONE, 0} 00039 }; 00040 00041 static const AVCodecTag flv_audio_codec_ids[] = { 00042 {CODEC_ID_MP3, FLV_CODECID_MP3 >> FLV_AUDIO_CODECID_OFFSET}, 00043 {CODEC_ID_PCM_U8, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET}, 00044 {CODEC_ID_PCM_S16BE, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET}, 00045 {CODEC_ID_PCM_S16LE, FLV_CODECID_PCM_LE >> FLV_AUDIO_CODECID_OFFSET}, 00046 {CODEC_ID_ADPCM_SWF, FLV_CODECID_ADPCM >> FLV_AUDIO_CODECID_OFFSET}, 00047 {CODEC_ID_AAC, FLV_CODECID_AAC >> FLV_AUDIO_CODECID_OFFSET}, 00048 {CODEC_ID_NELLYMOSER, FLV_CODECID_NELLYMOSER >> FLV_AUDIO_CODECID_OFFSET}, 00049 {CODEC_ID_SPEEX, FLV_CODECID_SPEEX >> FLV_AUDIO_CODECID_OFFSET}, 00050 {CODEC_ID_NONE, 0} 00051 }; 00052 00053 typedef struct FLVContext { 00054 int reserved; 00055 int64_t duration_offset; 00056 int64_t filesize_offset; 00057 int64_t duration; 00058 int delay; 00059 int64_t last_video_ts; 00060 } FLVContext; 00061 00062 static int get_audio_flags(AVCodecContext *enc){ 00063 int flags = (enc->bits_per_coded_sample == 16) ? FLV_SAMPLESSIZE_16BIT : FLV_SAMPLESSIZE_8BIT; 00064 00065 if (enc->codec_id == CODEC_ID_AAC) // specs force these parameters 00066 return FLV_CODECID_AAC | FLV_SAMPLERATE_44100HZ | FLV_SAMPLESSIZE_16BIT | FLV_STEREO; 00067 else if (enc->codec_id == CODEC_ID_SPEEX) { 00068 if (enc->sample_rate != 16000) { 00069 av_log(enc, AV_LOG_ERROR, "flv only supports wideband (16kHz) Speex audio\n"); 00070 return -1; 00071 } 00072 if (enc->channels != 1) { 00073 av_log(enc, AV_LOG_ERROR, "flv only supports mono Speex audio\n"); 00074 return -1; 00075 } 00076 if (enc->frame_size / 320 > 8) { 00077 av_log(enc, AV_LOG_WARNING, "Warning: Speex stream has more than " 00078 "8 frames per packet. Adobe Flash " 00079 "Player cannot handle this!\n"); 00080 } 00081 return FLV_CODECID_SPEEX | FLV_SAMPLERATE_11025HZ | FLV_SAMPLESSIZE_16BIT; 00082 } else { 00083 switch (enc->sample_rate) { 00084 case 44100: 00085 flags |= FLV_SAMPLERATE_44100HZ; 00086 break; 00087 case 22050: 00088 flags |= FLV_SAMPLERATE_22050HZ; 00089 break; 00090 case 11025: 00091 flags |= FLV_SAMPLERATE_11025HZ; 00092 break; 00093 case 8000: //nellymoser only 00094 case 5512: //not mp3 00095 if(enc->codec_id != CODEC_ID_MP3){ 00096 flags |= FLV_SAMPLERATE_SPECIAL; 00097 break; 00098 } 00099 default: 00100 av_log(enc, AV_LOG_ERROR, "flv does not support that sample rate, choose from (44100, 22050, 11025).\n"); 00101 return -1; 00102 } 00103 } 00104 00105 if (enc->channels > 1) { 00106 flags |= FLV_STEREO; 00107 } 00108 00109 switch(enc->codec_id){ 00110 case CODEC_ID_MP3: 00111 flags |= FLV_CODECID_MP3 | FLV_SAMPLESSIZE_16BIT; 00112 break; 00113 case CODEC_ID_PCM_U8: 00114 flags |= FLV_CODECID_PCM | FLV_SAMPLESSIZE_8BIT; 00115 break; 00116 case CODEC_ID_PCM_S16BE: 00117 flags |= FLV_CODECID_PCM | FLV_SAMPLESSIZE_16BIT; 00118 break; 00119 case CODEC_ID_PCM_S16LE: 00120 flags |= FLV_CODECID_PCM_LE | FLV_SAMPLESSIZE_16BIT; 00121 break; 00122 case CODEC_ID_ADPCM_SWF: 00123 flags |= FLV_CODECID_ADPCM | FLV_SAMPLESSIZE_16BIT; 00124 break; 00125 case CODEC_ID_NELLYMOSER: 00126 if (enc->sample_rate == 8000) { 00127 flags |= FLV_CODECID_NELLYMOSER_8KHZ_MONO | FLV_SAMPLESSIZE_16BIT; 00128 } else { 00129 flags |= FLV_CODECID_NELLYMOSER | FLV_SAMPLESSIZE_16BIT; 00130 } 00131 break; 00132 case 0: 00133 flags |= enc->codec_tag<<4; 00134 break; 00135 default: 00136 av_log(enc, AV_LOG_ERROR, "codec not compatible with flv\n"); 00137 return -1; 00138 } 00139 00140 return flags; 00141 } 00142 00143 static void put_amf_string(AVIOContext *pb, const char *str) 00144 { 00145 size_t len = strlen(str); 00146 avio_wb16(pb, len); 00147 avio_write(pb, str, len); 00148 } 00149 00150 static void put_avc_eos_tag(AVIOContext *pb, unsigned ts) { 00151 avio_w8(pb, FLV_TAG_TYPE_VIDEO); 00152 avio_wb24(pb, 5); /* Tag Data Size */ 00153 avio_wb24(pb, ts); /* lower 24 bits of timestamp in ms*/ 00154 avio_w8(pb, (ts >> 24) & 0x7F); /* MSB of ts in ms*/ 00155 avio_wb24(pb, 0); /* StreamId = 0 */ 00156 avio_w8(pb, 23); /* ub[4] FrameType = 1, ub[4] CodecId = 7 */ 00157 avio_w8(pb, 2); /* AVC end of sequence */ 00158 avio_wb24(pb, 0); /* Always 0 for AVC EOS. */ 00159 avio_wb32(pb, 16); /* Size of FLV tag */ 00160 } 00161 00162 static void put_amf_double(AVIOContext *pb, double d) 00163 { 00164 avio_w8(pb, AMF_DATA_TYPE_NUMBER); 00165 avio_wb64(pb, av_dbl2int(d)); 00166 } 00167 00168 static void put_amf_bool(AVIOContext *pb, int b) { 00169 avio_w8(pb, AMF_DATA_TYPE_BOOL); 00170 avio_w8(pb, !!b); 00171 } 00172 00173 static int flv_write_header(AVFormatContext *s) 00174 { 00175 AVIOContext *pb = s->pb; 00176 FLVContext *flv = s->priv_data; 00177 AVCodecContext *audio_enc = NULL, *video_enc = NULL; 00178 int i; 00179 double framerate = 0.0; 00180 int64_t metadata_size_pos, data_size; 00181 AVDictionaryEntry *tag = NULL; 00182 00183 for(i=0; i<s->nb_streams; i++){ 00184 AVCodecContext *enc = s->streams[i]->codec; 00185 if (enc->codec_type == AVMEDIA_TYPE_VIDEO) { 00186 if (s->streams[i]->r_frame_rate.den && s->streams[i]->r_frame_rate.num) { 00187 framerate = av_q2d(s->streams[i]->r_frame_rate); 00188 } else { 00189 framerate = 1/av_q2d(s->streams[i]->codec->time_base); 00190 } 00191 video_enc = enc; 00192 if(enc->codec_tag == 0) { 00193 av_log(enc, AV_LOG_ERROR, "video codec not compatible with flv\n"); 00194 return -1; 00195 } 00196 } else { 00197 audio_enc = enc; 00198 if(get_audio_flags(enc)<0) 00199 return -1; 00200 } 00201 av_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */ 00202 } 00203 avio_write(pb, "FLV", 3); 00204 avio_w8(pb,1); 00205 avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!audio_enc 00206 + FLV_HEADER_FLAG_HASVIDEO * !!video_enc); 00207 avio_wb32(pb,9); 00208 avio_wb32(pb,0); 00209 00210 for(i=0; i<s->nb_streams; i++){ 00211 if(s->streams[i]->codec->codec_tag == 5){ 00212 avio_w8(pb,8); // message type 00213 avio_wb24(pb,0); // include flags 00214 avio_wb24(pb,0); // time stamp 00215 avio_wb32(pb,0); // reserved 00216 avio_wb32(pb,11); // size 00217 flv->reserved=5; 00218 } 00219 } 00220 00221 flv->last_video_ts = -1; 00222 00223 /* write meta_tag */ 00224 avio_w8(pb, 18); // tag type META 00225 metadata_size_pos= avio_tell(pb); 00226 avio_wb24(pb, 0); // size of data part (sum of all parts below) 00227 avio_wb24(pb, 0); // time stamp 00228 avio_wb32(pb, 0); // reserved 00229 00230 /* now data of data_size size */ 00231 00232 /* first event name as a string */ 00233 avio_w8(pb, AMF_DATA_TYPE_STRING); 00234 put_amf_string(pb, "onMetaData"); // 12 bytes 00235 00236 /* mixed array (hash) with size and string/type/data tuples */ 00237 avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY); 00238 avio_wb32(pb, 5*!!video_enc + 5*!!audio_enc + 2); // +2 for duration and file size 00239 00240 put_amf_string(pb, "duration"); 00241 flv->duration_offset= avio_tell(pb); 00242 put_amf_double(pb, s->duration / AV_TIME_BASE); // fill in the guessed duration, it'll be corrected later if incorrect 00243 00244 if(video_enc){ 00245 put_amf_string(pb, "width"); 00246 put_amf_double(pb, video_enc->width); 00247 00248 put_amf_string(pb, "height"); 00249 put_amf_double(pb, video_enc->height); 00250 00251 put_amf_string(pb, "videodatarate"); 00252 put_amf_double(pb, video_enc->bit_rate / 1024.0); 00253 00254 put_amf_string(pb, "framerate"); 00255 put_amf_double(pb, framerate); 00256 00257 put_amf_string(pb, "videocodecid"); 00258 put_amf_double(pb, video_enc->codec_tag); 00259 } 00260 00261 if(audio_enc){ 00262 put_amf_string(pb, "audiodatarate"); 00263 put_amf_double(pb, audio_enc->bit_rate / 1024.0); 00264 00265 put_amf_string(pb, "audiosamplerate"); 00266 put_amf_double(pb, audio_enc->sample_rate); 00267 00268 put_amf_string(pb, "audiosamplesize"); 00269 put_amf_double(pb, audio_enc->codec_id == CODEC_ID_PCM_U8 ? 8 : 16); 00270 00271 put_amf_string(pb, "stereo"); 00272 put_amf_bool(pb, audio_enc->channels == 2); 00273 00274 put_amf_string(pb, "audiocodecid"); 00275 put_amf_double(pb, audio_enc->codec_tag); 00276 } 00277 00278 while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { 00279 put_amf_string(pb, tag->key); 00280 avio_w8(pb, AMF_DATA_TYPE_STRING); 00281 put_amf_string(pb, tag->value); 00282 } 00283 00284 put_amf_string(pb, "filesize"); 00285 flv->filesize_offset= avio_tell(pb); 00286 put_amf_double(pb, 0); // delayed write 00287 00288 put_amf_string(pb, ""); 00289 avio_w8(pb, AMF_END_OF_OBJECT); 00290 00291 /* write total size of tag */ 00292 data_size= avio_tell(pb) - metadata_size_pos - 10; 00293 avio_seek(pb, metadata_size_pos, SEEK_SET); 00294 avio_wb24(pb, data_size); 00295 avio_skip(pb, data_size + 10 - 3); 00296 avio_wb32(pb, data_size + 11); 00297 00298 for (i = 0; i < s->nb_streams; i++) { 00299 AVCodecContext *enc = s->streams[i]->codec; 00300 if (enc->codec_id == CODEC_ID_AAC || enc->codec_id == CODEC_ID_H264) { 00301 int64_t pos; 00302 avio_w8(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ? 00303 FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO); 00304 avio_wb24(pb, 0); // size patched later 00305 avio_wb24(pb, 0); // ts 00306 avio_w8(pb, 0); // ts ext 00307 avio_wb24(pb, 0); // streamid 00308 pos = avio_tell(pb); 00309 if (enc->codec_id == CODEC_ID_AAC) { 00310 avio_w8(pb, get_audio_flags(enc)); 00311 avio_w8(pb, 0); // AAC sequence header 00312 avio_write(pb, enc->extradata, enc->extradata_size); 00313 } else { 00314 avio_w8(pb, enc->codec_tag | FLV_FRAME_KEY); // flags 00315 avio_w8(pb, 0); // AVC sequence header 00316 avio_wb24(pb, 0); // composition time 00317 ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size); 00318 } 00319 data_size = avio_tell(pb) - pos; 00320 avio_seek(pb, -data_size - 10, SEEK_CUR); 00321 avio_wb24(pb, data_size); 00322 avio_skip(pb, data_size + 10 - 3); 00323 avio_wb32(pb, data_size + 11); // previous tag size 00324 } 00325 } 00326 00327 return 0; 00328 } 00329 00330 static int flv_write_trailer(AVFormatContext *s) 00331 { 00332 int64_t file_size; 00333 00334 AVIOContext *pb = s->pb; 00335 FLVContext *flv = s->priv_data; 00336 int i; 00337 00338 /* Add EOS tag */ 00339 for (i = 0; i < s->nb_streams; i++) { 00340 AVCodecContext *enc = s->streams[i]->codec; 00341 if (enc->codec_type == AVMEDIA_TYPE_VIDEO && 00342 enc->codec_id == CODEC_ID_H264) { 00343 put_avc_eos_tag(pb, flv->last_video_ts); 00344 } 00345 } 00346 00347 file_size = avio_tell(pb); 00348 00349 /* update informations */ 00350 avio_seek(pb, flv->duration_offset, SEEK_SET); 00351 put_amf_double(pb, flv->duration / (double)1000); 00352 avio_seek(pb, flv->filesize_offset, SEEK_SET); 00353 put_amf_double(pb, file_size); 00354 00355 avio_seek(pb, file_size, SEEK_SET); 00356 return 0; 00357 } 00358 00359 static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) 00360 { 00361 AVIOContext *pb = s->pb; 00362 AVCodecContext *enc = s->streams[pkt->stream_index]->codec; 00363 FLVContext *flv = s->priv_data; 00364 unsigned ts; 00365 int size= pkt->size; 00366 uint8_t *data= NULL; 00367 int flags, flags_size; 00368 00369 // av_log(s, AV_LOG_DEBUG, "type:%d pts: %"PRId64" size:%d\n", enc->codec_type, timestamp, size); 00370 00371 if(enc->codec_id == CODEC_ID_VP6 || enc->codec_id == CODEC_ID_VP6F || 00372 enc->codec_id == CODEC_ID_AAC) 00373 flags_size= 2; 00374 else if(enc->codec_id == CODEC_ID_H264) 00375 flags_size= 5; 00376 else 00377 flags_size= 1; 00378 00379 if (enc->codec_type == AVMEDIA_TYPE_VIDEO) { 00380 avio_w8(pb, FLV_TAG_TYPE_VIDEO); 00381 00382 flags = enc->codec_tag; 00383 if(flags == 0) { 00384 av_log(enc, AV_LOG_ERROR, "video codec %X not compatible with flv\n",enc->codec_id); 00385 return -1; 00386 } 00387 00388 flags |= pkt->flags & AV_PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER; 00389 } else { 00390 assert(enc->codec_type == AVMEDIA_TYPE_AUDIO); 00391 flags = get_audio_flags(enc); 00392 00393 assert(size); 00394 00395 avio_w8(pb, FLV_TAG_TYPE_AUDIO); 00396 } 00397 00398 if (enc->codec_id == CODEC_ID_H264) { 00399 /* check if extradata looks like mp4 formated */ 00400 if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1) { 00401 if (ff_avc_parse_nal_units_buf(pkt->data, &data, &size) < 0) 00402 return -1; 00403 } 00404 if (!flv->delay && pkt->dts < 0) 00405 flv->delay = -pkt->dts; 00406 } 00407 00408 ts = pkt->dts + flv->delay; // add delay to force positive dts 00409 if (enc->codec_type == AVMEDIA_TYPE_VIDEO) { 00410 if (flv->last_video_ts < ts) 00411 flv->last_video_ts = ts; 00412 } 00413 avio_wb24(pb,size + flags_size); 00414 avio_wb24(pb,ts); 00415 avio_w8(pb,(ts >> 24) & 0x7F); // timestamps are 32bits _signed_ 00416 avio_wb24(pb,flv->reserved); 00417 avio_w8(pb,flags); 00418 if (enc->codec_id == CODEC_ID_VP6) 00419 avio_w8(pb,0); 00420 if (enc->codec_id == CODEC_ID_VP6F) 00421 avio_w8(pb, enc->extradata_size ? enc->extradata[0] : 0); 00422 else if (enc->codec_id == CODEC_ID_AAC) 00423 avio_w8(pb,1); // AAC raw 00424 else if (enc->codec_id == CODEC_ID_H264) { 00425 avio_w8(pb,1); // AVC NALU 00426 avio_wb24(pb,pkt->pts - pkt->dts); 00427 } 00428 00429 avio_write(pb, data ? data : pkt->data, size); 00430 00431 avio_wb32(pb,size+flags_size+11); // previous tag size 00432 flv->duration = FFMAX(flv->duration, pkt->pts + flv->delay + pkt->duration); 00433 00434 avio_flush(pb); 00435 00436 av_free(data); 00437 00438 return pb->error; 00439 } 00440 00441 AVOutputFormat ff_flv_muxer = { 00442 "flv", 00443 NULL_IF_CONFIG_SMALL("FLV format"), 00444 "video/x-flv", 00445 "flv", 00446 sizeof(FLVContext), 00447 #if CONFIG_LIBMP3LAME 00448 CODEC_ID_MP3, 00449 #else // CONFIG_LIBMP3LAME 00450 CODEC_ID_ADPCM_SWF, 00451 #endif // CONFIG_LIBMP3LAME 00452 CODEC_ID_FLV1, 00453 flv_write_header, 00454 flv_write_packet, 00455 flv_write_trailer, 00456 .codec_tag= (const AVCodecTag* const []){flv_video_codec_ids, flv_audio_codec_ids, 0}, 00457 .flags= AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, 00458 };