Получение артефактов при попытке чтения видеопотока с YouTube - PullRequest
13 голосов
/ 21 июля 2011

Я пытаюсь прочитать видеокадры из потока RTSP, полученного с YouTube. Вот ссылка на мое тестовое видео:

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

Если я читаю фреймы из локального файла - все хорошо, но когда читаю их из потока, я получаю только много артефактов. Я гуглил и обнаружил, что может быть проблема с UDP-пакетами, и переключение на TCP может помочь, но я действительно не могу найти, где это можно изменить.

Вот функция чтения кадра:

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;  
}

В моем журнале также появляется много сообщений об ошибках:

[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

... и т. Д.

edit: это 99,9% проблемы UDP-TCP. Я нашел эту ссылку:

RTSP: //195.200.199.8/mpeg4/media.amp

Это тестовая камера, доступная онлайн. Это течет с артефактами. Однако, если у него есть параметр 'tcp' и я использую это

RTSP: //195.200.199.8/mpeg4/media.amp ТСР

все работает без артефактов.

Итак, чтобы исправить мой вопрос: есть ли способ заставить YouTube или ffmpeg использовать TCP?

Ответы [ 3 ]

3 голосов
/ 21 июля 2011

транспортный протокол является свойством запрашиваемого вами сокета IP.таким образом, у вас может быть одинаковый URL (и ip: порт) как для TCP, так и для UDP.Это означает, что клиент должен открыть порт TCP, а не порт UDP.

Этот параметр выбирается при создании сокета.

sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)

или

sock = socket(PF_INET, SOCK_STREAM, IPPROTO_UDP)

Теперь я понятия не имею, где ffmpeg делает это, но, конечно, вышеизложенное может дать вам подсказку, как это выяснить.

1 голос
/ 23 февраля 2012
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);

//...
0 голосов
/ 26 августа 2011

RTSP RFC (http://www.ietf.org/rfc/rfc2326.txt), по-видимому, предполагает, что вы можете указать свои транспортные предпочтения во время запросов в разделе 12.39. Я не знаю, поможет ли это.

...