void SingularSampleBuffer::resetCapacity(SINT capacity) { DEBUG_ASSERT_CLASS_INVARIANT_SingularSampleBuffer; if (m_primaryBuffer.size() != capacity) { SampleBuffer(capacity).swap(m_primaryBuffer); } resetOffsets(); DEBUG_ASSERT_CLASS_INVARIANT_SingularSampleBuffer; }
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; }