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.

178 lines
4.4KB

  1. /*
  2. * FLV encoder.
  3. * Copyright (c) 2003 The FFmpeg Project.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #include "avformat.h"
  20. #undef NDEBUG
  21. #include <assert.h>
  22. typedef struct FLVContext {
  23. int hasAudio;
  24. int hasVideo;
  25. int reserved;
  26. } FLVContext;
  27. static void put_be24(ByteIOContext *pb, int value)
  28. {
  29. put_byte(pb, (value>>16) & 0xFF );
  30. put_byte(pb, (value>> 8) & 0xFF );
  31. put_byte(pb, (value>> 0) & 0xFF );
  32. }
  33. static int flv_write_header(AVFormatContext *s)
  34. {
  35. ByteIOContext *pb = &s->pb;
  36. FLVContext *flv = s->priv_data;
  37. int i;
  38. flv->hasAudio = 0;
  39. flv->hasVideo = 0;
  40. put_tag(pb,"FLV");
  41. put_byte(pb,1);
  42. put_byte(pb,0); // delayed write
  43. put_be32(pb,9);
  44. put_be32(pb,0);
  45. for(i=0; i<s->nb_streams; i++){
  46. AVCodecContext *enc = &s->streams[i]->codec;
  47. av_set_pts_info(s->streams[i], 24, 1, 1000); /* 24 bit pts in ms */
  48. if(enc->codec_tag == 5){
  49. put_byte(pb,8); // message type
  50. put_be24(pb,0); // include flags
  51. put_be24(pb,0); // time stamp
  52. put_be32(pb,0); // reserved
  53. put_be32(pb,11); // size
  54. flv->reserved=5;
  55. }
  56. }
  57. return 0;
  58. }
  59. static int flv_write_trailer(AVFormatContext *s)
  60. {
  61. int64_t file_size;
  62. int flags = 0;
  63. ByteIOContext *pb = &s->pb;
  64. FLVContext *flv = s->priv_data;
  65. file_size = url_ftell(pb);
  66. flags |= flv->hasAudio ? 4 : 0;
  67. flags |= flv->hasVideo ? 1 : 0;
  68. url_fseek(pb, 4, SEEK_SET);
  69. put_byte(pb,flags);
  70. url_fseek(pb, file_size, SEEK_SET);
  71. return 0;
  72. }
  73. static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
  74. {
  75. ByteIOContext *pb = &s->pb;
  76. AVCodecContext *enc = &s->streams[pkt->stream_index]->codec;
  77. FLVContext *flv = s->priv_data;
  78. int size= pkt->size;
  79. int flags;
  80. // av_log(s, AV_LOG_DEBUG, "type:%d pts: %lld size:%d\n", enc->codec_type, timestamp, size);
  81. if (enc->codec_type == CODEC_TYPE_VIDEO) {
  82. put_byte(pb, 9);
  83. flags = 2; // choose h263
  84. flags |= pkt->flags & PKT_FLAG_KEY ? 0x10 : 0x20; // add keyframe indicator
  85. flv->hasVideo = 1;
  86. } else {
  87. assert(enc->codec_type == CODEC_TYPE_AUDIO);
  88. flags = 0x02;
  89. switch (enc->sample_rate) {
  90. case 44100:
  91. flags |= 0x0C;
  92. break;
  93. case 22050:
  94. flags |= 0x08;
  95. break;
  96. case 11025:
  97. flags |= 0x04;
  98. break;
  99. case 8000: //nellymoser only
  100. case 5512: //not mp3
  101. flags |= 0x00;
  102. break;
  103. default:
  104. assert(0);
  105. }
  106. if (enc->channels > 1) {
  107. flags |= 0x01;
  108. }
  109. switch(enc->codec_id){
  110. case CODEC_ID_MP3:
  111. flags |= 0x20;
  112. break;
  113. case 0:
  114. flags |= enc->codec_tag<<4;
  115. break;
  116. default:
  117. assert(0);
  118. }
  119. assert(size);
  120. put_byte(pb, 8);
  121. // We got audio! Make sure we set this to the global flags on closure
  122. flv->hasAudio = 1;
  123. }
  124. put_be24(pb,size+1); // include flags
  125. put_be24(pb,pkt->pts);
  126. put_be32(pb,flv->reserved);
  127. put_byte(pb,flags);
  128. put_buffer(pb, pkt->data, size);
  129. put_be32(pb,size+1+11); // reserved
  130. put_flush_packet(pb);
  131. return 0;
  132. }
  133. static AVOutputFormat flv_oformat = {
  134. "flv",
  135. "flv format",
  136. "video/x-flashvideo",
  137. "flv",
  138. sizeof(FLVContext),
  139. #ifdef CONFIG_MP3LAME
  140. CODEC_ID_MP3,
  141. #else // CONFIG_MP3LAME
  142. CODEC_ID_NONE,
  143. #endif // CONFIG_MP3LAME
  144. CODEC_ID_FLV1,
  145. flv_write_header,
  146. flv_write_packet,
  147. flv_write_trailer,
  148. };
  149. int flvenc_init(void)
  150. {
  151. av_register_output_format(&flv_oformat);
  152. return 0;
  153. }