<p dir="ltr">Thanks for the reply.</p>
<p dir="ltr">I whant to save the audio and video streams synchronized into a file avi.</p>
<div class="gmail_quote">Il 24/Mar/2015 21:12 "wm4" <<a href="mailto:nfxjfg@googlemail.com">nfxjfg@googlemail.com</a>> ha scritto:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Tue, 24 Mar 2015 17:31:16 +0100<br>
Alessio Volpe <<a href="mailto:alessio.volpe.av@gmail.com">alessio.volpe.av@gmail.com</a>> wrote:<br>
<br>
> Hi, this is my program:<br>
><br>
> -------------------------------------------------------------<br>
><br>
> #include <stdio.h><br>
> #include <stdlib.h><br>
> #include <libavcodec/avcodec.h><br>
> #include <libavformat/avformat.h><br>
> #include <libavformat/avio.h><br>
> #include <sys/time.h><br>
><br>
> time_t get_time()<br>
> {<br>
>   struct timeval tv;<br>
><br>
>   gettimeofday( &tv, NULL );<br>
><br>
>   return tv.tv_sec;<br>
> }<br>
><br>
> int main( int argc, char* argv[] )<br>
> {<br>
>   AVFormatContext *ifcx = NULL;<br>
>   AVInputFormat *ifmt;<br>
>   AVCodecContext *iccx_video, *iccx_audio;<br>
>   AVCodec *icodec;<br>
>   AVStream *ist_video, *ist_audio;<br>
>   int i_index_video, i_index_audio;<br>
>   time_t timenow, timestart;<br>
>   int got_key_frame = 0;<br>
><br>
>   AVFormatContext *ofcx;<br>
>   AVOutputFormat *ofmt;<br>
>   AVCodecContext *occx;<br>
>   AVCodec *ocodec;<br>
>   AVStream *ost_video, *ost_audio;<br>
>   int o_index_video, o_index_audio;<br>
><br>
>   AVPacket pkt;<br>
><br>
>   int ix, ix_video, ix_audio;<br>
><br>
>   const char *sFileInput;<br>
>   const char *sFileOutput;<br>
>   int bRunTime;<br>
><br>
>   //Indirizzo RTSP<br>
>   sFileInput = "rtsp://<a href="http://10.4.1.175/media/video1" target="_blank">10.4.1.175/media/video1</a>";<br>
><br>
>   //File di output<br>
>   sFileOutput = "camera.avi";<br>
><br>
>   //Tempo di run dell'acquisizione<br>
>   bRunTime = 15; //Registra 15 secondi<br>
><br>
>   // Initialize library<br>
>   av_log_set_level( AV_LOG_DEBUG );<br>
>   av_register_all();<br>
>   avcodec_register_all();<br>
>   avformat_network_init();<br>
><br>
>   //<br>
>   // Input<br>
>   //<br>
><br>
>   //open rtsp<br>
>   if ( avformat_open_input( &ifcx, sFileInput, NULL, NULL) != 0 ) {<br>
>     printf( "ERROR: Cannot open input file\n" );<br>
>     return EXIT_FAILURE;<br>
>   }<br>
><br>
>   if ( avformat_find_stream_info( ifcx, NULL ) < 0 ) {<br>
>     printf( "ERROR: Cannot find stream info\n" );<br>
>     avformat_close_input( &ifcx );<br>
>     return EXIT_FAILURE;<br>
>   }<br>
><br>
>   snprintf( ifcx->filename, sizeof( ifcx->filename ), "%s", sFileInput );<br>
><br>
>   //search video stream<br>
>   i_index_video = -1;<br>
>   for ( ix = 0; ix < ifcx->nb_streams; ix++ ) {<br>
>     iccx_video = ifcx->streams[ ix ]->codec;<br>
>     if ( iccx_video->codec_type == AVMEDIA_TYPE_VIDEO ) {<br>
>       ist_video = ifcx->streams[ ix ];<br>
>       i_index_video = ix;<br>
>       break;<br>
>     }<br>
>   }<br>
>   if ( i_index_video < 0 ) {<br>
>     printf( "ERROR: Cannot find input video stream\n" );<br>
>     avformat_close_input( &ifcx );<br>
>     return EXIT_FAILURE;<br>
>   }<br>
><br>
><br>
>   //search audio stream<br>
>   i_index_audio = -1;<br>
>   for ( ix = 0; ix < ifcx->nb_streams; ix++ ) {<br>
>     iccx_audio = ifcx->streams[ ix ]->codec;<br>
>     if ( iccx_audio->codec_type == AVMEDIA_TYPE_AUDIO ) {<br>
>       ist_audio = ifcx->streams[ ix ];<br>
>       i_index_audio = ix;<br>
>       break;<br>
>     }<br>
>   }<br>
>   if ( i_index_audio < 0 ) {<br>
>     printf( "ERROR: Cannot find input video stream\n" );<br>
>     avformat_close_input( &ifcx );<br>
>     return EXIT_FAILURE;<br>
>   }<br>
><br>
>   //<br>
>   // Output<br>
>   //<br>
><br>
>   //open output file<br>
>   ofmt = av_guess_format( NULL, sFileOutput, NULL ); //Return the output<br>
> format<br>
>   ofcx = avformat_alloc_context();<br>
>   ofcx->oformat = ofmt;<br>
>   avio_open2( &ofcx->pb, sFileOutput, AVIO_FLAG_WRITE, NULL, NULL );<br>
><br>
>   // Create Video output stream<br>
>   ost_video = avformat_new_stream( ofcx, NULL );<br>
>   ost_audio = avformat_new_stream( ofcx, NULL );<br>
><br>
>   avcodec_copy_context( ost_video->codec, iccx_video ); //Copia il codec<br>
> dello stream di input<br>
>   avcodec_copy_context( ost_audio->codec, iccx_audio );<br>
><br>
><br>
>   ost_video->sample_aspect_ratio.num = iccx_video->sample_aspect_ratio.num;<br>
>   ost_video->sample_aspect_ratio.den = iccx_video->sample_aspect_ratio.den;<br>
><br>
>   // Assume r_frame_rate is accurate<br>
>   ost_video->r_frame_rate = ist_video->r_frame_rate;<br>
>   ost_video->avg_frame_rate = ost_video->r_frame_rate;<br>
>   ost_video->time_base = (AVRational){ost_video->r_frame_rate.den,<br>
> ost_video->r_frame_rate.num}; //ost->time_base = av_inv_q(<br>
> ost->r_frame_rate ); //error<br>
>   ost_video->codec->time_base = ost_video->time_base;<br>
><br>
>   // Create Audio output stream<br>
>   ost_audio->sample_aspect_ratio.num = iccx_audio->sample_aspect_ratio.num;<br>
>   ost_audio->sample_aspect_ratio.den = iccx_audio->sample_aspect_ratio.den;<br>
><br>
><br>
>   ost_audio->r_frame_rate = ist_audio->r_frame_rate;<br>
>   ost_audio->avg_frame_rate = ost_audio->r_frame_rate;<br>
>   ost_audio->time_base = (AVRational){ost_audio->r_frame_rate.den,<br>
> ost_audio->r_frame_rate.num}; //ost->time_base = av_inv_q(<br>
> ost->r_frame_rate ); //error<br>
>   ost_audio->codec->time_base = ost_audio->time_base;<br>
><br>
>   avformat_write_header( ofcx, NULL );<br>
><br>
>   snprintf( ofcx->filename, sizeof( ofcx->filename ), "%s", sFileOutput );<br>
><br>
>   //start reading packets from stream and write them to file<br>
><br>
>   av_dump_format( ifcx, 0, ifcx->filename, 0 ); //INFO INPUT<br>
>   av_dump_format( ofcx, 0, ofcx->filename, 1 ); //INFO OUTPUT<br>
><br>
>   timestart = timenow = get_time();<br>
><br>
>   ix_video = 0;<br>
>   ix_audio = 0;<br>
><br>
>   double video_pts, audio_pts;<br>
><br>
>   av_init_packet( &pkt );<br>
><br>
>   double audio_time, video_time;<br>
><br>
>   while ( av_read_frame( ifcx, &pkt ) >= 0 && timenow - timestart <=<br>
> bRunTime ) { //&& (getchar() != 'q')){<br>
>     av_packet_rescale_ts(&pkt,<br>
> ofcx->streams[i_index_video]->codec->time_base,<br>
> ifcx->streams[i_index_video]->time_base);<br>
>       if ( pkt.stream_index == i_index_video ) { //packet is video<br>
>        //Make sure we start on a key frame - UN I-FRAME<br>
>       if ( timestart == timenow && ! ( pkt.flags & AV_PKT_FLAG_KEY ) ) {<br>
>         timestart = timenow = get_time();<br>
>         continue;<br>
>       }<br>
>       got_key_frame = 1;<br>
><br>
> //      video_pts = (double)ost_video->pts.val * ost_video->time_base.num /<br>
> ost_video->time_base.den;<br>
> //      audio_pts = (double)ost_audio->pts.val * ost_audio->time_base.num /<br>
> ost_audio->time_base.den;<br>
><br>
>       pkt.stream_index = ost_video->id;<br>
> //      /* prepare packet for muxing */<br>
> //     pkt.dts = av_rescale_q_rnd(pkt.dts,<br>
> ofcx->streams[i_index_video]->codec->time_base,<br>
> ofcx->streams[i_index_video]->time_base,<br>
> AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);<br>
> //     pkt.pts = av_rescale_q_rnd(pkt.pts,<br>
> ofcx->streams[i_index_video]->codec->time_base,<br>
> ofcx->streams[i_index_video]->time_base,<br>
> AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);<br>
> //     pkt.duration = av_rescale_q(pkt.duration,<br>
> ofcx->streams[i_index_video]->codec->time_base,<br>
> ofcx->streams[i_index_video]->time_base);<br>
><br>
><br>
>       pkt.pts = ix_video++;<br>
>       pkt.dts = pkt.pts;<br>
><br>
> //      /*Also, some streams have multiple ticks-per-frame, so if the video<br>
> runs at double speed you might need to this right below the above line:<br>
><br>
> //        pkt.pts *= ifcx->streams[0]->codec->ticks_per_frame;<br>
> //        pkt.dts *= ifcx->streams[0]->codec->ticks_per_frame;<br>
><br>
>       //av_write_frame( ofcx, &pkt );<br>
>       av_interleaved_write_frame( ofcx, &pkt );<br>
>     }<br>
>     else{ //packet is audio<br>
><br>
>         pkt.pts = ix_video++;<br>
>         pkt.dts = pkt.pts;<br>
><br>
>     //av_write_frame( ofcx, &pkt );<br>
>     av_interleaved_write_frame( ofcx, &pkt );<br>
><br>
>     }<br>
><br>
>     //CICLO PER SINCRONIZZARE E SCRIVERE SU DISCO<br>
><br>
> //    printf("vpcopy[%d].pts = %d", i, vpcopy[i].pts);<br>
> //    printf("\n");<br>
><br>
> //    if(i == 30) {<br>
> //        for(j=0; j<30-1; j++)<br>
> //        {<br>
> //            min = j;<br>
><br>
> //        for(k=j+1; k<30; k++)<br>
> //          if(vpcopy[j].pts < vpcopy[min].pts) //cambiare questa<br>
> condizione per invertire l'ordine<br>
> //            min = k;<br>
><br>
> //        temp=vpcopy[min];<br>
> //        vpcopy[min]=vpcopy[j];<br>
> //        vpcopy[j]=temp;<br>
><br>
> //        printf("vpcopy[%d].pts = %d", i, vpcopy[i].pts);<br>
> //        printf("\n");<br>
><br>
> //        av_interleaved_write_frame( ofcx, &vpcopy[j] );<br>
> //        }<br>
> //        i = 0;<br>
> //    }<br>
><br>
><br>
>     av_free_packet( &pkt );<br>
>     av_init_packet( &pkt );<br>
><br>
>     timenow = get_time();<br>
>   }<br>
>   av_read_pause( ifcx );<br>
>   av_write_trailer( ofcx );<br>
>   avio_close( ofcx->pb );<br>
>   avformat_free_context( ofcx );<br>
><br>
>   avformat_network_deinit();<br>
><br>
>   return EXIT_SUCCESS;<br>
> }<br>
><br>
> -------------------------------------------------------------<br>
><br>
> I would like to synchronize the video and audio.<br>
><br>
> How should I use the pts and dts?<br>
<br>
It looks like you just want to receive the data and display it. This<br>
should be helpful: <a href="http://dranger.com/ffmpeg/" target="_blank">http://dranger.com/ffmpeg/</a> (it starts with the<br>
basics, but also touches A/V sync).<br>
_______________________________________________<br>
Libav-user mailing list<br>
<a href="mailto:Libav-user@ffmpeg.org">Libav-user@ffmpeg.org</a><br>
<a href="http://ffmpeg.org/mailman/listinfo/libav-user" target="_blank">http://ffmpeg.org/mailman/listinfo/libav-user</a><br>
</blockquote></div>