4

I'm trying to stream from an Axis ip camera which uses RTSP over HTTP. I can get the normal RTSP stream to work, but I can't find any information or documentation on how to actually set the tunneling mode for the stream. It is supported in the source code by setting the control_transport to RTSP_MODE_TUNNEL . My question is simple how do I do this with the following code?

 int ret = avformat_open_input(&pFormatCtx, [@"rtsp://ip/axis-media/media.amp" UTF8String], NULL, NULL);

I tried the following:

pFormatCtx = avformat_alloc_context();
pFormatCtx->priv_data = malloc(sizeof(RTSPState));
RTSPState *rt = pFormatCtx->priv_data;
rt->control_transport = RTSP_MODE_TUNNEL;
int ret = avformat_open_input(&pFormatCtx, [@"rtsp://ip/axis-media/media.amp" UTF8String], NULL, NULL);

But it simply ignores it for me (It still keeps using RTP). I tried this aswell

 int ret = avformat_open_input(&pFormatCtx, [@"rtsp://ip/axis-media/media.amp" UTF8String], NULL, NULL);
RTSPState *rt = pFormatCtx->priv_data;
rt->control_transport = RTSP_MODE_TUNNEL;

How would I solve this? I'm thinking it's something really simple since the ENUM is there.

Working solution is

AVDictionary *opts = 0;
int ret = av_dict_set(&opts, "rtsp_transport", "http", 0);


ret = avformat_open_input(&pFormatCtx, [@"rtsp://ip:80/axis-media/media.amp" UTF8String], NULL, &opts);

av_dict_free(&opts);
paty.r15
  • 361
  • 4
  • 16
Jon Andersen
  • 496
  • 6
  • 20

1 Answers1

10

did you try this

AVDictionary *opts = 0;
    if (usesTcp) {
        int ret = av_dict_set(&opts, "rtsp_transport", "tcp", 0);
    }


    err = avformat_open_input(&avfContext, filename, NULL, &opts);
    av_dict_free(&opts);
Michelle Cannon
  • 1,341
  • 8
  • 8
  • Thanks! Works like a charm. Your stackoverflow and company blog provided a lot of useful information when looking into this problem. – Jon Andersen Jan 22 '13 at 21:01
  • @Michelle Cannon : how are you setting the usesTcp flag? Is there anyway to find out if the RTSP stream is over tcp, http or udp? – Tushar Koul Nov 07 '13 at 05:19
  • we manually set it, because we usually know what we want. the main issue is that after you open the input stream its entirely in the hands of ffmpeg,. So you have some choices but they are very few. (1) create a custom IO handler for ffmpeg . (2) modify ffmpeg with a hook after it tries to connect. or something we've been having good success with, use a "tunnel" to get the stream before you pass it to the player. We've been using a local live 555 proxy implementation for that. So we can do whatever we want before we hand it over to streamMorePlay our player. – Michelle Cannon Nov 07 '13 at 05:33
  • we always love to help developers, so feel free to contract us. – Michelle Cannon Nov 07 '13 at 05:38
  • Btw, it seems a bunch of the avformat_open_input options are documented at https://www.ffmpeg.org/ffmpeg-protocols.html#rtsp. For rtsp_transport looks like it accepts "udp", "tcp", "http", and "udp_multicast". There's also the "prefer_tcp" option for "rtsp_flags" which tries TCP first then UDP if it can't connect, I think. I've confirmed that "rtsp_transport" values work at least in libav 11.7 (also testing with an Axis camera, incidentally). – Jason C Oct 09 '16 at 03:14