[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