[Libav-user] Recording an RTSP stream

Roman Fietze roman.fietze at telemotive.de
Wed Apr 2 13:05:25 CEST 2014


Hallo Mert,

Sorry for the delay.

On Thu, 27.03.2014 13:23:23 Mert Gedik wrote:

> I am appreciated If you share an example of how to do that you
> mentioned

Here the hopefully correct code snippets to be able to do that (our
source code is in C++, so I hope my "conversion" is correct):

First open your input streams using e.g. avformat_open_input.

Find your stream info using avformat_find_stream_info.

Now open your output stream, etc. and copy over the data from the
input in case you want a stream copy. A good template is e.g. the code
in ffmpeg.c and ffmpeg_opts.c. Look for "if (ost->stream_copy)" and
check what the do. The relevant parts are the time_base setups. Those
define the PTS/DTS calculations. I do it similiar to ffmpeg, because I
am cutting the video in pieces and need a common time base. It could
be you can skip this step and do not modify DTS/PTS/duration at all,
but then you have to take care of the correct setup of the time bases
in your output streams. Be warned, that writing the output header can
modify thos values when calling avformat_write_header.

Read a packet using av_read_frame.

All incoming PTS/DTS and duration values of every packet are converted
to e.g. microseconds using

  av_rescale_q(packet.dts, instream->time_base, AV_TIME_BASE_Q);

When writing a packet all timestamps are scaled to the output stream's
time base using the opposite calculation:

  av_rescale_q_rnd(ts,
		AV_TIME_BASE_Q,
		outstream->time_base,
		AVRounding(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX))

for DTS/PTS and w/o _rnd for the duration.

Now you should use av_interleaved_write_frame instead of just
av_write_frame in case you have video and audio, just in case there
are minor "glitches" in your sequence of packets, DTS or PTS.

>From time to time I do this one, to reduce the size of the index when
streaming for a long time:

    AVStream *ps = ...
    unsigned int nmax = pformatctx->max_index_size / sizeof(AVIndexEntry);

    if ((unsigned)ps->nb_index_entries >= nmax)
    {
        int i;
        for (i = 0; 2 * i < ps->nb_index_entries; i++)
            ps->index_entries[i] = ps->index_entries[2*i];
        ps->nb_index_entries = i;
    }

I did try to write down the IMHO most important parts. If you need
more details about one or the otrher step I can provide you more
detailed info or code.


Roman

-- 
Roman Fietze              Telemotive AG Buero Muehlhausen
Breitwiesen                             73347 Muehlhausen
Tel.: +49(0)7335/18493-45        http://www.telemotive.de



More information about the Libav-user mailing list