add new h264 and aac flv ids
[libav.git] / libavformat / flvenc.c
CommitLineData
d4f5d74a 1/*
7fbde343 2 * FLV muxer
d4f5d74a
GM
3 * Copyright (c) 2003 The FFmpeg Project.
4 *
b78e7197
DB
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
d4f5d74a
GM
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
b78e7197 10 * version 2.1 of the License, or (at your option) any later version.
d4f5d74a 11 *
b78e7197 12 * FFmpeg is distributed in the hope that it will be useful,
d4f5d74a
GM
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
b78e7197 18 * License along with FFmpeg; if not, write to the Free Software
5509bffa 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
d4f5d74a
GM
20 */
21#include "avformat.h"
6cac3a3b 22#include "flv.h"
148c9bdb 23#include "riff.h"
d4f5d74a 24
068f2a22
MN
25#undef NDEBUG
26#include <assert.h>
27
7caf0cc6 28static const AVCodecTag flv_video_codec_ids[] = {
148c9bdb
AH
29 {CODEC_ID_FLV1, FLV_CODECID_H263 },
30 {CODEC_ID_FLASHSV, FLV_CODECID_SCREEN},
31 {CODEC_ID_VP6F, FLV_CODECID_VP6 },
09d8c0ae 32 {CODEC_ID_VP6, FLV_CODECID_VP6 },
148c9bdb
AH
33 {CODEC_ID_NONE, 0}
34};
35
7caf0cc6 36static const AVCodecTag flv_audio_codec_ids[] = {
148c9bdb 37 {CODEC_ID_MP3, FLV_CODECID_MP3 >> FLV_AUDIO_CODECID_OFFSET},
44de39f9
MN
38 {CODEC_ID_PCM_S8, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET},
39 {CODEC_ID_PCM_S16BE, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET},
148c9bdb
AH
40 {CODEC_ID_PCM_S16LE, FLV_CODECID_PCM_LE >> FLV_AUDIO_CODECID_OFFSET},
41 {CODEC_ID_ADPCM_SWF, FLV_CODECID_ADPCM >> FLV_AUDIO_CODECID_OFFSET},
b7d1cd02 42 {CODEC_ID_NELLYMOSER, FLV_CODECID_NELLYMOSER >> FLV_AUDIO_CODECID_OFFSET},
148c9bdb
AH
43 {CODEC_ID_NONE, 0}
44};
45
d4f5d74a
GM
46typedef struct FLVContext {
47 int hasAudio;
48 int hasVideo;
11a8e425 49 int reserved;
634b8cfa
BC
50 offset_t duration_offset;
51 offset_t filesize_offset;
52 int64_t duration;
d4f5d74a
GM
53} FLVContext;
54
37cdf93d 55static int get_audio_flags(AVCodecContext *enc){
6cac3a3b 56 int flags = (enc->bits_per_sample == 16) ? FLV_SAMPLESSIZE_16BIT : FLV_SAMPLESSIZE_8BIT;
37cdf93d
MN
57
58 switch (enc->sample_rate) {
59 case 44100:
6cac3a3b 60 flags |= FLV_SAMPLERATE_44100HZ;
37cdf93d
MN
61 break;
62 case 22050:
6cac3a3b 63 flags |= FLV_SAMPLERATE_22050HZ;
37cdf93d
MN
64 break;
65 case 11025:
6cac3a3b 66 flags |= FLV_SAMPLERATE_11025HZ;
37cdf93d
MN
67 break;
68 case 8000: //nellymoser only
69 case 5512: //not mp3
4838727e 70 if(enc->codec_id != CODEC_ID_MP3){
ec627278
MN
71 flags |= FLV_SAMPLERATE_SPECIAL;
72 break;
4838727e 73 }
37cdf93d 74 default:
755bfeab 75 av_log(enc, AV_LOG_ERROR, "flv does not support that sample rate, choose from (44100, 22050, 11025).\n");
37cdf93d
MN
76 return -1;
77 }
78
79 if (enc->channels > 1) {
6cac3a3b 80 flags |= FLV_STEREO;
37cdf93d 81 }
115329f1 82
37cdf93d
MN
83 switch(enc->codec_id){
84 case CODEC_ID_MP3:
6cac3a3b 85 flags |= FLV_CODECID_MP3 | FLV_SAMPLESSIZE_16BIT;
37cdf93d 86 break;
923bd441 87 case CODEC_ID_PCM_S8:
44de39f9 88 flags |= FLV_CODECID_PCM | FLV_SAMPLESSIZE_8BIT;
bb270c08 89 break;
923bd441 90 case CODEC_ID_PCM_S16BE:
44de39f9 91 flags |= FLV_CODECID_PCM | FLV_SAMPLESSIZE_16BIT;
bb270c08 92 break;
923bd441 93 case CODEC_ID_PCM_S16LE:
6cac3a3b 94 flags |= FLV_CODECID_PCM_LE | FLV_SAMPLESSIZE_16BIT;
bb270c08 95 break;
2fde8aae 96 case CODEC_ID_ADPCM_SWF:
e9509536 97 flags |= FLV_CODECID_ADPCM | FLV_SAMPLESSIZE_16BIT;
bb270c08 98 break;
b7d1cd02
BW
99 case CODEC_ID_NELLYMOSER:
100 flags |= FLV_CODECID_NELLYMOSER | FLV_SAMPLESSIZE_16BIT;
101 break;
37cdf93d
MN
102 case 0:
103 flags |= enc->codec_tag<<4;
104 break;
105 default:
a254c574 106 av_log(enc, AV_LOG_ERROR, "codec not compatible with flv\n");
37cdf93d
MN
107 return -1;
108 }
115329f1 109
37cdf93d
MN
110 return flags;
111}
112
fd0fb306
MN
113static void put_amf_string(ByteIOContext *pb, const char *str)
114{
115 size_t len = strlen(str);
116 put_be16(pb, len);
117 put_buffer(pb, str, len);
118}
119
120static void put_amf_double(ByteIOContext *pb, double d)
121{
6cac3a3b 122 put_byte(pb, AMF_DATA_TYPE_NUMBER);
fd0fb306
MN
123 put_be64(pb, av_dbl2int(d));
124}
125
148c9bdb
AH
126static void put_amf_bool(ByteIOContext *pb, int b) {
127 put_byte(pb, AMF_DATA_TYPE_BOOL);
128 put_byte(pb, !!b);
129}
130
d4f5d74a
GM
131static int flv_write_header(AVFormatContext *s)
132{
899681cd 133 ByteIOContext *pb = s->pb;
d4f5d74a 134 FLVContext *flv = s->priv_data;
148c9bdb 135 int i, width, height, samplerate, samplesize, channels, audiocodecid, videocodecid;
fd0fb306
MN
136 double framerate = 0.0;
137 int metadata_size_pos, data_size;
d4f5d74a 138
d4f5d74a
GM
139 flv->hasAudio = 0;
140 flv->hasVideo = 0;
141
11a8e425 142 for(i=0; i<s->nb_streams; i++){
01f4895c 143 AVCodecContext *enc = s->streams[i]->codec;
fd0fb306
MN
144 if (enc->codec_type == CODEC_TYPE_VIDEO) {
145 width = enc->width;
146 height = enc->height;
147 if (s->streams[i]->r_frame_rate.den && s->streams[i]->r_frame_rate.num) {
148 framerate = av_q2d(s->streams[i]->r_frame_rate);
149 } else {
150 framerate = 1/av_q2d(s->streams[i]->codec->time_base);
151 }
152 flv->hasVideo=1;
148c9bdb 153
bb85077f 154 videocodecid = enc->codec_tag;
148c9bdb
AH
155 if(videocodecid == 0) {
156 av_log(enc, AV_LOG_ERROR, "video codec not compatible with flv\n");
157 return -1;
158 }
fd0fb306
MN
159 } else {
160 flv->hasAudio=1;
161 samplerate = enc->sample_rate;
148c9bdb
AH
162 channels = enc->channels;
163
bb85077f 164 audiocodecid = enc->codec_tag;
148c9bdb
AH
165 samplesize = (enc->codec_id == CODEC_ID_PCM_S8) ? 8 : 16;
166
c45388b1
MN
167 if(get_audio_flags(enc)<0)
168 return -1;
fd0fb306 169 }
254629b1 170 av_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */
c45388b1
MN
171 }
172 put_tag(pb,"FLV");
173 put_byte(pb,1);
174 put_byte(pb, FLV_HEADER_FLAG_HASAUDIO * flv->hasAudio
175 + FLV_HEADER_FLAG_HASVIDEO * flv->hasVideo);
176 put_be32(pb,9);
177 put_be32(pb,0);
178
179 for(i=0; i<s->nb_streams; i++){
180 if(s->streams[i]->codec->codec_tag == 5){
11a8e425
MN
181 put_byte(pb,8); // message type
182 put_be24(pb,0); // include flags
183 put_be24(pb,0); // time stamp
184 put_be32(pb,0); // reserved
185 put_be32(pb,11); // size
186 flv->reserved=5;
187 }
188 }
d4f5d74a 189
fd0fb306
MN
190 /* write meta_tag */
191 put_byte(pb, 18); // tag type META
192 metadata_size_pos= url_ftell(pb);
193 put_be24(pb, 0); // size of data part (sum of all parts below)
194 put_be24(pb, 0); // time stamp
195 put_be32(pb, 0); // reserved
196
197 /* now data of data_size size */
198
199 /* first event name as a string */
6cac3a3b 200 put_byte(pb, AMF_DATA_TYPE_STRING);
fd0fb306
MN
201 put_amf_string(pb, "onMetaData"); // 12 bytes
202
203 /* mixed array (hash) with size and string/type/data tuples */
6cac3a3b 204 put_byte(pb, AMF_DATA_TYPE_MIXEDARRAY);
148c9bdb 205 put_be32(pb, 5*flv->hasVideo + 4*flv->hasAudio + 2); // +2 for duration and file size
fd0fb306 206
634b8cfa
BC
207 put_amf_string(pb, "duration");
208 flv->duration_offset= url_ftell(pb);
209 put_amf_double(pb, 0); // delayed write
fd0fb306
MN
210
211 if(flv->hasVideo){
212 put_amf_string(pb, "width");
213 put_amf_double(pb, width);
214
215 put_amf_string(pb, "height");
216 put_amf_double(pb, height);
217
218 put_amf_string(pb, "videodatarate");
219 put_amf_double(pb, s->bit_rate / 1024.0);
220
221 put_amf_string(pb, "framerate");
222 put_amf_double(pb, framerate);
148c9bdb
AH
223
224 put_amf_string(pb, "videocodecid");
225 put_amf_double(pb, videocodecid);
fd0fb306
MN
226 }
227
228 if(flv->hasAudio){
229 put_amf_string(pb, "audiosamplerate");
230 put_amf_double(pb, samplerate);
148c9bdb
AH
231
232 put_amf_string(pb, "audiosamplesize");
233 put_amf_double(pb, samplesize);
234
235 put_amf_string(pb, "stereo");
236 put_amf_bool(pb, (channels == 2));
237
238 put_amf_string(pb, "audiocodecid");
239 put_amf_double(pb, audiocodecid);
fd0fb306
MN
240 }
241
634b8cfa
BC
242 put_amf_string(pb, "filesize");
243 flv->filesize_offset= url_ftell(pb);
244 put_amf_double(pb, 0); // delayed write
fd0fb306
MN
245
246 put_amf_string(pb, "");
6cac3a3b 247 put_byte(pb, AMF_END_OF_OBJECT);
fd0fb306
MN
248
249 /* write total size of tag */
250 data_size= url_ftell(pb) - metadata_size_pos - 10;
251 url_fseek(pb, metadata_size_pos, SEEK_SET);
252 put_be24(pb, data_size);
253 url_fseek(pb, data_size + 10 - 3, SEEK_CUR);
254 put_be32(pb, data_size + 11);
255
d4f5d74a
GM
256 return 0;
257}
258
d4f5d74a
GM
259static int flv_write_trailer(AVFormatContext *s)
260{
14b32253 261 int64_t file_size;
14b32253 262
899681cd 263 ByteIOContext *pb = s->pb;
d4f5d74a
GM
264 FLVContext *flv = s->priv_data;
265
14b32253 266 file_size = url_ftell(pb);
634b8cfa
BC
267
268 /* update informations */
269 url_fseek(pb, flv->duration_offset, SEEK_SET);
270 put_amf_double(pb, flv->duration / (double)1000);
271 url_fseek(pb, flv->filesize_offset, SEEK_SET);
272 put_amf_double(pb, file_size);
273
d4f5d74a
GM
274 url_fseek(pb, file_size, SEEK_SET);
275 return 0;
276}
277
e928649b 278static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
d4f5d74a 279{
899681cd 280 ByteIOContext *pb = s->pb;
01f4895c 281 AVCodecContext *enc = s->streams[pkt->stream_index]->codec;
d4f5d74a 282 FLVContext *flv = s->priv_data;
e928649b 283 int size= pkt->size;
f683dbdc 284 int flags, flags_size;
d4f5d74a 285
949b1a13 286// av_log(s, AV_LOG_DEBUG, "type:%d pts: %"PRId64" size:%d\n", enc->codec_type, timestamp, size);
115329f1 287
f683dbdc
MN
288 if(enc->codec_id == CODEC_ID_VP6 || enc->codec_id == CODEC_ID_VP6F)
289 flags_size= 2;
290 else
291 flags_size= 1;
292
d4f5d74a 293 if (enc->codec_type == CODEC_TYPE_VIDEO) {
6cac3a3b 294 put_byte(pb, FLV_TAG_TYPE_VIDEO);
09d8c0ae 295
bb85077f 296 flags = enc->codec_tag;
09d8c0ae
BL
297 if(flags == 0) {
298 av_log(enc, AV_LOG_ERROR, "video codec %X not compatible with flv\n",enc->codec_id);
299 return -1;
300 }
301
6cac3a3b 302 flags |= pkt->flags & PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER;
75293f05
MN
303 } else {
304 assert(enc->codec_type == CODEC_TYPE_AUDIO);
37cdf93d 305 flags = get_audio_flags(enc);
115329f1 306
068f2a22 307 assert(size);
068f2a22 308
6cac3a3b 309 put_byte(pb, FLV_TAG_TYPE_AUDIO);
75293f05
MN
310 }
311
f683dbdc 312 put_be24(pb,size + flags_size);
75293f05 313 put_be24(pb,pkt->pts);
018b6fb4
AB
314 put_byte(pb,pkt->pts >> 24);
315 put_be24(pb,flv->reserved);
75293f05 316 put_byte(pb,flags);
09d8c0ae
BL
317 if (enc->codec_id == CODEC_ID_VP6)
318 put_byte(pb,0);
319 if (enc->codec_id == CODEC_ID_VP6F)
320 put_byte(pb, enc->extradata_size ? enc->extradata[0] : 0);
75293f05 321 put_buffer(pb, pkt->data, size);
f683dbdc 322 put_be32(pb,size+flags_size+11); // previous tag size
634b8cfa 323 flv->duration = pkt->pts + pkt->duration;
115329f1 324
d4f5d74a
GM
325 put_flush_packet(pb);
326 return 0;
327}
328
ff70e601 329AVOutputFormat flv_muxer = {
d4f5d74a
GM
330 "flv",
331 "flv format",
e817a73d 332 "video/x-flv",
d4f5d74a
GM
333 "flv",
334 sizeof(FLVContext),
6ebe07fb 335#ifdef CONFIG_LIBMP3LAME
80783dc2 336 CODEC_ID_MP3,
6ebe07fb 337#else // CONFIG_LIBMP3LAME
964ff354 338 CODEC_ID_ADPCM_SWF,
6ebe07fb 339#endif // CONFIG_LIBMP3LAME
d4f5d74a
GM
340 CODEC_ID_FLV1,
341 flv_write_header,
342 flv_write_packet,
343 flv_write_trailer,
6c77805f 344 .codec_tag= (const AVCodecTag*[]){flv_video_codec_ids, flv_audio_codec_ids, 0},
d4f5d74a 345};