You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

322 lines
9.3KB

  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. #undef NDEBUG
  25. #include <assert.h>
  26. static const CodecTag flv_video_codec_ids[] = {
  27. {CODEC_ID_FLV1, FLV_CODECID_H263 },
  28. {CODEC_ID_FLASHSV, FLV_CODECID_SCREEN},
  29. {CODEC_ID_VP6F, FLV_CODECID_VP6 },
  30. {CODEC_ID_NONE, 0}
  31. };
  32. static const CodecTag flv_audio_codec_ids[] = {
  33. {CODEC_ID_MP3, FLV_CODECID_MP3 >> FLV_AUDIO_CODECID_OFFSET},
  34. {CODEC_ID_PCM_S8, FLV_CODECID_PCM_BE >> FLV_AUDIO_CODECID_OFFSET},
  35. {CODEC_ID_PCM_S16BE, FLV_CODECID_PCM_BE >> FLV_AUDIO_CODECID_OFFSET},
  36. {CODEC_ID_PCM_S16LE, FLV_CODECID_PCM_LE >> FLV_AUDIO_CODECID_OFFSET},
  37. {CODEC_ID_ADPCM_SWF, FLV_CODECID_ADPCM >> FLV_AUDIO_CODECID_OFFSET},
  38. {CODEC_ID_NONE, 0}
  39. };
  40. typedef struct FLVContext {
  41. int hasAudio;
  42. int hasVideo;
  43. int reserved;
  44. offset_t duration_offset;
  45. offset_t filesize_offset;
  46. int64_t duration;
  47. } FLVContext;
  48. static int get_audio_flags(AVCodecContext *enc){
  49. int flags = (enc->bits_per_sample == 16) ? FLV_SAMPLESSIZE_16BIT : FLV_SAMPLESSIZE_8BIT;
  50. switch (enc->sample_rate) {
  51. case 44100:
  52. flags |= FLV_SAMPLERATE_44100HZ;
  53. break;
  54. case 22050:
  55. flags |= FLV_SAMPLERATE_22050HZ;
  56. break;
  57. case 11025:
  58. flags |= FLV_SAMPLERATE_11025HZ;
  59. break;
  60. case 8000: //nellymoser only
  61. case 5512: //not mp3
  62. flags |= FLV_SAMPLERATE_SPECIAL;
  63. break;
  64. default:
  65. av_log(enc, AV_LOG_ERROR, "flv doesnt support that sample rate, choose from (44100, 22050, 11025)\n");
  66. return -1;
  67. }
  68. if (enc->channels > 1) {
  69. flags |= FLV_STEREO;
  70. }
  71. switch(enc->codec_id){
  72. case CODEC_ID_MP3:
  73. flags |= FLV_CODECID_MP3 | FLV_SAMPLESSIZE_16BIT;
  74. break;
  75. case CODEC_ID_PCM_S8:
  76. flags |= FLV_CODECID_PCM_BE | FLV_SAMPLESSIZE_8BIT;
  77. break;
  78. case CODEC_ID_PCM_S16BE:
  79. flags |= FLV_CODECID_PCM_BE | FLV_SAMPLESSIZE_16BIT;
  80. break;
  81. case CODEC_ID_PCM_S16LE:
  82. flags |= FLV_CODECID_PCM_LE | FLV_SAMPLESSIZE_16BIT;
  83. break;
  84. case CODEC_ID_ADPCM_SWF:
  85. flags |= FLV_CODECID_ADPCM;
  86. break;
  87. case 0:
  88. flags |= enc->codec_tag<<4;
  89. break;
  90. default:
  91. av_log(enc, AV_LOG_ERROR, "codec not compatible with flv\n");
  92. return -1;
  93. }
  94. return flags;
  95. }
  96. static void put_amf_string(ByteIOContext *pb, const char *str)
  97. {
  98. size_t len = strlen(str);
  99. put_be16(pb, len);
  100. put_buffer(pb, str, len);
  101. }
  102. static void put_amf_double(ByteIOContext *pb, double d)
  103. {
  104. put_byte(pb, AMF_DATA_TYPE_NUMBER);
  105. put_be64(pb, av_dbl2int(d));
  106. }
  107. static void put_amf_bool(ByteIOContext *pb, int b) {
  108. put_byte(pb, AMF_DATA_TYPE_BOOL);
  109. put_byte(pb, !!b);
  110. }
  111. static int flv_write_header(AVFormatContext *s)
  112. {
  113. ByteIOContext *pb = &s->pb;
  114. FLVContext *flv = s->priv_data;
  115. int i, width, height, samplerate, samplesize, channels, audiocodecid, videocodecid;
  116. double framerate = 0.0;
  117. int metadata_size_pos, data_size;
  118. flv->hasAudio = 0;
  119. flv->hasVideo = 0;
  120. for(i=0; i<s->nb_streams; i++){
  121. AVCodecContext *enc = s->streams[i]->codec;
  122. if (enc->codec_type == CODEC_TYPE_VIDEO) {
  123. width = enc->width;
  124. height = enc->height;
  125. if (s->streams[i]->r_frame_rate.den && s->streams[i]->r_frame_rate.num) {
  126. framerate = av_q2d(s->streams[i]->r_frame_rate);
  127. } else {
  128. framerate = 1/av_q2d(s->streams[i]->codec->time_base);
  129. }
  130. flv->hasVideo=1;
  131. videocodecid = codec_get_tag(flv_video_codec_ids, enc->codec_id);
  132. if(videocodecid == 0) {
  133. av_log(enc, AV_LOG_ERROR, "video codec not compatible with flv\n");
  134. return -1;
  135. }
  136. } else {
  137. flv->hasAudio=1;
  138. samplerate = enc->sample_rate;
  139. channels = enc->channels;
  140. audiocodecid = codec_get_tag(flv_audio_codec_ids, enc->codec_id);
  141. samplesize = (enc->codec_id == CODEC_ID_PCM_S8) ? 8 : 16;
  142. if(get_audio_flags(enc)<0)
  143. return -1;
  144. }
  145. av_set_pts_info(s->streams[i], 24, 1, 1000); /* 24 bit pts in ms */
  146. }
  147. put_tag(pb,"FLV");
  148. put_byte(pb,1);
  149. put_byte(pb, FLV_HEADER_FLAG_HASAUDIO * flv->hasAudio
  150. + FLV_HEADER_FLAG_HASVIDEO * flv->hasVideo);
  151. put_be32(pb,9);
  152. put_be32(pb,0);
  153. for(i=0; i<s->nb_streams; i++){
  154. if(s->streams[i]->codec->codec_tag == 5){
  155. put_byte(pb,8); // message type
  156. put_be24(pb,0); // include flags
  157. put_be24(pb,0); // time stamp
  158. put_be32(pb,0); // reserved
  159. put_be32(pb,11); // size
  160. flv->reserved=5;
  161. }
  162. }
  163. /* write meta_tag */
  164. put_byte(pb, 18); // tag type META
  165. metadata_size_pos= url_ftell(pb);
  166. put_be24(pb, 0); // size of data part (sum of all parts below)
  167. put_be24(pb, 0); // time stamp
  168. put_be32(pb, 0); // reserved
  169. /* now data of data_size size */
  170. /* first event name as a string */
  171. put_byte(pb, AMF_DATA_TYPE_STRING);
  172. put_amf_string(pb, "onMetaData"); // 12 bytes
  173. /* mixed array (hash) with size and string/type/data tuples */
  174. put_byte(pb, AMF_DATA_TYPE_MIXEDARRAY);
  175. put_be32(pb, 5*flv->hasVideo + 4*flv->hasAudio + 2); // +2 for duration and file size
  176. put_amf_string(pb, "duration");
  177. flv->duration_offset= url_ftell(pb);
  178. put_amf_double(pb, 0); // delayed write
  179. if(flv->hasVideo){
  180. put_amf_string(pb, "width");
  181. put_amf_double(pb, width);
  182. put_amf_string(pb, "height");
  183. put_amf_double(pb, height);
  184. put_amf_string(pb, "videodatarate");
  185. put_amf_double(pb, s->bit_rate / 1024.0);
  186. put_amf_string(pb, "framerate");
  187. put_amf_double(pb, framerate);
  188. put_amf_string(pb, "videocodecid");
  189. put_amf_double(pb, videocodecid);
  190. }
  191. if(flv->hasAudio){
  192. put_amf_string(pb, "audiosamplerate");
  193. put_amf_double(pb, samplerate);
  194. put_amf_string(pb, "audiosamplesize");
  195. put_amf_double(pb, samplesize);
  196. put_amf_string(pb, "stereo");
  197. put_amf_bool(pb, (channels == 2));
  198. put_amf_string(pb, "audiocodecid");
  199. put_amf_double(pb, audiocodecid);
  200. }
  201. put_amf_string(pb, "filesize");
  202. flv->filesize_offset= url_ftell(pb);
  203. put_amf_double(pb, 0); // delayed write
  204. put_amf_string(pb, "");
  205. put_byte(pb, AMF_END_OF_OBJECT);
  206. /* write total size of tag */
  207. data_size= url_ftell(pb) - metadata_size_pos - 10;
  208. url_fseek(pb, metadata_size_pos, SEEK_SET);
  209. put_be24(pb, data_size);
  210. url_fseek(pb, data_size + 10 - 3, SEEK_CUR);
  211. put_be32(pb, data_size + 11);
  212. return 0;
  213. }
  214. static int flv_write_trailer(AVFormatContext *s)
  215. {
  216. int64_t file_size;
  217. ByteIOContext *pb = &s->pb;
  218. FLVContext *flv = s->priv_data;
  219. file_size = url_ftell(pb);
  220. /* update informations */
  221. url_fseek(pb, flv->duration_offset, SEEK_SET);
  222. put_amf_double(pb, flv->duration / (double)1000);
  223. url_fseek(pb, flv->filesize_offset, SEEK_SET);
  224. put_amf_double(pb, file_size);
  225. url_fseek(pb, file_size, SEEK_SET);
  226. return 0;
  227. }
  228. static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
  229. {
  230. ByteIOContext *pb = &s->pb;
  231. AVCodecContext *enc = s->streams[pkt->stream_index]->codec;
  232. FLVContext *flv = s->priv_data;
  233. int size= pkt->size;
  234. int flags;
  235. // av_log(s, AV_LOG_DEBUG, "type:%d pts: %"PRId64" size:%d\n", enc->codec_type, timestamp, size);
  236. if (enc->codec_type == CODEC_TYPE_VIDEO) {
  237. put_byte(pb, FLV_TAG_TYPE_VIDEO);
  238. flags = FLV_CODECID_H263;
  239. flags |= pkt->flags & PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER;
  240. } else {
  241. assert(enc->codec_type == CODEC_TYPE_AUDIO);
  242. flags = get_audio_flags(enc);
  243. assert(size);
  244. put_byte(pb, FLV_TAG_TYPE_AUDIO);
  245. }
  246. put_be24(pb,size+1); // include flags
  247. put_be24(pb,pkt->pts);
  248. put_be32(pb,flv->reserved);
  249. put_byte(pb,flags);
  250. put_buffer(pb, pkt->data, size);
  251. put_be32(pb,size+1+11); // previous tag size
  252. flv->duration = pkt->pts + pkt->duration;
  253. put_flush_packet(pb);
  254. return 0;
  255. }
  256. AVOutputFormat flv_muxer = {
  257. "flv",
  258. "flv format",
  259. "video/x-flv",
  260. "flv",
  261. sizeof(FLVContext),
  262. #ifdef CONFIG_MP3LAME
  263. CODEC_ID_MP3,
  264. #else // CONFIG_MP3LAME
  265. CODEC_ID_NONE,
  266. #endif // CONFIG_MP3LAME
  267. CODEC_ID_FLV1,
  268. flv_write_header,
  269. flv_write_packet,
  270. flv_write_trailer,
  271. };