⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 theoravidfmt.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    return res;}void CTheoraVideoFormat::Reset(){    DPRINTF(D_THEORA_VIDFMT, ("CTheoraVideoFormat::Reset()\n"));    m_bNeedKeyframe = TRUE;    m_lastFrameSize.cx = 0;    m_lastFrameSize.cy = 0;    ogg_stream_reset(&m_os);    ogg_sync_reset(&m_oy);    CVideoFormat::Reset();}void CTheoraVideoFormat::Close(){    HX_RELEASE(m_pStream);    HX_RELEASE(m_pRegistry);}IHXBuffer* CTheoraVideoFormat::OggPktToIHXBuffer(ogg_packet* pOp){    UINT32 ulDataSize = sizeof(ogg_packet) + pOp->bytes;    IHXBuffer* pRet = CreateBuffer(ulDataSize);    if (pRet)    {	ogg_packet* pOggPkt = (ogg_packet*)pRet->GetBuffer();	UINT8* pPktData = pRet->GetBuffer() + sizeof(ogg_packet);	// Copy ogg_packet struct	*pOggPkt = *pOp;	pOggPkt->packet = pPktData;		// Copy packet data	memcpy(pOggPkt->packet, pOp->packet, pOp->bytes);    }    return pRet;}CMediaPacket* CTheoraVideoFormat::CreateYUVPacket(theora_info* ti,                                                  yuv_buffer& yuv, 						  UINT32 ulTimestamp){    CMediaPacket* pRet = NULL;    if (yuv.y_width && yuv.y_height &&        (yuv.y_width == ti->width) &&        (yuv.y_height == ti->height) &&        (yuv.uv_width == ti->width / 2) &&        (yuv.uv_height == ti->height / 2))    {        // We only handle 4:2:0 output from the decoder right now	HXxSize* pDims = NULL;        // The color converter only accepts frame widths that are        // a multiple of 4. ti->frame_width should always be <=        // ti->width and ti->width is always a multiple of 16.        UINT32 uFrameWidth = (ti->frame_width + 3) & ~0x3;        UINT32 uFrameHeight = ti->frame_height;        UINT32 uAdjustedWidth = uFrameWidth;        UINT32 uAdjustedHeight = uFrameHeight;        UINT32 uXOffset = ti->offset_x;        UINT32 uYOffset = ti->offset_y;                BOOL bStrechX = FALSE;        if (m_uAspectNum > m_uAspectDenom)        {            UINT32 uQ = uAdjustedWidth / m_uAspectDenom;            UINT32 uR = uAdjustedWidth - uQ * m_uAspectDenom;            uAdjustedWidth = (uQ * m_uAspectNum +                              (uR * m_uAspectNum) / m_uAspectDenom);            uAdjustedWidth =  (uAdjustedWidth + 3) &  ~0x3;            bStrechX = TRUE;            if (!m_pPhaseInfo)            {                CreatePhaseInfo(m_uAspectNum);            }        }        else if (m_uAspectNum < m_uAspectDenom)        {            UINT32 uQ = uAdjustedHeight / m_uAspectNum;            UINT32 uR = uAdjustedHeight - uQ * m_uAspectNum;            uAdjustedHeight = (uQ * m_uAspectDenom +                               (uR * m_uAspectDenom) / m_uAspectNum);            if (!m_pPhaseInfo)            {                CreatePhaseInfo(m_uAspectDenom);            }        }        UINT32 ulLumaSize = uAdjustedWidth * uAdjustedHeight;        UINT32 ulChromaSize = ulLumaSize / 4;        UINT32 ulFrameSize = ulLumaSize + 2 * ulChromaSize;	if ((m_lastFrameSize.cx != uAdjustedWidth) ||	    (m_lastFrameSize.cy != uAdjustedHeight))	{            	    pDims = new HXxSize;	    if (pDims)	    {		DPRINTF(D_THEORA_VIDFMT, ("CreateYUVPacket() : Setting frame size\n"));		m_lastFrameSize.cx = uAdjustedWidth;		m_lastFrameSize.cy = uAdjustedHeight;				*pDims = m_lastFrameSize;	    }	}        pRet = GetMediaPacket(ulFrameSize, ulTimestamp, pDims);		if (pRet)	{            UINT8* pData = pRet->m_pData;            int lumaOffset = uXOffset + uYOffset * yuv.y_stride;            int chromaOffset = (uXOffset / 2 +                                 (uYOffset / 2) * yuv.uv_stride);                        if (m_pPhaseInfo)            {                // We are doing aspect ratio adjustment.                if (bStrechX)                {                    // We are stretching in the X direction                    // Copy and stretch Luma plane                    CopyAndStretchX(pData, yuv.y + lumaOffset,                                     uFrameWidth, uFrameHeight,                                     yuv.y_stride,                                    m_uAspectNum, m_uAspectDenom,                                    uAdjustedWidth,                                    m_pPhaseInfo);                                    // Copy and stretch first chroma plane                    CopyAndStretchX(pData, yuv.u + chromaOffset,                                     uFrameWidth / 2, uFrameHeight / 2,                                     yuv.uv_stride,                                    m_uAspectNum, m_uAspectDenom,                                    uAdjustedWidth / 2,                                    m_pPhaseInfo);                                    // Copy and stretch second chroma plane                    CopyAndStretchX(pData, yuv.v + chromaOffset,                                     uFrameWidth / 2, uFrameHeight / 2,                                     yuv.uv_stride,                                    m_uAspectNum, m_uAspectDenom,                                    uAdjustedWidth / 2,                                    m_pPhaseInfo);                }                else                {                    // We are stretching in the Y direction                    // Copy and stretch Luma plane                    CopyAndStretchY(pData, yuv.y + lumaOffset,                                     uFrameWidth, uFrameHeight,                                     yuv.y_stride,                                    m_uAspectNum, m_uAspectDenom,                                    uAdjustedHeight,                                    m_pPhaseInfo);                                    // Copy and stretch first chroma plane                    CopyAndStretchY(pData, yuv.u + chromaOffset,                                     uFrameWidth / 2, uFrameHeight / 2,                                     yuv.uv_stride,                                    m_uAspectNum, m_uAspectDenom,                                    uAdjustedHeight / 2,                                    m_pPhaseInfo);                                    // Copy and stretch second chroma plane                    CopyAndStretchY(pData, yuv.v + chromaOffset,                                     uFrameWidth / 2, uFrameHeight / 2,                                     yuv.uv_stride,                                    m_uAspectNum, m_uAspectDenom,                                    uAdjustedHeight / 2,                                    m_pPhaseInfo);                }            }            else            {                // Copy Luma plane                CopyPixelData(pData, yuv.y + lumaOffset,                               uFrameWidth, uFrameHeight,                               yuv.y_stride);                                // Copy first chroma plane                CopyPixelData(pData, yuv.u + chromaOffset,                               uFrameWidth / 2, uFrameHeight / 2,                               yuv.uv_stride);                                // Copy second chroma plane                CopyPixelData(pData, yuv.v + chromaOffset,                               uFrameWidth / 2, uFrameHeight / 2,                               yuv.uv_stride);            }        }	else	{	    HX_DELETE(pDims);	}    }    return pRet;}IHXBuffer* CTheoraVideoFormat::CreateBuffer(UINT32 ulSize){    IHXBuffer* pRet = NULL;        if (m_pCommonClassFactory &&	(HXR_OK == m_pCommonClassFactory->CreateInstance(IID_IHXBuffer,							 (void**)&pRet)) &&	(HXR_OK != pRet->SetSize(ulSize)))    {	HX_RELEASE(pRet);    }    return pRet;}BOOL CTheoraVideoFormat::IsHeader(ogg_packet* pOp) const{    BOOL bRet = FALSE;    if (pOp && pOp->packet && (pOp->bytes >= 7) &&	((pOp->packet[0] & 0x80) == 0x80) &&	(!memcmp(pOp->packet + 1, "theora", 6)))    {	bRet = TRUE;    }    return bRet;}BOOL CTheoraVideoFormat::IsKeyframe(ogg_packet* pOp) const{    BOOL bRet = FALSE;    if (pOp && pOp->packet && ((pOp->packet[0] & 0xc0) == 0))    {	bRet = TRUE;    }    return bRet;}void CTheoraVideoFormat::HandleIdentHdr(ogg_packet* pOp){    if (IsHeader(pOp) && (pOp->bytes >= 42) && (pOp->packet[0] == 0x80))    {	const unsigned char* pIdent = (const unsigned char*)pOp->packet;		// Ident Header	m_ulFPSNum = ((pIdent[0x16] << 24) | (pIdent[0x17] << 16) |		      (pIdent[0x18] << 8) | (pIdent[0x19]));	m_ulFPSDenom = ((pIdent[0x1a] << 24) | (pIdent[0x1b] << 16) |			(pIdent[0x1c] << 8) | (pIdent[0x1d]));        // Attempt to reduce the numerator and denominator        // by finding the greatest common denominator.        UINT32 tmp = gcd(m_ulFPSNum, m_ulFPSDenom);        if (tmp > 1)        {            m_ulFPSNum /= tmp;            m_ulFPSDenom /= tmp;        }    }}UINT32 CTheoraVideoFormat::CalcTimestamp(UINT32 ulFrame) const{    UINT32 uRet = 0;    if (m_ulFPSNum)    {        ogg_int64_t q = ulFrame / m_ulFPSNum;        ogg_int64_t r = ulFrame - (q * m_ulFPSNum);        ogg_int64_t mult = ((ogg_int64_t)m_ulFPSDenom) * 1000;        ogg_int64_t ts = ((q * mult) +                           ((r * mult) / m_ulFPSNum));        uRet = INT64_TO_UINT32(ts);    }    return uRet;}void CTheoraVideoFormat::ChangeState(State newState){    DPRINTF(D_THEORA_VIDFMT, ("CTheoraVideoFormat::ChangeState() : %d -> %d\n",			      m_state, newState));    m_state = newState;}CMediaPacket* CTheoraVideoFormat::GetMediaPacket(UINT32 uFrameSize,                                   UINT32 uTimestamp,                                   HXxSize* pDims){    CMediaPacket* pRet = (CMediaPacket*)m_pFramePool->Get(uFrameSize);        if (pRet)    {        pRet->Init(pRet->m_pData, uFrameSize, uTimestamp, 0, pDims);    }    else    {        UCHAR* pData = new UCHAR[uFrameSize];                if (pData)        {            pRet = new CMediaPacket(pData,                                     pData,                                    uFrameSize,                                    uFrameSize,                                    uTimestamp,                                    0,                                    pDims /* desc */);            if (!pRet)            {                HX_VECTOR_DELETE(pData);            }        }    }    if (pRet)    {        if (pDims)        {            pRet->SetSampleDescKiller(&DestroySampleDesc);        }    }    return pRet;}void CTheoraVideoFormat::CreatePhaseInfo(UINT32 uPhaseCt){    m_pPhaseInfo = new UINT8[uPhaseCt];    if (m_pPhaseInfo)    {        for (UINT32 i = 0; i < uPhaseCt; i++)        {            m_pPhaseInfo[i] = (UINT8)MulDiv(256, i , uPhaseCt);        }    }}void CTheoraVideoFormat::updateBitrateInfo(theora_info* ti){    if (ti && m_pStream && m_pRegistry)    {        INT32 clipBitrate = ti->target_bitrate;        UINT32 uStreamRegID;        if (HXR_OK == getRegistryID(m_pStream, uStreamRegID))        {            CHXString propName;            if (HXR_OK == getPropName(uStreamRegID, "ClipBandwidth",                                      propName))            {                m_pRegistry->SetIntByName(propName, clipBitrate);            }        }    }}void CTheoraVideoFormat::updateTACInfo(theora_comment* tc){    if (tc && m_pStream && m_pRegistry)    {        IHXStreamSource* pStreamSrc = NULL;        UINT32 uSourceRegID;        if ((HXR_OK == m_pStream->GetSource(pStreamSrc)) &&            (HXR_OK == getRegistryID(pStreamSrc, uSourceRegID)))        {            int tagInfoCount = sizeof(zm_tagInfo) / sizeof(TheoraTagMapping);            for (int i = 0; i < tagInfoCount; i++)            {                char* pTheoraTag = zm_tagInfo[i].m_pTheoraTag;                const char* pPropName = zm_tagInfo[i].m_pPropName;                int commentCount = theora_comment_query_count(tc, pTheoraTag);                                if (commentCount > 0)                {                    CHXString value = theora_comment_query(tc, pTheoraTag, 0);                    for (int j = 1; j < commentCount; j++)                    {                        value += ", ";                        value += theora_comment_query(tc, pTheoraTag, j);                    }                    IHXBuffer* pPropValBuf = NULL;                                        if (HXR_OK == CreateStringBuffer(pPropValBuf,                                                      value,                                                     m_pCommonClassFactory))                    {                                                CHXString propName;                        if (HXR_OK == getPropName(uSourceRegID, pPropName,                                                  propName))                        {                            m_pRegistry->SetStrByName(propName, pPropValBuf);                        }                    }                    HX_RELEASE(pPropValBuf);                }            }        }        HX_RELEASE(pStreamSrc);    }}HX_RESULT CTheoraVideoFormat::getPropName(UINT32 uBaseID, const char* pChildPropName,                                CHXString& propName){    HX_RESULT res = HXR_INVALID_PARAMETER;    if (!m_pRegistry)    {        res = HXR_UNEXPECTED;    }    else if (pChildPropName && strlen(pChildPropName))    {        IHXRegistry* pReg = NULL;        IHXBuffer* pBasePropName = NULL;        res = m_pRegistry->GetPropName(uBaseID, pBasePropName);        if (HXR_OK == res)        {            propName = (const char*)pBasePropName->GetBuffer();            propName += '.';            propName += pChildPropName;        }        HX_RELEASE(pBasePropName);    }    return res;}HX_RESULT CTheoraVideoFormat::getRegistryID(IUnknown* pUnk, REF(UINT32) uRegID){    HX_RESULT res = HXR_INVALID_PARAMETER;    if (pUnk)    {        IHXRegistryID* pRegID = NULL;        res = pUnk->QueryInterface(IID_IHXRegistryID, (void**)&pRegID);        if (HXR_OK == res)        {            res = pRegID->GetID(uRegID);        }        HX_RELEASE(pRegID);    }    return res;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -