3 * Copyright (c) 2003 The FFmpeg Project
5 * This file is part of FFmpeg.
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.
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.
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
22 #include "libavutil/intreadwrite.h"
23 #include "libavutil/dict.h"
24 #include "libavutil/intfloat.h"
25 #include "libavutil/avassert.h"
33 static 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 }
46 static 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 }
60 typedef struct FLVContext
{
62 int64_t duration_offset
;
63 int64_t filesize_offset
;
65 int64_t delay
; ///< first dts delay (needed for AVC & Speex)
67 AVCodecContext
*audio_enc
;
68 AVCodecContext
*video_enc
;
70 AVCodecContext
*data_enc
;
73 typedef struct FLVStreamContext
{
74 int64_t last_ts
; ///< last timestamp for each stream
77 static int get_audio_flags(AVFormatContext
*s
, AVCodecContext
*enc
)
79 int flags
= (enc
->bits_per_coded_sample
== 16) ? FLV_SAMPLESSIZE_16BIT
80 : FLV_SAMPLESSIZE_8BIT
;
82 if (enc
->codec_id
== AV_CODEC_ID_AAC
) // specs force these parameters
83 return FLV_CODECID_AAC
| FLV_SAMPLERATE_44100HZ
|
84 FLV_SAMPLESSIZE_16BIT
| FLV_STEREO
;
85 else if (enc
->codec_id
== AV_CODEC_ID_SPEEX
) {
86 if (enc
->sample_rate
!= 16000) {
87 av_log(s
, AV_LOG_ERROR
,
88 "FLV only supports wideband (16kHz) Speex audio\n");
89 return AVERROR(EINVAL
);
91 if (enc
->channels
!= 1) {
92 av_log(s
, AV_LOG_ERROR
, "FLV only supports mono Speex audio\n");
93 return AVERROR(EINVAL
);
95 return FLV_CODECID_SPEEX
| FLV_SAMPLERATE_11025HZ
| FLV_SAMPLESSIZE_16BIT
;
97 switch (enc
->sample_rate
) {
99 flags
|= FLV_SAMPLERATE_44100HZ
;
102 flags
|= FLV_SAMPLERATE_22050HZ
;
105 flags
|= FLV_SAMPLERATE_11025HZ
;
107 case 16000: // nellymoser only
108 case 8000: // nellymoser only
109 case 5512: // not MP3
110 if (enc
->codec_id
!= AV_CODEC_ID_MP3
) {
111 flags
|= FLV_SAMPLERATE_SPECIAL
;
115 av_log(s
, AV_LOG_ERROR
,
116 "FLV does not support sample rate %d, "
117 "choose from (44100, 22050, 11025)\n", enc
->sample_rate
);
118 return AVERROR(EINVAL
);
122 if (enc
->channels
> 1)
125 switch (enc
->codec_id
) {
126 case AV_CODEC_ID_MP3
:
127 flags
|= FLV_CODECID_MP3
| FLV_SAMPLESSIZE_16BIT
;
129 case AV_CODEC_ID_PCM_U8
:
130 flags
|= FLV_CODECID_PCM
| FLV_SAMPLESSIZE_8BIT
;
132 case AV_CODEC_ID_PCM_S16BE
:
133 flags
|= FLV_CODECID_PCM
| FLV_SAMPLESSIZE_16BIT
;
135 case AV_CODEC_ID_PCM_S16LE
:
136 flags
|= FLV_CODECID_PCM_LE
| FLV_SAMPLESSIZE_16BIT
;
138 case AV_CODEC_ID_ADPCM_SWF
:
139 flags
|= FLV_CODECID_ADPCM
| FLV_SAMPLESSIZE_16BIT
;
141 case AV_CODEC_ID_NELLYMOSER
:
142 if (enc
->sample_rate
== 8000)
143 flags
|= FLV_CODECID_NELLYMOSER_8KHZ_MONO
| FLV_SAMPLESSIZE_16BIT
;
144 else if (enc
->sample_rate
== 16000)
145 flags
|= FLV_CODECID_NELLYMOSER_16KHZ_MONO
| FLV_SAMPLESSIZE_16BIT
;
147 flags
|= FLV_CODECID_NELLYMOSER
| FLV_SAMPLESSIZE_16BIT
;
149 case AV_CODEC_ID_PCM_MULAW
:
150 flags
= FLV_CODECID_PCM_MULAW
| FLV_SAMPLERATE_SPECIAL
| FLV_SAMPLESSIZE_16BIT
;
152 case AV_CODEC_ID_PCM_ALAW
:
153 flags
= FLV_CODECID_PCM_ALAW
| FLV_SAMPLERATE_SPECIAL
| FLV_SAMPLESSIZE_16BIT
;
156 flags
|= enc
->codec_tag
<< 4;
159 av_log(s
, AV_LOG_ERROR
, "Audio codec '%s' not compatible with FLV\n",
160 avcodec_get_name(enc
->codec_id
));
161 return AVERROR(EINVAL
);
167 static void put_amf_string(AVIOContext
*pb
, const char *str
)
169 size_t len
= strlen(str
);
171 avio_write(pb
, str
, len
);
174 static void put_avc_eos_tag(AVIOContext
*pb
, unsigned ts
)
176 avio_w8(pb
, FLV_TAG_TYPE_VIDEO
);
177 avio_wb24(pb
, 5); /* Tag Data Size */
178 avio_wb24(pb
, ts
); /* lower 24 bits of timestamp in ms */
179 avio_w8(pb
, (ts
>> 24) & 0x7F); /* MSB of ts in ms */
180 avio_wb24(pb
, 0); /* StreamId = 0 */
181 avio_w8(pb
, 23); /* ub[4] FrameType = 1, ub[4] CodecId = 7 */
182 avio_w8(pb
, 2); /* AVC end of sequence */
183 avio_wb24(pb
, 0); /* Always 0 for AVC EOS. */
184 avio_wb32(pb
, 16); /* Size of FLV tag */
187 static void put_amf_double(AVIOContext
*pb
, double d
)
189 avio_w8(pb
, AMF_DATA_TYPE_NUMBER
);
190 avio_wb64(pb
, av_double2int(d
));
193 static void put_amf_bool(AVIOContext
*pb
, int b
)
195 avio_w8(pb
, AMF_DATA_TYPE_BOOL
);
199 static void write_metadata(AVFormatContext
*s
, unsigned int ts
)
201 AVIOContext
*pb
= s
->pb
;
202 FLVContext
*flv
= s
->priv_data
;
203 int metadata_count
= 0;
204 int64_t metadata_size_pos
, data_size
, metadata_count_pos
;
205 AVDictionaryEntry
*tag
= NULL
;
208 avio_w8(pb
, 18); // tag type META
209 metadata_size_pos
= avio_tell(pb
);
210 avio_wb24(pb
, 0); // size of data part (sum of all parts below)
211 avio_wb24(pb
, ts
); // timestamp
212 avio_wb32(pb
, 0); // reserved
214 /* now data of data_size size */
216 /* first event name as a string */
217 avio_w8(pb
, AMF_DATA_TYPE_STRING
);
218 put_amf_string(pb
, "onMetaData"); // 12 bytes
220 /* mixed array (hash) with size and string/type/data tuples */
221 avio_w8(pb
, AMF_DATA_TYPE_MIXEDARRAY
);
222 metadata_count_pos
= avio_tell(pb
);
223 metadata_count
= 4 * !!flv
->video_enc
+
224 5 * !!flv
->audio_enc
+
225 1 * !!flv
->data_enc
+
226 2; // +2 for duration and file size
228 avio_wb32(pb
, metadata_count
);
230 put_amf_string(pb
, "duration");
231 flv
->duration_offset
= avio_tell(pb
);
233 // fill in the guessed duration, it'll be corrected later if incorrect
234 put_amf_double(pb
, s
->duration
/ AV_TIME_BASE
);
236 if (flv
->video_enc
) {
237 put_amf_string(pb
, "width");
238 put_amf_double(pb
, flv
->video_enc
->width
);
240 put_amf_string(pb
, "height");
241 put_amf_double(pb
, flv
->video_enc
->height
);
243 put_amf_string(pb
, "videodatarate");
244 put_amf_double(pb
, flv
->video_enc
->bit_rate
/ 1024.0);
246 if (flv
->framerate
!= 0.0) {
247 put_amf_string(pb
, "framerate");
248 put_amf_double(pb
, flv
->framerate
);
252 put_amf_string(pb
, "videocodecid");
253 put_amf_double(pb
, flv
->video_enc
->codec_tag
);
256 if (flv
->audio_enc
) {
257 put_amf_string(pb
, "audiodatarate");
258 put_amf_double(pb
, flv
->audio_enc
->bit_rate
/ 1024.0);
260 put_amf_string(pb
, "audiosamplerate");
261 put_amf_double(pb
, flv
->audio_enc
->sample_rate
);
263 put_amf_string(pb
, "audiosamplesize");
264 put_amf_double(pb
, flv
->audio_enc
->codec_id
== AV_CODEC_ID_PCM_U8
? 8 : 16);
266 put_amf_string(pb
, "stereo");
267 put_amf_bool(pb
, flv
->audio_enc
->channels
== 2);
269 put_amf_string(pb
, "audiocodecid");
270 put_amf_double(pb
, flv
->audio_enc
->codec_tag
);
274 put_amf_string(pb
, "datastream");
275 put_amf_double(pb
, 0.0);
278 while ((tag
= av_dict_get(s
->metadata
, "", tag
, AV_DICT_IGNORE_SUFFIX
))) {
279 if( !strcmp(tag
->key
, "width")
280 ||!strcmp(tag
->key
, "height")
281 ||!strcmp(tag
->key
, "videodatarate")
282 ||!strcmp(tag
->key
, "framerate")
283 ||!strcmp(tag
->key
, "videocodecid")
284 ||!strcmp(tag
->key
, "audiodatarate")
285 ||!strcmp(tag
->key
, "audiosamplerate")
286 ||!strcmp(tag
->key
, "audiosamplesize")
287 ||!strcmp(tag
->key
, "stereo")
288 ||!strcmp(tag
->key
, "audiocodecid")
289 ||!strcmp(tag
->key
, "duration")
290 ||!strcmp(tag
->key
, "onMetaData")
292 av_log(s
, AV_LOG_DEBUG
, "Ignoring metadata for %s\n", tag
->key
);
295 put_amf_string(pb
, tag
->key
);
296 avio_w8(pb
, AMF_DATA_TYPE_STRING
);
297 put_amf_string(pb
, tag
->value
);
301 put_amf_string(pb
, "filesize");
302 flv
->filesize_offset
= avio_tell(pb
);
303 put_amf_double(pb
, 0); // delayed write
305 put_amf_string(pb
, "");
306 avio_w8(pb
, AMF_END_OF_OBJECT
);
308 /* write total size of tag */
309 data_size
= avio_tell(pb
) - metadata_size_pos
- 10;
311 avio_seek(pb
, metadata_count_pos
, SEEK_SET
);
312 avio_wb32(pb
, metadata_count
);
314 avio_seek(pb
, metadata_size_pos
, SEEK_SET
);
315 avio_wb24(pb
, data_size
);
316 avio_skip(pb
, data_size
+ 10 - 3);
317 avio_wb32(pb
, data_size
+ 11);
320 static int flv_write_header(AVFormatContext
*s
)
323 AVIOContext
*pb
= s
->pb
;
324 FLVContext
*flv
= s
->priv_data
;
327 for (i
= 0; i
< s
->nb_streams
; i
++) {
328 AVCodecContext
*enc
= s
->streams
[i
]->codec
;
329 FLVStreamContext
*sc
;
330 switch (enc
->codec_type
) {
331 case AVMEDIA_TYPE_VIDEO
:
332 if (s
->streams
[i
]->avg_frame_rate
.den
&&
333 s
->streams
[i
]->avg_frame_rate
.num
) {
334 flv
->framerate
= av_q2d(s
->streams
[i
]->avg_frame_rate
);
336 if (flv
->video_enc
) {
337 av_log(s
, AV_LOG_ERROR
,
338 "at most one video stream is supported in flv\n");
339 return AVERROR(EINVAL
);
341 flv
->video_enc
= enc
;
342 if (enc
->codec_tag
== 0) {
343 av_log(s
, AV_LOG_ERROR
, "Video codec '%s' for stream %d is not compatible with FLV\n",
344 avcodec_get_name(enc
->codec_id
), i
);
345 return AVERROR(EINVAL
);
347 if (enc
->codec_id
== AV_CODEC_ID_MPEG4
||
348 enc
->codec_id
== AV_CODEC_ID_H263
) {
349 int error
= s
->strict_std_compliance
> FF_COMPLIANCE_UNOFFICIAL
;
350 av_log(s
, error
? AV_LOG_ERROR
: AV_LOG_WARNING
,
351 "Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(enc
->codec_id
));
354 av_log(s
, AV_LOG_ERROR
,
355 "use vstrict=-1 / -strict -1 to use it anyway.\n");
356 return AVERROR(EINVAL
);
358 } else if (enc
->codec_id
== AV_CODEC_ID_VP6
) {
359 av_log(s
, AV_LOG_WARNING
,
360 "Muxing VP6 in flv will produce flipped video on playback.\n");
363 case AVMEDIA_TYPE_AUDIO
:
364 if (flv
->audio_enc
) {
365 av_log(s
, AV_LOG_ERROR
,
366 "at most one audio stream is supported in flv\n");
367 return AVERROR(EINVAL
);
369 flv
->audio_enc
= enc
;
370 if (get_audio_flags(s
, enc
) < 0)
371 return AVERROR_INVALIDDATA
;
372 if (enc
->codec_id
== AV_CODEC_ID_PCM_S16BE
)
373 av_log(s
, AV_LOG_WARNING
,
374 "16-bit big-endian audio in flv is valid but most likely unplayable (hardware dependent); use s16le\n");
376 case AVMEDIA_TYPE_DATA
:
377 if (enc
->codec_id
!= AV_CODEC_ID_TEXT
&& enc
->codec_id
!= AV_CODEC_ID_NONE
) {
378 av_log(s
, AV_LOG_ERROR
, "Data codec '%s' for stream %d is not compatible with FLV\n",
379 avcodec_get_name(enc
->codec_id
), i
);
380 return AVERROR_INVALIDDATA
;
385 av_log(s
, AV_LOG_ERROR
, "Codec type '%s' for stream %d is not compatible with FLV\n",
386 av_get_media_type_string(enc
->codec_type
), i
);
387 return AVERROR(EINVAL
);
389 avpriv_set_pts_info(s
->streams
[i
], 32, 1, 1000); /* 32 bit pts in ms */
391 sc
= av_mallocz(sizeof(FLVStreamContext
));
393 return AVERROR(ENOMEM
);
394 s
->streams
[i
]->priv_data
= sc
;
398 flv
->delay
= AV_NOPTS_VALUE
;
400 avio_write(pb
, "FLV", 3);
402 avio_w8(pb
, FLV_HEADER_FLAG_HASAUDIO
* !!flv
->audio_enc
+
403 FLV_HEADER_FLAG_HASVIDEO
* !!flv
->video_enc
);
407 for (i
= 0; i
< s
->nb_streams
; i
++)
408 if (s
->streams
[i
]->codec
->codec_tag
== 5) {
409 avio_w8(pb
, 8); // message type
410 avio_wb24(pb
, 0); // include flags
411 avio_wb24(pb
, 0); // time stamp
412 avio_wb32(pb
, 0); // reserved
413 avio_wb32(pb
, 11); // size
417 write_metadata(s
, 0);
419 for (i
= 0; i
< s
->nb_streams
; i
++) {
420 AVCodecContext
*enc
= s
->streams
[i
]->codec
;
421 if (enc
->codec_id
== AV_CODEC_ID_AAC
|| enc
->codec_id
== AV_CODEC_ID_H264
|| enc
->codec_id
== AV_CODEC_ID_MPEG4
) {
423 avio_w8(pb
, enc
->codec_type
== AVMEDIA_TYPE_VIDEO
?
424 FLV_TAG_TYPE_VIDEO
: FLV_TAG_TYPE_AUDIO
);
425 avio_wb24(pb
, 0); // size patched later
426 avio_wb24(pb
, 0); // ts
427 avio_w8(pb
, 0); // ts ext
428 avio_wb24(pb
, 0); // streamid
430 if (enc
->codec_id
== AV_CODEC_ID_AAC
) {
431 avio_w8(pb
, get_audio_flags(s
, enc
));
432 avio_w8(pb
, 0); // AAC sequence header
433 avio_write(pb
, enc
->extradata
, enc
->extradata_size
);
435 avio_w8(pb
, enc
->codec_tag
| FLV_FRAME_KEY
); // flags
436 avio_w8(pb
, 0); // AVC sequence header
437 avio_wb24(pb
, 0); // composition time
438 ff_isom_write_avcc(pb
, enc
->extradata
, enc
->extradata_size
);
440 data_size
= avio_tell(pb
) - pos
;
441 avio_seek(pb
, -data_size
- 10, SEEK_CUR
);
442 avio_wb24(pb
, data_size
);
443 avio_skip(pb
, data_size
+ 10 - 3);
444 avio_wb32(pb
, data_size
+ 11); // previous tag size
451 static int flv_write_trailer(AVFormatContext
*s
)
455 AVIOContext
*pb
= s
->pb
;
456 FLVContext
*flv
= s
->priv_data
;
460 for (i
= 0; i
< s
->nb_streams
; i
++) {
461 AVCodecContext
*enc
= s
->streams
[i
]->codec
;
462 FLVStreamContext
*sc
= s
->streams
[i
]->priv_data
;
463 if (enc
->codec_type
== AVMEDIA_TYPE_VIDEO
&&
464 (enc
->codec_id
== AV_CODEC_ID_H264
|| enc
->codec_id
== AV_CODEC_ID_MPEG4
))
465 put_avc_eos_tag(pb
, sc
->last_ts
);
468 file_size
= avio_tell(pb
);
470 /* update information */
471 if (avio_seek(pb
, flv
->duration_offset
, SEEK_SET
) < 0)
472 av_log(s
, AV_LOG_WARNING
, "Failed to update header with correct duration.\n");
474 put_amf_double(pb
, flv
->duration
/ (double)1000);
475 if (avio_seek(pb
, flv
->filesize_offset
, SEEK_SET
) < 0)
476 av_log(s
, AV_LOG_WARNING
, "Failed to update header with correct filesize.\n");
478 put_amf_double(pb
, file_size
);
480 avio_seek(pb
, file_size
, SEEK_SET
);
484 static int flv_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
486 AVIOContext
*pb
= s
->pb
;
487 AVCodecContext
*enc
= s
->streams
[pkt
->stream_index
]->codec
;
488 FLVContext
*flv
= s
->priv_data
;
489 FLVStreamContext
*sc
= s
->streams
[pkt
->stream_index
]->priv_data
;
491 int size
= pkt
->size
;
492 uint8_t *data
= NULL
;
493 int flags
= -1, flags_size
, ret
;
495 if (enc
->codec_id
== AV_CODEC_ID_VP6F
|| enc
->codec_id
== AV_CODEC_ID_VP6A
||
496 enc
->codec_id
== AV_CODEC_ID_VP6
|| enc
->codec_id
== AV_CODEC_ID_AAC
)
498 else if (enc
->codec_id
== AV_CODEC_ID_H264
|| enc
->codec_id
== AV_CODEC_ID_MPEG4
)
503 if (flv
->delay
== AV_NOPTS_VALUE
)
504 flv
->delay
= -pkt
->dts
;
506 if (pkt
->dts
< -flv
->delay
) {
507 av_log(s
, AV_LOG_WARNING
,
508 "Packets are not in the proper order with respect to DTS\n");
509 return AVERROR(EINVAL
);
512 ts
= pkt
->dts
+ flv
->delay
; // add delay to force positive dts
514 if (s
->event_flags
& AVSTREAM_EVENT_FLAG_METADATA_UPDATED
) {
515 write_metadata(s
, ts
);
516 s
->event_flags
&= ~AVSTREAM_EVENT_FLAG_METADATA_UPDATED
;
519 switch (enc
->codec_type
) {
520 case AVMEDIA_TYPE_VIDEO
:
521 avio_w8(pb
, FLV_TAG_TYPE_VIDEO
);
523 flags
= enc
->codec_tag
;
525 av_log(s
, AV_LOG_ERROR
,
526 "Video codec '%s' is not compatible with FLV\n",
527 avcodec_get_name(enc
->codec_id
));
528 return AVERROR(EINVAL
);
531 flags
|= pkt
->flags
& AV_PKT_FLAG_KEY
? FLV_FRAME_KEY
: FLV_FRAME_INTER
;
533 case AVMEDIA_TYPE_AUDIO
:
534 flags
= get_audio_flags(s
, enc
);
538 avio_w8(pb
, FLV_TAG_TYPE_AUDIO
);
540 case AVMEDIA_TYPE_DATA
:
541 avio_w8(pb
, FLV_TAG_TYPE_META
);
544 return AVERROR(EINVAL
);
547 if (enc
->codec_id
== AV_CODEC_ID_H264
|| enc
->codec_id
== AV_CODEC_ID_MPEG4
) {
548 /* check if extradata looks like mp4 formated */
549 if (enc
->extradata_size
> 0 && *(uint8_t*)enc
->extradata
!= 1)
550 if ((ret
= ff_avc_parse_nal_units_buf(pkt
->data
, &data
, &size
)) < 0)
552 } else if (enc
->codec_id
== AV_CODEC_ID_AAC
&& pkt
->size
> 2 &&
553 (AV_RB16(pkt
->data
) & 0xfff0) == 0xfff0) {
554 if (!s
->streams
[pkt
->stream_index
]->nb_frames
) {
555 av_log(s
, AV_LOG_ERROR
, "Malformed AAC bitstream detected: "
556 "use the audio bitstream filter 'aac_adtstoasc' to fix it "
557 "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
558 return AVERROR_INVALIDDATA
;
560 av_log(s
, AV_LOG_WARNING
, "aac bitstream error\n");
563 /* check Speex packet duration */
564 if (enc
->codec_id
== AV_CODEC_ID_SPEEX
&& ts
- sc
->last_ts
> 160)
565 av_log(s
, AV_LOG_WARNING
, "Warning: Speex stream has more than "
566 "8 frames per packet. Adobe Flash "
567 "Player cannot handle this!\n");
569 if (sc
->last_ts
< ts
)
572 if (size
+ flags_size
>= 1<<24) {
573 av_log(s
, AV_LOG_ERROR
, "Too large packet with size %u >= %u\n",
574 size
+ flags_size
, 1<<24);
575 return AVERROR(EINVAL
);
578 avio_wb24(pb
, size
+ flags_size
);
579 avio_wb24(pb
, ts
& 0xFFFFFF);
580 avio_w8(pb
, (ts
>> 24) & 0x7F); // timestamps are 32 bits _signed_
581 avio_wb24(pb
, flv
->reserved
);
583 if (enc
->codec_type
== AVMEDIA_TYPE_DATA
) {
585 int64_t metadata_size_pos
= avio_tell(pb
);
586 if (enc
->codec_id
== AV_CODEC_ID_TEXT
) {
587 // legacy FFmpeg magic?
588 avio_w8(pb
, AMF_DATA_TYPE_STRING
);
589 put_amf_string(pb
, "onTextData");
590 avio_w8(pb
, AMF_DATA_TYPE_MIXEDARRAY
);
592 put_amf_string(pb
, "type");
593 avio_w8(pb
, AMF_DATA_TYPE_STRING
);
594 put_amf_string(pb
, "Text");
595 put_amf_string(pb
, "text");
596 avio_w8(pb
, AMF_DATA_TYPE_STRING
);
597 put_amf_string(pb
, pkt
->data
);
598 put_amf_string(pb
, "");
599 avio_w8(pb
, AMF_END_OF_OBJECT
);
601 // just pass the metadata through
602 avio_write(pb
, data
? data
: pkt
->data
, size
);
604 /* write total size of tag */
605 data_size
= avio_tell(pb
) - metadata_size_pos
;
606 avio_seek(pb
, metadata_size_pos
- 10, SEEK_SET
);
607 avio_wb24(pb
, data_size
);
608 avio_seek(pb
, data_size
+ 10 - 3, SEEK_CUR
);
609 avio_wb32(pb
, data_size
+ 11);
611 av_assert1(flags
>=0);
613 if (enc
->codec_id
== AV_CODEC_ID_VP6
)
615 if (enc
->codec_id
== AV_CODEC_ID_VP6F
|| enc
->codec_id
== AV_CODEC_ID_VP6A
) {
616 if (enc
->extradata_size
)
617 avio_w8(pb
, enc
->extradata
[0]);
619 avio_w8(pb
, ((FFALIGN(enc
->width
, 16) - enc
->width
) << 4) |
620 (FFALIGN(enc
->height
, 16) - enc
->height
));
621 } else if (enc
->codec_id
== AV_CODEC_ID_AAC
)
622 avio_w8(pb
, 1); // AAC raw
623 else if (enc
->codec_id
== AV_CODEC_ID_H264
|| enc
->codec_id
== AV_CODEC_ID_MPEG4
) {
624 avio_w8(pb
, 1); // AVC NALU
625 avio_wb24(pb
, pkt
->pts
- pkt
->dts
);
628 avio_write(pb
, data
? data
: pkt
->data
, size
);
630 avio_wb32(pb
, size
+ flags_size
+ 11); // previous tag size
631 flv
->duration
= FFMAX(flv
->duration
,
632 pkt
->pts
+ flv
->delay
+ pkt
->duration
);
640 AVOutputFormat ff_flv_muxer
= {
642 .long_name
= NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),
643 .mime_type
= "video/x-flv",
645 .priv_data_size
= sizeof(FLVContext
),
646 .audio_codec
= CONFIG_LIBMP3LAME
? AV_CODEC_ID_MP3
: AV_CODEC_ID_ADPCM_SWF
,
647 .video_codec
= AV_CODEC_ID_FLV1
,
648 .write_header
= flv_write_header
,
649 .write_packet
= flv_write_packet
,
650 .write_trailer
= flv_write_trailer
,
651 .codec_tag
= (const AVCodecTag
* const []) {
652 flv_video_codec_ids
, flv_audio_codec_ids
, 0
654 .flags
= AVFMT_GLOBALHEADER
| AVFMT_VARIABLE_FPS
|