13

I'm trying to read the video frames from the RTSP stream that I get from YouTube. Here is the link for my test video:

rtsp://v8.cache5.c.youtube.com/CiILENy73wIaGQkJlrXMiAG8BxMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp

If I'm reading frames from the local file - everything is fine, but when read them from a stream I get nothing but lots of artifacts. I've googled around and found out that there might be a problem with UDP packets and switching to TCP may help but I really can't find where it is possible to change this.

Here is the function for reading a frame:

bool nextFrame(AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx, int videoStream, AVFrame *pFrame) {  AVPacket packet;
    int frameFinished = 0;

    while( !frameFinished && av_read_frame(pFormatCtx, &packet) >= 0 ) {
        // Is this a packet from the video stream?
        if( packet.stream_index == videoStream ) {
            // Decode video frame
            avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
        }

        // Free the packet that was allocated by av_read_frame
        av_free_packet(&packet);    
       }    
       return frameFinished!=0;  
}

I'm also getting lots of error messages in my log:

[h263 @ 0x7804c00] warning: first frame is no keyframe
[h263 @ 0x7804c00] illegal ac vlc code at 6x1
[h263 @ 0x7804c00] Error at MB: 18
[h263 @ 0x7804c00] concealing 99 DC, 99 AC, 99 MV errors
[h263 @ 0x7804c00] I cbpy damaged at 10 4
[h263 @ 0x7804c00] Error at MB: 58
[h263 @ 0x7804c00] concealing 99 DC, 99 AC, 99 MV errors
[h263 @ 0x7804c00] I cbpy damaged at 6 6
[h263 @ 0x7804c00] Error at MB: 78
[h263 @ 0x7804c00] concealing 76 DC, 76 AC, 76 MV errors
[h263 @ 0x7804c00] I cbpy damaged at 5 5
[h263 @ 0x7804c00] Error at MB: 65
[h263 @ 0x7804c00] concealing 88 DC, 88 AC, 88 MV errors
[h263 @ 0x7804c00] illegal ac vlc code at 7x5
[h263 @ 0x7804c00] Error at MB: 67
[h263 @ 0x7804c00] concealing 86 DC, 86 AC, 86 MV errors

...and so on

edit: this is 99.9% a UDP-TCP problem. I've found this link:

rtsp://195.200.199.8/mpeg4/media.amp

This is some test camera available online. It streams with artifacts. However if it has get parameter 'tcp' and if I use this

rtsp://195.200.199.8/mpeg4/media.amp?tcp

everything works without artifacts.

So to correct my question: is there any way to force YouTube or ffmpeg to use TCP ?

givi
  • 1,883
  • 4
  • 22
  • 32

3 Answers3

3

the transport protocol is a property of the IP socket you request. as such, you can have the same url (and ip:port) on both TCP and UDP transports. This means that its up to the client to open a TCP port rather than a UDP port.

This it is selected when you create your socket.

sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)

or

sock = socket(PF_INET, SOCK_STREAM, IPPROTO_UDP)

Now, I have no clue where ffmpeg does this, but surely the above can give you a clue on how to find out.

moliad
  • 1,503
  • 8
  • 13
  • Nope this is not up to client. If the server does not send data over tcp, what client will do? If youtube sends data only over udp for rtsp stream, there is no way from client to receive data from tcp port; there will be nothing on that tcp port. So only if the server sends data over tcp then client will be able to receive data over tcp. – Muhammad Razib Jul 21 '11 at 18:23
  • 5
    The question is "how can I force a TCP connection"... the answer is by asking for it. The client *chooses* the transport this is completely independent of the server providing tcp or udp transport or not. now, *does* youtube have a TCP rtsp:// interface? that is actually a different question. – moliad Jul 21 '11 at 23:24
1
AVDictionary *format_opts = NULL;
av_dict_set(&format_opts,"rtsp_transport","tcp",0); 

if(avformat_open_input(&context, url,NULL, **&format_opts**) != 0)
{ 
av_dict_free(&format_opts);
return; //error
} 

//if you want more info about RTSP session, you can use RTSPState
//(#include "libavformat\rtsp.h") :
RTSPState *pRTSPState = (RTSPState*)context->priv_data;

//.....

av_dict_free(&format_opts);

//...
Amos
  • 11
  • 2
0

The RTSP RFC ( http://www.ietf.org/rfc/rfc2326.txt ) seems to suggest you can specify your transport(s) of preference during the requests in section 12.39. I don't know if that helps.

zeFrenchy
  • 6,541
  • 1
  • 27
  • 36