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(); unsigned short 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:PALETTE rtStart=%10I64d\n"), rtStart) ); ParsePalette(&SegmentBuffer, m_nSegSize); break; case OBJECT: TRACE_HDMVSUB( (_T("CHdmvSub:OBJECT %lS\n"), ReftimeToCString(rtStart)) ); ParseObject(&SegmentBuffer, m_nSegSize); break; case PRESENTATION_SEG: TRACE_HDMVSUB( (_T("CHdmvSub:PRESENTATION_SEG %lS (size=%d)\n"), ReftimeToCString(rtStart), m_nSegSize) ); // Enqueue the current presentation segment if any EnqueuePresentationSegment(rtStart); // Parse the new presentation segment ParsePresentationSegment(rtStart, &SegmentBuffer); break; case WINDOW_DEF: //TRACE_HDMVSUB( (_T("CHdmvSub:WINDOW_DEF %lS\n"), ReftimeToCString(rtStart)) ); break; case END_OF_DISPLAY: //TRACE_HDMVSUB( (_T("CHdmvSub:END_OF_DISPLAY %lS\n"), ReftimeToCString(rtStart)) ); break; default: TRACE_HDMVSUB( (_T("CHdmvSub:UNKNOWN Seg %d rtStart=0x%10dd\n"), m_nCurSegment, rtStart) ); } m_nCurSegment = NO_SEGMENT; } } } } return hr; }
HRESULT CHdmvSub::ParseSample(IMediaSample* pSample) { CheckPointer(pSample, E_POINTER); HRESULT hr; REFERENCE_TIME rtStart = INVALID_TIME, rtStop = INVALID_TIME; BYTE* pData = nullptr; int lSampleLen; hr = pSample->GetPointer(&pData); if (FAILED(hr) || pData == nullptr) { 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(); unsigned short 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:PALETTE rtStart=%10I64d\n"), rtStart); ParsePalette(&SegmentBuffer, m_nSegSize); break; case OBJECT: TRACE_HDMVSUB(_T("CHdmvSub:OBJECT %s\n"), ReftimeToString(rtStart)); ParseObject(&SegmentBuffer, m_nSegSize); break; case PRESENTATION_SEG: TRACE_HDMVSUB(_T("CHdmvSub:PRESENTATION_SEG %s (size=%d)\n"), ReftimeToString(rtStart), m_nSegSize); // Enqueue the current presentation segment if any EnqueuePresentationSegment(rtStart); // Parse the new presentation segment ParsePresentationSegment(rtStart, &SegmentBuffer); break; case WINDOW_DEF: //TRACE_HDMVSUB(_T("CHdmvSub:WINDOW_DEF %s\n"), ReftimeToString(rtStart)); break; case END_OF_DISPLAY: //TRACE_HDMVSUB(_T("CHdmvSub:END_OF_DISPLAY %s\n"), ReftimeToString(rtStart)); break; default: TRACE_HDMVSUB(_T("CHdmvSub:UNKNOWN Seg %d rtStart=0x%10dd\n"), m_nCurSegment, rtStart); } m_nCurSegment = NO_SEGMENT; } } } } return hr; }
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; }
HRESULT CPGSSub::ParseSample(REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, BYTE* pData, size_t nLen) { CheckPointer(pData, E_POINTER); CAutoLock cAutoLock(&m_csCritSec); CGolombBuffer sampleBuffer(pData, nLen); while (!sampleBuffer.IsEOF()) { if (m_nCurSegment == NO_SEGMENT) { HDMV_SEGMENT_TYPE nSegType = (HDMV_SEGMENT_TYPE)sampleBuffer.ReadByte(); unsigned short nUnitSize = sampleBuffer.ReadShort(); nLen -= 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) { size_t nSize = std::min(m_nSegSize - m_nSegBufferPos, nLen); 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_PGSSUB(_T("CPGSSub:PALETTE %s\n"), ReftimeToString(rtStart)); ParsePalette(&SegmentBuffer, m_nSegSize); break; case OBJECT: TRACE_PGSSUB(_T("CPGSSub:OBJECT %s\n"), ReftimeToString(rtStart)); ParseObject(&SegmentBuffer, m_nSegSize); break; case PRESENTATION_SEG: TRACE_PGSSUB(_T("CPGSSub:PRESENTATION_SEG %s (size=%d)\n"), ReftimeToString(rtStart), m_nSegSize); if (rtStart == INVALID_TIME) { break; } // Update the timestamp for the previous segment UpdateTimeStamp(rtStart); // Parse the new presentation segment ParsePresentationSegment(rtStart, &SegmentBuffer); break; case WINDOW_DEF: //TRACE_PGSSUB(_T("CPGSSub:WINDOW_DEF %s\n"), ReftimeToString(rtStart)); break; case END_OF_DISPLAY: TRACE_PGSSUB(_T("CPGSSub:END_OF_DISPLAY %s\n"), ReftimeToString(rtStart)); // Enqueue the current presentation segment if any EnqueuePresentationSegment(); break; default: TRACE_PGSSUB(_T("CPGSSub:UNKNOWN Seg %d %s\n"), m_nCurSegment, ReftimeToString(rtStart)); } m_nCurSegment = NO_SEGMENT; } } } return S_OK; }