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 offset_t duration_offset
;
52 offset_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_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 flags
|= FLV_CODECID_NELLYMOSER
| FLV_SAMPLESSIZE_16BIT
;
109 flags
|= enc
->codec_tag
<<4;
112 av_log(enc
, AV_LOG_ERROR
, "codec not compatible with flv\n");
119 static void put_amf_string(ByteIOContext
*pb
, const char *str
)
121 size_t len
= strlen(str
);
123 put_buffer(pb
, str
, len
);
126 static void put_amf_double(ByteIOContext
*pb
, double d
)
128 put_byte(pb
, AMF_DATA_TYPE_NUMBER
);
129 put_be64(pb
, av_dbl2int(d
));
132 static void put_amf_bool(ByteIOContext
*pb
, int b
) {
133 put_byte(pb
, AMF_DATA_TYPE_BOOL
);
137 static int flv_write_header(AVFormatContext
*s
)
139 ByteIOContext
*pb
= s
->pb
;
140 FLVContext
*flv
= s
->priv_data
;
141 AVCodecContext
*audio_enc
= NULL
, *video_enc
= NULL
;
143 double framerate
= 0.0;
144 int metadata_size_pos
, data_size
;
146 for(i
=0; i
<s
->nb_streams
; i
++){
147 AVCodecContext
*enc
= s
->streams
[i
]->codec
;
148 if (enc
->codec_type
== CODEC_TYPE_VIDEO
) {
149 if (s
->streams
[i
]->r_frame_rate
.den
&& s
->streams
[i
]->r_frame_rate
.num
) {
150 framerate
= av_q2d(s
->streams
[i
]->r_frame_rate
);
152 framerate
= 1/av_q2d(s
->streams
[i
]->codec
->time_base
);
155 if(enc
->codec_tag
== 0) {
156 av_log(enc
, AV_LOG_ERROR
, "video codec not compatible with flv\n");
161 if(get_audio_flags(enc
)<0)
164 av_set_pts_info(s
->streams
[i
], 32, 1, 1000); /* 32 bit pts in ms */
168 put_byte(pb
, FLV_HEADER_FLAG_HASAUDIO
* !!audio_enc
169 + FLV_HEADER_FLAG_HASVIDEO
* !!video_enc
);
173 for(i
=0; i
<s
->nb_streams
; i
++){
174 if(s
->streams
[i
]->codec
->codec_tag
== 5){
175 put_byte(pb
,8); // message type
176 put_be24(pb
,0); // include flags
177 put_be24(pb
,0); // time stamp
178 put_be32(pb
,0); // reserved
179 put_be32(pb
,11); // size
185 put_byte(pb
, 18); // tag type META
186 metadata_size_pos
= url_ftell(pb
);
187 put_be24(pb
, 0); // size of data part (sum of all parts below)
188 put_be24(pb
, 0); // time stamp
189 put_be32(pb
, 0); // reserved
191 /* now data of data_size size */
193 /* first event name as a string */
194 put_byte(pb
, AMF_DATA_TYPE_STRING
);
195 put_amf_string(pb
, "onMetaData"); // 12 bytes
197 /* mixed array (hash) with size and string/type/data tuples */
198 put_byte(pb
, AMF_DATA_TYPE_MIXEDARRAY
);
199 put_be32(pb
, 5*!!video_enc
+ 4*!!audio_enc
+ 2); // +2 for duration and file size
201 put_amf_string(pb
, "duration");
202 flv
->duration_offset
= url_ftell(pb
);
203 put_amf_double(pb
, 0); // delayed write
206 put_amf_string(pb
, "width");
207 put_amf_double(pb
, video_enc
->width
);
209 put_amf_string(pb
, "height");
210 put_amf_double(pb
, video_enc
->height
);
212 put_amf_string(pb
, "videodatarate");
213 put_amf_double(pb
, s
->bit_rate
/ 1024.0);
215 put_amf_string(pb
, "framerate");
216 put_amf_double(pb
, framerate
);
218 put_amf_string(pb
, "videocodecid");
219 put_amf_double(pb
, video_enc
->codec_tag
);
223 put_amf_string(pb
, "audiosamplerate");
224 put_amf_double(pb
, audio_enc
->sample_rate
);
226 put_amf_string(pb
, "audiosamplesize");
227 put_amf_double(pb
, audio_enc
->codec_id
== CODEC_ID_PCM_S8
? 8 : 16);
229 put_amf_string(pb
, "stereo");
230 put_amf_bool(pb
, audio_enc
->channels
== 2);
232 put_amf_string(pb
, "audiocodecid");
233 put_amf_double(pb
, audio_enc
->codec_tag
);
236 put_amf_string(pb
, "filesize");
237 flv
->filesize_offset
= url_ftell(pb
);
238 put_amf_double(pb
, 0); // delayed write
240 put_amf_string(pb
, "");
241 put_byte(pb
, AMF_END_OF_OBJECT
);
243 /* write total size of tag */
244 data_size
= url_ftell(pb
) - metadata_size_pos
- 10;
245 url_fseek(pb
, metadata_size_pos
, SEEK_SET
);
246 put_be24(pb
, data_size
);
247 url_fseek(pb
, data_size
+ 10 - 3, SEEK_CUR
);
248 put_be32(pb
, data_size
+ 11);
250 for (i
= 0; i
< s
->nb_streams
; i
++) {
251 AVCodecContext
*enc
= s
->streams
[i
]->codec
;
252 if (enc
->codec_id
== CODEC_ID_AAC
|| enc
->codec_id
== CODEC_ID_H264
) {
254 put_byte(pb
, enc
->codec_type
== CODEC_TYPE_VIDEO
?
255 FLV_TAG_TYPE_VIDEO
: FLV_TAG_TYPE_AUDIO
);
256 put_be24(pb
, 0); // size patched later
257 put_be24(pb
, 0); // ts
258 put_byte(pb
, 0); // ts ext
259 put_be24(pb
, 0); // streamid
261 if (enc
->codec_id
== CODEC_ID_AAC
) {
262 put_byte(pb
, get_audio_flags(enc
));
263 put_byte(pb
, 0); // AAC sequence header
264 put_buffer(pb
, enc
->extradata
, enc
->extradata_size
);
266 put_byte(pb
, enc
->codec_tag
| FLV_FRAME_KEY
); // flags
267 put_byte(pb
, 0); // AVC sequence header
268 put_be24(pb
, 0); // composition time
269 ff_isom_write_avcc(pb
, enc
->extradata
, enc
->extradata_size
);
271 data_size
= url_ftell(pb
) - pos
;
272 url_fseek(pb
, -data_size
- 10, SEEK_CUR
);
273 put_be24(pb
, data_size
);
274 url_fseek(pb
, data_size
+ 10 - 3, SEEK_CUR
);
275 put_be32(pb
, data_size
+ 11); // previous tag size
282 static int flv_write_trailer(AVFormatContext
*s
)
286 ByteIOContext
*pb
= s
->pb
;
287 FLVContext
*flv
= s
->priv_data
;
289 file_size
= url_ftell(pb
);
291 /* update informations */
292 url_fseek(pb
, flv
->duration_offset
, SEEK_SET
);
293 put_amf_double(pb
, flv
->duration
/ (double)1000);
294 url_fseek(pb
, flv
->filesize_offset
, SEEK_SET
);
295 put_amf_double(pb
, file_size
);
297 url_fseek(pb
, file_size
, SEEK_SET
);
301 static int flv_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
303 ByteIOContext
*pb
= s
->pb
;
304 AVCodecContext
*enc
= s
->streams
[pkt
->stream_index
]->codec
;
305 FLVContext
*flv
= s
->priv_data
;
308 int flags
, flags_size
;
310 // av_log(s, AV_LOG_DEBUG, "type:%d pts: %"PRId64" size:%d\n", enc->codec_type, timestamp, size);
312 if(enc
->codec_id
== CODEC_ID_VP6
|| enc
->codec_id
== CODEC_ID_VP6F
||
313 enc
->codec_id
== CODEC_ID_AAC
)
315 else if(enc
->codec_id
== CODEC_ID_H264
)
320 if (enc
->codec_type
== CODEC_TYPE_VIDEO
) {
321 put_byte(pb
, FLV_TAG_TYPE_VIDEO
);
323 flags
= enc
->codec_tag
;
325 av_log(enc
, AV_LOG_ERROR
, "video codec %X not compatible with flv\n",enc
->codec_id
);
329 flags
|= pkt
->flags
& PKT_FLAG_KEY
? FLV_FRAME_KEY
: FLV_FRAME_INTER
;
331 assert(enc
->codec_type
== CODEC_TYPE_AUDIO
);
332 flags
= get_audio_flags(enc
);
336 put_byte(pb
, FLV_TAG_TYPE_AUDIO
);
339 if (enc
->codec_id
== CODEC_ID_H264
&&
340 /* check if extradata looks like mp4 formated */
341 enc
->extradata_size
> 0 && *(uint8_t*)enc
->extradata
!= 1) {
342 if (ff_avc_parse_nal_units(pkt
->data
, &pkt
->data
, &pkt
->size
) < 0)
346 /* cast needed to get negative value */
347 if (!flv
->delay
&& (int32_t)pkt
->dts
< 0)
348 flv
->delay
= -(int32_t)pkt
->dts
;
351 ts
= pkt
->dts
+ flv
->delay
; // add delay to force positive dts
352 put_be24(pb
,size
+ flags_size
);
354 put_byte(pb
,ts
>> 24);
355 put_be24(pb
,flv
->reserved
);
357 if (enc
->codec_id
== CODEC_ID_VP6
)
359 if (enc
->codec_id
== CODEC_ID_VP6F
)
360 put_byte(pb
, enc
->extradata_size
? enc
->extradata
[0] : 0);
361 else if (enc
->codec_id
== CODEC_ID_AAC
)
362 put_byte(pb
,1); // AAC raw
363 else if (enc
->codec_id
== CODEC_ID_H264
) {
364 put_byte(pb
,1); // AVC NALU
365 put_be24(pb
,pkt
->pts
- (int32_t)pkt
->dts
);
367 put_buffer(pb
, pkt
->data
, size
);
368 put_be32(pb
,size
+flags_size
+11); // previous tag size
369 flv
->duration
= FFMAX(flv
->duration
, pkt
->pts
+ flv
->delay
+ pkt
->duration
);
371 put_flush_packet(pb
);
375 AVOutputFormat flv_muxer
= {
377 NULL_IF_CONFIG_SMALL("FLV format"),
381 #ifdef CONFIG_LIBMP3LAME
383 #else // CONFIG_LIBMP3LAME
385 #endif // CONFIG_LIBMP3LAME
390 .codec_tag
= (const AVCodecTag
*[]){flv_video_codec_ids
, flv_audio_codec_ids
, 0},
391 .flags
= AVFMT_GLOBALHEADER
,