xvid 视频传输源码

C/C++ code

HRESULT CRtpRender::DoRenderSample( IMediaSample *pSample )
{
    HRESULT hr;
    ValidateReadPtr(pSample,sizeof(IMediaSample));
    //Add media sample data
    byte* pbPayload=0;
    hr=pSample->GetPointer(&pbPayload);
    if(FAILED(hr))
    {
        return hr;
    }
    int status=0;
    size_t dataLength;
    dataLength=pSample->GetActualDataLength();
 
    //把pSample分块发送
    SendDismantleFrame(dataLength,pbPayload,1024,sess);
    checkerror(status);
    return hr;
}
 
//这个函数是进行分块发送,可能是所谓的拆帧
void CRtpRender::SendDismantleFrame( int count,byte* buf,int groupCount,RTPSession& sess )
{
    int status=0;
    int sumCount=count;
    if(count<=groupCount)
    {
        status = sess.SendPacket(buf,count,0,false,33);//发送数据包
         
    }
    else
    {
        int packetCount=0;
        int curCount=0;
        while(sumCount>0)
        {
            if(sumCount-groupCount<=0)
            {
                status = sess.SendPacket(buf,sumCount,0,false,33);//发送数据包
                sumCount=0;
            }
            else
            {
                status = sess.SendPacket(buf,groupCount,0,false,0);//发送数据包
                sumCount=sumCount-groupCount;
                buf=&buf[groupCount];
 
            }
            packetCount++;
 
        }
 
    }
}
 
//初始化Session
STDMETHODIMP CRtpRender::Initialize()
{
#ifdef WIN32
    WSADATA dat;
    WSAStartup(MAKEWORD(2,2),&dat);//指示程序所采用的socket的版本
#endif // WIN32
    uint16_t portbase,destport;
    uint32_t destip;
    std::string ipstr;
    int status,i,num;    
    portbase=6000;
        ipstr="127.0.0.1";
    destip = inet_addr(ipstr.c_str());
    if (destip == INADDR_NONE)
    {
        std::cerr << "Bad IP address specified" << std::endl;
        return -1;
    }
    destip = ntohl(destip);
    destport=8000;
    RTPUDPv4TransmissionParams transparams;
    RTPSessionParams sessparams;
 
    // IMPORTANT: The local timestamp unit MUST be set, otherwise
    //            RTCP Sender Report info will be calculated wrong
    // In this case, we'll be sending 10 samples each second, so we'll
    // put the timestamp unit to (1.0/10.0)
    sessparams.SetOwnTimestampUnit(1.0/33.0);//设置发送频率        
 
    sessparams.SetAcceptOwnPackets(true);//允许接受自身的的数据包
    transparams.SetPortbase(portbase);//设置端口用于接受数据或发送数据
    status = sess.Create(sessparams,&transparams);    //创建RTP任务
    checkerror(status);
 
    //RTPIPv4Address addr(destip,destport);//目标地址
 
    //status = sess.AddDestination(addr);//将目标地址添加会话中
 
 
    return NOERROR;
}


接收端....


//接收数据线程函数
DWORD WINAPI ReceiveData( LPVOID lpParameter )
{
    while(TRUE)
    {
        g_pRtpStream->sess.Poll();
        g_pRtpStream->sess.BeginDataAccess();//对访问的数据进行加锁
        uint32_t intTimestampPrev=0;
        uint32_t intTimestamp;
        byte* sumByte=NULL;
        byte* sumByteBegin=NULL;
        UINT intSumCount=0;
 
 
        // check incoming packets
        if (g_pRtpStream->sess.GotoFirstSourceWithData())//遍历数据源中的所有数据
        {
            do
            {
 
                RTPPacket *pack;
                while ((pack = g_pRtpStream->sess.GetNextPacket()) != NULL)
                {
                    intTimestamp = pack->GetTimestamp();
                    UINT segmentCount=pack->GetPacketLength();
                    segmentCount=pack->GetPayloadLength();
                    byte* bufByte=NULL;
                    intSumCount+=segmentCount;
                    bufByte=(byte *)pack->GetPayloadData();//获得数据
                    if (intTimestamp!=intTimestampPrev)
                    {
                        if (sumByte!=NULL)
                        {
 
                            InsertFrameHead(sumByte,intSumCount-segmentCount);//加入一个链表
                            intSumCount=segmentCount;
                        }
                        sumByte=(byte*)malloc(segmentCount);
                    }
                    else
                    {
                        sumByte=(byte *)realloc((void*)sumByte,intSumCount);
                    }
 
                    memcpy(sumByte+intSumCount-segmentCount,bufByte,segmentCount);
                    intTimestampPrev=intTimestamp;
                    g_pRtpStream->sess.DeletePacket(pack);
                     //delete buf;
 
                }
 
            } while (g_pRtpStream->sess.GotoNextSourceWithData());
            free((void*) sumByte);
 
        }
 
        g_pRtpStream->sess.EndDataAccess();//解锁
 
        RTPTime::Wait(RTPTime(1,0));
    }
    return 0;
}
 
HRESULT CRtpStream::FillBuffer( IMediaSample *pms )
{
    CheckPointer(pms,E_POINTER);
            Frame* frameData=NULL;
                    frameData=(Frame*)malloc(sizeof(Frame));
    while (1)
    {
         
 
 
        GetHeadFrame(frameData);
        Sleep(10);
        if(frameData->count<0)
            continue;
        else
            break;
    }
 
 
    HRESULT hr=S_OK;
    byte* payload;
    hr = pms->GetPointer(&payload);
    if(FAILED(hr)) 
    {
        return hr;
    }    
    pms->SetActualDataLength(frameData->count);
 
    long pmsSize;
    pmsSize=pms->GetSize();
 
    memcpy((void*)payload,(void*)frameData->data,frameData->count>pmsSize?pmsSize:frameData->count);
 
    free(frameData->data);
    free(frameData);
 
    return NOERROR;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值