我想了解一下,在视频服务器端,具体是怎么封包并进行rtp传输的详细过程。另外,在收到rtp包后,在把数据放入解码器前,需要做那些工作。
希望各位能说的具体点,谢谢。

解决方案 »

  1.   

    没有人来呀,我是第一个了。
    udp你了解吧,RTP其实就是在UDP的基础上增加了12个字节。里面包含序列号、时钟戳、媒体的类型等,这些你在网上找找看看,而且还有RFC 的里面就是讲RTP的。
    收到了RTP后,首先是要分析了,如根据序列号判断是否有丢包了,计算延时是多少了,这些可以有也可以不要。然后是去掉RTP的包头。剩下的就是数据了,然后是解码的操作了,过程就是这些了。不知道这些是否对你有帮助。
      

  2.   

    应该简单吧,
    RTP协议帧格式里面,
    你把数据体解析出来就OK了啊。
      

  3.   


    1,对解码出来的数据帧,根据什么规则来对其分包,然后添加RTP头?
    2,在接收端如何判断收到一个完整的数据帧?我看到有的用5个“$”符号标识包头,然后根据位来判断是否是尾包,不知道对不对。
    3,接收段对包的处理,主要是 去RTP包头,计算时延,反馈RTCP,判断丢包,重复包,排序,还有其他要做的工作没有?
      

  4.   

    1、一般的是一帧一个rtp,所以不用进行分包了,
    2、和1 一样的,
    3、看你的具体的需求了。去掉RTP包后,就是你编码后的数据了,然后解码即可了。
      

  5.   

    RTP的分包如果你采用rfc的标准,那么根据编码格式不同,数据包的格式是不同的,如H264需要在原始数据上添加NAL头的额外数据的。一个包一帧,跟多包包一帧,或者一个包多个帧都不相同的,如果你仅仅是使用rtp的协议,自己按自己的定义来封包也未尝不可的。至于rtcp的反馈信息你可以使用也可以不使用的。说了这么多其实仍然觉得跟没说一样,总的说来rtp除了那个头里面有些附加数据外,至于处理看你自己喜好了。。我在做p2p视频时也用rtp包来传打洞信息。那么这个时候数据包中rtp头的那些信息对打洞来说没有一点用处的。。
      

  6.   

    我也正在做这个,用了FFMPEG的libavformat去提取数据,可以自己定义大小封装包,包的大小一般只要不超过路由器对转发包的最大值就可以了,收到包查看RTP头信息,做相关的检查。得到真正的数据包,然后用libavcodec解码,FFMPEG给了我们一个例子来实现。他说了这样一段话:As I've already mentioned, a video file can contain several audio and video streams, and each of those streams is split up into packets of a particular size. Our job is to read these packets one by one using libavformat, filter out all those that aren't part of the video stream we're interested in, and hand them on to libavcodec for decoding. In doing this, we'll have to take care of the fact that the boundary between two frames can occur in the middle of a packet.Sound complicated? Lucikly, we can encapsulate this whole process in a routine that simply returns the next video frame:bool GetNextFrame(AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx, 
        int videoStream, AVFrame *pFrame)
    {
        static AVPacket packet;
        static int      bytesRemaining=0;
        static uint8_t  *rawData;
        static bool     fFirstTime=true;
        int             bytesDecoded;
        int             frameFinished;    // First time we're called, set packet.data to NULL to indicate it
        // doesn't have to be freed
        if(fFirstTime)
        {
            fFirstTime=false;
            packet.data=NULL;
        }    // Decode packets until we have decoded a complete frame
        while(true)
        {
            // Work on the current packet until we have decoded all of it
            while(bytesRemaining > 0)
            {
                // Decode the next chunk of data
                bytesDecoded=avcodec_decode_video(pCodecCtx, pFrame,
                    &frameFinished, rawData, bytesRemaining);            // Was there an error?
                if(bytesDecoded < 0)
                {
                    fprintf(stderr, "Error while decoding frame\n");
                    return false;
                }            bytesRemaining-=bytesDecoded;
                rawData+=bytesDecoded;            // Did we finish the current frame? Then we can return
                if(frameFinished)
                    return true;
            }        // Read the next packet, skipping all packets that aren't for this
            // stream
            do
            {
                // Free old packet
                if(packet.data!=NULL)
                    av_free_packet(&packet);            // Read new packet
                if(av_read_packet(pFormatCtx, &packet)<0)
                    goto loop_exit;
            } while(packet.stream_index!=videoStream);        bytesRemaining=packet.size;
            rawData=packet.data;
        }loop_exit:    // Decode the rest of the last frame
        bytesDecoded=avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, 
            rawData, bytesRemaining);    // Free last packet
        if(packet.data!=NULL)
            av_free_packet(&packet);    return frameFinished!=0;
    }
      

  7.   

    你可以看看这个:Using libavformat and libavcodec