示例#1
0
HRESULT CDVBSub::ParsePage(CGolombBuffer& gb, WORD wSegLength, CAutoPtr<DVB_PAGE>& pPage)
{
	HRESULT		hr		= S_OK;
	WORD		wEnd	= (WORD)gb.GetPos() + wSegLength;
	int			nPos	= 0;
	
	pPage.Attach (DNew DVB_PAGE());
	pPage->PageTimeOut			= gb.ReadByte();
	pPage->PageVersionNumber	= (BYTE)gb.BitRead(4);
	pPage->PageState			= (BYTE)gb.BitRead(2);
	pPage->RegionCount			= 0;
	gb.BitRead(2);	// Reserved
	while (gb.GetPos() < wEnd)
	{
		if (nPos < MAX_REGIONS)
		{
			pPage->Regions[nPos].Id			= gb.ReadByte();
			gb.ReadByte();	// Reserved
			pPage->Regions[nPos].HorizAddr	= gb.ReadShort();
			pPage->Regions[nPos].VertAddr	= gb.ReadShort();
			pPage->RegionCount++;
		}
		nPos++;
	}

	return S_OK;
}
示例#2
0
HRESULT CDVBSub::ParseClut(CGolombBuffer& gb, WORD wSegLength)
{
    HRESULT hr = E_POINTER;

    if (m_pCurrentPage) {
        size_t nExpectedSize = 2;
        size_t nEnd = gb.GetPos() + wSegLength;

        BYTE id = gb.ReadByte();
        POSITION posClut = FindClut(m_pCurrentPage, id);
        if (!posClut) {
            posClut = m_pCurrentPage->CLUTs.AddTail(CAutoPtr<DVB_CLUT>(DEBUG_NEW DVB_CLUT()));
        }
        const auto& pClut = m_pCurrentPage->CLUTs.GetAt(posClut);

        pClut->id = id;
        pClut->version_number = (BYTE)gb.BitRead(4);
        gb.BitRead(4);  // Reserved

        pClut->size = 0;
        while (gb.GetPos() < nEnd) {
            nExpectedSize += 2;
            pClut->palette[pClut->size].entry_id = gb.ReadByte();

            BYTE _2_bit   = (BYTE)gb.BitRead(1);
            BYTE _4_bit   = (BYTE)gb.BitRead(1);
            BYTE _8_bit   = (BYTE)gb.BitRead(1);
            UNREFERENCED_PARAMETER(_2_bit);
            UNREFERENCED_PARAMETER(_4_bit);
            UNREFERENCED_PARAMETER(_8_bit);
            gb.BitRead(4);  // Reserved

            if (gb.BitRead(1)) {
                nExpectedSize += 4;
                pClut->palette[pClut->size].Y  = gb.ReadByte();
                pClut->palette[pClut->size].Cr = gb.ReadByte();
                pClut->palette[pClut->size].Cb = gb.ReadByte();
                pClut->palette[pClut->size].T  = 0xff - gb.ReadByte();
            } else {
                nExpectedSize += 2;
                pClut->palette[pClut->size].Y  = (BYTE)gb.BitRead(6) << 2;
                pClut->palette[pClut->size].Cr = (BYTE)gb.BitRead(4) << 4;
                pClut->palette[pClut->size].Cb = (BYTE)gb.BitRead(4) << 4;
                pClut->palette[pClut->size].T  = 0xff - ((BYTE)gb.BitRead(2) << 6);
            }
            if (!pClut->palette[pClut->size].Y) {
                pClut->palette[pClut->size].Cr = 0;
                pClut->palette[pClut->size].Cb = 0;
                pClut->palette[pClut->size].T  = 0;
            }

            pClut->size++;
        }

        hr = (wSegLength == nExpectedSize) ? S_OK : E_UNEXPECTED;
    }

    return hr;
}
示例#3
0
HRESULT CDVBSub::ParseClut(CGolombBuffer& gb, WORD wSegLength)
{
	HRESULT				hr		= S_OK;
	int					nEnd	= gb.GetPos() + wSegLength;
	BYTE				CLUT_id	= gb.ReadByte();

	if (m_pCurrentPage != NULL) {

		CDVBSub::DVB_CLUT	DummyClut;
		CDVBSub::DVB_CLUT*	pClut = FindClut(m_pCurrentPage, CLUT_id);
		if (pClut == NULL) {
			pClut = &DummyClut;
		}

		pClut->id				= CLUT_id;
		pClut->version_number	= (BYTE)gb.BitRead(4);
		gb.BitRead(4);	// Reserved

		pClut->Size = 0;
		while (gb.GetPos() < nEnd) {
			BYTE entry_id	= gb.ReadByte();
			BYTE _2_bit		= (BYTE)gb.BitRead(1);
			BYTE _4_bit		= (BYTE)gb.BitRead(1);
			BYTE _8_bit		= (BYTE)gb.BitRead(1);
			UNREFERENCED_PARAMETER(_2_bit);
			UNREFERENCED_PARAMETER(_4_bit);
			UNREFERENCED_PARAMETER(_8_bit);
			gb.BitRead(4);	// Reserved

			pClut->Palette[entry_id].entry_id = entry_id;
			if (gb.BitRead(1)) {
				pClut->Palette[entry_id].Y	= gb.ReadByte();
				pClut->Palette[entry_id].Cr	= gb.ReadByte();
				pClut->Palette[entry_id].Cb	= gb.ReadByte();
				pClut->Palette[entry_id].T	= 0xff-gb.ReadByte();
			} else {
				pClut->Palette[entry_id].Y	= (BYTE)gb.BitRead(6)<<2;
				pClut->Palette[entry_id].Cr	= (BYTE)gb.BitRead(4)<<4;
				pClut->Palette[entry_id].Cb	= (BYTE)gb.BitRead(4)<<4;
				pClut->Palette[entry_id].T	= 0xff-((BYTE)gb.BitRead(2)<<6);
			}
			if (!pClut->Palette[entry_id].Y) {
				pClut->Palette[entry_id].Cr	= 0;
				pClut->Palette[entry_id].Cb	= 0;
				pClut->Palette[entry_id].T	= 0;
			}

			pClut->Size = max (pClut->Size, entry_id + 1);
		}

		if (DummyClut.Size) {
			m_pCurrentPage->Clut.AddTail(DummyClut);
		}
	}	

	return hr;
}
示例#4
0
HRESULT CDVBSub::ParseClut(CGolombBuffer& gb, WORD wSegLength)
{
    HRESULT hr = E_FAIL;
    int nEnd = gb.GetPos() + wSegLength;

    if (m_pCurrentPage && wSegLength > 2) {
        DVB_CLUT* pClut = DNew DVB_CLUT();
        if (pClut) {
            pClut->id = gb.ReadByte();
            pClut->version_number = (BYTE)gb.BitRead(4);
            gb.BitRead(4);  // Reserved

            pClut->size = 0;
            while (gb.GetPos() < nEnd) {
                BYTE entry_id = gb.ReadByte();
                BYTE _2_bit   = (BYTE)gb.BitRead(1);
                BYTE _4_bit   = (BYTE)gb.BitRead(1);
                BYTE _8_bit   = (BYTE)gb.BitRead(1);
                UNREFERENCED_PARAMETER(_2_bit);
                UNREFERENCED_PARAMETER(_4_bit);
                UNREFERENCED_PARAMETER(_8_bit);
                gb.BitRead(4);  // Reserved

                pClut->palette[entry_id].entry_id = entry_id;
                if (gb.BitRead(1)) {
                    pClut->palette[entry_id].Y  = gb.ReadByte();
                    pClut->palette[entry_id].Cr = gb.ReadByte();
                    pClut->palette[entry_id].Cb = gb.ReadByte();
                    pClut->palette[entry_id].T  = 0xff - gb.ReadByte();
                } else {
                    pClut->palette[entry_id].Y  = (BYTE)gb.BitRead(6) << 2;
                    pClut->palette[entry_id].Cr = (BYTE)gb.BitRead(4) << 4;
                    pClut->palette[entry_id].Cb = (BYTE)gb.BitRead(4) << 4;
                    pClut->palette[entry_id].T  = 0xff - ((BYTE)gb.BitRead(2) << 6);
                }
                if (!pClut->palette[entry_id].Y) {
                    pClut->palette[entry_id].Cr = 0;
                    pClut->palette[entry_id].Cb = 0;
                    pClut->palette[entry_id].T = 0;
                }

                if (pClut->size <= entry_id) {
                    pClut->size = entry_id + 1;
                }
            }

            m_pCurrentPage->CLUTs.AddTail(pClut);
            hr = S_OK;
        } else {
            hr = E_OUTOFMEMORY;
        }
    }

    return hr;
}
示例#5
0
HRESULT CDVBSub::ParseRegion(CGolombBuffer& gb, WORD wSegLength)
{
    HRESULT hr = E_POINTER;

    if (m_pCurrentPage) {
        size_t nExpectedSize = 10;
        size_t nEnd = gb.GetPos() + wSegLength;

        BYTE id = gb.ReadByte();
        POSITION posRegion = FindRegion(m_pCurrentPage, id);
        if (!posRegion) {
            posRegion = m_pCurrentPage->regions.AddTail(CAutoPtr<DVB_REGION>(DEBUG_NEW DVB_REGION()));
        }
        const auto& pRegion = m_pCurrentPage->regions.GetAt(posRegion);

        pRegion->id = id;
        pRegion->version_number = (BYTE)gb.BitRead(4);
        pRegion->fill_flag = (BYTE)gb.BitRead(1);
        gb.BitRead(3);  // Reserved
        pRegion->width = gb.ReadShort();
        pRegion->height = gb.ReadShort();
        pRegion->level_of_compatibility = (BYTE)gb.BitRead(3);
        pRegion->depth = (BYTE)gb.BitRead(3);
        gb.BitRead(2);  // Reserved
        pRegion->CLUT_id = gb.ReadByte();
        pRegion->_8_bit_pixel_code = gb.ReadByte();
        pRegion->_4_bit_pixel_code = (BYTE)gb.BitRead(4);
        pRegion->_2_bit_pixel_code = (BYTE)gb.BitRead(2);
        gb.BitRead(2);  // Reserved

        while (gb.GetPos() < nEnd) {
            nExpectedSize += 6;
            DVB_OBJECT object;
            object.object_id = gb.ReadShort();
            object.object_type = (BYTE)gb.BitRead(2);
            object.object_provider_flag = (BYTE)gb.BitRead(2);
            object.object_horizontal_position = (short)gb.BitRead(12);
            gb.BitRead(4);  // Reserved
            object.object_vertical_position = (short)gb.BitRead(12);
            if (object.object_type == 0x01 || object.object_type == 0x02) {
                nExpectedSize += 2;
                object.foreground_pixel_code = gb.ReadByte();
                object.background_pixel_code = gb.ReadByte();
            }
            pRegion->objects.AddTail(object);
        }

        hr = (wSegLength == nExpectedSize) ? S_OK : E_UNEXPECTED;
    }

    return hr;
}
示例#6
0
HRESULT CDVBSub::ParseRegion(CGolombBuffer& gb, WORD wSegLength)
{
	HRESULT					hr		= S_OK;
	WORD					wEnd	= (WORD)gb.GetPos() + wSegLength;
	CDVBSub::DVB_REGION*	pRegion;
	CDVBSub::DVB_REGION		DummyRegion;

	pRegion = FindRegion (m_pCurrentPage, gb.ReadByte());

	if (pRegion == NULL)
		pRegion = &DummyRegion;

	if (pRegion != NULL)
	{
		pRegion->version_number			= (BYTE)gb.BitRead(4);
		pRegion->fill_flag				= (BYTE)gb.BitRead(1);
		gb.BitRead(3);	// Reserved
		pRegion->width					= gb.ReadShort();
		pRegion->height					= gb.ReadShort();
		pRegion->level_of_compatibility	= (BYTE)gb.BitRead(3);
		pRegion->depth					= (BYTE)gb.BitRead(3);
		gb.BitRead(2);	// Reserved
		pRegion->CLUT_id				= gb.ReadByte();
		pRegion->_8_bit_pixel_code		= gb.ReadByte();
		pRegion->_4_bit_pixel_code		= (BYTE)gb.BitRead(4);
		pRegion->_2_bit_pixel_code		= (BYTE)gb.BitRead(2);
		gb.BitRead(2);	// Reserved

		pRegion->ObjectCount = 0;
		while (gb.GetPos() < wEnd)
		{
			DVB_OBJECT*		pObject = &pRegion->Objects[pRegion->ObjectCount];
			pObject->object_id					= gb.ReadShort();
			pObject->object_type				= (BYTE)gb.BitRead(2);
			pObject->object_provider_flag		= (BYTE)gb.BitRead(2);
			pObject->object_horizontal_position	= (SHORT)gb.BitRead(12);
			gb.BitRead(4);	// Reserved
			pObject->object_vertical_position	= (SHORT)gb.BitRead(12);
			if (pObject->object_type == 0x01 || pObject->object_type == 0x02)
			{
				pObject->foreground_pixel_code	= gb.ReadByte();
				pObject->background_pixel_code	= gb.ReadByte();
			}
			pRegion->ObjectCount++;
		}
	}
	else
		gb.SkipBytes (wSegLength-1);

	return S_OK;
}
void CompositionObject::Dvb8PixelsCodeString(SubPicDesc& spd, CGolombBuffer& gb, SHORT& nX, SHORT& nY)
{
    BYTE			bTemp;
    BYTE			nPaletteIndex = 0;
    SHORT			nCount;
    bool			bQuit	= false;

    while(!bQuit && !gb.IsEOF())
    {
        nCount			= 0;
        nPaletteIndex	= 0;
        bTemp			= gb.ReadByte();
        if(bTemp != 0)
        {
            nPaletteIndex = bTemp;
            nCount		  = 1;
        }
        else
        {
            if(gb.BitRead(1) == 0)								// switch_1
            {
                nCount = (SHORT)gb.BitRead(7);					// run_length_1-127
                if(nCount == 0)
                    bQuit = true;
            }
            else
            {
                nCount			= (SHORT)gb.BitRead(7);			// run_length_3-127
                nPaletteIndex	= gb.ReadByte();
            }
        }

        if(nX + nCount > m_width)
        {
            ASSERT(FALSE);
            break;
        }

        if(nCount > 0)
        {
            FillSolidRect(spd, nX, nY, nCount, 1, m_Colors[nPaletteIndex]);
            nX += nCount;
        }
    }

    gb.BitByteAlign();
}
示例#8
0
void CompositionObject::Dvb4PixelsCodeString(SubPicDesc& spd, CGolombBuffer& gb, short& nX, short& nY)
{
    bool bQuit = false;

    while (!bQuit && !gb.IsEOF()) {
        short nCount = 0;
        BYTE nPaletteIndex = 0;
        BYTE bTemp = (BYTE)gb.BitRead(4);
        if (bTemp != 0) {
            nPaletteIndex = bTemp;
            nCount = 1;
        } else {
            if (gb.BitRead(1) == 0) {                               // switch_1
                nCount = (short)gb.BitRead(3);                      // run_length_3-9
                if (nCount != 0) {
                    nCount += 2;
                } else {
                    bQuit = true;
                }
            } else {
                if (gb.BitRead(1) == 0) {                           // switch_2
                    nCount = 4 + (short)gb.BitRead(2);              // run_length_4-7
                    nPaletteIndex = (BYTE)gb.BitRead(4);            // 4-bit_pixel-code
                } else {
                    switch (gb.BitRead(2)) {                        // switch_3
                        case 0:
                            nCount = 1;
                            break;
                        case 1:
                            nCount = 2;
                            break;
                        case 2:                                     // if (switch_3 == '10')
                            nCount = 9 + (short)gb.BitRead(4);      // run_length_9-24
                            nPaletteIndex = (BYTE)gb.BitRead(4);    // 4-bit_pixel-code
                            break;
                        case 3:
                            nCount = 25 + gb.ReadByte();            // run_length_25-280
                            nPaletteIndex = (BYTE)gb.BitRead(4);    // 4-bit_pixel-code
                            break;
                    }
                }
            }
        }

#if 0
        if (nX + nCount > m_width) {
            ASSERT(FALSE);
            break;
        }
#endif

        if (nCount > 0) {
            FillSolidRect(spd, nX, nY, nCount, 1, m_Colors[nPaletteIndex]);
            nX += nCount;
        }
    }

    gb.BitByteAlign();
}
示例#9
0
HRESULT CDVBSub::ParseClut(CGolombBuffer& gb, WORD wSegLength)
{
	HRESULT				hr		= S_OK;
	WORD				wEnd	= (WORD)gb.GetPos() + wSegLength;
	CDVBSub::DVB_CLUT*	pClut;

	pClut	= FindClut (m_pCurrentPage, gb.ReadByte());
//	ASSERT (pClut != NULL);
	if (pClut != NULL)
	{
		pClut->version_number	= (BYTE)gb.BitRead(4);
		gb.BitRead(4);	// Reserved

		pClut->Size = 0;
		while (gb.GetPos() < wEnd)
		{
			BYTE entry_id	= gb.ReadByte()+1;
			BYTE _2_bit		= (BYTE)gb.BitRead(1);
			BYTE _4_bit		= (BYTE)gb.BitRead(1);
			BYTE _8_bit		= (BYTE)gb.BitRead(1);
			gb.BitRead(4);	// Reserved
			
			pClut->Palette[entry_id].entry_id = entry_id;
			if (gb.BitRead(1))
			{
				pClut->Palette[entry_id].Y	= gb.ReadByte();
				pClut->Palette[entry_id].Cr	= gb.ReadByte();
				pClut->Palette[entry_id].Cb	= gb.ReadByte();
				pClut->Palette[entry_id].T	= 255-gb.ReadByte();
			}
			else
			{
				pClut->Palette[entry_id].Y	= (BYTE)gb.BitRead(6)<<2;
				pClut->Palette[entry_id].Cr	= (BYTE)gb.BitRead(4)<<4;
				pClut->Palette[entry_id].Cb	= (BYTE)gb.BitRead(4)<<4;
				pClut->Palette[entry_id].T	= 255-((BYTE)gb.BitRead(2)<<6);
			}
			pClut->Size = max (pClut->Size, entry_id);
		}
	}

	return hr;
}
void CompositionObject::Dvb2PixelsCodeString(SubPicDesc& spd, CGolombBuffer& gb, short& nX, short& nY)
{
    BYTE  bTemp;
    BYTE  nPaletteIndex = 0;
    short nCount;
    bool  bQuit = false;

    while (!bQuit && !gb.IsEOF()) {
        nCount = 0;
        nPaletteIndex = 0;
        bTemp = (BYTE)gb.BitRead(2);
        if (bTemp != 0) {
            nPaletteIndex = bTemp;
            nCount = 1;
        } else {
            if (gb.BitRead(1) == 1) {                               // switch_1
                nCount = 3 + (short)gb.BitRead(3);                  // run_length_3-9
                nPaletteIndex = (BYTE)gb.BitRead(2);
            } else {
                if (gb.BitRead(1) == 0) {                           // switch_2
                    switch (gb.BitRead(2)) {                        // switch_3
                        case 0:
                            bQuit = true;
                            break;
                        case 1:
                            nCount = 2;
                            break;
                        case 2:                                     // if (switch_3 == '10')
                            nCount = 12 + (short)gb.BitRead(4);     // run_length_12-27
                            nPaletteIndex = (BYTE)gb.BitRead(2);    // 4-bit_pixel-code
                            break;
                        case 3:
                            nCount = 29 + gb.ReadByte();            // run_length_29-284
                            nPaletteIndex = (BYTE)gb.BitRead(2);    // 4-bit_pixel-code
                            break;
                    }
                } else {
                    nCount = 1;
                }
            }
        }

        if (nX + nCount > m_width) {
            ASSERT(FALSE);
            break;
        }

        if (nCount > 0) {
            FillSolidRect(spd, nX, nY, nCount, 1, m_Colors[nPaletteIndex]);
            nX += nCount;
        }
    }

    gb.BitByteAlign();
}
示例#11
0
HRESULT CDVBSub::ParsePage(CGolombBuffer& gb, WORD wSegLength, CAutoPtr<DVB_PAGE>& pPage)
{
    size_t nExpectedSize = 2;
    size_t nEnd = gb.GetPos() + wSegLength;

    pPage = CAutoPtr<DVB_PAGE>(DEBUG_NEW DVB_PAGE());

    pPage->pageTimeOut = gb.ReadByte();
    pPage->pageVersionNumber = (BYTE)gb.BitRead(4);
    pPage->pageState = (BYTE)gb.BitRead(2);
    gb.BitRead(2);  // Reserved
    while (gb.GetPos() < nEnd) {
        nExpectedSize += 6;
        DVB_REGION_POS regionPos;
        regionPos.id = gb.ReadByte();
        gb.ReadByte();  // Reserved
        regionPos.horizAddr = gb.ReadShort();
        regionPos.vertAddr = gb.ReadShort();
        pPage->regionsPos.AddTail(regionPos);
    }

    return (wSegLength == nExpectedSize) ? S_OK : E_UNEXPECTED;
}
void CompositionObject::DvbRenderField(SubPicDesc& spd, CGolombBuffer& gb, SHORT nXStart, SHORT nYStart, SHORT nLength)
{
    //FillSolidRect (spd, 0,  0, 300, 10, 0xFFFF0000);	// Red opaque
    //FillSolidRect (spd, 0, 10, 300, 10, 0xCC00FF00);	// Green 80%
    //FillSolidRect (spd, 0, 20, 300, 10, 0x100000FF);	// Blue 60%
    //return;
    SHORT	nX		= nXStart;
    SHORT	nY		= nYStart;
    INT64	nEnd	= gb.GetPos() + nLength;
    while(gb.GetPos() < nEnd)
    {
        BYTE	bType	= gb.ReadByte();
        switch(bType)
        {
        case 0x10 :
            Dvb2PixelsCodeString(spd, gb, nX, nY);
            break;
        case 0x11 :
            Dvb4PixelsCodeString(spd, gb, nX, nY);
            break;
        case 0x12 :
            Dvb8PixelsCodeString(spd, gb, nX, nY);
            break;
        case 0x20 :
            gb.SkipBytes(2);
            break;
        case 0x21 :
            gb.SkipBytes(4);
            break;
        case 0x22 :
            gb.SkipBytes(16);
            break;
        case 0xF0 :
            nX  = nXStart;
            nY += 2;
            break;
        default :
            ASSERT(FALSE);
            break;
        }
    }
}
示例#13
0
HRESULT CHdmvSub::ParseSample(IMediaSample* pSample)
{
	CheckPointer (pSample, E_POINTER);
	HRESULT				hr;
	REFERENCE_TIME		rtStart = INVALID_TIME, rtStop = INVALID_TIME;
	BYTE*				pData = NULL;
	int					lSampleLen;

	hr = pSample->GetPointer(&pData);
	if(FAILED(hr) || pData == NULL) {
		return hr;
	}
	lSampleLen = pSample->GetActualDataLength();

	pSample->GetTime(&rtStart, &rtStop);
	if (pData) {
		CGolombBuffer		SampleBuffer (pData, lSampleLen);

		while (!SampleBuffer.IsEOF()) {
			if (m_nCurSegment == NO_SEGMENT) {
				HDMV_SEGMENT_TYPE	nSegType	= (HDMV_SEGMENT_TYPE)SampleBuffer.ReadByte();
				USHORT				nUnitSize	= SampleBuffer.ReadShort();
				lSampleLen -=3;

				switch (nSegType) {
					case PALETTE :
					case OBJECT :
					case PRESENTATION_SEG :
					case END_OF_DISPLAY :
						m_nCurSegment = nSegType;
						AllocSegment (nUnitSize);
						break;

					case WINDOW_DEF :
					case INTERACTIVE_SEG :
					case HDMV_SUB1 :
					case HDMV_SUB2 :
						// Ignored stuff...
						SampleBuffer.SkipBytes(nUnitSize);
						break;
					default :
						return VFW_E_SAMPLE_REJECTED;
				}
			}

			if (m_nCurSegment != NO_SEGMENT) {
				if (m_nSegBufferPos < m_nSegSize) {
					int		nSize = min (m_nSegSize-m_nSegBufferPos, lSampleLen);
					SampleBuffer.ReadBuffer (m_pSegBuffer+m_nSegBufferPos, nSize);
					m_nSegBufferPos += nSize;
				}

				if (m_nSegBufferPos >= m_nSegSize) {
					CGolombBuffer	SegmentBuffer (m_pSegBuffer, m_nSegSize);

					switch (m_nCurSegment) {
						case PALETTE :
							TRACE_HDMVSUB ("CHdmvSub:PALETTE            rtStart=%10I64d\n", rtStart);
							ParsePalette(&SegmentBuffer, m_nSegSize);
							break;
						case OBJECT :
							//TRACE_HDMVSUB ("CHdmvSub:OBJECT             %S\n", ReftimeToString(rtStart));
							ParseObject(&SegmentBuffer, m_nSegSize);
							break;
						case PRESENTATION_SEG :
							TRACE_HDMVSUB ("CHdmvSub:PRESENTATION_SEG   %S (size=%d)\n", ReftimeToString(rtStart), m_nSegSize);

							if (m_pCurrentObject) {
								m_pCurrentObject->m_rtStop = rtStart;
								m_pObjects.AddTail (m_pCurrentObject);
								TRACE_HDMVSUB ("CHdmvSub:HDMV : %S => %S\n", ReftimeToString (m_pCurrentObject->m_rtStart), ReftimeToString(rtStart));
								m_pCurrentObject = NULL;
							}

							if (ParsePresentationSegment(&SegmentBuffer) > 0) {
								m_pCurrentObject->m_rtStart	= rtStart;
								m_pCurrentObject->m_rtStop	= _I64_MAX;
							}
							break;
						case WINDOW_DEF :
							// TRACE_HDMVSUB ("CHdmvSub:WINDOW_DEF         %S\n", ReftimeToString(rtStart));
							break;
						case END_OF_DISPLAY :
							// TRACE_HDMVSUB ("CHdmvSub:END_OF_DISPLAY     %S\n", ReftimeToString(rtStart));
							break;
						default :
							TRACE_HDMVSUB ("CHdmvSub:UNKNOWN Seg %d     rtStart=0x%10dd\n", m_nCurSegment, rtStart);
					}

					m_nCurSegment = NO_SEGMENT;
				}
			}
		}
	}

	return hr;
}
示例#14
0
HRESULT CDVBSub::ParseSample (IMediaSample* pSample)
{
    CheckPointer (pSample, E_POINTER);
    HRESULT				hr;
    BYTE*				pData = NULL;
    int					nSize;
    DVB_SEGMENT_TYPE	nCurSegment;

    hr = pSample->GetPointer(&pData);
    if(FAILED(hr) || pData == NULL) {
        return hr;
    }
    nSize = pSample->GetActualDataLength();

    if (*((LONG*)pData) == 0xBD010000) {
        CGolombBuffer	gb (pData, nSize);

        gb.SkipBytes(4);
        WORD	wLength	= (WORD)gb.BitRead(16);
        UNUSED_ALWAYS(wLength);

        if (gb.BitRead(2) != 2) {
            return E_FAIL;    // type
        }

        gb.BitRead(2);		// scrambling
        gb.BitRead(1);		// priority
        gb.BitRead(1);		// alignment
        gb.BitRead(1);		// copyright
        gb.BitRead(1);		// original
        BYTE fpts = (BYTE)gb.BitRead(1);		// fpts
        BYTE fdts = (BYTE)gb.BitRead(1);		// fdts
        gb.BitRead(1);	// escr
        gb.BitRead(1);	// esrate
        gb.BitRead(1);	// dsmtrickmode
        gb.BitRead(1);	// morecopyright
        gb.BitRead(1);	// crc
        gb.BitRead(1);	// extension
        gb.BitRead(8);	// hdrlen

        if(fpts) {
            BYTE b = (BYTE)gb.BitRead(4);
            if(!(fdts && b == 3 || !fdts && b == 2)) {
                ASSERT(0);
                return(E_FAIL);
            }

            REFERENCE_TIME	pts = 0;
            pts |= gb.BitRead(3) << 30;
            MARKER; // 32..30
            pts |= gb.BitRead(15) << 15;
            MARKER; // 29..15
            pts |= gb.BitRead(15);
            MARKER; // 14..0
            pts = 10000*pts/90;

            m_rtStart	= pts;
            m_rtStop	= pts+1;
        } else {
            m_rtStart	= INVALID_TIME;
            m_rtStop	= INVALID_TIME;
        }

        nSize -= 14;
        pData += 14;
        pSample->GetTime(&m_rtStart, &m_rtStop);
        pSample->GetMediaTime(&m_rtStart, &m_rtStop);
    } else if (SUCCEEDED (pSample->GetTime(&m_rtStart, &m_rtStop))) {
        pSample->SetTime(&m_rtStart, &m_rtStop);
    }

    //FILE* hFile = fopen ("D:\\Sources\\mpc-hc\\A garder\\TestSubRip\\dvbsub.dat", "ab");
    //if(hFile != NULL)
    //{
    //	//BYTE	Buff[5] = {48};

    //	//*((DWORD*)(Buff+1)) = lSampleLen;
    //	//fwrite (Buff,  1, sizeof(Buff), hFile);
    //	fwrite (pData, 1, lSampleLen, hFile);
    //	fclose(hFile);
    //}

    if (AddToBuffer (pData, nSize) == S_OK) {
        CGolombBuffer		gb (m_pBuffer+m_nBufferReadPos, m_nBufferWritePos-m_nBufferReadPos);
        int					nLastPos = 0;

        while (!gb.IsEOF()) {
            if (gb.ReadByte() == 0x0F) {
                WORD				wPageId;
                WORD				wSegLength;

                nCurSegment	= (DVB_SEGMENT_TYPE) gb.ReadByte();
                wPageId			= gb.ReadShort();
                wSegLength		= gb.ReadShort();

                if (gb.RemainingSize() < wSegLength) {
                    hr = S_FALSE;
                    break;
                }

                switch (nCurSegment) {
                case PAGE : {
                    CAutoPtr<DVB_PAGE>	pPage;
                    ParsePage(gb, wSegLength, pPage);

                    if (pPage->PageState == DPS_ACQUISITION) {
                        m_pCurrentPage = pPage;
                        m_pCurrentPage->rtStart = m_rtStart;
                        TRACE_DVB ("DVB - Page started  %S\n", ReftimeToString(m_rtStart));
                        m_rtStart = INVALID_TIME;
                    } else {
                        TRACE_DVB ("DVB - Page update\n");
                    }
                }
                break;
                case REGION :
                    ParseRegion(gb, wSegLength);
                    TRACE_DVB ("DVB - Region\n");
                    break;
                case CLUT :
                    ParseClut(gb, wSegLength);
                    TRACE_DVB ("DVB - Clut \n");
                    break;
                case OBJECT :
                    ParseObject(gb, wSegLength);
                    TRACE_DVB ("DVB - Object\n");
                    break;
                case DISPLAY :
                    ParseDisplay(gb, wSegLength);
                    break;
                case END_OF_DISPLAY :
                    if (m_pCurrentPage != NULL && m_rtStart != INVALID_TIME) {
                        m_pCurrentPage->rtStop = m_rtStart;
                        TRACE_DVB ("DVB - End display %S - %S\n", ReftimeToString(m_pCurrentPage->rtStart), ReftimeToString(m_pCurrentPage->rtStop));
                        m_Pages.AddTail (m_pCurrentPage.Detach());
                    }
                    break;
                default :
                    //					gb.SkipBytes(wSegLength);
                    break;
                }
                nLastPos = gb.GetPos();
            }
        }
        m_nBufferReadPos += nLastPos;
    }

    return hr;
}
示例#15
0
文件: HdmvSub.cpp 项目: Tphive/mpc-be
HRESULT CHdmvSub::ParseSample(BYTE* pData, int lSampleLen, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop)
{
	HRESULT hr = S_OK;

	if (pData) {
		CGolombBuffer SampleBuffer (pData, lSampleLen);

		while (!SampleBuffer.IsEOF()) {
			if (m_nCurSegment == NO_SEGMENT) {
				HDMV_SEGMENT_TYPE	nSegType	= (HDMV_SEGMENT_TYPE)SampleBuffer.ReadByte();
				USHORT				nUnitSize	= SampleBuffer.ReadShort();
				lSampleLen -=3;

				switch (nSegType) {
					case PALETTE :
					case OBJECT :
					case PRESENTATION_SEG :
					case END_OF_DISPLAY :
						m_nCurSegment = nSegType;
						AllocSegment(nUnitSize);
						break;

					case WINDOW_DEF :
					case INTERACTIVE_SEG :
					case HDMV_SUB1 :
					case HDMV_SUB2 :
						// Ignored stuff...
						SampleBuffer.SkipBytes(nUnitSize);
						break;
					default :
						return VFW_E_SAMPLE_REJECTED;
				}
			}

			if (m_nCurSegment != NO_SEGMENT) {
				if (m_nSegBufferPos < m_nSegSize) {
					int nSize = min(m_nSegSize - m_nSegBufferPos, lSampleLen);
					SampleBuffer.ReadBuffer(m_pSegBuffer + m_nSegBufferPos, nSize);
					m_nSegBufferPos += nSize;
				}

				if (m_nSegBufferPos >= m_nSegSize) {
					CGolombBuffer SegmentBuffer(m_pSegBuffer, m_nSegSize);

					switch (m_nCurSegment) {
						case PALETTE :
							TRACE_HDMVSUB(_T("CHdmvSub::ParseSample() : PALETTE\n"));
							ParsePalette(&SegmentBuffer, m_nSegSize);
							break;
						case OBJECT :
							TRACE_HDMVSUB(_T("CHdmvSub::ParseSample() : OBJECT\n"));
							ParseObject(&SegmentBuffer, m_nSegSize);
							break;
						case PRESENTATION_SEG :
							TRACE_HDMVSUB(_T("CHdmvSub::ParseSample() : PRESENTATION_SEG = [%10I64d], %s, size = %d\n"), rtStart, ReftimeToString(rtStart), m_nSegSize);
							ParsePresentationSegment(&SegmentBuffer, rtStart);
							break;
						case WINDOW_DEF :
							//TRACE_HDMVSUB(_T("CHdmvSub::ParseSample() : WINDOW_DEF = %10I64d, %S\n"), rtStart, ReftimeToString(rtStart));
							break;
						case END_OF_DISPLAY :
							//TRACE_HDMVSUB(_T("CHdmvSub::ParseSample() : END_OF_DISPLAY = %10I64d, %S\n"), rtStart, ReftimeToString(rtStart));
							break;
						default :
							TRACE_HDMVSUB(_T("CHdmvSub::ParseSample() : UNKNOWN Seg [%d] = [%10I64d], %s\n"), m_nCurSegment, rtStart, ReftimeToString(rtStart));
					}

					m_nCurSegment = NO_SEGMENT;
				}
			}
		}
	}

	return hr;
}
示例#16
0
HRESULT CDVBSub::ParseSample(IMediaSample* pSample)
{
	CheckPointer (pSample, E_POINTER);
	HRESULT				hr;
	BYTE*				pData = NULL;
	int					nSize;
	DVB_SEGMENT_TYPE	nCurSegment;

	hr = pSample->GetPointer(&pData);
	if (FAILED(hr) || pData == NULL) {
		return hr;
	}
	nSize = pSample->GetActualDataLength();

	if (*((LONG*)pData) == 0xBD010000) {
		CGolombBuffer	gb (pData, nSize);

		gb.SkipBytes(4);
		WORD	wLength	= (WORD)gb.BitRead(16);
		UNREFERENCED_PARAMETER(wLength);

		if (gb.BitRead(2) != 2) {
			return E_FAIL;    // type
		}

		gb.BitRead(2);	// scrambling
		gb.BitRead(1);	// priority
		gb.BitRead(1);	// alignment
		gb.BitRead(1);	// copyright
		gb.BitRead(1);	// original
		BYTE fpts = (BYTE)gb.BitRead(1);	// fpts
		BYTE fdts = (BYTE)gb.BitRead(1);	// fdts
		gb.BitRead(1);	// escr
		gb.BitRead(1);	// esrate
		gb.BitRead(1);	// dsmtrickmode
		gb.BitRead(1);	// morecopyright
		gb.BitRead(1);	// crc
		gb.BitRead(1);	// extension
		gb.BitRead(8);	// hdrlen

		if (fpts) {
			BYTE b = (BYTE)gb.BitRead(4);
			if (!(fdts && b == 3 || !fdts && b == 2)) {
				ASSERT(0);
				return(E_FAIL);
			}

			REFERENCE_TIME	pts = 0;
			pts |= gb.BitRead(3) << 30;
			MARKER; // 32..30
			pts |= gb.BitRead(15) << 15;
			MARKER; // 29..15
			pts |= gb.BitRead(15);
			MARKER; // 14..0
			pts = 10000*pts/90;

			m_rtStart	= pts;
			m_rtStop	= pts+1;
		} else {
			m_rtStart	= INVALID_TIME;
			m_rtStop	= INVALID_TIME;
		}

		nSize -= 14;
		pData += 14;
		pSample->GetTime(&m_rtStart, &m_rtStop);
		pSample->GetMediaTime(&m_rtStart, &m_rtStop);
	} else if (SUCCEEDED (pSample->GetTime(&m_rtStart, &m_rtStop))) {
		pSample->SetTime(&m_rtStart, &m_rtStop);
	}

	if (AddToBuffer (pData, nSize) == S_OK) {
		CGolombBuffer	gb (m_pBuffer+m_nBufferReadPos, m_nBufferWritePos-m_nBufferReadPos);
		int				nLastPos = 0;

		while (!gb.IsEOF()) {
			if (gb.ReadByte() == 0x0F) {
				WORD	wPageId;
				WORD	wSegLength;

				nCurSegment	= (DVB_SEGMENT_TYPE) gb.ReadByte();
				wPageId		= gb.ReadShort();
				wSegLength	= gb.ReadShort();

				if (gb.RemainingSize() < wSegLength) {
					hr = S_FALSE;
					break;
				}

				TRACE_DVB (_T("DVB - ParseSample, Segment = [%ws], PageId = [%d], SegLength/Buffer = [%d]/[%d]\n"), GetSegmentType(nCurSegment), wPageId, wSegLength, gb.RemainingSize());

				switch (nCurSegment) {
					case PAGE : {
						CAutoPtr<DVB_PAGE>	pPage;
						ParsePage(gb, wSegLength, pPage);

						if (pPage->PageState == DPS_ACQUISITION || pPage->PageState == DPS_MODE) {
							TRACE_DVB (_T("DVB - Page start\n"));

							if (m_pCurrentPage != NULL) {
								m_pCurrentPage->rtStop = min(m_pCurrentPage->rtStop, m_rtStart);
								TRACE_DVB (_T("DVB - store Page : %ws => %ws\n"), ReftimeToString(m_pCurrentPage->rtStart), ReftimeToString(m_pCurrentPage->rtStop));
								m_Pages.AddTail (m_pCurrentPage.Detach());
							}
							UpdateTimeStamp(m_rtStart);

							m_pCurrentPage = pPage;
							m_pCurrentPage->rtStart	= m_rtStart;
							m_pCurrentPage->rtStop	= m_pCurrentPage->rtStart + m_pCurrentPage->PageTimeOut * UNITS; // TODO - need to limit the duration of the segment

							TRACE_DVB (_T("DVB - Page started : %ws, TimeOut = %d\n"), ReftimeToString(m_pCurrentPage->rtStart), m_pCurrentPage->PageTimeOut);
						} else if (pPage->PageState == DPS_NORMAL) {
							TRACE_DVB (_T("DVB - Page update\n"));

							if (m_pCurrentPage && !m_pCurrentPage->RegionCount && pPage->RegionCount) {
								m_pCurrentPage = pPage;
								m_pCurrentPage->rtStart	= m_rtStart;
								m_pCurrentPage->rtStop	= m_pCurrentPage->rtStart + m_pCurrentPage->PageTimeOut * UNITS; // TODO - need to limit the duration of the segment

								TRACE_DVB (_T("DVB - Page started[update] : %ws, TimeOut = %d\n"), ReftimeToString(m_pCurrentPage->rtStart), m_pCurrentPage->PageTimeOut);
							}
						}
					}
					break;
					case REGION :
						ParseRegion(gb, wSegLength);
						TRACE_DVB (_T("DVB - Region\n"));
						break;
					case CLUT :
						ParseClut(gb, wSegLength);
						TRACE_DVB (_T("DVB - Clut\n"));
						break;
					case OBJECT :
						ParseObject(gb, wSegLength);
						TRACE_DVB (_T("DVB - Object\n"));
						break;
					case DISPLAY :
						ParseDisplay(gb, wSegLength);
						TRACE_DVB (_T("DVB - Display\n"));
						break;
					case END_OF_DISPLAY :
						/*
						if (m_pCurrentPage != NULL && (m_pCurrentPage->rtStart != m_rtStart)) {
							m_pCurrentPage->rtStop = max(m_pCurrentPage->rtStop, m_rtStart);
							TRACE_DVB (_T("DVB - End display : %ws => %ws\n"), ReftimeToString(m_pCurrentPage->rtStart), ReftimeToString(m_pCurrentPage->rtStop));
							m_Pages.AddTail (m_pCurrentPage.Detach());
						}
						*/
						TRACE_DVB (_T("DVB - End display\n"));
						break;
					default :
						TRACE_DVB (_T("DVB - unknown Segment\n"));
						break;
				}
				nLastPos = gb.GetPos();
			}
		}
		m_nBufferReadPos += nLastPos;
	}

	return hr;
}