flvenc.c
Go to the documentation of this file.
1 /*
2  * FLV muxer
3  * Copyright (c) 2003 The Libav Project
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/intfloat.h"
23 #include "avformat.h"
24 #include "flv.h"
25 #include "internal.h"
26 #include "avc.h"
27 #include "metadata.h"
28 #include "libavutil/dict.h"
29 
30 #undef NDEBUG
31 #include <assert.h>
32 
33 static const AVCodecTag flv_video_codec_ids[] = {
40  {CODEC_ID_NONE, 0}
41 };
42 
43 static const AVCodecTag flv_audio_codec_ids[] = {
52  {CODEC_ID_NONE, 0}
53 };
54 
55 typedef struct FLVContext {
56  int reserved;
57  int64_t duration_offset;
58  int64_t filesize_offset;
59  int64_t duration;
60  int64_t delay;
61 } FLVContext;
62 
63 typedef struct FLVStreamContext {
64  int64_t last_ts;
66 
69 
70  if (enc->codec_id == CODEC_ID_AAC) // specs force these parameters
72  else if (enc->codec_id == CODEC_ID_SPEEX) {
73  if (enc->sample_rate != 16000) {
74  av_log(enc, AV_LOG_ERROR, "flv only supports wideband (16kHz) Speex audio\n");
75  return -1;
76  }
77  if (enc->channels != 1) {
78  av_log(enc, AV_LOG_ERROR, "flv only supports mono Speex audio\n");
79  return -1;
80  }
82  } else {
83  switch (enc->sample_rate) {
84  case 44100:
85  flags |= FLV_SAMPLERATE_44100HZ;
86  break;
87  case 22050:
88  flags |= FLV_SAMPLERATE_22050HZ;
89  break;
90  case 11025:
91  flags |= FLV_SAMPLERATE_11025HZ;
92  break;
93  case 16000: //nellymoser only
94  case 8000: //nellymoser only
95  case 5512: //not mp3
96  if(enc->codec_id != CODEC_ID_MP3){
97  flags |= FLV_SAMPLERATE_SPECIAL;
98  break;
99  }
100  default:
101  av_log(enc, AV_LOG_ERROR, "flv does not support that sample rate, choose from (44100, 22050, 11025).\n");
102  return -1;
103  }
104  }
105 
106  if (enc->channels > 1) {
107  flags |= FLV_STEREO;
108  }
109 
110  switch(enc->codec_id){
111  case CODEC_ID_MP3:
113  break;
114  case CODEC_ID_PCM_U8:
116  break;
117  case CODEC_ID_PCM_S16BE:
119  break;
120  case CODEC_ID_PCM_S16LE:
122  break;
123  case CODEC_ID_ADPCM_SWF:
125  break;
126  case CODEC_ID_NELLYMOSER:
127  if (enc->sample_rate == 8000) {
129  } else if (enc->sample_rate == 16000) {
131  } else {
133  }
134  break;
135  case 0:
136  flags |= enc->codec_tag<<4;
137  break;
138  default:
139  av_log(enc, AV_LOG_ERROR, "codec not compatible with flv\n");
140  return -1;
141  }
142 
143  return flags;
144 }
145 
146 static void put_amf_string(AVIOContext *pb, const char *str)
147 {
148  size_t len = strlen(str);
149  avio_wb16(pb, len);
150  avio_write(pb, str, len);
151 }
152 
153 static void put_avc_eos_tag(AVIOContext *pb, unsigned ts) {
155  avio_wb24(pb, 5); /* Tag Data Size */
156  avio_wb24(pb, ts); /* lower 24 bits of timestamp in ms*/
157  avio_w8(pb, (ts >> 24) & 0x7F); /* MSB of ts in ms*/
158  avio_wb24(pb, 0); /* StreamId = 0 */
159  avio_w8(pb, 23); /* ub[4] FrameType = 1, ub[4] CodecId = 7 */
160  avio_w8(pb, 2); /* AVC end of sequence */
161  avio_wb24(pb, 0); /* Always 0 for AVC EOS. */
162  avio_wb32(pb, 16); /* Size of FLV tag */
163 }
164 
165 static void put_amf_double(AVIOContext *pb, double d)
166 {
168  avio_wb64(pb, av_double2int(d));
169 }
170 
171 static void put_amf_bool(AVIOContext *pb, int b) {
173  avio_w8(pb, !!b);
174 }
175 
177 {
178  AVIOContext *pb = s->pb;
179  FLVContext *flv = s->priv_data;
180  AVCodecContext *audio_enc = NULL, *video_enc = NULL;
181  int i, metadata_count = 0;
182  double framerate = 0.0;
183  int64_t metadata_size_pos, data_size, metadata_count_pos;
185 
186  for(i=0; i<s->nb_streams; i++){
187  AVCodecContext *enc = s->streams[i]->codec;
188  FLVStreamContext *sc;
189  if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
190  if (s->streams[i]->r_frame_rate.den && s->streams[i]->r_frame_rate.num) {
191  framerate = av_q2d(s->streams[i]->r_frame_rate);
192  } else {
193  framerate = 1/av_q2d(s->streams[i]->codec->time_base);
194  }
195  video_enc = enc;
196  if(enc->codec_tag == 0) {
197  av_log(enc, AV_LOG_ERROR, "video codec not compatible with flv\n");
198  return -1;
199  }
200  } else {
201  audio_enc = enc;
202  if(get_audio_flags(enc)<0)
203  return -1;
204  }
205  avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */
206 
207  sc = av_mallocz(sizeof(FLVStreamContext));
208  if (!sc)
209  return AVERROR(ENOMEM);
210  s->streams[i]->priv_data = sc;
211  sc->last_ts = -1;
212  }
213  flv->delay = AV_NOPTS_VALUE;
214 
215  avio_write(pb, "FLV", 3);
216  avio_w8(pb,1);
217  avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!audio_enc
218  + FLV_HEADER_FLAG_HASVIDEO * !!video_enc);
219  avio_wb32(pb,9);
220  avio_wb32(pb,0);
221 
222  for(i=0; i<s->nb_streams; i++){
223  if(s->streams[i]->codec->codec_tag == 5){
224  avio_w8(pb,8); // message type
225  avio_wb24(pb,0); // include flags
226  avio_wb24(pb,0); // time stamp
227  avio_wb32(pb,0); // reserved
228  avio_wb32(pb,11); // size
229  flv->reserved=5;
230  }
231  }
232 
233  /* write meta_tag */
234  avio_w8(pb, 18); // tag type META
235  metadata_size_pos= avio_tell(pb);
236  avio_wb24(pb, 0); // size of data part (sum of all parts below)
237  avio_wb24(pb, 0); // time stamp
238  avio_wb32(pb, 0); // reserved
239 
240  /* now data of data_size size */
241 
242  /* first event name as a string */
244  put_amf_string(pb, "onMetaData"); // 12 bytes
245 
246  /* mixed array (hash) with size and string/type/data tuples */
248  metadata_count_pos = avio_tell(pb);
249  metadata_count = 5*!!video_enc + 5*!!audio_enc + 2; // +2 for duration and file size
250  avio_wb32(pb, metadata_count);
251 
252  put_amf_string(pb, "duration");
253  flv->duration_offset= avio_tell(pb);
254  put_amf_double(pb, s->duration / AV_TIME_BASE); // fill in the guessed duration, it'll be corrected later if incorrect
255 
256  if(video_enc){
257  put_amf_string(pb, "width");
258  put_amf_double(pb, video_enc->width);
259 
260  put_amf_string(pb, "height");
261  put_amf_double(pb, video_enc->height);
262 
263  put_amf_string(pb, "videodatarate");
264  put_amf_double(pb, video_enc->bit_rate / 1024.0);
265 
266  put_amf_string(pb, "framerate");
267  put_amf_double(pb, framerate);
268 
269  put_amf_string(pb, "videocodecid");
270  put_amf_double(pb, video_enc->codec_tag);
271  }
272 
273  if(audio_enc){
274  put_amf_string(pb, "audiodatarate");
275  put_amf_double(pb, audio_enc->bit_rate / 1024.0);
276 
277  put_amf_string(pb, "audiosamplerate");
278  put_amf_double(pb, audio_enc->sample_rate);
279 
280  put_amf_string(pb, "audiosamplesize");
281  put_amf_double(pb, audio_enc->codec_id == CODEC_ID_PCM_U8 ? 8 : 16);
282 
283  put_amf_string(pb, "stereo");
284  put_amf_bool(pb, audio_enc->channels == 2);
285 
286  put_amf_string(pb, "audiocodecid");
287  put_amf_double(pb, audio_enc->codec_tag);
288  }
289 
290  while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
291  put_amf_string(pb, tag->key);
293  put_amf_string(pb, tag->value);
294  metadata_count++;
295  }
296 
297  put_amf_string(pb, "filesize");
298  flv->filesize_offset= avio_tell(pb);
299  put_amf_double(pb, 0); // delayed write
300 
301  put_amf_string(pb, "");
303 
304  /* write total size of tag */
305  data_size= avio_tell(pb) - metadata_size_pos - 10;
306 
307  avio_seek(pb, metadata_count_pos, SEEK_SET);
308  avio_wb32(pb, metadata_count);
309 
310  avio_seek(pb, metadata_size_pos, SEEK_SET);
311  avio_wb24(pb, data_size);
312  avio_skip(pb, data_size + 10 - 3);
313  avio_wb32(pb, data_size + 11);
314 
315  for (i = 0; i < s->nb_streams; i++) {
316  AVCodecContext *enc = s->streams[i]->codec;
317  if (enc->codec_id == CODEC_ID_AAC || enc->codec_id == CODEC_ID_H264) {
318  int64_t pos;
321  avio_wb24(pb, 0); // size patched later
322  avio_wb24(pb, 0); // ts
323  avio_w8(pb, 0); // ts ext
324  avio_wb24(pb, 0); // streamid
325  pos = avio_tell(pb);
326  if (enc->codec_id == CODEC_ID_AAC) {
327  avio_w8(pb, get_audio_flags(enc));
328  avio_w8(pb, 0); // AAC sequence header
329  avio_write(pb, enc->extradata, enc->extradata_size);
330  } else {
331  avio_w8(pb, enc->codec_tag | FLV_FRAME_KEY); // flags
332  avio_w8(pb, 0); // AVC sequence header
333  avio_wb24(pb, 0); // composition time
335  }
336  data_size = avio_tell(pb) - pos;
337  avio_seek(pb, -data_size - 10, SEEK_CUR);
338  avio_wb24(pb, data_size);
339  avio_skip(pb, data_size + 10 - 3);
340  avio_wb32(pb, data_size + 11); // previous tag size
341  }
342  }
343 
344  return 0;
345 }
346 
348 {
349  int64_t file_size;
350 
351  AVIOContext *pb = s->pb;
352  FLVContext *flv = s->priv_data;
353  int i;
354 
355  /* Add EOS tag */
356  for (i = 0; i < s->nb_streams; i++) {
357  AVCodecContext *enc = s->streams[i]->codec;
358  FLVStreamContext *sc = s->streams[i]->priv_data;
359  if (enc->codec_type == AVMEDIA_TYPE_VIDEO &&
360  enc->codec_id == CODEC_ID_H264) {
361  put_avc_eos_tag(pb, sc->last_ts);
362  }
363  }
364 
365  file_size = avio_tell(pb);
366 
367  /* update information */
368  avio_seek(pb, flv->duration_offset, SEEK_SET);
369  put_amf_double(pb, flv->duration / (double)1000);
370  avio_seek(pb, flv->filesize_offset, SEEK_SET);
371  put_amf_double(pb, file_size);
372 
373  avio_seek(pb, file_size, SEEK_SET);
374  return 0;
375 }
376 
378 {
379  AVIOContext *pb = s->pb;
380  AVCodecContext *enc = s->streams[pkt->stream_index]->codec;
381  FLVContext *flv = s->priv_data;
383  unsigned ts;
384  int size= pkt->size;
385  uint8_t *data= NULL;
386  int flags, flags_size;
387 
388 // av_log(s, AV_LOG_DEBUG, "type:%d pts: %"PRId64" size:%d\n", enc->codec_type, timestamp, size);
389 
390  if(enc->codec_id == CODEC_ID_VP6 || enc->codec_id == CODEC_ID_VP6F ||
391  enc->codec_id == CODEC_ID_AAC)
392  flags_size= 2;
393  else if(enc->codec_id == CODEC_ID_H264)
394  flags_size= 5;
395  else
396  flags_size= 1;
397 
398  if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
400 
401  flags = enc->codec_tag;
402  if(flags == 0) {
403  av_log(enc, AV_LOG_ERROR, "video codec %X not compatible with flv\n",enc->codec_id);
404  return -1;
405  }
406 
408  } else {
409  assert(enc->codec_type == AVMEDIA_TYPE_AUDIO);
410  flags = get_audio_flags(enc);
411 
412  assert(size);
413 
415  }
416 
417  if (enc->codec_id == CODEC_ID_H264) {
418  /* check if extradata looks like MP4 */
419  if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1) {
420  if (ff_avc_parse_nal_units_buf(pkt->data, &data, &size) < 0)
421  return -1;
422  }
423  }
424  if (flv->delay == AV_NOPTS_VALUE)
425  flv->delay = -pkt->dts;
426  if (pkt->dts < -flv->delay) {
427  av_log(s, AV_LOG_WARNING, "Packets are not in the proper order with "
428  "respect to DTS\n");
429  return AVERROR(EINVAL);
430  }
431 
432  ts = pkt->dts + flv->delay; // add delay to force positive dts
433 
434  /* check Speex packet duration */
435  if (enc->codec_id == CODEC_ID_SPEEX && ts - sc->last_ts > 160) {
436  av_log(s, AV_LOG_WARNING, "Warning: Speex stream has more than "
437  "8 frames per packet. Adobe Flash "
438  "Player cannot handle this!\n");
439  }
440 
441  if (sc->last_ts < ts)
442  sc->last_ts = ts;
443 
444  avio_wb24(pb,size + flags_size);
445  avio_wb24(pb,ts);
446  avio_w8(pb,(ts >> 24) & 0x7F); // timestamps are 32bits _signed_
447  avio_wb24(pb,flv->reserved);
448  avio_w8(pb,flags);
449  if (enc->codec_id == CODEC_ID_VP6)
450  avio_w8(pb,0);
451  if (enc->codec_id == CODEC_ID_VP6F)
452  avio_w8(pb, enc->extradata_size ? enc->extradata[0] : 0);
453  else if (enc->codec_id == CODEC_ID_AAC)
454  avio_w8(pb,1); // AAC raw
455  else if (enc->codec_id == CODEC_ID_H264) {
456  avio_w8(pb,1); // AVC NALU
457  avio_wb24(pb,pkt->pts - pkt->dts);
458  }
459 
460  avio_write(pb, data ? data : pkt->data, size);
461 
462  avio_wb32(pb,size+flags_size+11); // previous tag size
463  flv->duration = FFMAX(flv->duration, pkt->pts + flv->delay + pkt->duration);
464 
465  avio_flush(pb);
466 
467  av_free(data);
468 
469  return pb->error;
470 }
471 
473  .name = "flv",
474  .long_name = NULL_IF_CONFIG_SMALL("FLV format"),
475  .mime_type = "video/x-flv",
476  .extensions = "flv",
477  .priv_data_size = sizeof(FLVContext),
479  .audio_codec = CODEC_ID_MP3,
480 #else // CONFIG_LIBMP3LAME
481  .audio_codec = CODEC_ID_ADPCM_SWF,
482 #endif // CONFIG_LIBMP3LAME
483  .video_codec = CODEC_ID_FLV1,
487  .codec_tag= (const AVCodecTag* const []){flv_video_codec_ids, flv_audio_codec_ids, 0},
489 };