Libav
|
00001 /* 00002 * FLV muxer 00003 * Copyright (c) 2003 The FFmpeg Project 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg 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 * FFmpeg 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 FFmpeg; 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 "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) // specs force these parameters 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: //nellymoser only 00091 case 5512: //not mp3 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); /* 32 bit pts in ms */ 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); // message type 00197 put_be24(pb,0); // include flags 00198 put_be24(pb,0); // time stamp 00199 put_be32(pb,0); // reserved 00200 put_be32(pb,11); // size 00201 flv->reserved=5; 00202 } 00203 } 00204 00205 /* write meta_tag */ 00206 put_byte(pb, 18); // tag type META 00207 metadata_size_pos= url_ftell(pb); 00208 put_be24(pb, 0); // size of data part (sum of all parts below) 00209 put_be24(pb, 0); // time stamp 00210 put_be32(pb, 0); // reserved 00211 00212 /* now data of data_size size */ 00213 00214 /* first event name as a string */ 00215 put_byte(pb, AMF_DATA_TYPE_STRING); 00216 put_amf_string(pb, "onMetaData"); // 12 bytes 00217 00218 /* mixed array (hash) with size and string/type/data tuples */ 00219 put_byte(pb, AMF_DATA_TYPE_MIXEDARRAY); 00220 put_be32(pb, 5*!!video_enc + 5*!!audio_enc + 2); // +2 for duration and file size 00221 00222 put_amf_string(pb, "duration"); 00223 flv->duration_offset= url_ftell(pb); 00224 put_amf_double(pb, s->duration / AV_TIME_BASE); // fill in the guessed duration, it'll be corrected later if incorrect 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); // delayed write 00263 00264 put_amf_string(pb, ""); 00265 put_byte(pb, AMF_END_OF_OBJECT); 00266 00267 /* write total size of tag */ 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); // size patched later 00281 put_be24(pb, 0); // ts 00282 put_byte(pb, 0); // ts ext 00283 put_be24(pb, 0); // streamid 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); // AAC sequence header 00288 put_buffer(pb, enc->extradata, enc->extradata_size); 00289 } else { 00290 put_byte(pb, enc->codec_tag | FLV_FRAME_KEY); // flags 00291 put_byte(pb, 0); // AVC sequence header 00292 put_be24(pb, 0); // composition time 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); // previous tag size 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 /* update informations */ 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 // av_log(s, AV_LOG_DEBUG, "type:%d pts: %"PRId64" size:%d\n", enc->codec_type, timestamp, size); 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 /* check if extradata looks like mp4 formated */ 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; // add delay to force positive dts 00375 put_be24(pb,size + flags_size); 00376 put_be24(pb,ts); 00377 put_byte(pb,(ts >> 24) & 0x7F); // timestamps are 32bits _signed_ 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); // AAC raw 00386 else if (enc->codec_id == CODEC_ID_H264) { 00387 put_byte(pb,1); // AVC NALU 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); // previous tag size 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 // CONFIG_LIBMP3LAME 00412 CODEC_ID_ADPCM_SWF, 00413 #endif // CONFIG_LIBMP3LAME 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 };