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
29 static 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
},
38 static 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
},
49 typedef struct FLVContext
{
51 int64_t duration_offset
;
52 int64_t filesize_offset
;
54 int delay
; ///< first dts delay for AVC
57 static int get_audio_flags(AVCodecContext
*enc
){
58 int flags
= (enc
->bits_per_coded_sample
== 16) ? FLV_SAMPLESSIZE_16BIT
: FLV_SAMPLESSIZE_8BIT
;
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
;
63 switch (enc
->sample_rate
) {
65 flags
|= FLV_SAMPLERATE_44100HZ
;
68 flags
|= FLV_SAMPLERATE_22050HZ
;
71 flags
|= FLV_SAMPLERATE_11025HZ
;
73 case 8000: //nellymoser only
75 if(enc
->codec_id
!= CODEC_ID_MP3
){
76 flags
|= FLV_SAMPLERATE_SPECIAL
;
80 av_log(enc
, AV_LOG_ERROR
, "flv does not support that sample rate, choose from (44100, 22050, 11025).\n");
85 if (enc
->channels
> 1) {
89 switch(enc
->codec_id
){
91 flags
|= FLV_CODECID_MP3
| FLV_SAMPLESSIZE_16BIT
;
94 flags
|= FLV_CODECID_PCM
| FLV_SAMPLESSIZE_8BIT
;
96 case CODEC_ID_PCM_S16BE
:
97 flags
|= FLV_CODECID_PCM
| FLV_SAMPLESSIZE_16BIT
;
99 case CODEC_ID_PCM_S16LE
:
100 flags
|= FLV_CODECID_PCM_LE
| FLV_SAMPLESSIZE_16BIT
;
102 case CODEC_ID_ADPCM_SWF
:
103 flags
|= FLV_CODECID_ADPCM
| FLV_SAMPLESSIZE_16BIT
;
105 case CODEC_ID_NELLYMOSER
:
106 if (enc
->sample_rate
== 8000) {
107 flags
|= FLV_CODECID_NELLYMOSER_8KHZ_MONO
| FLV_SAMPLESSIZE_16BIT
;
109 flags
|= FLV_CODECID_NELLYMOSER
| FLV_SAMPLESSIZE_16BIT
;
113 flags
|= enc
->codec_tag
<<4;
116 av_log(enc
, AV_LOG_ERROR
, "codec not compatible with flv\n");
123 static void put_amf_string(ByteIOContext
*pb
, const char *str
)
125 size_t len
= strlen(str
);
127 put_buffer(pb
, str
, len
);
130 static void put_amf_double(ByteIOContext
*pb
, double d
)
132 put_byte(pb
, AMF_DATA_TYPE_NUMBER
);
133 put_be64(pb
, av_dbl2int(d
));
136 static void put_amf_bool(ByteIOContext
*pb
, int b
) {
137 put_byte(pb
, AMF_DATA_TYPE_BOOL
);
141 static int flv_write_header(AVFormatContext
*s
)
143 ByteIOContext
*pb
= s
->pb
;
144 FLVContext
*flv
= s
->priv_data
;
145 AVCodecContext
*audio_enc
= NULL
, *video_enc
= NULL
;
147 double framerate
= 0.0;
148 int metadata_size_pos
, data_size
;
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
);
156 framerate
= 1/av_q2d(s
->streams
[i
]->codec
->time_base
);
159 if(enc
->codec_tag
== 0) {
160 av_log(enc
, AV_LOG_ERROR
, "video codec not compatible with flv\n");
165 if(get_audio_flags(enc
)<0)
168 av_set_pts_info(s
->streams
[i
], 32, 1, 1000); /* 32 bit pts in ms */
172 put_byte(pb
, FLV_HEADER_FLAG_HASAUDIO
* !!audio_enc
173 + FLV_HEADER_FLAG_HASVIDEO
* !!video_enc
);
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
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
195 /* now data of data_size size */
197 /* first event name as a string */
198 put_byte(pb
, AMF_DATA_TYPE_STRING
);
199 put_amf_string(pb
, "onMetaData"); // 12 bytes
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
205 put_amf_string(pb
, "duration");
206 flv
->duration_offset
= url_ftell(pb
);
207 put_amf_double(pb
, 0); // delayed write
210 put_amf_string(pb
, "width");
211 put_amf_double(pb
, video_enc
->width
);
213 put_amf_string(pb
, "height");
214 put_amf_double(pb
, video_enc
->height
);
216 put_amf_string(pb
, "videodatarate");
217 put_amf_double(pb
, s
->bit_rate
/ 1024.0);
219 put_amf_string(pb
, "framerate");
220 put_amf_double(pb
, framerate
);
222 put_amf_string(pb
, "videocodecid");
223 put_amf_double(pb
, video_enc
->codec_tag
);
227 put_amf_string(pb
, "audiosamplerate");
228 put_amf_double(pb
, audio_enc
->sample_rate
);
230 put_amf_string(pb
, "audiosamplesize");
231 put_amf_double(pb
, audio_enc
->codec_id
== CODEC_ID_PCM_S8
? 8 : 16);
233 put_amf_string(pb
, "stereo");
234 put_amf_bool(pb
, audio_enc
->channels
== 2);
236 put_amf_string(pb
, "audiocodecid");
237 put_amf_double(pb
, audio_enc
->codec_tag
);
240 put_amf_string(pb
, "filesize");
241 flv
->filesize_offset
= url_ftell(pb
);
242 put_amf_double(pb
, 0); // delayed write
244 put_amf_string(pb
, "");
245 put_byte(pb
, AMF_END_OF_OBJECT
);
247 /* write total size of tag */
248 data_size
= url_ftell(pb
) - metadata_size_pos
- 10;
249 url_fseek(pb
, metadata_size_pos
, SEEK_SET
);
250 put_be24(pb
, data_size
);
251 url_fseek(pb
, data_size
+ 10 - 3, SEEK_CUR
);
252 put_be32(pb
, data_size
+ 11);
254 for (i
= 0; i
< s
->nb_streams
; i
++) {
255 AVCodecContext
*enc
= s
->streams
[i
]->codec
;
256 if (enc
->codec_id
== CODEC_ID_AAC
|| enc
->codec_id
== CODEC_ID_H264
) {
258 put_byte(pb
, enc
->codec_type
== CODEC_TYPE_VIDEO
?
259 FLV_TAG_TYPE_VIDEO
: FLV_TAG_TYPE_AUDIO
);
260 put_be24(pb
, 0); // size patched later
261 put_be24(pb
, 0); // ts
262 put_byte(pb
, 0); // ts ext
263 put_be24(pb
, 0); // streamid
265 if (enc
->codec_id
== CODEC_ID_AAC
) {
266 put_byte(pb
, get_audio_flags(enc
));
267 put_byte(pb
, 0); // AAC sequence header
268 put_buffer(pb
, enc
->extradata
, enc
->extradata_size
);
270 put_byte(pb
, enc
->codec_tag
| FLV_FRAME_KEY
); // flags
271 put_byte(pb
, 0); // AVC sequence header
272 put_be24(pb
, 0); // composition time
273 ff_isom_write_avcc(pb
, enc
->extradata
, enc
->extradata_size
);
275 data_size
= url_ftell(pb
) - pos
;
276 url_fseek(pb
, -data_size
- 10, SEEK_CUR
);
277 put_be24(pb
, data_size
);
278 url_fseek(pb
, data_size
+ 10 - 3, SEEK_CUR
);
279 put_be32(pb
, data_size
+ 11); // previous tag size
286 static int flv_write_trailer(AVFormatContext
*s
)
290 ByteIOContext
*pb
= s
->pb
;
291 FLVContext
*flv
= s
->priv_data
;
293 file_size
= url_ftell(pb
);
295 /* update informations */
296 url_fseek(pb
, flv
->duration_offset
, SEEK_SET
);
297 put_amf_double(pb
, flv
->duration
/ (double)1000);
298 url_fseek(pb
, flv
->filesize_offset
, SEEK_SET
);
299 put_amf_double(pb
, file_size
);
301 url_fseek(pb
, file_size
, SEEK_SET
);
305 static int flv_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
307 ByteIOContext
*pb
= s
->pb
;
308 AVCodecContext
*enc
= s
->streams
[pkt
->stream_index
]->codec
;
309 FLVContext
*flv
= s
->priv_data
;
312 int flags
, flags_size
;
314 // av_log(s, AV_LOG_DEBUG, "type:%d pts: %"PRId64" size:%d\n", enc->codec_type, timestamp, size);
316 if(enc
->codec_id
== CODEC_ID_VP6
|| enc
->codec_id
== CODEC_ID_VP6F
||
317 enc
->codec_id
== CODEC_ID_AAC
)
319 else if(enc
->codec_id
== CODEC_ID_H264
)
324 if (enc
->codec_type
== CODEC_TYPE_VIDEO
) {
325 put_byte(pb
, FLV_TAG_TYPE_VIDEO
);
327 flags
= enc
->codec_tag
;
329 av_log(enc
, AV_LOG_ERROR
, "video codec %X not compatible with flv\n",enc
->codec_id
);
333 flags
|= pkt
->flags
& PKT_FLAG_KEY
? FLV_FRAME_KEY
: FLV_FRAME_INTER
;
335 assert(enc
->codec_type
== CODEC_TYPE_AUDIO
);
336 flags
= get_audio_flags(enc
);
340 put_byte(pb
, FLV_TAG_TYPE_AUDIO
);
343 if (enc
->codec_id
== CODEC_ID_H264
&&
344 /* check if extradata looks like mp4 formated */
345 enc
->extradata_size
> 0 && *(uint8_t*)enc
->extradata
!= 1) {
346 if (ff_avc_parse_nal_units(pkt
->data
, &pkt
->data
, &pkt
->size
) < 0)
350 /* cast needed to get negative value */
351 if (!flv
->delay
&& pkt
->dts
< 0)
352 flv
->delay
= -pkt
->dts
;
355 ts
= pkt
->dts
+ flv
->delay
; // add delay to force positive dts
356 put_be24(pb
,size
+ flags_size
);
358 put_byte(pb
,(ts
>> 24) & 0x7F); // timestamps are 32bits _signed_
359 put_be24(pb
,flv
->reserved
);
361 if (enc
->codec_id
== CODEC_ID_VP6
)
363 if (enc
->codec_id
== CODEC_ID_VP6F
)
364 put_byte(pb
, enc
->extradata_size
? enc
->extradata
[0] : 0);
365 else if (enc
->codec_id
== CODEC_ID_AAC
)
366 put_byte(pb
,1); // AAC raw
367 else if (enc
->codec_id
== CODEC_ID_H264
) {
368 put_byte(pb
,1); // AVC NALU
369 put_be24(pb
,pkt
->pts
- pkt
->dts
);
371 put_buffer(pb
, pkt
->data
, size
);
372 put_be32(pb
,size
+flags_size
+11); // previous tag size
373 flv
->duration
= FFMAX(flv
->duration
, pkt
->pts
+ flv
->delay
+ pkt
->duration
);
375 put_flush_packet(pb
);
379 AVOutputFormat flv_muxer
= {
381 NULL_IF_CONFIG_SMALL("FLV format"),
385 #ifdef CONFIG_LIBMP3LAME
387 #else // CONFIG_LIBMP3LAME
389 #endif // CONFIG_LIBMP3LAME
394 .codec_tag
= (const AVCodecTag
* const []){flv_video_codec_ids
, flv_audio_codec_ids
, 0},
395 .flags
= AVFMT_GLOBALHEADER
,