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

📄 theoravidfmt.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: theoravidfmt.cpp,v 1.10.2.2 2004/11/24 18:29:04 acolwell Exp $ *  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. *  * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks.  You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL.  Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. *  * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. *  * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. *  * Technology Compatibility Kit Test Suite(s) Location: *    http://www.helixcommunity.org/content/tck *  * Contributor(s): *  * ***** END LICENSE BLOCK ***** */ #include "theoravidfmt.h"#include "pckunpck.h"#include "debug.h"#define D_THEORA_VIDFMT 0 //0x4000000const TheoraTagMapping CTheoraVideoFormat::zm_tagInfo[] = {    {"TITLE", "Title"},    {"ARTIST", "Author"},    {"AUTHOR", "Author"},    {"DESCRIPTION", "Description"},    {"COPYRIGHT", "Copyright"}};static UINT32 gcd(UINT32 a, UINT32 b){    // Compute the greatest common denominator    while(b != 0)    {        UINT32 tmp = b;        b = a % b;        a = tmp;    }    return a;}CTheoraVideoFormat::CTheoraVideoFormat(IHXCommonClassFactory* pCCF, 				       CVideoRenderer* pVidRend,                                       IHXStream* pStream) :    CVideoFormat(pCCF, pVidRend),    m_state(stStart),    m_ulFPSNum(0),    m_ulFPSDenom(0),    m_uAspectNum(0),    m_uAspectDenom(0),    m_pPhaseInfo(NULL),    m_currentSerialNum(0),    m_bNeedKeyframe(TRUE),    m_pStream(pStream),    m_pRegistry(NULL){#ifdef _DEBUG    debug_level() |= D_THEORA_VIDFMT;#endif    DPRINTF(D_THEORA_VIDFMT, ("CTheoraVideoFormat::CTheoraVideoFormat()\n"));    ogg_sync_init(&m_oy);    ogg_stream_init(&m_os, m_currentSerialNum);    theora_info_init(&m_ti);    theora_comment_init(&m_tc);    memset(&m_ts, 0, sizeof(m_ts));    m_lastFrameSize.cx = 0;    m_lastFrameSize.cy = 0;    if (m_pStream)    {        m_pStream->AddRef();    }        if (pVidRend)    {        IUnknown* pContext = pVidRend->GetContext();        if (pContext)        {            pContext->QueryInterface(IID_IHXRegistry, (void**)&m_pRegistry);        }    }}CTheoraVideoFormat::~CTheoraVideoFormat(){    DPRINTF(D_THEORA_VIDFMT, ("CTheoraVideoFormat::~CTheoraVideoFormat()\n"));    ogg_sync_clear(&m_oy);    ogg_stream_clear(&m_os);    theora_clear(&m_ts);    theora_info_clear(&m_ti);    theora_comment_clear(&m_tc);    HX_VECTOR_DELETE(m_pPhaseInfo);    HX_RELEASE(m_pStream);    HX_RELEASE(m_pRegistry);}CMediaPacket* CTheoraVideoFormat::CreateAssembledPacket(IHXPacket* pCodecData){    DPRINTF(D_THEORA_VIDFMT, ("CTheoraVideoFormat::CreateAssembledPacket(%u)\n",			      pCodecData));    CMediaPacket* pRet = NULL;    if (pCodecData && !pCodecData->IsLost())    {	IHXBuffer* pInputBuffer = pCodecData->GetBuffer();	// Copy data into the ogg_sync_state object	char* buffer = ogg_sync_buffer(&m_oy, pInputBuffer->GetSize());	memcpy(buffer, pInputBuffer->GetBuffer(), pInputBuffer->GetSize());	ogg_sync_wrote(&m_oy, pInputBuffer->GetSize());		HX_RELEASE(pInputBuffer);	ogg_page og;	UINT32 ulFrameCount = 0;	while (1 == ogg_sync_pageout(&m_oy, &og))	{	    DPRINTF(D_THEORA_VIDFMT, ("CTheoraVideoFormat::CAP() : Got page\n"));	    if (ogg_page_serialno(&og) != m_currentSerialNum)	    {		m_currentSerialNum = ogg_page_serialno(&og);		ogg_stream_init(&m_os, m_currentSerialNum);	    }	    	    if (ogg_stream_pagein(&m_os, &og) == 0)	    {		ogg_packet op;		while(1 == ogg_stream_packetout(&m_os, &op))		{		    DPRINTF(D_THEORA_VIDFMT, ("CTheoraVideoFormat::CAP() : Got packet\n"));		    IHXBuffer* pPktBuf = OggPktToIHXBuffer(&op);		    if (op.b_o_s)		    {			HandleIdentHdr(&op);		    }		    if (pPktBuf)		    {			BOOL bCreatePkt = TRUE;			UINT32 ulTimestamp = pCodecData->GetTime();						if (!IsHeader(&op))			{			    ulTimestamp += CalcTimestamp(ulFrameCount);			    if (m_bNeedKeyframe)			    {				if (IsKeyframe(&op))				{				    m_bNeedKeyframe = FALSE;				}				else				{				    bCreatePkt = FALSE;				}			    }			}			DPRINTF(D_THEORA_VIDFMT, 				("CTheoraVideoFormat::CAP() : PKT_TS %u FRAME_TS %u\n", 				 pCodecData->GetTime(),				 ulTimestamp));						if (bCreatePkt)			{			    CMediaPacket* pMediaPkt = 				new CMediaPacket(pPktBuf,						 pPktBuf->GetBuffer(),						 pPktBuf->GetSize(),						 pPktBuf->GetSize(),						 ulTimestamp,						 MDPCKT_USES_IHXBUFFER_FLAG,						 (void*)1);			    if (pMediaPkt)			    {				DPRINTF(D_THEORA_VIDFMT, ("CTheoraVideoFormat::CAP() : adding packet\n"));				ReturnAssembledPacket(pMediaPkt);				pMediaPkt = NULL;			    }			}						HX_RELEASE(pPktBuf);		    }		    ulFrameCount++;		}	    }	}    }    return pRet;}staticvoid CopyPixelData(REF(UINT8*) pDest, char* pSrc, UINT32 width, UINT32 height, 		   int stride){    for (int i = 0; i < height; i++)    {	memcpy(pDest, pSrc, width);	pSrc += stride;	pDest += width;    }}staticvoid CopyAndStretchX(REF(UINT8*) pDest, const char* pSrc,                      UINT32 uWidth, UINT32 uHeight, int stride,                     UINT32 uAspectNum, UINT32 uAspectDen,                     UINT32 uAdjustedWidth,                     const UINT8* pPhaseInfo){    for (UINT32 i = 0; i < uHeight; i++)    {        UINT32 uPhaseCt = 0;        const UINT8* pDestEnd = pDest + uAdjustedWidth;        const unsigned char* pCur = (const unsigned char*)pSrc;        while (pDest < pDestEnd)        {            UINT32 uLeft = pCur[0];            UINT32 uRight = pCur[1];            if (uLeft < uRight)            {                UINT32 uDelta = uRight - uLeft;                *pDest++ =  uLeft + ((uDelta * pPhaseInfo[uPhaseCt]) >> 8);            }            else if (uLeft > uRight)            {                UINT32 uDelta = uLeft - uRight;                *pDest++ =  uLeft - ((uDelta * pPhaseInfo[uPhaseCt]) >> 8);            }            else            {                *pDest++ = (UINT8)uLeft;            }            HX_ASSERT(uAspectDen < uAspectNum);            uPhaseCt += uAspectDen;            while(uPhaseCt >= uAspectNum)            {                uPhaseCt -= uAspectNum;                pCur++;            }        }        pSrc += stride;    }}staticvoid CopyAndStretchY(REF(UINT8*) pDest, const char* pSrc,                      UINT32 uWidth, UINT32 uHeight, int stride,                     UINT32 uAspectNum, UINT32 uAspectDen,                     UINT32 uAdjustedHeight,                     const UINT8* pPhaseInfo){    UINT32 uPhaseCt = 0;    for (UINT32 i = 0; i < uAdjustedHeight; i++)    {        const unsigned char* pCur = (const unsigned char*)pSrc;                for (UINT32 j = 0; j < uWidth; j++)        {            UINT32 uTop = *pCur;            UINT32 uBottom = *(pCur + stride);            if (uTop < uBottom)            {                UINT32 uDelta = uBottom - uTop;                *pDest++ =  uTop + ((uDelta * pPhaseInfo[uPhaseCt]) >> 8);            }            else if (uTop > uBottom)            {                UINT32 uDelta = uTop - uBottom;                *pDest++ =  uTop - ((uDelta * pPhaseInfo[uPhaseCt]) >> 8);            }            else            {                *pDest++ = (UINT8)uTop;            }            pCur++;        }        HX_ASSERT(uAspectNum < uAspectDen);        uPhaseCt += uAspectNum;        while(uPhaseCt >= uAspectDen)        {            uPhaseCt -= uAspectDen;            pSrc += stride;        }    }}static void DestroySampleDesc(void* pSampleDesc, void* pUserData){    HXxSize* pDims = (HXxSize*)pSampleDesc;    delete pDims;}CMediaPacket* CTheoraVideoFormat::CreateDecodedPacket(CMediaPacket* pCodedPacket){    DPRINTF(D_THEORA_VIDFMT, ("CTheoraVideoFormat::CreateDecodedPacket(%p)\n",			      pCodedPacket));    CMediaPacket* pRet = NULL;        if (pCodedPacket && pCodedPacket->m_pData)    {	yuv_buffer yuv;	ogg_packet* pOp = (ogg_packet*)pCodedPacket->m_pData;	DPRINTF(D_THEORA_VIDFMT, 		("CTheoraVideoFormat::CreateDecodedPacket() : bytes %u\n",		 pOp->bytes));    	int err = 0;	if (pOp->b_o_s)	{            // Clear out old state            theora_clear(&m_ts);            theora_info_clear(&m_ti);            theora_comment_clear(&m_tc);            HX_VECTOR_DELETE(m_pPhaseInfo);            // Prep for new state            theora_info_init(&m_ti);            theora_comment_init(&m_tc);            memset(&m_ts, 0, sizeof(m_ts));	    ChangeState(stNeedIdent);	}    	switch(m_state) {	case stNeedIdent:	    if ( 0 == theora_decode_header(&m_ti, &m_tc, pOp))	    {                m_uAspectNum = m_ti.aspect_numerator;                m_uAspectDenom = m_ti.aspect_denominator;                                if (m_uAspectNum && m_uAspectDenom &&                    (m_uAspectNum != m_uAspectDenom))                {                    UINT32 tmp = gcd(m_uAspectNum, m_uAspectDenom);                    if (tmp > 1)                    {                        m_uAspectNum /= tmp;                         m_uAspectDenom /= tmp;                    }                }                else                {                    m_uAspectNum = 1;                    m_uAspectDenom = 1;                }                updateBitrateInfo(&m_ti);		ChangeState(stNeedComments);	    }	    break;	case stNeedComments:	    if ( 0 == theora_decode_header(&m_ti, &m_tc, pOp))	    {                updateTACInfo(&m_tc);		ChangeState(stNeedCodebooks);	    }	    break;	case stNeedCodebooks:	    if ( 0 == theora_decode_header(&m_ti, &m_tc, pOp))	    {		theora_decode_init(&m_ts, &m_ti);		ChangeState(stReady);	    }	    break;	case stReady: {	    theora_decode_packetin(&m_ts, pOp);	    	    err = theora_decode_YUVout(&m_ts, &yuv);	    	    if (0 == err)	    {		pRet = CreateYUVPacket(&m_ti, yuv, pCodedPacket->m_ulTime);	    }	    DPRINTF(D_THEORA_VIDFMT, ("YUVout err %d\n", err));	    DPRINTF(D_THEORA_VIDFMT, ("YUVout y_width %d\n", yuv.y_width));	    DPRINTF(D_THEORA_VIDFMT, ("YUVout y_height %d\n", yuv.y_height));	    DPRINTF(D_THEORA_VIDFMT, ("YUVout y_stride %d\n", yuv.y_stride));	    DPRINTF(D_THEORA_VIDFMT, ("YUVout uv_width %d\n", yuv.uv_width));	    DPRINTF(D_THEORA_VIDFMT, ("YUVout uv_height %d\n", yuv.uv_height));	    DPRINTF(D_THEORA_VIDFMT, ("YUVout uv_stride %d\n", yuv.uv_stride));	} break;	};    }    if (pCodedPacket != NULL)    {	pCodedPacket->Clear();	delete pCodedPacket;    }    DPRINTF(D_THEORA_VIDFMT, 	    ("CTheoraVideoFormat::CreateDecodedPacket() : pRet %p\n", pRet));    return pRet;}HX_RESULT CTheoraVideoFormat::InitBitmapInfoHeader(HXBitmapInfoHeader &BitmapInfoHeader,					 CMediaPacket* pVideoPacket){    HX_RESULT res = HXR_FAILED;    if (pVideoPacket && pVideoPacket->m_pSampleDesc)    {	HXxSize* pDims = (HXxSize*)pVideoPacket->m_pSampleDesc;	BitmapInfoHeader.biWidth = pDims->cx;	BitmapInfoHeader.biHeight = pDims->cy;	BitmapInfoHeader.biSizeImage = (BitmapInfoHeader.biWidth * 					BitmapInfoHeader.biHeight * 					BitmapInfoHeader.biBitCount / 8);	res = HXR_OK;    }

⌨️ 快捷键说明

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