1/* 2 * FLV muxer 3 * Copyright (c) 2003 The FFmpeg Project 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21#include "avformat.h" 22#include "flv.h" 23#include "riff.h" 24#include "avc.h" 25 26#undef NDEBUG 27#include <assert.h> 28 29static const AVCodecTag flv_video_codec_ids[] = { 30 {CODEC_ID_FLV1, FLV_CODECID_H263 }, 31 {CODEC_ID_FLASHSV, FLV_CODECID_SCREEN}, 32 {CODEC_ID_VP6F, FLV_CODECID_VP6 }, 33 {CODEC_ID_VP6, FLV_CODECID_VP6 }, 34 {CODEC_ID_H264, FLV_CODECID_H264 }, 35 {CODEC_ID_NONE, 0} 36}; 37 38static const AVCodecTag flv_audio_codec_ids[] = { 39 {CODEC_ID_MP3, FLV_CODECID_MP3 >> FLV_AUDIO_CODECID_OFFSET}, 40 {CODEC_ID_PCM_S8, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET}, 41 {CODEC_ID_PCM_S16BE, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET}, 42 {CODEC_ID_PCM_S16LE, FLV_CODECID_PCM_LE >> FLV_AUDIO_CODECID_OFFSET}, 43 {CODEC_ID_ADPCM_SWF, FLV_CODECID_ADPCM >> FLV_AUDIO_CODECID_OFFSET}, 44 {CODEC_ID_AAC, FLV_CODECID_AAC >> FLV_AUDIO_CODECID_OFFSET}, 45 {CODEC_ID_NELLYMOSER, FLV_CODECID_NELLYMOSER >> FLV_AUDIO_CODECID_OFFSET}, 46 {CODEC_ID_NONE, 0} 47}; 48 49typedef struct FLVContext { 50 int reserved; 51 int64_t duration_offset; 52 int64_t filesize_offset; 53 int64_t duration; 54 int delay; ///< first dts delay for AVC 55} FLVContext; 56 57static int get_audio_flags(AVCodecContext *enc){ 58 int flags = (enc->bits_per_coded_sample == 16) ? FLV_SAMPLESSIZE_16BIT : FLV_SAMPLESSIZE_8BIT; 59 60 if (enc->codec_id == CODEC_ID_AAC) // specs force these parameters 61 return FLV_CODECID_AAC | FLV_SAMPLERATE_44100HZ | FLV_SAMPLESSIZE_16BIT | FLV_STEREO; 62 else { 63 switch (enc->sample_rate) { 64 case 44100: 65 flags |= FLV_SAMPLERATE_44100HZ; 66 break; 67 case 22050: 68 flags |= FLV_SAMPLERATE_22050HZ; 69 break; 70 case 11025: 71 flags |= FLV_SAMPLERATE_11025HZ; 72 break; 73 case 8000: //nellymoser only 74 case 5512: //not mp3 75 if(enc->codec_id != CODEC_ID_MP3){ 76 flags |= FLV_SAMPLERATE_SPECIAL; 77 break; 78 } 79 default: 80 av_log(enc, AV_LOG_ERROR, "flv does not support that sample rate, choose from (44100, 22050, 11025).\n"); 81 return -1; 82 } 83 } 84 85 if (enc->channels > 1) { 86 flags |= FLV_STEREO; 87 } 88 89 switch(enc->codec_id){ 90 case CODEC_ID_MP3: 91 flags |= FLV_CODECID_MP3 | FLV_SAMPLESSIZE_16BIT; 92 break; 93 case CODEC_ID_PCM_S8: 94 flags |= FLV_CODECID_PCM | FLV_SAMPLESSIZE_8BIT; 95 break; 96 case CODEC_ID_PCM_S16BE: 97 flags |= FLV_CODECID_PCM | FLV_SAMPLESSIZE_16BIT; 98 break; 99 case CODEC_ID_PCM_S16LE: 100 flags |= FLV_CODECID_PCM_LE | FLV_SAMPLESSIZE_16BIT; 101 break; 102 case CODEC_ID_ADPCM_SWF: 103 flags |= FLV_CODECID_ADPCM | FLV_SAMPLESSIZE_16BIT; 104 break; 105 case CODEC_ID_NELLYMOSER: 106 if (enc->sample_rate == 8000) { 107 flags |= FLV_CODECID_NELLYMOSER_8KHZ_MONO | FLV_SAMPLESSIZE_16BIT; 108 } else { 109 flags |= FLV_CODECID_NELLYMOSER | FLV_SAMPLESSIZE_16BIT; 110 } 111 break; 112 case 0: 113 flags |= enc->codec_tag<<4; 114 break; 115 default: 116 av_log(enc, AV_LOG_ERROR, "codec not compatible with flv\n"); 117 return -1; 118 } 119 120 return flags; 121} 122 123static void put_amf_string(ByteIOContext *pb, const char *str) 124{ 125 size_t len = strlen(str); 126 put_be16(pb, len); 127 put_buffer(pb, str, len); 128} 129 130static void put_amf_double(ByteIOContext *pb, double d) 131{ 132 put_byte(pb, AMF_DATA_TYPE_NUMBER); 133 put_be64(pb, av_dbl2int(d)); 134} 135 136static void put_amf_bool(ByteIOContext *pb, int b) { 137 put_byte(pb, AMF_DATA_TYPE_BOOL); 138 put_byte(pb, !!b); 139} 140 141static int flv_write_header(AVFormatContext *s) 142{ 143 ByteIOContext *pb = s->pb; 144 FLVContext *flv = s->priv_data; 145 AVCodecContext *audio_enc = NULL, *video_enc = NULL; 146 int i; 147 double framerate = 0.0; 148 int metadata_size_pos, data_size; 149 150 for(i=0; i<s->nb_streams; i++){ 151 AVCodecContext *enc = s->streams[i]->codec; 152 if (enc->codec_type == CODEC_TYPE_VIDEO) { 153 if (s->streams[i]->r_frame_rate.den && s->streams[i]->r_frame_rate.num) { 154 framerate = av_q2d(s->streams[i]->r_frame_rate); 155 } else { 156 framerate = 1/av_q2d(s->streams[i]->codec->time_base); 157 } 158 video_enc = enc; 159 if(enc->codec_tag == 0) { 160 av_log(enc, AV_LOG_ERROR, "video codec not compatible with flv\n"); 161 return -1; 162 } 163 } else { 164 audio_enc = enc; 165 if(get_audio_flags(enc)<0) 166 return -1; 167 } 168 av_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */ 169 } 170 put_tag(pb,"FLV"); 171 put_byte(pb,1); 172 put_byte(pb, FLV_HEADER_FLAG_HASAUDIO * !!audio_enc 173 + FLV_HEADER_FLAG_HASVIDEO * !!video_enc); 174 put_be32(pb,9); 175 put_be32(pb,0); 176 177 for(i=0; i<s->nb_streams; i++){ 178 if(s->streams[i]->codec->codec_tag == 5){ 179 put_byte(pb,8); // message type 180 put_be24(pb,0); // include flags 181 put_be24(pb,0); // time stamp 182 put_be32(pb,0); // reserved 183 put_be32(pb,11); // size 184 flv->reserved=5; 185 } 186 } 187 188 /* write meta_tag */ 189 put_byte(pb, 18); // tag type META 190 metadata_size_pos= url_ftell(pb); 191 put_be24(pb, 0); // size of data part (sum of all parts below) 192 put_be24(pb, 0); // time stamp 193 put_be32(pb, 0); // reserved 194 195 /* now data of data_size size */ 196 197 /* first event name as a string */ 198 put_byte(pb, AMF_DATA_TYPE_STRING); 199 put_amf_string(pb, "onMetaData"); // 12 bytes 200 201 /* mixed array (hash) with size and string/type/data tuples */ 202 put_byte(pb, AMF_DATA_TYPE_MIXEDARRAY); 203 put_be32(pb, 5*!!video_enc + 4*!!audio_enc + 2); // +2 for duration and file size 204 205 put_amf_string(pb, "duration"); 206 flv->duration_offset= url_ftell(pb); 207 put_amf_double(pb, 0); // delayed write 208 209 if(video_enc){ 210 put_amf_string(pb, "width"); 211 put_amf_double(pb, video_enc->width); 212 213 put_amf_string(pb, "height"); 214 put_amf_double(pb, video_enc->height); 215 216 put_amf_string(pb, "videodatarate"); 217 put_amf_double(pb, video_enc->bit_rate / 1024.0); 218 219 put_amf_string(pb, "framerate"); 220 put_amf_double(pb, framerate); 221 222 put_amf_string(pb, "videocodecid"); 223 put_amf_double(pb, video_enc->codec_tag); 224 } 225 226 if(audio_enc){ 227 put_amf_string(pb, "audiodatarate"); 228 put_amf_double(pb, audio_enc->bit_rate / 1024.0); 229 230 put_amf_string(pb, "audiosamplerate"); 231 put_amf_double(pb, audio_enc->sample_rate); 232 233 put_amf_string(pb, "audiosamplesize"); 234 put_amf_double(pb, audio_enc->codec_id == CODEC_ID_PCM_S8 ? 8 : 16); 235 236 put_amf_string(pb, "stereo"); 237 put_amf_bool(pb, audio_enc->channels == 2); 238 239 put_amf_string(pb, "audiocodecid"); 240 put_amf_double(pb, audio_enc->codec_tag); 241 } 242 243 put_amf_string(pb, "filesize"); 244 flv->filesize_offset= url_ftell(pb); 245 put_amf_double(pb, 0); // delayed write 246 247 put_amf_string(pb, ""); 248 put_byte(pb, AMF_END_OF_OBJECT); 249 250 /* write total size of tag */ 251 data_size= url_ftell(pb) - metadata_size_pos - 10; 252 url_fseek(pb, metadata_size_pos, SEEK_SET); 253 put_be24(pb, data_size); 254 url_fseek(pb, data_size + 10 - 3, SEEK_CUR); 255 put_be32(pb, data_size + 11); 256 257 for (i = 0; i < s->nb_streams; i++) { 258 AVCodecContext *enc = s->streams[i]->codec; 259 if (enc->codec_id == CODEC_ID_AAC || enc->codec_id == CODEC_ID_H264) { 260 int64_t pos; 261 put_byte(pb, enc->codec_type == CODEC_TYPE_VIDEO ? 262 FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO); 263 put_be24(pb, 0); // size patched later 264 put_be24(pb, 0); // ts 265 put_byte(pb, 0); // ts ext 266 put_be24(pb, 0); // streamid 267 pos = url_ftell(pb); 268 if (enc->codec_id == CODEC_ID_AAC) { 269 put_byte(pb, get_audio_flags(enc)); 270 put_byte(pb, 0); // AAC sequence header 271 put_buffer(pb, enc->extradata, enc->extradata_size); 272 } else { 273 put_byte(pb, enc->codec_tag | FLV_FRAME_KEY); // flags 274 put_byte(pb, 0); // AVC sequence header 275 put_be24(pb, 0); // composition time 276 ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size); 277 } 278 data_size = url_ftell(pb) - pos; 279 url_fseek(pb, -data_size - 10, SEEK_CUR); 280 put_be24(pb, data_size); 281 url_fseek(pb, data_size + 10 - 3, SEEK_CUR); 282 put_be32(pb, data_size + 11); // previous tag size 283 } 284 } 285 286 return 0; 287} 288 289static int flv_write_trailer(AVFormatContext *s) 290{ 291 int64_t file_size; 292 293 ByteIOContext *pb = s->pb; 294 FLVContext *flv = s->priv_data; 295 296 file_size = url_ftell(pb); 297 298 /* update informations */ 299 url_fseek(pb, flv->duration_offset, SEEK_SET); 300 put_amf_double(pb, flv->duration / (double)1000); 301 url_fseek(pb, flv->filesize_offset, SEEK_SET); 302 put_amf_double(pb, file_size); 303 304 url_fseek(pb, file_size, SEEK_SET); 305 return 0; 306} 307 308static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) 309{ 310 ByteIOContext *pb = s->pb; 311 AVCodecContext *enc = s->streams[pkt->stream_index]->codec; 312 FLVContext *flv = s->priv_data; 313 unsigned ts; 314 int size= pkt->size; 315 uint8_t *data= NULL; 316 int flags, flags_size; 317 318// av_log(s, AV_LOG_DEBUG, "type:%d pts: %"PRId64" size:%d\n", enc->codec_type, timestamp, size); 319 320 if(enc->codec_id == CODEC_ID_VP6 || enc->codec_id == CODEC_ID_VP6F || 321 enc->codec_id == CODEC_ID_AAC) 322 flags_size= 2; 323 else if(enc->codec_id == CODEC_ID_H264) 324 flags_size= 5; 325 else 326 flags_size= 1; 327 328 if (enc->codec_type == CODEC_TYPE_VIDEO) { 329 put_byte(pb, FLV_TAG_TYPE_VIDEO); 330 331 flags = enc->codec_tag; 332 if(flags == 0) { 333 av_log(enc, AV_LOG_ERROR, "video codec %X not compatible with flv\n",enc->codec_id); 334 return -1; 335 } 336 337 flags |= pkt->flags & PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER; 338 } else { 339 assert(enc->codec_type == CODEC_TYPE_AUDIO); 340 flags = get_audio_flags(enc); 341 342 assert(size); 343 344 put_byte(pb, FLV_TAG_TYPE_AUDIO); 345 } 346 347 if (enc->codec_id == CODEC_ID_H264) { 348 /* check if extradata looks like mp4 formated */ 349 if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1) { 350 if (ff_avc_parse_nal_units_buf(pkt->data, &data, &size) < 0) 351 return -1; 352 } 353 if (!flv->delay && pkt->dts < 0) 354 flv->delay = -pkt->dts; 355 } 356 357 ts = pkt->dts + flv->delay; // add delay to force positive dts 358 put_be24(pb,size + flags_size); 359 put_be24(pb,ts); 360 put_byte(pb,(ts >> 24) & 0x7F); // timestamps are 32bits _signed_ 361 put_be24(pb,flv->reserved); 362 put_byte(pb,flags); 363 if (enc->codec_id == CODEC_ID_VP6) 364 put_byte(pb,0); 365 if (enc->codec_id == CODEC_ID_VP6F) 366 put_byte(pb, enc->extradata_size ? enc->extradata[0] : 0); 367 else if (enc->codec_id == CODEC_ID_AAC) 368 put_byte(pb,1); // AAC raw 369 else if (enc->codec_id == CODEC_ID_H264) { 370 put_byte(pb,1); // AVC NALU 371 put_be24(pb,pkt->pts - pkt->dts); 372 } 373 374 put_buffer(pb, data ? data : pkt->data, size); 375 376 put_be32(pb,size+flags_size+11); // previous tag size 377 flv->duration = FFMAX(flv->duration, pkt->pts + flv->delay + pkt->duration); 378 379 put_flush_packet(pb); 380 381 av_free(data); 382 383 return 0; 384} 385 386AVOutputFormat flv_muxer = { 387 "flv", 388 NULL_IF_CONFIG_SMALL("FLV format"), 389 "video/x-flv", 390 "flv", 391 sizeof(FLVContext), 392#if CONFIG_LIBMP3LAME 393 CODEC_ID_MP3, 394#else // CONFIG_LIBMP3LAME 395 CODEC_ID_ADPCM_SWF, 396#endif // CONFIG_LIBMP3LAME 397 CODEC_ID_FLV1, 398 flv_write_header, 399 flv_write_packet, 400 flv_write_trailer, 401 .codec_tag= (const AVCodecTag* const []){flv_video_codec_ids, flv_audio_codec_ids, 0}, 402 .flags= AVFMT_GLOBALHEADER, 403}; 404