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