[Libav-user] RTSP record (normally)

Евгений Гарифуллин grisme at yandex.ru
Tue Dec 31 16:55:51 CET 2013


Hi, all.

I am newbe in this mail-list. I want to record RTSP-stream into files 
via libavformat / libavcodec programmaticaly, without trans-coding.

Here is the code (how i trying to record stream, without error checking):

ff_FormatContext = avformat_alloc_context();
     ff_Dict = NULL;
     av_dict_set(&ff_Dict, "rtsp_transport", "tcp", 0);
     avformat_open_input(&ff_FormatContext, vs_stream_url_c, NULL, 
&ff_Dict);
     avformat_find_stream_info(ff_FormatContext, NULL);
     vs_index = -1;
     for (vs_iterator = 0; vs_iterator < ff_FormatContext->nb_streams; 
vs_iterator++)
     { if (ff_FormatContext->streams[vs_iterator]->codec->coder_type == 
AVMEDIA_TYPE_VIDEO)
       {
         vs_index = vs_iterator;
         break;
       }
     }
     if (vs_index == -1){
         printf("[ THREAD ] Error : Video streams not founded.\n");
         return -1;
     }
     ff_CodecContext = ff_FormatContext->streams[vs_index]->codec;
     ff_Codec = avcodec_find_decoder(ff_CodecContext->codec_id);

     avcodec_open2(ff_CodecContext, ff_Codec, NULL) < 0)

     ff_Frame = avcodec_alloc_frame();
     numBytes = avpicture_get_size(ff_CodecContext->pix_fmt, 
ff_CodecContext->width, ff_CodecContext->height);
     buffer = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
     avpicture_fill((AVPicture *)ff_Frame, buffer, 
ff_CodecContext->pix_fmt, ff_CodecContext->width, ff_CodecContext->height);
     av_init_packet(&ff_Packet);
     av_read_play(ff_FormatContext);

  secondmeter1 = time(0);

     /* Creating output format */
     ff_OutputFormat = av_guess_format("mp4", NULL, NULL);
     ff_OutputFormatContext = avformat_alloc_context();
     ff_OutputFormatContext->oformat = ff_OutputFormat;
     ff_OutputStream = avformat_new_stream(ff_OutputFormatContext, NULL);
     avcodec_copy_context(ff_OutputStream->codec, ff_CodecContext);
     ff_OutputStream->codec->flags = CODEC_FLAG_GLOBAL_HEADER;
     ff_OutputStream->codec->time_base.den = ff_CodecContext->time_base.den;
     ff_OutputStream->codec->time_base.num = ff_CodecContext->time_base.num;
     outputFileName = new char[0];
     sprintf(outputFileName, "%svideo_%015d.mp4", vs_stream_savepath_c, 
(int)secondmeter1);
     frameCounter = 0;
     avio_open2(&ff_OutputFormatContext->pb, (const 
char*)outputFileName, AVIO_FLAG_WRITE,NULL,NULL);
     int ix = 0;
     while (1 == 1)
     {
         av_read_frame(ff_FormatContext, &ff_Packet);
         if(ff_Packet.stream_index == vs_index){
             printf(" DATA : PTS = %d DTS = %d DURATION = %d\n", 
ff_Packet.pts, ff_Packet.dts, ff_Packet.duration);
             // I CAN NOT UNDERSTAND, HOW I'D FILL THIS STRUCTS BEFORE 
FRAME WRITING
             ff_Packet.stream_index = ff_OutputStream->id;
             ff_OutputStream->pts.val   = ff_Packet.pts;
             ff_OutputStream->duration  = ff_Packet.duration;
             ff_OutputStream->r_frame_rate = 
ff_FormatContext->streams[vs_index]->r_frame_rate;

             if (frameCounter == 0) 
avformat_write_header(ff_OutputFormatContext, NULL);
             av_write_frame(ff_OutputFormatContext, &ff_Packet);
             frameCounter++;
             if (frameCounter == 512)
             {
                 frameCounter = 0;
                 av_write_trailer(ff_OutputFormatContext);
                 avio_close(ff_OutputFormatContext->pb);
                 secondmeter1 = time(0);

                 sprintf(outputFileName, "%svideo_%015d.mp4", 
vs_stream_savepath_c, (int)secondmeter1);
avio_open2(&ff_OutputFormatContext->pb, (const char*)outputFileName, 
AVIO_FLAG_WRITE,NULL,NULL);
             }
         }
         av_free_packet(&ff_Packet);
         av_init_packet(&ff_Packet);
         #ifdef __MINGW32__
             Sleep(50);
         #endif // _WIN32
     }

Code writes video by segments (every 512 frame - new segment with 
timestamp in filename)
Into output file i see wrong duration / FPS information. Video playing 
so fast.
Please help. :(


More information about the Libav-user mailing list