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 22#include "libavutil/intreadwrite.h" 23#include "libavutil/dict.h" 24#include "libavutil/intfloat.h" 25#include "libavutil/avassert.h" 26#include "avc.h" 27#include "avformat.h" 28#include "flv.h" 29#include "internal.h" 30#include "metadata.h" 31 32 33static const AVCodecTag flv_video_codec_ids[] = { 34 { AV_CODEC_ID_FLV1, FLV_CODECID_H263 }, 35 { AV_CODEC_ID_H263, FLV_CODECID_REALH263 }, 36 { AV_CODEC_ID_MPEG4, FLV_CODECID_MPEG4 }, 37 { AV_CODEC_ID_FLASHSV, FLV_CODECID_SCREEN }, 38 { AV_CODEC_ID_FLASHSV2, FLV_CODECID_SCREEN2 }, 39 { AV_CODEC_ID_VP6F, FLV_CODECID_VP6 }, 40 { AV_CODEC_ID_VP6, FLV_CODECID_VP6 }, 41 { AV_CODEC_ID_VP6A, FLV_CODECID_VP6A }, 42 { AV_CODEC_ID_H264, FLV_CODECID_H264 }, 43 { AV_CODEC_ID_NONE, 0 } 44}; 45 46static const AVCodecTag flv_audio_codec_ids[] = { 47 { AV_CODEC_ID_MP3, FLV_CODECID_MP3 >> FLV_AUDIO_CODECID_OFFSET }, 48 { AV_CODEC_ID_PCM_U8, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET }, 49 { AV_CODEC_ID_PCM_S16BE, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET }, 50 { AV_CODEC_ID_PCM_S16LE, FLV_CODECID_PCM_LE >> FLV_AUDIO_CODECID_OFFSET }, 51 { AV_CODEC_ID_ADPCM_SWF, FLV_CODECID_ADPCM >> FLV_AUDIO_CODECID_OFFSET }, 52 { AV_CODEC_ID_AAC, FLV_CODECID_AAC >> FLV_AUDIO_CODECID_OFFSET }, 53 { AV_CODEC_ID_NELLYMOSER, FLV_CODECID_NELLYMOSER >> FLV_AUDIO_CODECID_OFFSET }, 54 { AV_CODEC_ID_PCM_MULAW, FLV_CODECID_PCM_MULAW >> FLV_AUDIO_CODECID_OFFSET }, 55 { AV_CODEC_ID_PCM_ALAW, FLV_CODECID_PCM_ALAW >> FLV_AUDIO_CODECID_OFFSET }, 56 { AV_CODEC_ID_SPEEX, FLV_CODECID_SPEEX >> FLV_AUDIO_CODECID_OFFSET }, 57 { AV_CODEC_ID_NONE, 0 } 58}; 59 60typedef struct FLVContext { 61 int reserved; 62 int64_t duration_offset; 63 int64_t filesize_offset; 64 int64_t duration; 65 int64_t delay; ///< first dts delay (needed for AVC & Speex) 66} FLVContext; 67 68typedef struct FLVStreamContext { 69 int64_t last_ts; ///< last timestamp for each stream 70} FLVStreamContext; 71 72static int get_audio_flags(AVFormatContext *s, AVCodecContext *enc) 73{ 74 int flags = (enc->bits_per_coded_sample == 16) ? FLV_SAMPLESSIZE_16BIT 75 : FLV_SAMPLESSIZE_8BIT; 76 77 if (enc->codec_id == AV_CODEC_ID_AAC) // specs force these parameters 78 return FLV_CODECID_AAC | FLV_SAMPLERATE_44100HZ | 79 FLV_SAMPLESSIZE_16BIT | FLV_STEREO; 80 else if (enc->codec_id == AV_CODEC_ID_SPEEX) { 81 if (enc->sample_rate != 16000) { 82 av_log(s, AV_LOG_ERROR, 83 "FLV only supports wideband (16kHz) Speex audio\n"); 84 return AVERROR(EINVAL); 85 } 86 if (enc->channels != 1) { 87 av_log(s, AV_LOG_ERROR, "FLV only supports mono Speex audio\n"); 88 return AVERROR(EINVAL); 89 } 90 return FLV_CODECID_SPEEX | FLV_SAMPLERATE_11025HZ | FLV_SAMPLESSIZE_16BIT; 91 } else { 92 switch (enc->sample_rate) { 93 case 44100: 94 flags |= FLV_SAMPLERATE_44100HZ; 95 break; 96 case 22050: 97 flags |= FLV_SAMPLERATE_22050HZ; 98 break; 99 case 11025: 100 flags |= FLV_SAMPLERATE_11025HZ; 101 break; 102 case 16000: // nellymoser only 103 case 8000: // nellymoser only 104 case 5512: // not MP3 105 if (enc->codec_id != AV_CODEC_ID_MP3) { 106 flags |= FLV_SAMPLERATE_SPECIAL; 107 break; 108 } 109 default: 110 av_log(s, AV_LOG_ERROR, 111 "FLV does not support sample rate %d, " 112 "choose from (44100, 22050, 11025)\n", enc->sample_rate); 113 return AVERROR(EINVAL); 114 } 115 } 116 117 if (enc->channels > 1) 118 flags |= FLV_STEREO; 119 120 switch (enc->codec_id) { 121 case AV_CODEC_ID_MP3: 122 flags |= FLV_CODECID_MP3 | FLV_SAMPLESSIZE_16BIT; 123 break; 124 case AV_CODEC_ID_PCM_U8: 125 flags |= FLV_CODECID_PCM | FLV_SAMPLESSIZE_8BIT; 126 break; 127 case AV_CODEC_ID_PCM_S16BE: 128 flags |= FLV_CODECID_PCM | FLV_SAMPLESSIZE_16BIT; 129 break; 130 case AV_CODEC_ID_PCM_S16LE: 131 flags |= FLV_CODECID_PCM_LE | FLV_SAMPLESSIZE_16BIT; 132 break; 133 case AV_CODEC_ID_ADPCM_SWF: 134 flags |= FLV_CODECID_ADPCM | FLV_SAMPLESSIZE_16BIT; 135 break; 136 case AV_CODEC_ID_NELLYMOSER: 137 if (enc->sample_rate == 8000) 138 flags |= FLV_CODECID_NELLYMOSER_8KHZ_MONO | FLV_SAMPLESSIZE_16BIT; 139 else if (enc->sample_rate == 16000) 140 flags |= FLV_CODECID_NELLYMOSER_16KHZ_MONO | FLV_SAMPLESSIZE_16BIT; 141 else 142 flags |= FLV_CODECID_NELLYMOSER | FLV_SAMPLESSIZE_16BIT; 143 break; 144 case AV_CODEC_ID_PCM_MULAW: 145 flags = FLV_CODECID_PCM_MULAW | FLV_SAMPLERATE_SPECIAL | FLV_SAMPLESSIZE_16BIT; 146 break; 147 case AV_CODEC_ID_PCM_ALAW: 148 flags = FLV_CODECID_PCM_ALAW | FLV_SAMPLERATE_SPECIAL | FLV_SAMPLESSIZE_16BIT; 149 break; 150 case 0: 151 flags |= enc->codec_tag << 4; 152 break; 153 default: 154 av_log(s, AV_LOG_ERROR, "Audio codec '%s' not compatible with FLV\n", 155 avcodec_get_name(enc->codec_id)); 156 return AVERROR(EINVAL); 157 } 158 159 return flags; 160} 161 162static void put_amf_string(AVIOContext *pb, const char *str) 163{ 164 size_t len = strlen(str); 165 avio_wb16(pb, len); 166 avio_write(pb, str, len); 167} 168 169static void put_avc_eos_tag(AVIOContext *pb, unsigned ts) 170{ 171 avio_w8(pb, FLV_TAG_TYPE_VIDEO); 172 avio_wb24(pb, 5); /* Tag Data Size */ 173 avio_wb24(pb, ts); /* lower 24 bits of timestamp in ms */ 174 avio_w8(pb, (ts >> 24) & 0x7F); /* MSB of ts in ms */ 175 avio_wb24(pb, 0); /* StreamId = 0 */ 176 avio_w8(pb, 23); /* ub[4] FrameType = 1, ub[4] CodecId = 7 */ 177 avio_w8(pb, 2); /* AVC end of sequence */ 178 avio_wb24(pb, 0); /* Always 0 for AVC EOS. */ 179 avio_wb32(pb, 16); /* Size of FLV tag */ 180} 181 182static void put_amf_double(AVIOContext *pb, double d) 183{ 184 avio_w8(pb, AMF_DATA_TYPE_NUMBER); 185 avio_wb64(pb, av_double2int(d)); 186} 187 188static void put_amf_bool(AVIOContext *pb, int b) 189{ 190 avio_w8(pb, AMF_DATA_TYPE_BOOL); 191 avio_w8(pb, !!b); 192} 193 194static int flv_write_header(AVFormatContext *s) 195{ 196 AVIOContext *pb = s->pb; 197 FLVContext *flv = s->priv_data; 198 AVCodecContext *audio_enc = NULL, *video_enc = NULL, *data_enc = NULL; 199 int i, metadata_count = 0; 200 double framerate = 0.0; 201 int64_t metadata_size_pos, data_size, metadata_count_pos; 202 AVDictionaryEntry *tag = NULL; 203 204 for (i = 0; i < s->nb_streams; i++) { 205 AVCodecContext *enc = s->streams[i]->codec; 206 FLVStreamContext *sc; 207 switch (enc->codec_type) { 208 case AVMEDIA_TYPE_VIDEO: 209 if (s->streams[i]->avg_frame_rate.den && 210 s->streams[i]->avg_frame_rate.num) { 211 framerate = av_q2d(s->streams[i]->avg_frame_rate); 212 } 213 if (video_enc) { 214 av_log(s, AV_LOG_ERROR, 215 "at most one video stream is supported in flv\n"); 216 return AVERROR(EINVAL); 217 } 218 video_enc = enc; 219 if (enc->codec_tag == 0) { 220 av_log(s, AV_LOG_ERROR, "Video codec '%s' for stream %d is not compatible with FLV\n", 221 avcodec_get_name(enc->codec_id), i); 222 return AVERROR(EINVAL); 223 } 224 if (enc->codec_id == AV_CODEC_ID_MPEG4 || 225 enc->codec_id == AV_CODEC_ID_H263) { 226 int error = enc->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL; 227 av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING, 228 "Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(enc->codec_id)); 229 230 if (error) { 231 av_log(s, AV_LOG_ERROR, 232 "use vstrict=-1 / -strict -1 to use it anyway.\n"); 233 return AVERROR(EINVAL); 234 } 235 } 236 break; 237 case AVMEDIA_TYPE_AUDIO: 238 if (audio_enc) { 239 av_log(s, AV_LOG_ERROR, 240 "at most one audio stream is supported in flv\n"); 241 return AVERROR(EINVAL); 242 } 243 audio_enc = enc; 244 if (get_audio_flags(s, enc) < 0) 245 return AVERROR_INVALIDDATA; 246 if (enc->codec_id == AV_CODEC_ID_PCM_S16BE) 247 av_log(s, AV_LOG_WARNING, 248 "16-bit big-endian audio in flv is valid but most likely unplayable (hardware dependent); use s16le\n"); 249 break; 250 case AVMEDIA_TYPE_DATA: 251 if (enc->codec_id != AV_CODEC_ID_TEXT) { 252 av_log(s, AV_LOG_ERROR, "Data codec '%s' for stream %d is not compatible with FLV\n", 253 avcodec_get_name(enc->codec_id), i); 254 return AVERROR_INVALIDDATA; 255 } 256 data_enc = enc; 257 break; 258 default: 259 av_log(s, AV_LOG_ERROR, "Codec type '%s' for stream %d is not compatible with FLV\n", 260 av_get_media_type_string(enc->codec_type), i); 261 return AVERROR(EINVAL); 262 } 263 avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */ 264 265 sc = av_mallocz(sizeof(FLVStreamContext)); 266 if (!sc) 267 return AVERROR(ENOMEM); 268 s->streams[i]->priv_data = sc; 269 sc->last_ts = -1; 270 } 271 272 flv->delay = AV_NOPTS_VALUE; 273 274 avio_write(pb, "FLV", 3); 275 avio_w8(pb, 1); 276 avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!audio_enc + 277 FLV_HEADER_FLAG_HASVIDEO * !!video_enc); 278 avio_wb32(pb, 9); 279 avio_wb32(pb, 0); 280 281 for (i = 0; i < s->nb_streams; i++) 282 if (s->streams[i]->codec->codec_tag == 5) { 283 avio_w8(pb, 8); // message type 284 avio_wb24(pb, 0); // include flags 285 avio_wb24(pb, 0); // time stamp 286 avio_wb32(pb, 0); // reserved 287 avio_wb32(pb, 11); // size 288 flv->reserved = 5; 289 } 290 291 /* write meta_tag */ 292 avio_w8(pb, 18); // tag type META 293 metadata_size_pos = avio_tell(pb); 294 avio_wb24(pb, 0); // size of data part (sum of all parts below) 295 avio_wb24(pb, 0); // timestamp 296 avio_wb32(pb, 0); // reserved 297 298 /* now data of data_size size */ 299 300 /* first event name as a string */ 301 avio_w8(pb, AMF_DATA_TYPE_STRING); 302 put_amf_string(pb, "onMetaData"); // 12 bytes 303 304 /* mixed array (hash) with size and string/type/data tuples */ 305 avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY); 306 metadata_count_pos = avio_tell(pb); 307 metadata_count = 4 * !!video_enc + 308 5 * !!audio_enc + 309 1 * !!data_enc + 310 2; // +2 for duration and file size 311 312 avio_wb32(pb, metadata_count); 313 314 put_amf_string(pb, "duration"); 315 flv->duration_offset= avio_tell(pb); 316 317 // fill in the guessed duration, it'll be corrected later if incorrect 318 put_amf_double(pb, s->duration / AV_TIME_BASE); 319 320 if (video_enc) { 321 put_amf_string(pb, "width"); 322 put_amf_double(pb, video_enc->width); 323 324 put_amf_string(pb, "height"); 325 put_amf_double(pb, video_enc->height); 326 327 put_amf_string(pb, "videodatarate"); 328 put_amf_double(pb, video_enc->bit_rate / 1024.0); 329 330 if (framerate != 0.0) { 331 put_amf_string(pb, "framerate"); 332 put_amf_double(pb, framerate); 333 metadata_count++; 334 } 335 336 put_amf_string(pb, "videocodecid"); 337 put_amf_double(pb, video_enc->codec_tag); 338 } 339 340 if (audio_enc) { 341 put_amf_string(pb, "audiodatarate"); 342 put_amf_double(pb, audio_enc->bit_rate / 1024.0); 343 344 put_amf_string(pb, "audiosamplerate"); 345 put_amf_double(pb, audio_enc->sample_rate); 346 347 put_amf_string(pb, "audiosamplesize"); 348 put_amf_double(pb, audio_enc->codec_id == AV_CODEC_ID_PCM_U8 ? 8 : 16); 349 350 put_amf_string(pb, "stereo"); 351 put_amf_bool(pb, audio_enc->channels == 2); 352 353 put_amf_string(pb, "audiocodecid"); 354 put_amf_double(pb, audio_enc->codec_tag); 355 } 356 357 if (data_enc) { 358 put_amf_string(pb, "datastream"); 359 put_amf_double(pb, 0.0); 360 } 361 362 while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { 363 if( !strcmp(tag->key, "width") 364 ||!strcmp(tag->key, "height") 365 ||!strcmp(tag->key, "videodatarate") 366 ||!strcmp(tag->key, "framerate") 367 ||!strcmp(tag->key, "videocodecid") 368 ||!strcmp(tag->key, "audiodatarate") 369 ||!strcmp(tag->key, "audiosamplerate") 370 ||!strcmp(tag->key, "audiosamplesize") 371 ||!strcmp(tag->key, "stereo") 372 ||!strcmp(tag->key, "audiocodecid") 373 ||!strcmp(tag->key, "duration") 374 ||!strcmp(tag->key, "onMetaData") 375 ){ 376 av_log(s, AV_LOG_DEBUG, "Ignoring metadata for %s\n", tag->key); 377 continue; 378 } 379 put_amf_string(pb, tag->key); 380 avio_w8(pb, AMF_DATA_TYPE_STRING); 381 put_amf_string(pb, tag->value); 382 metadata_count++; 383 } 384 385 put_amf_string(pb, "filesize"); 386 flv->filesize_offset = avio_tell(pb); 387 put_amf_double(pb, 0); // delayed write 388 389 put_amf_string(pb, ""); 390 avio_w8(pb, AMF_END_OF_OBJECT); 391 392 /* write total size of tag */ 393 data_size = avio_tell(pb) - metadata_size_pos - 10; 394 395 avio_seek(pb, metadata_count_pos, SEEK_SET); 396 avio_wb32(pb, metadata_count); 397 398 avio_seek(pb, metadata_size_pos, SEEK_SET); 399 avio_wb24(pb, data_size); 400 avio_skip(pb, data_size + 10 - 3); 401 avio_wb32(pb, data_size + 11); 402 403 for (i = 0; i < s->nb_streams; i++) { 404 AVCodecContext *enc = s->streams[i]->codec; 405 if (enc->codec_id == AV_CODEC_ID_AAC || enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) { 406 int64_t pos; 407 avio_w8(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ? 408 FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO); 409 avio_wb24(pb, 0); // size patched later 410 avio_wb24(pb, 0); // ts 411 avio_w8(pb, 0); // ts ext 412 avio_wb24(pb, 0); // streamid 413 pos = avio_tell(pb); 414 if (enc->codec_id == AV_CODEC_ID_AAC) { 415 avio_w8(pb, get_audio_flags(s, enc)); 416 avio_w8(pb, 0); // AAC sequence header 417 avio_write(pb, enc->extradata, enc->extradata_size); 418 } else { 419 avio_w8(pb, enc->codec_tag | FLV_FRAME_KEY); // flags 420 avio_w8(pb, 0); // AVC sequence header 421 avio_wb24(pb, 0); // composition time 422 ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size); 423 } 424 data_size = avio_tell(pb) - pos; 425 avio_seek(pb, -data_size - 10, SEEK_CUR); 426 avio_wb24(pb, data_size); 427 avio_skip(pb, data_size + 10 - 3); 428 avio_wb32(pb, data_size + 11); // previous tag size 429 } 430 } 431 432 return 0; 433} 434 435static int flv_write_trailer(AVFormatContext *s) 436{ 437 int64_t file_size; 438 439 AVIOContext *pb = s->pb; 440 FLVContext *flv = s->priv_data; 441 int i; 442 443 /* Add EOS tag */ 444 for (i = 0; i < s->nb_streams; i++) { 445 AVCodecContext *enc = s->streams[i]->codec; 446 FLVStreamContext *sc = s->streams[i]->priv_data; 447 if (enc->codec_type == AVMEDIA_TYPE_VIDEO && 448 (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4)) 449 put_avc_eos_tag(pb, sc->last_ts); 450 } 451 452 file_size = avio_tell(pb); 453 454 /* update information */ 455 if (avio_seek(pb, flv->duration_offset, SEEK_SET) < 0) 456 av_log(s, AV_LOG_WARNING, "Failed to update header with correct duration.\n"); 457 else 458 put_amf_double(pb, flv->duration / (double)1000); 459 if (avio_seek(pb, flv->filesize_offset, SEEK_SET) < 0) 460 av_log(s, AV_LOG_WARNING, "Failed to update header with correct filesize.\n"); 461 else 462 put_amf_double(pb, file_size); 463 464 avio_seek(pb, file_size, SEEK_SET); 465 return 0; 466} 467 468static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) 469{ 470 AVIOContext *pb = s->pb; 471 AVCodecContext *enc = s->streams[pkt->stream_index]->codec; 472 FLVContext *flv = s->priv_data; 473 FLVStreamContext *sc = s->streams[pkt->stream_index]->priv_data; 474 unsigned ts; 475 int size = pkt->size; 476 uint8_t *data = NULL; 477 int flags = -1, flags_size, ret; 478 479 if (enc->codec_id == AV_CODEC_ID_VP6F || enc->codec_id == AV_CODEC_ID_VP6A || 480 enc->codec_id == AV_CODEC_ID_VP6 || enc->codec_id == AV_CODEC_ID_AAC) 481 flags_size = 2; 482 else if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) 483 flags_size = 5; 484 else 485 flags_size = 1; 486 487 switch (enc->codec_type) { 488 case AVMEDIA_TYPE_VIDEO: 489 avio_w8(pb, FLV_TAG_TYPE_VIDEO); 490 491 flags = enc->codec_tag; 492 if (flags == 0) { 493 av_log(s, AV_LOG_ERROR, 494 "Video codec '%s' is not compatible with FLV\n", 495 avcodec_get_name(enc->codec_id)); 496 return AVERROR(EINVAL); 497 } 498 499 flags |= pkt->flags & AV_PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER; 500 break; 501 case AVMEDIA_TYPE_AUDIO: 502 flags = get_audio_flags(s, enc); 503 504 av_assert0(size); 505 506 avio_w8(pb, FLV_TAG_TYPE_AUDIO); 507 break; 508 case AVMEDIA_TYPE_DATA: 509 avio_w8(pb, FLV_TAG_TYPE_META); 510 break; 511 default: 512 return AVERROR(EINVAL); 513 } 514 515 if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) { 516 /* check if extradata looks like mp4 formated */ 517 if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1) 518 if ((ret = ff_avc_parse_nal_units_buf(pkt->data, &data, &size)) < 0) 519 return ret; 520 } else if (enc->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 && 521 (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) { 522 if (!s->streams[pkt->stream_index]->nb_frames) { 523 av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: " 524 "use audio bitstream filter 'aac_adtstoasc' to fix it " 525 "('-bsf:a aac_adtstoasc' option with ffmpeg)\n"); 526 return AVERROR_INVALIDDATA; 527 } 528 av_log(s, AV_LOG_WARNING, "aac bitstream error\n"); 529 } 530 531 if (flv->delay == AV_NOPTS_VALUE) 532 flv->delay = -pkt->dts; 533 534 if (pkt->dts < -flv->delay) { 535 av_log(s, AV_LOG_WARNING, 536 "Packets are not in the proper order with respect to DTS\n"); 537 return AVERROR(EINVAL); 538 } 539 540 ts = pkt->dts + flv->delay; // add delay to force positive dts 541 542 /* check Speex packet duration */ 543 if (enc->codec_id == AV_CODEC_ID_SPEEX && ts - sc->last_ts > 160) 544 av_log(s, AV_LOG_WARNING, "Warning: Speex stream has more than " 545 "8 frames per packet. Adobe Flash " 546 "Player cannot handle this!\n"); 547 548 if (sc->last_ts < ts) 549 sc->last_ts = ts; 550 551 avio_wb24(pb, size + flags_size); 552 avio_wb24(pb, ts & 0xFFFFFF); 553 avio_w8(pb, (ts >> 24) & 0x7F); // timestamps are 32 bits _signed_ 554 avio_wb24(pb, flv->reserved); 555 556 if (enc->codec_type == AVMEDIA_TYPE_DATA) { 557 int data_size; 558 int64_t metadata_size_pos = avio_tell(pb); 559 avio_w8(pb, AMF_DATA_TYPE_STRING); 560 put_amf_string(pb, "onTextData"); 561 avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY); 562 avio_wb32(pb, 2); 563 put_amf_string(pb, "type"); 564 avio_w8(pb, AMF_DATA_TYPE_STRING); 565 put_amf_string(pb, "Text"); 566 put_amf_string(pb, "text"); 567 avio_w8(pb, AMF_DATA_TYPE_STRING); 568 put_amf_string(pb, pkt->data); 569 put_amf_string(pb, ""); 570 avio_w8(pb, AMF_END_OF_OBJECT); 571 /* write total size of tag */ 572 data_size = avio_tell(pb) - metadata_size_pos; 573 avio_seek(pb, metadata_size_pos - 10, SEEK_SET); 574 avio_wb24(pb, data_size); 575 avio_seek(pb, data_size + 10 - 3, SEEK_CUR); 576 avio_wb32(pb, data_size + 11); 577 } else { 578 av_assert1(flags>=0); 579 avio_w8(pb,flags); 580 if (enc->codec_id == AV_CODEC_ID_VP6) 581 avio_w8(pb,0); 582 if (enc->codec_id == AV_CODEC_ID_VP6F || enc->codec_id == AV_CODEC_ID_VP6A) { 583 if (enc->extradata_size) 584 avio_w8(pb, enc->extradata[0]); 585 else 586 avio_w8(pb, ((FFALIGN(enc->width, 16) - enc->width) << 4) | 587 (FFALIGN(enc->height, 16) - enc->height)); 588 } else if (enc->codec_id == AV_CODEC_ID_AAC) 589 avio_w8(pb, 1); // AAC raw 590 else if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) { 591 avio_w8(pb, 1); // AVC NALU 592 avio_wb24(pb, pkt->pts - pkt->dts); 593 } 594 595 avio_write(pb, data ? data : pkt->data, size); 596 597 avio_wb32(pb, size + flags_size + 11); // previous tag size 598 flv->duration = FFMAX(flv->duration, 599 pkt->pts + flv->delay + pkt->duration); 600 } 601 602 av_free(data); 603 604 return pb->error; 605} 606 607AVOutputFormat ff_flv_muxer = { 608 .name = "flv", 609 .long_name = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"), 610 .mime_type = "video/x-flv", 611 .extensions = "flv", 612 .priv_data_size = sizeof(FLVContext), 613 .audio_codec = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_ADPCM_SWF, 614 .video_codec = AV_CODEC_ID_FLV1, 615 .write_header = flv_write_header, 616 .write_packet = flv_write_packet, 617 .write_trailer = flv_write_trailer, 618 .codec_tag = (const AVCodecTag* const []) { 619 flv_video_codec_ids, flv_audio_codec_ids, 0 620 }, 621 .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS | 622 AVFMT_TS_NONSTRICT, 623}; 624