1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2009-2014 x264 project
6 * Authors: Kieran Kunhya <kieran@kunhya.com>
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.
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.
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.
22 * This program is also available under a commercial proprietary license.
23 * For more information, contact us at licensing@x264.com.
24 *****************************************************************************/
27 #include "flv_bytestream.h"
46 uint64_t i_framerate_pos;
47 uint64_t i_duration_pos;
48 uint64_t i_filesize_pos;
49 uint64_t i_bitrate_pos;
51 uint8_t b_write_length;
65 static int write_header( flv_buffer *c )
67 flv_put_tag( c, "FLV" ); // Signature
68 flv_put_byte( c, 1 ); // Version
69 flv_put_byte( c, 1 ); // Video Only
70 flv_put_be32( c, 9 ); // DataOffset
71 flv_put_be32( c, 0 ); // PreviousTagSize0
73 return flv_flush_data( c );
76 static int open_file( char *psz_filename, hnd_t *p_handle, cli_output_opt_t *opt )
79 flv_hnd_t *p_flv = calloc( 1, sizeof(flv_hnd_t) );
83 p_flv->b_dts_compress = opt->use_dts_compress;
85 p_flv->c = flv_create_writer( psz_filename );
89 CHECK( write_header( p_flv->c ) );
95 static int set_param( hnd_t handle, x264_param_t *p_param )
97 flv_hnd_t *p_flv = handle;
98 flv_buffer *c = p_flv->c;
100 flv_put_byte( c, FLV_TAG_TYPE_META ); // Tag Type "script data"
102 int start = c->d_cur;
103 flv_put_be24( c, 0 ); // data length
104 flv_put_be24( c, 0 ); // timestamp
105 flv_put_be32( c, 0 ); // reserved
107 flv_put_byte( c, AMF_DATA_TYPE_STRING );
108 flv_put_amf_string( c, "onMetaData" );
110 flv_put_byte( c, AMF_DATA_TYPE_MIXEDARRAY );
111 flv_put_be32( c, 7 );
113 flv_put_amf_string( c, "width" );
114 flv_put_amf_double( c, p_param->i_width );
116 flv_put_amf_string( c, "height" );
117 flv_put_amf_double( c, p_param->i_height );
119 flv_put_amf_string( c, "framerate" );
121 if( !p_param->b_vfr_input )
122 flv_put_amf_double( c, (double)p_param->i_fps_num / p_param->i_fps_den );
125 p_flv->i_framerate_pos = c->d_cur + c->d_total + 1;
126 flv_put_amf_double( c, 0 ); // written at end of encoding
129 flv_put_amf_string( c, "videocodecid" );
130 flv_put_amf_double( c, FLV_CODECID_H264 );
132 flv_put_amf_string( c, "duration" );
133 p_flv->i_duration_pos = c->d_cur + c->d_total + 1;
134 flv_put_amf_double( c, 0 ); // written at end of encoding
136 flv_put_amf_string( c, "filesize" );
137 p_flv->i_filesize_pos = c->d_cur + c->d_total + 1;
138 flv_put_amf_double( c, 0 ); // written at end of encoding
140 flv_put_amf_string( c, "videodatarate" );
141 p_flv->i_bitrate_pos = c->d_cur + c->d_total + 1;
142 flv_put_amf_double( c, 0 ); // written at end of encoding
144 flv_put_amf_string( c, "" );
145 flv_put_byte( c, AMF_END_OF_OBJECT );
147 unsigned length = c->d_cur - start;
148 flv_rewrite_amf_be24( c, length - 10, start );
150 flv_put_be32( c, length + 1 ); // tag length
152 p_flv->i_fps_num = p_param->i_fps_num;
153 p_flv->i_fps_den = p_param->i_fps_den;
154 p_flv->d_timebase = (double)p_param->i_timebase_num / p_param->i_timebase_den;
155 p_flv->b_vfr_input = p_param->b_vfr_input;
156 p_flv->i_delay_frames = p_param->i_bframe ? (p_param->i_bframe_pyramid ? 2 : 1) : 0;
161 static int write_headers( hnd_t handle, x264_nal_t *p_nal )
163 flv_hnd_t *p_flv = handle;
164 flv_buffer *c = p_flv->c;
166 int sps_size = p_nal[0].i_payload;
167 int pps_size = p_nal[1].i_payload;
168 int sei_size = p_nal[2].i_payload;
171 /* It is within the spec to write this as-is but for
172 * mplayer/ffmpeg playback this is deferred until before the first frame */
174 p_flv->sei = malloc( sei_size );
177 p_flv->sei_len = sei_size;
179 memcpy( p_flv->sei, p_nal[2].p_payload, sei_size );
182 uint8_t *sps = p_nal[0].p_payload + 4;
184 flv_put_byte( c, FLV_TAG_TYPE_VIDEO );
185 flv_put_be24( c, 0 ); // rewrite later
186 flv_put_be24( c, 0 ); // timestamp
187 flv_put_byte( c, 0 ); // timestamp extended
188 flv_put_be24( c, 0 ); // StreamID - Always 0
189 p_flv->start = c->d_cur; // needed for overwriting length
191 flv_put_byte( c, 7 | FLV_FRAME_KEY ); // Frametype and CodecID
192 flv_put_byte( c, 0 ); // AVC sequence header
193 flv_put_be24( c, 0 ); // composition time
195 flv_put_byte( c, 1 ); // version
196 flv_put_byte( c, sps[1] ); // profile
197 flv_put_byte( c, sps[2] ); // profile
198 flv_put_byte( c, sps[3] ); // level
199 flv_put_byte( c, 0xff ); // 6 bits reserved (111111) + 2 bits nal size length - 1 (11)
200 flv_put_byte( c, 0xe1 ); // 3 bits reserved (111) + 5 bits number of sps (00001)
202 flv_put_be16( c, sps_size - 4 );
203 flv_append_data( c, sps, sps_size - 4 );
206 flv_put_byte( c, 1 ); // number of pps
207 flv_put_be16( c, pps_size - 4 );
208 flv_append_data( c, p_nal[1].p_payload + 4, pps_size - 4 );
210 // rewrite data length info
211 unsigned length = c->d_cur - p_flv->start;
212 flv_rewrite_amf_be24( c, length, p_flv->start - 10 );
213 flv_put_be32( c, length + 11 ); // Last tag size
214 CHECK( flv_flush_data( c ) );
216 return sei_size + sps_size + pps_size;
219 static int write_frame( hnd_t handle, uint8_t *p_nalu, int i_size, x264_picture_t *p_picture )
221 flv_hnd_t *p_flv = handle;
222 flv_buffer *c = p_flv->c;
224 #define convert_timebase_ms( timestamp, timebase ) (int64_t)((timestamp) * (timebase) * 1000 + 0.5)
226 if( !p_flv->i_framenum )
228 p_flv->i_delay_time = p_picture->i_dts * -1;
229 if( !p_flv->b_dts_compress && p_flv->i_delay_time )
230 x264_cli_log( "flv", X264_LOG_INFO, "initial delay %"PRId64" ms\n",
231 convert_timebase_ms( p_picture->i_pts + p_flv->i_delay_time, p_flv->d_timebase ) );
238 if( p_flv->b_dts_compress )
240 if( p_flv->i_framenum == 1 )
241 p_flv->i_init_delta = convert_timebase_ms( p_picture->i_dts + p_flv->i_delay_time, p_flv->d_timebase );
242 dts = p_flv->i_framenum > p_flv->i_delay_frames
243 ? convert_timebase_ms( p_picture->i_dts, p_flv->d_timebase )
244 : p_flv->i_framenum * p_flv->i_init_delta / (p_flv->i_delay_frames + 1);
245 cts = convert_timebase_ms( p_picture->i_pts, p_flv->d_timebase );
249 dts = convert_timebase_ms( p_picture->i_dts + p_flv->i_delay_time, p_flv->d_timebase );
250 cts = convert_timebase_ms( p_picture->i_pts + p_flv->i_delay_time, p_flv->d_timebase );
254 if( p_flv->i_framenum )
256 if( p_flv->i_prev_dts == dts )
257 x264_cli_log( "flv", X264_LOG_WARNING, "duplicate DTS %"PRId64" generated by rounding\n"
258 " decoding framerate cannot exceed 1000fps\n", dts );
259 if( p_flv->i_prev_cts == cts )
260 x264_cli_log( "flv", X264_LOG_WARNING, "duplicate CTS %"PRId64" generated by rounding\n"
261 " composition framerate cannot exceed 1000fps\n", cts );
263 p_flv->i_prev_dts = dts;
264 p_flv->i_prev_cts = cts;
266 // A new frame - write packet header
267 flv_put_byte( c, FLV_TAG_TYPE_VIDEO );
268 flv_put_be24( c, 0 ); // calculated later
269 flv_put_be24( c, dts );
270 flv_put_byte( c, dts >> 24 );
271 flv_put_be24( c, 0 );
273 p_flv->start = c->d_cur;
274 flv_put_byte( c, p_picture->b_keyframe ? FLV_FRAME_KEY : FLV_FRAME_INTER );
275 flv_put_byte( c, 1 ); // AVC NALU
276 flv_put_be24( c, offset );
280 flv_append_data( c, p_flv->sei, p_flv->sei_len );
284 flv_append_data( c, p_nalu, i_size );
286 unsigned length = c->d_cur - p_flv->start;
287 flv_rewrite_amf_be24( c, length, p_flv->start - 10 );
288 flv_put_be32( c, 11 + length ); // Last tag size
289 CHECK( flv_flush_data( c ) );
296 static void rewrite_amf_double( FILE *fp, uint64_t position, double value )
298 uint64_t x = endian_fix64( flv_dbl2int( value ) );
299 fseek( fp, position, SEEK_SET );
300 fwrite( &x, 8, 1, fp );
303 static int close_file( hnd_t handle, int64_t largest_pts, int64_t second_largest_pts )
305 flv_hnd_t *p_flv = handle;
306 flv_buffer *c = p_flv->c;
308 CHECK( flv_flush_data( c ) );
310 double total_duration = (2 * largest_pts - second_largest_pts) * p_flv->d_timebase;
312 if( x264_is_regular_file( c->fp ) && total_duration > 0 )
315 uint64_t filesize = ftell( c->fp );
317 if( p_flv->i_framerate_pos )
319 framerate = (double)p_flv->i_framenum / total_duration;
320 rewrite_amf_double( c->fp, p_flv->i_framerate_pos, framerate );
323 rewrite_amf_double( c->fp, p_flv->i_duration_pos, total_duration );
324 rewrite_amf_double( c->fp, p_flv->i_filesize_pos, filesize );
325 rewrite_amf_double( c->fp, p_flv->i_bitrate_pos, filesize * 8 / ( total_duration * 1000 ) );
335 const cli_output_t flv_output = { open_file, set_param, write_headers, write_frame, close_file };