]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - libavformat/flvenc.c
Emit the SDP lines in the correct order
[frescor/ffmpeg.git] / libavformat / flvenc.c
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
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  },
35     {CODEC_ID_NONE,    0}
36 };
37
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},
46     {CODEC_ID_SPEEX,     FLV_CODECID_SPEEX  >> FLV_AUDIO_CODECID_OFFSET},
47     {CODEC_ID_NONE,      0}
48 };
49
50 typedef struct FLVContext {
51     int reserved;
52     int64_t duration_offset;
53     int64_t filesize_offset;
54     int64_t duration;
55     int delay; ///< first dts delay for AVC
56 } FLVContext;
57
58 static int get_audio_flags(AVCodecContext *enc){
59     int flags = (enc->bits_per_coded_sample == 16) ? FLV_SAMPLESSIZE_16BIT : FLV_SAMPLESSIZE_8BIT;
60
61     if (enc->codec_id == CODEC_ID_AAC) // specs force these parameters
62         return FLV_CODECID_AAC | FLV_SAMPLERATE_44100HZ | FLV_SAMPLESSIZE_16BIT | FLV_STEREO;
63     else if (enc->codec_id == CODEC_ID_SPEEX) {
64         if (enc->sample_rate != 16000) {
65             av_log(enc, AV_LOG_ERROR, "flv only supports wideband (16kHz) Speex audio\n");
66             return -1;
67         }
68         if (enc->channels != 1) {
69             av_log(enc, AV_LOG_ERROR, "flv only supports mono Speex audio\n");
70             return -1;
71         }
72         if (enc->frame_size / 320 > 8) {
73             av_log(enc, AV_LOG_WARNING, "Warning: Speex stream has more than "
74                                         "8 frames per packet. Adobe Flash "
75                                         "Player cannot handle this!\n");
76         }
77         return FLV_CODECID_SPEEX | FLV_SAMPLERATE_11025HZ | FLV_SAMPLESSIZE_16BIT;
78     } else {
79     switch (enc->sample_rate) {
80         case    44100:
81             flags |= FLV_SAMPLERATE_44100HZ;
82             break;
83         case    22050:
84             flags |= FLV_SAMPLERATE_22050HZ;
85             break;
86         case    11025:
87             flags |= FLV_SAMPLERATE_11025HZ;
88             break;
89         case     8000: //nellymoser only
90         case     5512: //not mp3
91             if(enc->codec_id != CODEC_ID_MP3){
92                 flags |= FLV_SAMPLERATE_SPECIAL;
93                 break;
94             }
95         default:
96             av_log(enc, AV_LOG_ERROR, "flv does not support that sample rate, choose from (44100, 22050, 11025).\n");
97             return -1;
98     }
99     }
100
101     if (enc->channels > 1) {
102         flags |= FLV_STEREO;
103     }
104
105     switch(enc->codec_id){
106     case CODEC_ID_MP3:
107         flags |= FLV_CODECID_MP3    | FLV_SAMPLESSIZE_16BIT;
108         break;
109     case CODEC_ID_PCM_S8:
110         flags |= FLV_CODECID_PCM    | FLV_SAMPLESSIZE_8BIT;
111         break;
112     case CODEC_ID_PCM_S16BE:
113         flags |= FLV_CODECID_PCM    | FLV_SAMPLESSIZE_16BIT;
114         break;
115     case CODEC_ID_PCM_S16LE:
116         flags |= FLV_CODECID_PCM_LE | FLV_SAMPLESSIZE_16BIT;
117         break;
118     case CODEC_ID_ADPCM_SWF:
119         flags |= FLV_CODECID_ADPCM | FLV_SAMPLESSIZE_16BIT;
120         break;
121     case CODEC_ID_NELLYMOSER:
122         if (enc->sample_rate == 8000) {
123             flags |= FLV_CODECID_NELLYMOSER_8KHZ_MONO | FLV_SAMPLESSIZE_16BIT;
124         } else {
125             flags |= FLV_CODECID_NELLYMOSER | FLV_SAMPLESSIZE_16BIT;
126         }
127         break;
128     case 0:
129         flags |= enc->codec_tag<<4;
130         break;
131     default:
132         av_log(enc, AV_LOG_ERROR, "codec not compatible with flv\n");
133         return -1;
134     }
135
136     return flags;
137 }
138
139 static void put_amf_string(ByteIOContext *pb, const char *str)
140 {
141     size_t len = strlen(str);
142     put_be16(pb, len);
143     put_buffer(pb, str, len);
144 }
145
146 static void put_amf_double(ByteIOContext *pb, double d)
147 {
148     put_byte(pb, AMF_DATA_TYPE_NUMBER);
149     put_be64(pb, av_dbl2int(d));
150 }
151
152 static void put_amf_bool(ByteIOContext *pb, int b) {
153     put_byte(pb, AMF_DATA_TYPE_BOOL);
154     put_byte(pb, !!b);
155 }
156
157 static int flv_write_header(AVFormatContext *s)
158 {
159     ByteIOContext *pb = s->pb;
160     FLVContext *flv = s->priv_data;
161     AVCodecContext *audio_enc = NULL, *video_enc = NULL;
162     int i;
163     double framerate = 0.0;
164     int metadata_size_pos, data_size;
165
166     for(i=0; i<s->nb_streams; i++){
167         AVCodecContext *enc = s->streams[i]->codec;
168         if (enc->codec_type == CODEC_TYPE_VIDEO) {
169             if (s->streams[i]->r_frame_rate.den && s->streams[i]->r_frame_rate.num) {
170                 framerate = av_q2d(s->streams[i]->r_frame_rate);
171             } else {
172                 framerate = 1/av_q2d(s->streams[i]->codec->time_base);
173             }
174             video_enc = enc;
175             if(enc->codec_tag == 0) {
176                 av_log(enc, AV_LOG_ERROR, "video codec not compatible with flv\n");
177                 return -1;
178             }
179         } else {
180             audio_enc = enc;
181             if(get_audio_flags(enc)<0)
182                 return -1;
183         }
184         av_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */
185     }
186     put_tag(pb,"FLV");
187     put_byte(pb,1);
188     put_byte(pb,   FLV_HEADER_FLAG_HASAUDIO * !!audio_enc
189                  + FLV_HEADER_FLAG_HASVIDEO * !!video_enc);
190     put_be32(pb,9);
191     put_be32(pb,0);
192
193     for(i=0; i<s->nb_streams; i++){
194         if(s->streams[i]->codec->codec_tag == 5){
195             put_byte(pb,8); // message type
196             put_be24(pb,0); // include flags
197             put_be24(pb,0); // time stamp
198             put_be32(pb,0); // reserved
199             put_be32(pb,11); // size
200             flv->reserved=5;
201         }
202     }
203
204     /* write meta_tag */
205     put_byte(pb, 18);         // tag type META
206     metadata_size_pos= url_ftell(pb);
207     put_be24(pb, 0);          // size of data part (sum of all parts below)
208     put_be24(pb, 0);          // time stamp
209     put_be32(pb, 0);          // reserved
210
211     /* now data of data_size size */
212
213     /* first event name as a string */
214     put_byte(pb, AMF_DATA_TYPE_STRING);
215     put_amf_string(pb, "onMetaData"); // 12 bytes
216
217     /* mixed array (hash) with size and string/type/data tuples */
218     put_byte(pb, AMF_DATA_TYPE_MIXEDARRAY);
219     put_be32(pb, 5*!!video_enc + 5*!!audio_enc + 2); // +2 for duration and file size
220
221     put_amf_string(pb, "duration");
222     flv->duration_offset= url_ftell(pb);
223     put_amf_double(pb, 0); // delayed write
224
225     if(video_enc){
226         put_amf_string(pb, "width");
227         put_amf_double(pb, video_enc->width);
228
229         put_amf_string(pb, "height");
230         put_amf_double(pb, video_enc->height);
231
232         put_amf_string(pb, "videodatarate");
233         put_amf_double(pb, video_enc->bit_rate / 1024.0);
234
235         put_amf_string(pb, "framerate");
236         put_amf_double(pb, framerate);
237
238         put_amf_string(pb, "videocodecid");
239         put_amf_double(pb, video_enc->codec_tag);
240     }
241
242     if(audio_enc){
243         put_amf_string(pb, "audiodatarate");
244         put_amf_double(pb, audio_enc->bit_rate / 1024.0);
245
246         put_amf_string(pb, "audiosamplerate");
247         put_amf_double(pb, audio_enc->sample_rate);
248
249         put_amf_string(pb, "audiosamplesize");
250         put_amf_double(pb, audio_enc->codec_id == CODEC_ID_PCM_S8 ? 8 : 16);
251
252         put_amf_string(pb, "stereo");
253         put_amf_bool(pb, audio_enc->channels == 2);
254
255         put_amf_string(pb, "audiocodecid");
256         put_amf_double(pb, audio_enc->codec_tag);
257     }
258
259     put_amf_string(pb, "filesize");
260     flv->filesize_offset= url_ftell(pb);
261     put_amf_double(pb, 0); // delayed write
262
263     put_amf_string(pb, "");
264     put_byte(pb, AMF_END_OF_OBJECT);
265
266     /* write total size of tag */
267     data_size= url_ftell(pb) - metadata_size_pos - 10;
268     url_fseek(pb, metadata_size_pos, SEEK_SET);
269     put_be24(pb, data_size);
270     url_fseek(pb, data_size + 10 - 3, SEEK_CUR);
271     put_be32(pb, data_size + 11);
272
273     for (i = 0; i < s->nb_streams; i++) {
274         AVCodecContext *enc = s->streams[i]->codec;
275         if (enc->codec_id == CODEC_ID_AAC || enc->codec_id == CODEC_ID_H264) {
276             int64_t pos;
277             put_byte(pb, enc->codec_type == CODEC_TYPE_VIDEO ?
278                      FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO);
279             put_be24(pb, 0); // size patched later
280             put_be24(pb, 0); // ts
281             put_byte(pb, 0); // ts ext
282             put_be24(pb, 0); // streamid
283             pos = url_ftell(pb);
284             if (enc->codec_id == CODEC_ID_AAC) {
285                 put_byte(pb, get_audio_flags(enc));
286                 put_byte(pb, 0); // AAC sequence header
287                 put_buffer(pb, enc->extradata, enc->extradata_size);
288             } else {
289                 put_byte(pb, enc->codec_tag | FLV_FRAME_KEY); // flags
290                 put_byte(pb, 0); // AVC sequence header
291                 put_be24(pb, 0); // composition time
292                 ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size);
293             }
294             data_size = url_ftell(pb) - pos;
295             url_fseek(pb, -data_size - 10, SEEK_CUR);
296             put_be24(pb, data_size);
297             url_fseek(pb, data_size + 10 - 3, SEEK_CUR);
298             put_be32(pb, data_size + 11); // previous tag size
299         }
300     }
301
302     return 0;
303 }
304
305 static int flv_write_trailer(AVFormatContext *s)
306 {
307     int64_t file_size;
308
309     ByteIOContext *pb = s->pb;
310     FLVContext *flv = s->priv_data;
311
312     file_size = url_ftell(pb);
313
314     /* update informations */
315     url_fseek(pb, flv->duration_offset, SEEK_SET);
316     put_amf_double(pb, flv->duration / (double)1000);
317     url_fseek(pb, flv->filesize_offset, SEEK_SET);
318     put_amf_double(pb, file_size);
319
320     url_fseek(pb, file_size, SEEK_SET);
321     return 0;
322 }
323
324 static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
325 {
326     ByteIOContext *pb = s->pb;
327     AVCodecContext *enc = s->streams[pkt->stream_index]->codec;
328     FLVContext *flv = s->priv_data;
329     unsigned ts;
330     int size= pkt->size;
331     uint8_t *data= NULL;
332     int flags, flags_size;
333
334 //    av_log(s, AV_LOG_DEBUG, "type:%d pts: %"PRId64" size:%d\n", enc->codec_type, timestamp, size);
335
336     if(enc->codec_id == CODEC_ID_VP6 || enc->codec_id == CODEC_ID_VP6F ||
337        enc->codec_id == CODEC_ID_AAC)
338         flags_size= 2;
339     else if(enc->codec_id == CODEC_ID_H264)
340         flags_size= 5;
341     else
342         flags_size= 1;
343
344     if (enc->codec_type == CODEC_TYPE_VIDEO) {
345         put_byte(pb, FLV_TAG_TYPE_VIDEO);
346
347         flags = enc->codec_tag;
348         if(flags == 0) {
349             av_log(enc, AV_LOG_ERROR, "video codec %X not compatible with flv\n",enc->codec_id);
350             return -1;
351         }
352
353         flags |= pkt->flags & PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER;
354     } else {
355         assert(enc->codec_type == CODEC_TYPE_AUDIO);
356         flags = get_audio_flags(enc);
357
358         assert(size);
359
360         put_byte(pb, FLV_TAG_TYPE_AUDIO);
361     }
362
363     if (enc->codec_id == CODEC_ID_H264) {
364         /* check if extradata looks like mp4 formated */
365         if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1) {
366             if (ff_avc_parse_nal_units_buf(pkt->data, &data, &size) < 0)
367                 return -1;
368         }
369         if (!flv->delay && pkt->dts < 0)
370             flv->delay = -pkt->dts;
371     }
372
373     ts = pkt->dts + flv->delay; // add delay to force positive dts
374     put_be24(pb,size + flags_size);
375     put_be24(pb,ts);
376     put_byte(pb,(ts >> 24) & 0x7F); // timestamps are 32bits _signed_
377     put_be24(pb,flv->reserved);
378     put_byte(pb,flags);
379     if (enc->codec_id == CODEC_ID_VP6)
380         put_byte(pb,0);
381     if (enc->codec_id == CODEC_ID_VP6F)
382         put_byte(pb, enc->extradata_size ? enc->extradata[0] : 0);
383     else if (enc->codec_id == CODEC_ID_AAC)
384         put_byte(pb,1); // AAC raw
385     else if (enc->codec_id == CODEC_ID_H264) {
386         put_byte(pb,1); // AVC NALU
387         put_be24(pb,pkt->pts - pkt->dts);
388     }
389
390     put_buffer(pb, data ? data : pkt->data, size);
391
392     put_be32(pb,size+flags_size+11); // previous tag size
393     flv->duration = FFMAX(flv->duration, pkt->pts + flv->delay + pkt->duration);
394
395     put_flush_packet(pb);
396
397     av_free(data);
398
399     return 0;
400 }
401
402 AVOutputFormat flv_muxer = {
403     "flv",
404     NULL_IF_CONFIG_SMALL("FLV format"),
405     "video/x-flv",
406     "flv",
407     sizeof(FLVContext),
408 #if CONFIG_LIBMP3LAME
409     CODEC_ID_MP3,
410 #else // CONFIG_LIBMP3LAME
411     CODEC_ID_ADPCM_SWF,
412 #endif // CONFIG_LIBMP3LAME
413     CODEC_ID_FLV1,
414     flv_write_header,
415     flv_write_packet,
416     flv_write_trailer,
417     .codec_tag= (const AVCodecTag* const []){flv_video_codec_ids, flv_audio_codec_ids, 0},
418     .flags= AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
419 };