[FFmpeg-devel] [PATCH] SDP muxer

Stefano Sabatini stefano.sabatini-lala
Thu Nov 20 00:23:08 CET 2008

On date Monday 2008-11-17 10:00:49 +0100, Luca Abeni encoded:
> Hi,
> Stefano Sabatini wrote:
> [...]
> >> Anyway, whatever solution is chosen the important thing is not to break
> >> the current libavformat API (avf_sdp_create(), and the way rtp:// URLs
> >> are specified).
> > 
> > Yes, this solution won't break neither URLs syntax neither old API
> > interface, while on the other hand I'm extending the interface, in
> > order to create a representation of an SDP from a list of RTP files.
> Ok, good. Note that avf_sdp_create() should already be able to do what
> you need (you just need to prepare a proper "AVFormatContext *ac[]"
> before calling it). So, I guess everything you need is a new muxer which
> sets up the "ac" array and calls avf_sdp_create().

The problem with avf_sdp_create() is that it takes AVOutputFormat,
while I think the expected behaviour for the muxer would be to take a
list of *AVStreams* and create from these the header.

So I write a write_header() function which is very similar to
avf_sdp_create(), but which reads from streams rather than from a list
of files.

I'm attaching my implementation, but I'm somehow not satisfied with it).

Patch consists of the part (I'll split it when we'll agree on some
solution for the problem I'm going to discuss):

* cosmetics to sdp.c: struct sdp_session_level -> SDPContext and other
renames in order to make them more meaningful and consistent (e.g.:
sdp_write_media -> write_sdp_media
sdp_media_attributes -> write_sdp_media_attributes
sdp_write_header -> write_sdp_header)

* implement SDP muxer write_header() function and structure

* implement av_dup_stream() in lavf

* implement ffmpeg.c support to SDP mapping

Usage example:
stefano at geppetto ~/s/ffmpeg> ffmpeg -t 0 -i test.flv -acodec libmp3lame -f rtp rtp://localhost:5004 -acodec pcm_mulaw -ar 8000 -f rtp rtp://localhost:5008 -title "test SDP" -f sdp - -map_sdp 0:2 -map_sdp 1:2
FFmpeg version SVN-r15884, Copyright (c) 2000-2008 Fabrice Bellard, et al.

Seems stream 0 codec frame rate differs from container frame rate: 1000.00 (1000/1) -> 25.00 (25/1)
Input #0, flv, from 'test.flv':
  Duration: 00:00:30.03, start: 0.000000, bitrate: 64 kb/s
    Stream #0.0: Video: flv, yuv420p, 320x240, 25.00 tb(r)
    Stream #0.1: Audio: mp3, 44100 Hz, mono, s16, 64 kb/s
Output #0, rtp, to 'rtp://localhost:5004':
    Stream #0.0: Audio: libmp3lame, 44100 Hz, mono, s16, 64 kb/s
Output #1, rtp, to 'rtp://localhost:5008':
    Stream #1.0: Audio: pcm_mulaw, 8000 Hz, mono, s16, 64 kb/s
Output #2, sdp, to 'pipe:':
    Stream #2.0: Audio: libmp3lame, 44100 Hz, mono, s16, 64 kb/s
    Stream #2.1: Audio: pcm_mulaw, 8000 Hz, mono, s16, 64 kb/s
Stream mapping:
  Stream #0.1 -> #0.0
  Stream #0.1 -> #1.0
SDP file mapping
  Output file #0 -> #2
  Output file #1 -> #2
o=- 0 0 IN IP4
t=0 0
s=test SDP
a=tool:libavformat 52.23.1
m=audio 5004 RTP/AVP 14
c=IN IP4 localhost
m=audio 5008 RTP/AVP 0
c=IN IP4 localhost
Press [q] to stop encoding
size=       0kB time=0.05 bitrate=   4.3kbits/s    
video:0kB audio:0kB global headers:0kB muxing overhead -93.285372%

The use of av_dup_stream() is necessary for the "special" status of
the SDP muxer, which takes streams which have been already defined.

For this reason I'm duplicating the output stream which is mapped to
the SDP, alternative solution, consisting into simply copy the already
defined stream in the SDP muxer simply isn't valid (crashes or double
free problems):

        if ((st = rtp_ctx->streams[0])) {
            // duplicate st and put the duplicated stream in sdp_ctx
            if (!(st2 = av_dup_stream(sdp_ctx, sdp_ctx->nb_streams, st))) {
                fprintf(stderr, "Could not alloc stream\n");
            // copy file filename in the stream, used to extract later
            // the output port
            st2->filename = strdup(rtp_ctx->filename);

also since the destination port for the RTP stream/SDP description is
extracted from the filename, I'm copying in the stream the filename of
the corresponding file so that I can access it later when calling
write_header() in the SDP muxer.

av_dup_stream() is also very similar to av_new_stream(), so I'm aware
they could be factorized, I didn't do it because I don't like so much
this solution, and I hope that someone has some better idea.

FFmpeg = Fantastic and Forgiving Merciful Patchable Epic Gospel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: implement-sdp-muxer-00.patch
Type: text/x-diff
Size: 14048 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20081120/66dbd824/attachment.patch>

More information about the ffmpeg-devel mailing list