400RMB
只完成播放缓冲区部分,网络部分未做
另外送一个VOD代码
软解压

解决方案 »

  1.   

    我有完整的程序,可以播放vcd,dvd,mp3...,效果很好绝对超值的vod视频点播系统100兆网可以支持60路vcd并发点播。一口价1000块。[email protected]
      

  2.   

    include <dshow.h>
    #include <streams.h>
    #include <windows.h>
    #include <mmsystem.h>
    #include <stdio.h>class CMemStream : public CAsyncStream
    {
    public:
        CMemStream(LPBYTE pbData, LONGLONG llLength, DWORD dwKBPerSec = INFINITE) :
            m_pbData(pbData),
            m_llLength(llLength),
            m_rllPosition(0),
            m_dwKBPerSec(dwKBPerSec)
        {
            m_dwTimeStart  = timeGetTime(); clearPlayBuf();

    m_packetsize  = 1024*32; m_packetnum  = 32; //1M m_playbufsize  = m_packetsize * m_packetnum; m_playbuf      = new BYTE[m_playbufsize];

    m_llLength  = 4000000000000; m_fileheadsize = m_packetsize * 10;

    hMutex  = CreateMutex(NULL,FALSE,"protect buf");

    m_bheadover  = FALSE; m_breadnum     = 0; hLogFile = fopen("log.txt","w+");

        }
      
    ~CMemStream()
      {
    clearPlayBuf(); delete m_playbuf; fclose(hLogFile);
      }    HRESULT Read(PBYTE pbBuffer,
                     DWORD dwBytesToRead,
                     BOOL bAlign,
                     LPDWORD pdwBytesRead)
        {
            CAutoLock lck(&m_csLock);
            DWORD dwReadLength;


    dwReadLength = dwBytesToRead;
            
    //当没有处理完播放头的时候处于等待状态
    if(!m_bheadover)
    {
    while(m_a_fw < m_fileheadsize)
    {
    fprintf(hLogFile,"Wait Head\n");
    Sleep(100);
    }
    } m_bheadover = TRUE;


    while(CanR()==false)
    {
    fprintf(hLogFile,"CanR=false");
    Sleep(100);
    }
    fprintf(hLogFile,"\n"); m_rllPosition = m_a_fr % m_playbufsize; //fprintf(hLogFile,"Read:m_rllPosition=%d\n",m_rllPosition);
    //fprintf(hLogFile,"Read:m_wllPosition=%d\n\n",m_wllPosition);

    //读取缓冲区数据并播放
    WaitForSingleObject(hMutex,INFINITE); 

    CopyMemory((PVOID)pbBuffer,
     (PVOID)(m_playbuf+m_rllPosition),
                       dwReadLength);

    ReleaseMutex(hMutex);

    m_a_fr  += dwReadLength;

    *pdwBytesRead   = dwReadLength;
            
    return S_OK;
        } bool Write(PBYTE buf)
      {
    if(CanW()==false)
    {
    fprintf(hLogFile,"CanW=false");
    return false;
    }
    fprintf(hLogFile,"\n");

    m_wllPosition = m_a_fw % m_playbufsize;

    //fprintf(hLogFile,"Write:m_rllPosition=%d\n",m_rllPosition);
    //fprintf(hLogFile,"Write:m_wllPosition=%d\n\n",m_wllPosition);

    //添加新的数据进缓冲区
    WaitForSingleObject(hMutex,INFINITE); 
      
    CopyMemory((PVOID)(m_playbuf+m_wllPosition),
     (PVOID)buf,
     m_packetsize);  ReleaseMutex(hMutex); m_a_fw += m_packetsize;

    return true;
      }
      
    ULONG getPacketSize()
    {
    return m_packetsize;
    }

    HRESULT SetPointer(LONGLONG llPos)
        {
            if (llPos < 0 || llPos > m_llLength) {
                return S_FALSE;
            } else {
    //关键,过滤器要对流预读,会有一次跳回0.
    //害的我调试了两天,发发牢骚,哈哈~
                m_a_fr = llPos;
                return S_OK;
            }
        }

    void setFileHeadSize(ULONG fileheadsize)
    {
    if(fileheadsize > m_packetsize *10)
    {
    m_fileheadsize = fileheadsize;
    }else{
    m_fileheadsize = m_packetsize*10;
    }
    }
        LONGLONG Size(LONGLONG *pSizeAvailable)
        {
            LONGLONG llCurrentAvailable =
                Int32x32To64((timeGetTime() - m_dwTimeStart),m_dwKBPerSec);
            *pSizeAvailable = min(m_llLength, llCurrentAvailable);
            return m_llLength;
        } void clearPlayBuf()
    {
    m_rllPosition  = 0; m_wllPosition  = 0;

    m_a_fr  = 0; m_a_fw  = 0;

    } bool CanR()
    {
      if ((m_a_fw - m_a_fr) >= m_packetsize)
    {
    return true;
    }else{
    return false;
    }
    }

    bool CanW()
    {
    if ((m_a_fw - m_a_fr) <= (m_playbufsize - m_packetsize))
    {
    return true;
    }else{
    return false;
    }
    }    DWORD Alignment()
        {
            return 1;
        }
        void Lock()
        {
            m_csLock.Lock();
        }
        void Unlock()
        {
            m_csLock.Unlock();
        }private:
        CCritSec m_csLock;
        const PBYTE m_pbData;
        LONGLONG m_llLength;
        DWORD m_dwKBPerSec;
        DWORD m_dwTimeStart;

    PBYTE m_playbuf; //自定义缓冲区
    ULONG m_playbufsize;    //自定义缓冲区大小
    ULONG m_packetsize; //一帧的大小
    ULONG m_packetnum; //缓冲区中帧的数量 ULONG m_wllPosition;    //相对写地址
      ULONG m_rllPosition;    //相对读地址    LONGLONG m_a_fr; //绝对读地址
    LONGLONG m_a_fw; //绝对写地址 HANDLE hMutex; //关键段保护

    ULONG m_fileheadsize; //要预读的文件头大小
    BOOL m_bheadover; //时候读完头

    ULONG m_breadnum; //流指针跳回0的次数 FILE *hLogFile;
    };class CMemReader : public CAsyncReader
    {
    public:
    STDMETHODIMP Register()
        {
            return S_OK;
        }
        STDMETHODIMP Unregister()
        {
            return S_OK;
        }
        CMemReader(CMemStream *pStream, CMediaType *pmt, HRESULT *phr) :
            CAsyncReader(NAME("Mem Reader"), NULL, pStream, phr)
        {
            m_mt = *pmt;
        }
    };