flv.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. /*****************************************************************************
  2. * flv.c: flv muxer
  3. *****************************************************************************
  4. * Copyright (C) 2009-2018 x264 project
  5. *
  6. * Authors: Kieran Kunhya <kieran@kunhya.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  21. *
  22. * This program is also available under a commercial proprietary license.
  23. * For more information, contact us at licensing@x264.com.
  24. *****************************************************************************/
  25. #include "output.h"
  26. #include "flv_bytestream.h"
  27. #define CHECK(x)\
  28. do {\
  29. if( (x) < 0 )\
  30. return -1;\
  31. } while( 0 )
  32. typedef struct
  33. {
  34. flv_buffer *c;
  35. uint8_t *sei;
  36. int sei_len;
  37. int64_t i_fps_num;
  38. int64_t i_fps_den;
  39. int64_t i_framenum;
  40. uint64_t i_framerate_pos;
  41. uint64_t i_duration_pos;
  42. uint64_t i_filesize_pos;
  43. uint64_t i_bitrate_pos;
  44. uint8_t b_write_length;
  45. int64_t i_prev_dts;
  46. int64_t i_prev_cts;
  47. int64_t i_delay_time;
  48. int64_t i_init_delta;
  49. int i_delay_frames;
  50. double d_timebase;
  51. int b_vfr_input;
  52. int b_dts_compress;
  53. unsigned start;
  54. } flv_hnd_t;
  55. static int write_header( flv_buffer *c )
  56. {
  57. flv_put_tag( c, "FLV" ); // Signature
  58. flv_put_byte( c, 1 ); // Version
  59. flv_put_byte( c, 1 ); // Video Only
  60. flv_put_be32( c, 9 ); // DataOffset
  61. flv_put_be32( c, 0 ); // PreviousTagSize0
  62. return flv_flush_data( c );
  63. }
  64. static int open_file( char *psz_filename, hnd_t *p_handle, cli_output_opt_t *opt )
  65. {
  66. flv_hnd_t *p_flv = calloc( 1, sizeof(flv_hnd_t) );
  67. if( p_flv )
  68. {
  69. flv_buffer *c = flv_create_writer( psz_filename );
  70. if( c )
  71. {
  72. if( !write_header( c ) )
  73. {
  74. p_flv->c = c;
  75. p_flv->b_dts_compress = opt->use_dts_compress;
  76. *p_handle = p_flv;
  77. return 0;
  78. }
  79. fclose( c->fp );
  80. free( c->data );
  81. free( c );
  82. }
  83. free( p_flv );
  84. }
  85. *p_handle = NULL;
  86. return -1;
  87. }
  88. static int set_param( hnd_t handle, x264_param_t *p_param )
  89. {
  90. flv_hnd_t *p_flv = handle;
  91. flv_buffer *c = p_flv->c;
  92. flv_put_byte( c, FLV_TAG_TYPE_META ); // Tag Type "script data"
  93. int start = c->d_cur;
  94. flv_put_be24( c, 0 ); // data length
  95. flv_put_be24( c, 0 ); // timestamp
  96. flv_put_be32( c, 0 ); // reserved
  97. flv_put_byte( c, AMF_DATA_TYPE_STRING );
  98. flv_put_amf_string( c, "onMetaData" );
  99. flv_put_byte( c, AMF_DATA_TYPE_MIXEDARRAY );
  100. flv_put_be32( c, 7 );
  101. flv_put_amf_string( c, "width" );
  102. flv_put_amf_double( c, p_param->i_width );
  103. flv_put_amf_string( c, "height" );
  104. flv_put_amf_double( c, p_param->i_height );
  105. flv_put_amf_string( c, "framerate" );
  106. if( !p_param->b_vfr_input )
  107. flv_put_amf_double( c, (double)p_param->i_fps_num / p_param->i_fps_den );
  108. else
  109. {
  110. p_flv->i_framerate_pos = c->d_cur + c->d_total + 1;
  111. flv_put_amf_double( c, 0 ); // written at end of encoding
  112. }
  113. flv_put_amf_string( c, "videocodecid" );
  114. flv_put_amf_double( c, FLV_CODECID_H264 );
  115. flv_put_amf_string( c, "duration" );
  116. p_flv->i_duration_pos = c->d_cur + c->d_total + 1;
  117. flv_put_amf_double( c, 0 ); // written at end of encoding
  118. flv_put_amf_string( c, "filesize" );
  119. p_flv->i_filesize_pos = c->d_cur + c->d_total + 1;
  120. flv_put_amf_double( c, 0 ); // written at end of encoding
  121. flv_put_amf_string( c, "videodatarate" );
  122. p_flv->i_bitrate_pos = c->d_cur + c->d_total + 1;
  123. flv_put_amf_double( c, 0 ); // written at end of encoding
  124. flv_put_amf_string( c, "" );
  125. flv_put_byte( c, AMF_END_OF_OBJECT );
  126. unsigned length = c->d_cur - start;
  127. flv_rewrite_amf_be24( c, length - 10, start );
  128. flv_put_be32( c, length + 1 ); // tag length
  129. p_flv->i_fps_num = p_param->i_fps_num;
  130. p_flv->i_fps_den = p_param->i_fps_den;
  131. p_flv->d_timebase = (double)p_param->i_timebase_num / p_param->i_timebase_den;
  132. p_flv->b_vfr_input = p_param->b_vfr_input;
  133. p_flv->i_delay_frames = p_param->i_bframe ? (p_param->i_bframe_pyramid ? 2 : 1) : 0;
  134. return 0;
  135. }
  136. static int write_headers( hnd_t handle, x264_nal_t *p_nal )
  137. {
  138. flv_hnd_t *p_flv = handle;
  139. flv_buffer *c = p_flv->c;
  140. int sps_size = p_nal[0].i_payload;
  141. int pps_size = p_nal[1].i_payload;
  142. int sei_size = p_nal[2].i_payload;
  143. // SEI
  144. /* It is within the spec to write this as-is but for
  145. * mplayer/ffmpeg playback this is deferred until before the first frame */
  146. p_flv->sei = malloc( sei_size );
  147. if( !p_flv->sei )
  148. return -1;
  149. p_flv->sei_len = sei_size;
  150. memcpy( p_flv->sei, p_nal[2].p_payload, sei_size );
  151. // SPS
  152. uint8_t *sps = p_nal[0].p_payload + 4;
  153. flv_put_byte( c, FLV_TAG_TYPE_VIDEO );
  154. flv_put_be24( c, 0 ); // rewrite later
  155. flv_put_be24( c, 0 ); // timestamp
  156. flv_put_byte( c, 0 ); // timestamp extended
  157. flv_put_be24( c, 0 ); // StreamID - Always 0
  158. p_flv->start = c->d_cur; // needed for overwriting length
  159. flv_put_byte( c, FLV_FRAME_KEY | FLV_CODECID_H264 ); // FrameType and CodecID
  160. flv_put_byte( c, 0 ); // AVC sequence header
  161. flv_put_be24( c, 0 ); // composition time
  162. flv_put_byte( c, 1 ); // version
  163. flv_put_byte( c, sps[1] ); // profile
  164. flv_put_byte( c, sps[2] ); // profile
  165. flv_put_byte( c, sps[3] ); // level
  166. flv_put_byte( c, 0xff ); // 6 bits reserved (111111) + 2 bits nal size length - 1 (11)
  167. flv_put_byte( c, 0xe1 ); // 3 bits reserved (111) + 5 bits number of sps (00001)
  168. flv_put_be16( c, sps_size - 4 );
  169. flv_append_data( c, sps, sps_size - 4 );
  170. // PPS
  171. flv_put_byte( c, 1 ); // number of pps
  172. flv_put_be16( c, pps_size - 4 );
  173. flv_append_data( c, p_nal[1].p_payload + 4, pps_size - 4 );
  174. // rewrite data length info
  175. unsigned length = c->d_cur - p_flv->start;
  176. flv_rewrite_amf_be24( c, length, p_flv->start - 10 );
  177. flv_put_be32( c, length + 11 ); // Last tag size
  178. CHECK( flv_flush_data( c ) );
  179. return sei_size + sps_size + pps_size;
  180. }
  181. static int write_frame( hnd_t handle, uint8_t *p_nalu, int i_size, x264_picture_t *p_picture )
  182. {
  183. flv_hnd_t *p_flv = handle;
  184. flv_buffer *c = p_flv->c;
  185. #define convert_timebase_ms( timestamp, timebase ) (int64_t)((timestamp) * (timebase) * 1000 + 0.5)
  186. if( !p_flv->i_framenum )
  187. {
  188. p_flv->i_delay_time = p_picture->i_dts * -1;
  189. if( !p_flv->b_dts_compress && p_flv->i_delay_time )
  190. x264_cli_log( "flv", X264_LOG_INFO, "initial delay %"PRId64" ms\n",
  191. convert_timebase_ms( p_picture->i_pts + p_flv->i_delay_time, p_flv->d_timebase ) );
  192. }
  193. int64_t dts;
  194. int64_t cts;
  195. int64_t offset;
  196. if( p_flv->b_dts_compress )
  197. {
  198. if( p_flv->i_framenum == 1 )
  199. p_flv->i_init_delta = convert_timebase_ms( p_picture->i_dts + p_flv->i_delay_time, p_flv->d_timebase );
  200. dts = p_flv->i_framenum > p_flv->i_delay_frames
  201. ? convert_timebase_ms( p_picture->i_dts, p_flv->d_timebase )
  202. : p_flv->i_framenum * p_flv->i_init_delta / (p_flv->i_delay_frames + 1);
  203. cts = convert_timebase_ms( p_picture->i_pts, p_flv->d_timebase );
  204. }
  205. else
  206. {
  207. dts = convert_timebase_ms( p_picture->i_dts + p_flv->i_delay_time, p_flv->d_timebase );
  208. cts = convert_timebase_ms( p_picture->i_pts + p_flv->i_delay_time, p_flv->d_timebase );
  209. }
  210. offset = cts - dts;
  211. if( p_flv->i_framenum )
  212. {
  213. if( p_flv->i_prev_dts == dts )
  214. x264_cli_log( "flv", X264_LOG_WARNING, "duplicate DTS %"PRId64" generated by rounding\n"
  215. " decoding framerate cannot exceed 1000fps\n", dts );
  216. if( p_flv->i_prev_cts == cts )
  217. x264_cli_log( "flv", X264_LOG_WARNING, "duplicate CTS %"PRId64" generated by rounding\n"
  218. " composition framerate cannot exceed 1000fps\n", cts );
  219. }
  220. p_flv->i_prev_dts = dts;
  221. p_flv->i_prev_cts = cts;
  222. // A new frame - write packet header
  223. flv_put_byte( c, FLV_TAG_TYPE_VIDEO );
  224. flv_put_be24( c, 0 ); // calculated later
  225. flv_put_be24( c, dts );
  226. flv_put_byte( c, dts >> 24 );
  227. flv_put_be24( c, 0 );
  228. p_flv->start = c->d_cur;
  229. flv_put_byte( c, (p_picture->b_keyframe ? FLV_FRAME_KEY : FLV_FRAME_INTER) | FLV_CODECID_H264 );
  230. flv_put_byte( c, 1 ); // AVC NALU
  231. flv_put_be24( c, offset );
  232. if( p_flv->sei )
  233. {
  234. flv_append_data( c, p_flv->sei, p_flv->sei_len );
  235. free( p_flv->sei );
  236. p_flv->sei = NULL;
  237. }
  238. flv_append_data( c, p_nalu, i_size );
  239. unsigned length = c->d_cur - p_flv->start;
  240. flv_rewrite_amf_be24( c, length, p_flv->start - 10 );
  241. flv_put_be32( c, 11 + length ); // Last tag size
  242. CHECK( flv_flush_data( c ) );
  243. p_flv->i_framenum++;
  244. return i_size;
  245. }
  246. static int rewrite_amf_double( FILE *fp, uint64_t position, double value )
  247. {
  248. uint64_t x = endian_fix64( flv_dbl2int( value ) );
  249. return !fseek( fp, position, SEEK_SET ) && fwrite( &x, 8, 1, fp ) == 1 ? 0 : -1;
  250. }
  251. #undef CHECK
  252. #define CHECK(x)\
  253. do {\
  254. if( (x) < 0 )\
  255. goto error;\
  256. } while( 0 )
  257. static int close_file( hnd_t handle, int64_t largest_pts, int64_t second_largest_pts )
  258. {
  259. int ret = -1;
  260. flv_hnd_t *p_flv = handle;
  261. flv_buffer *c = p_flv->c;
  262. CHECK( flv_flush_data( c ) );
  263. double total_duration;
  264. /* duration algorithm fails with one frame */
  265. if( p_flv->i_framenum == 1 )
  266. total_duration = p_flv->i_fps_num ? (double)p_flv->i_fps_den / p_flv->i_fps_num : 0;
  267. else
  268. total_duration = (2 * largest_pts - second_largest_pts) * p_flv->d_timebase;
  269. if( x264_is_regular_file( c->fp ) && total_duration > 0 )
  270. {
  271. double framerate;
  272. uint64_t filesize = ftell( c->fp );
  273. if( p_flv->i_framerate_pos )
  274. {
  275. framerate = (double)p_flv->i_framenum / total_duration;
  276. CHECK( rewrite_amf_double( c->fp, p_flv->i_framerate_pos, framerate ) );
  277. }
  278. CHECK( rewrite_amf_double( c->fp, p_flv->i_duration_pos, total_duration ) );
  279. CHECK( rewrite_amf_double( c->fp, p_flv->i_filesize_pos, filesize ) );
  280. CHECK( rewrite_amf_double( c->fp, p_flv->i_bitrate_pos, filesize * 8 / ( total_duration * 1000 ) ) );
  281. }
  282. ret = 0;
  283. error:
  284. fclose( c->fp );
  285. free( c->data );
  286. free( c );
  287. free( p_flv );
  288. return ret;
  289. }
  290. const cli_output_t flv_output = { open_file, set_param, write_headers, write_frame, close_file };