Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here's how I do it. What I found was when receiving H264 the framerate in the stream is not correct. It sends 1/90000 Timebase. I skip initializing the new stream from the incoming stream and just copy certain parameters. The incoming r_frame_rate should be accurate if max_analyze_frames works correctly.</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;libavcodec/avcodec.h&gt; #include &lt;libavformat/avformat.h&gt; #include &lt;libavformat/avio.h&gt; #include &lt;sys/time.h&gt; time_t get_time() { struct timeval tv; gettimeofday( &amp;tv, NULL ); return tv.tv_sec; } int main( int argc, char* argv[] ) { AVFormatContext *ifcx = NULL; AVInputFormat *ifmt; AVCodecContext *iccx; AVCodec *icodec; AVStream *ist; int i_index; time_t timenow, timestart; int got_key_frame = 0; AVFormatContext *ofcx; AVOutputFormat *ofmt; AVCodecContext *occx; AVCodec *ocodec; AVStream *ost; int o_index; AVPacket pkt; int ix; const char *sProg = argv[ 0 ]; const char *sFileInput; const char *sFileOutput; int bRunTime; if ( argc != 4 ) { printf( "Usage: %s url outfile runtime\n", sProg ); return EXIT_FAILURE; } sFileInput = argv[ 1 ]; sFileOutput = argv[ 2 ]; bRunTime = atoi( argv[ 3 ] ); // Initialize library av_log_set_level( AV_LOG_DEBUG ); av_register_all(); avcodec_register_all(); avformat_network_init(); // // Input // //open rtsp if ( avformat_open_input( &amp;ifcx, sFileInput, NULL, NULL) != 0 ) { printf( "ERROR: Cannot open input file\n" ); return EXIT_FAILURE; } if ( avformat_find_stream_info( ifcx, NULL ) &lt; 0 ) { printf( "ERROR: Cannot find stream info\n" ); avformat_close_input( &amp;ifcx ); return EXIT_FAILURE; } snprintf( ifcx-&gt;filename, sizeof( ifcx-&gt;filename ), "%s", sFileInput ); //search video stream i_index = -1; for ( ix = 0; ix &lt; ifcx-&gt;nb_streams; ix++ ) { iccx = ifcx-&gt;streams[ ix ]-&gt;codec; if ( iccx-&gt;codec_type == AVMEDIA_TYPE_VIDEO ) { ist = ifcx-&gt;streams[ ix ]; i_index = ix; break; } } if ( i_index &lt; 0 ) { printf( "ERROR: Cannot find input video stream\n" ); avformat_close_input( &amp;ifcx ); return EXIT_FAILURE; } // // Output // //open output file ofmt = av_guess_format( NULL, sFileOutput, NULL ); ofcx = avformat_alloc_context(); ofcx-&gt;oformat = ofmt; avio_open2( &amp;ofcx-&gt;pb, sFileOutput, AVIO_FLAG_WRITE, NULL, NULL ); // Create output stream //ost = avformat_new_stream( ofcx, (AVCodec *) iccx-&gt;codec ); ost = avformat_new_stream( ofcx, NULL ); avcodec_copy_context( ost-&gt;codec, iccx ); ost-&gt;sample_aspect_ratio.num = iccx-&gt;sample_aspect_ratio.num; ost-&gt;sample_aspect_ratio.den = iccx-&gt;sample_aspect_ratio.den; // Assume r_frame_rate is accurate ost-&gt;r_frame_rate = ist-&gt;r_frame_rate; ost-&gt;avg_frame_rate = ost-&gt;r_frame_rate; ost-&gt;time_base = av_inv_q( ost-&gt;r_frame_rate ); ost-&gt;codec-&gt;time_base = ost-&gt;time_base; avformat_write_header( ofcx, NULL ); snprintf( ofcx-&gt;filename, sizeof( ofcx-&gt;filename ), "%s", sFileOutput ); //start reading packets from stream and write them to file av_dump_format( ifcx, 0, ifcx-&gt;filename, 0 ); av_dump_format( ofcx, 0, ofcx-&gt;filename, 1 ); timestart = timenow = get_time(); ix = 0; //av_read_play(context);//play RTSP (Shouldn't need this since it defaults to playing on connect) av_init_packet( &amp;pkt ); while ( av_read_frame( ifcx, &amp;pkt ) &gt;= 0 &amp;&amp; timenow - timestart &lt;= bRunTime ) { if ( pkt.stream_index == i_index ) { //packet is video // Make sure we start on a key frame if ( timestart == timenow &amp;&amp; ! ( pkt.flags &amp; AV_PKT_FLAG_KEY ) ) { timestart = timenow = get_time(); continue; } got_key_frame = 1; pkt.stream_index = ost-&gt;id; pkt.pts = ix++; pkt.dts = pkt.pts; av_interleaved_write_frame( ofcx, &amp;pkt ); } av_free_packet( &amp;pkt ); av_init_packet( &amp;pkt ); timenow = get_time(); } av_read_pause( ifcx ); av_write_trailer( ofcx ); avio_close( ofcx-&gt;pb ); avformat_free_context( ofcx ); avformat_network_deinit(); return EXIT_SUCCESS; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload