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; }
HRESULT CMpeg2DataParser::ParsePAT() { HRESULT hr; CComPtr<ISectionList> pSectionList; DWORD dwLength; PSECTION data; WORD wTSID; WORD wSectionLength; CheckNoLog (m_pData->GetSection (PID_PAT, SI_PAT, &m_Filter, 5000, &pSectionList)); CheckNoLog (pSectionList->GetSectionData (0, &dwLength, &data)); CGolombBuffer gb ((BYTE*)data, dwLength); // program_association_section() CheckNoLog (ParseSIHeader (gb, SI_PAT, wSectionLength, wTSID)); while (gb.GetSize() - gb.GetPos() > 4) { WORD program_number = gb.BitRead(16); // program_number gb.BitRead(3); // reserved if (program_number==0) { gb.BitRead(13); // network_PID } else { WORD program_map_PID = gb.BitRead(13); // program_map_PID if (Channels.Lookup(program_number)) { Channels [program_number].SetPMT (program_map_PID); ParsePMT (Channels [program_number]); } } } return S_OK; }
HRESULT CDVBSub::ParseObject(CGolombBuffer& gb, WORD wSegLength) { HRESULT hr = E_FAIL; if (m_pCurrentPage && wSegLength > 2) { CompositionObject* pObject = DNew CompositionObject(); BYTE object_coding_method; pObject->m_object_id_ref = gb.ReadShort(); pObject->m_version_number = (BYTE)gb.BitRead(4); object_coding_method = (BYTE)gb.BitRead(2); // object_coding_method gb.BitRead(1); // non_modifying_colour_flag gb.BitRead(1); // reserved if (object_coding_method == 0x00) { pObject->SetRLEData(gb.GetBufferPos(), wSegLength - 3, wSegLength - 3); gb.SkipBytes(wSegLength - 3); m_pCurrentPage->Objects.AddTail(pObject); hr = S_OK; } else { delete pObject; hr = E_NOTIMPL; } } return hr; }
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(); }
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; }
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; }
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(); }
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; }
HRESULT CDVBSub::ParseDisplay(CGolombBuffer& gb, WORD wSegLength) { m_Display.version_number = (BYTE)gb.BitRead(4); m_Display.display_window_flag = (BYTE)gb.BitRead(1); gb.BitRead(3); // reserved m_Display.width = gb.ReadShort(); m_Display.height = gb.ReadShort(); if (m_Display.display_window_flag) { m_Display.horizontal_position_minimun = gb.ReadShort(); m_Display.horizontal_position_maximum = gb.ReadShort(); m_Display.vertical_position_minimun = gb.ReadShort(); m_Display.vertical_position_maximum = gb.ReadShort(); } 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(); }
HRESULT CDVBSub::ParseDisplay(CGolombBuffer& gb, WORD wSegLength) { int nExpectedSize = 5; m_displayInfo.version_number = (BYTE)gb.BitRead(4); m_displayInfo.display_window_flag = (BYTE)gb.BitRead(1); gb.BitRead(3); // reserved m_displayInfo.width = gb.ReadShort() + 1; m_displayInfo.height = gb.ReadShort() + 1; if (m_displayInfo.display_window_flag) { nExpectedSize += 8; m_displayInfo.horizontal_position_minimun = gb.ReadShort(); m_displayInfo.horizontal_position_maximum = gb.ReadShort(); m_displayInfo.vertical_position_minimun = gb.ReadShort(); m_displayInfo.vertical_position_maximum = gb.ReadShort(); } return (wSegLength == nExpectedSize) ? S_OK : E_UNEXPECTED; }
int HrdParameters(CGolombBuffer& gb) { UINT64 cnt = gb.UExpGolombRead(); // cpb_cnt_minus1 if (cnt > 32U) { return -1; } gb.BitRead(4); // bit_rate_scale gb.BitRead(4); // cpb_size_scale for (unsigned int i = 0; i <= cnt; i++ ) { gb.UExpGolombRead(); // bit_rate_value_minus1 gb.UExpGolombRead(); // cpb_size_value_minus1 gb.BitRead(1); // cbr_flag } gb.BitRead(5); // initial_cpb_removal_delay_length_minus1 gb.BitRead(5); // cpb_removal_delay_length_minus1 gb.BitRead(5); // dpb_output_delay_length_minus1 gb.BitRead(5); // time_offset_length return 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; }
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; }
HRESULT CMpeg2DataParser::ParsePMT(CDVBChannel& Channel) { HRESULT hr; CComPtr<ISectionList> pSectionList; DWORD dwLength; PSECTION data; WORD wTSID; WORD wSectionLength; CheckNoLog (m_pData->GetSection (Channel.GetPMT(), SI_PMT, &m_Filter, 5000, &pSectionList)); CheckNoLog (pSectionList->GetSectionData (0, &dwLength, &data)); CGolombBuffer gb ((BYTE*)data, dwLength); // TS_program_map_section() CheckNoLog (ParseSIHeader (gb, SI_PMT, wSectionLength, wTSID)); gb.BitRead(3); // reserved Channel.SetPCR (gb.BitRead(13)); // PCR_PID gb.BitRead(4); // reserved BeginEnumDescriptors(gb, nType, nLength) { // for (i=0;i<N;i++) { SkipDescriptor (gb, nType, nLength); // descriptor() }
HRESULT CDVBSub::ParseObject(CGolombBuffer& gb, WORD wSegLength) { HRESULT hr = E_POINTER; if (m_pCurrentPage) { size_t nExpectedSize = 3; size_t nEnd = gb.GetPos() + wSegLength; short id = gb.ReadShort(); POSITION posObject = FindObject(m_pCurrentPage, id); if (!posObject) { posObject = m_pCurrentPage->objects.AddTail(CAutoPtr<CompositionObject>(DEBUG_NEW CompositionObject())); } const auto& pObject = m_pCurrentPage->objects.GetAt(posObject); pObject->m_object_id_ref = id; pObject->m_version_number = (BYTE)gb.BitRead(4); BYTE object_coding_method = (BYTE)gb.BitRead(2); // object_coding_method gb.BitRead(1); // non_modifying_colour_flag gb.BitRead(1); // reserved if (object_coding_method == 0x00) { pObject->SetRLEData(gb.GetBufferPos(), wSegLength - nExpectedSize, wSegLength - nExpectedSize); gb.SkipBytes(wSegLength - 3); hr = (wSegLength >= nExpectedSize) ? S_OK : E_UNEXPECTED; } else { TRACE_DVB(_T("DVB - Text subtitles are currently not supported\n")); m_pCurrentPage->objects.RemoveTail(); hr = E_NOTIMPL; } } return hr; }
HRESULT CMpeg2DataParser::ParseSIHeader(CGolombBuffer& gb, DVB_SI SIType, WORD& wSectionLength, WORD& wTSID) { if (gb.BitRead(8) != SIType) { return ERROR_INVALID_DATA; // table_id } gb.BitRead(1); // section_syntax_indicator gb.BitRead(1); // reserved_future_use gb.BitRead(2); // reserved wSectionLength = gb.BitRead(12); // section_length wTSID = gb.BitRead(16); // transport_stream_id gb.BitRead(2); // reserved gb.BitRead(5); // version_number gb.BitRead(1); // current_next_indicator gb.BitRead(8); // section_number gb.BitRead(8); // last_section_number return S_OK; }
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; }
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; }
HRESULT CDVBSub::ParseRegion(CGolombBuffer& gb, WORD wSegLength) { int nEnd = 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() < nEnd) { 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; }
bool ParseDiracHeader(CGolombBuffer gb, unsigned* width, unsigned* height, REFERENCE_TIME* AvgTimePerFrame) { unsigned int version_major = gb.UintGolombRead(); if (version_major < 2) { return false; } gb.UintGolombRead(); /* version_minor */ gb.UintGolombRead(); /* profile */ gb.UintGolombRead(); /* level */ unsigned int video_format = gb.UintGolombRead(); dirac_source_params source = dirac_source_parameters_defaults[video_format]; if (gb.BitRead(1)) { source.width = gb.UintGolombRead(); source.height = gb.UintGolombRead(); } if (!source.width || !source.height) { return false; } if (gb.BitRead(1)) { source.chroma_format = gb.UintGolombRead(); } if (source.chroma_format > 2) { return false; } if (gb.BitRead(1)) { source.interlaced = gb.UintGolombRead(); } if (source.interlaced > 1) { return false; } AV_Rational frame_rate = {0,0}; if (gb.BitRead(1)) { source.frame_rate_index = gb.UintGolombRead(); if (source.frame_rate_index > 10) { return false; } if (!source.frame_rate_index) { frame_rate.num = gb.UintGolombRead(); frame_rate.den = gb.UintGolombRead(); } } if (source.frame_rate_index > 0) { if (source.frame_rate_index <= 8) { frame_rate = avpriv_frame_rate_tab[source.frame_rate_index]; } else { frame_rate = dirac_frame_rate[source.frame_rate_index-9]; } } if (!frame_rate.num || !frame_rate.den) { return false; } *width = source.width; *height = source.height; *AvgTimePerFrame = REF_SECOND_MULT * frame_rate.den/frame_rate.num; return true; }
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; }
HRESULT CMpeg2DataParser::ParseSDT(ULONG ulFreq) { HRESULT hr; CComPtr<ISectionList> pSectionList; DWORD dwLength; PSECTION data; WORD wTSID; WORD wONID; WORD wSectionLength; CheckNoLog (m_pData->GetSection (PID_SDT, SI_SDT, &m_Filter, 5000, &pSectionList)); CheckNoLog (pSectionList->GetSectionData (0, &dwLength, &data)); CGolombBuffer gb ((BYTE*)data, dwLength); // service_description_section() CheckNoLog (ParseSIHeader (gb, SI_SDT, wSectionLength, wTSID)); wONID = gb.BitRead(16); // original_network_id gb.BitRead(8); // reserved_future_use while (gb.GetSize() - gb.GetPos() > 4) { CDVBChannel Channel; Channel.SetFrequency (ulFreq); Channel.SetTSID (wTSID); Channel.SetONID (wONID); Channel.SetSID (gb.BitRead(16)); // service_id uimsbf gb.BitRead(6); // reserved_future_use bslbf gb.BitRead(1); // EIT_schedule_flag bslbf Channel.SetNowNextFlag(!!gb.BitRead(1)); // EIT_present_following_flag bslbf gb.BitRead(3); // running_status uimsbf Channel.SetEncrypted (!!gb.BitRead(1)); // free_CA_mode bslbf // Descriptors: BeginEnumDescriptors(gb, nType, nLength) { switch (nType) { case DT_SERVICE : gb.BitRead(8); // service_type nLength = gb.BitRead(8); // service_provider_name_length gb.ReadBuffer (DescBuffer, nLength); // service_provider_name nLength = gb.BitRead(8); // service_name_length gb.ReadBuffer (DescBuffer, nLength); // service_name DescBuffer[nLength] = 0; Channel.SetName (ConvertString (DescBuffer, nLength)); TRACE ("%15S %d\n", Channel.GetName(), Channel.GetSID()); break; default : SkipDescriptor (gb, nType, nLength); // descriptor() break; } } EndEnumDescriptors if (!Channels.Lookup(Channel.GetSID())) { Channels [Channel.GetSID()] = Channel; } } return S_OK; }
bool ParseAVCHeader(CGolombBuffer gb, avc_hdr& h, bool fullscan) { static BYTE profiles[] = {44, 66, 77, 88, 100, 110, 118, 122, 128, 144, 244}; static BYTE levels[] = {10, 11, 12, 13, 20, 21, 22, 30, 31, 32, 40, 41, 42, 50, 51, 52}; memset((void*)&h, 0, sizeof(h)); h.profile = (BYTE)gb.BitRead(8); if (!MatchValue(profiles, _countof(profiles), h.profile)) { return false; } gb.BitRead(8); h.level = (BYTE)gb.BitRead(8); if (!MatchValue(levels, _countof(levels), h.level)) { return false; } UINT64 sps_id = gb.UExpGolombRead(); // seq_parameter_set_id if (sps_id >= 32) { return false; } UINT64 chroma_format_idc = 0; if (h.profile >= 100) { // high profile chroma_format_idc = gb.UExpGolombRead(); if (chroma_format_idc == 3) { // chroma_format_idc gb.BitRead(1); // residue_transform_flag } gb.UExpGolombRead(); // bit_depth_luma_minus8 gb.UExpGolombRead(); // bit_depth_chroma_minus8 gb.BitRead(1); // qpprime_y_zero_transform_bypass_flag if (gb.BitRead(1)) { // seq_scaling_matrix_present_flag for (int i = 0; i < 8; i++) { if (gb.BitRead(1)) { // seq_scaling_list_present_flag for (int j = 0, size = i < 6 ? 16 : 64, next = 8; j < size && next != 0; ++j) { next = (next + gb.SExpGolombRead() + 256) & 255; } } } } } gb.UExpGolombRead(); // log2_max_frame_num_minus4 UINT64 pic_order_cnt_type = gb.UExpGolombRead(); if (pic_order_cnt_type == 0) { gb.UExpGolombRead(); // log2_max_pic_order_cnt_lsb_minus4 } else if (pic_order_cnt_type == 1) { gb.BitRead(1); // delta_pic_order_always_zero_flag gb.SExpGolombRead(); // offset_for_non_ref_pic gb.SExpGolombRead(); // offset_for_top_to_bottom_field UINT64 num_ref_frames_in_pic_order_cnt_cycle = gb.UExpGolombRead(); if (num_ref_frames_in_pic_order_cnt_cycle >= 256) { return false; } for (int i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) { gb.SExpGolombRead(); // offset_for_ref_frame[i] } } else if (pic_order_cnt_type != 2) { return false; } UINT64 ref_frame_count = gb.UExpGolombRead(); // num_ref_frames if (ref_frame_count > 30) { return false; } gb.BitRead(1); // gaps_in_frame_num_value_allowed_flag UINT64 pic_width_in_mbs_minus1 = gb.UExpGolombRead(); UINT64 pic_height_in_map_units_minus1 = gb.UExpGolombRead(); h.interlaced = !(BYTE)gb.BitRead(1); if (h.interlaced) { gb.BitRead(1); // mb_adaptive_frame_field_flag } BYTE direct_8x8_inference_flag = (BYTE)gb.BitRead(1); // direct_8x8_inference_flag if (h.interlaced && !direct_8x8_inference_flag) { return false; } if (gb.BitRead(1)) { // frame_cropping_flag h.crop_left = (unsigned int)gb.UExpGolombRead(); // frame_cropping_rect_left_offset h.crop_right = (unsigned int)gb.UExpGolombRead(); // frame_cropping_rect_right_offset h.crop_top = (unsigned int)gb.UExpGolombRead(); // frame_cropping_rect_top_offset h.crop_bottom = (unsigned int)gb.UExpGolombRead(); // frame_cropping_rect_bottom_offset } if (gb.BitRead(1)) { // vui_parameters_present_flag if (gb.BitRead(1)) { // aspect_ratio_info_present_flag BYTE aspect_ratio_idc = (BYTE)gb.BitRead(8); // aspect_ratio_idc if (255 == aspect_ratio_idc) { h.sar.num = (WORD)gb.BitRead(16); // sar_width h.sar.den = (WORD)gb.BitRead(16); // sar_height } else if (aspect_ratio_idc < 17) { h.sar.num = pixel_aspect[aspect_ratio_idc][0]; h.sar.den = pixel_aspect[aspect_ratio_idc][1]; } else { return false; } } else { h.sar.num = 1; h.sar.den = 1; } if (gb.BitRead(1)) { // overscan_info_present_flag gb.BitRead(1); // overscan_appropriate_flag } if (gb.BitRead(1)) { // video_signal_type_present_flag gb.BitRead(3); // video_format gb.BitRead(1); // video_full_range_flag if (gb.BitRead(1)) { // colour_description_present_flag gb.BitRead(8); // colour_primaries gb.BitRead(8); // transfer_characteristics gb.BitRead(8); // matrix_coefficients } } if (gb.BitRead(1)) { // chroma_location_info_present_flag gb.UExpGolombRead(); // chroma_sample_loc_type_top_field gb.UExpGolombRead(); // chroma_sample_loc_type_bottom_field } if (gb.BitRead(1)) { // timing_info_present_flag __int64 num_units_in_tick = gb.BitRead(32); __int64 time_scale = gb.BitRead(32); /*long fixed_frame_rate_flag = */gb.BitRead(1); // Trick for weird parameters if ((num_units_in_tick < 1000) || (num_units_in_tick > 1001)) { if ((time_scale % num_units_in_tick != 0) && ((time_scale*1001) % num_units_in_tick == 0)) { time_scale = (time_scale * 1001) / num_units_in_tick; num_units_in_tick = 1001; } else { time_scale = (time_scale * 1000) / num_units_in_tick; num_units_in_tick = 1000; } } time_scale = time_scale / 2; // VUI consider fields even for progressive stream : divide by 2! if (time_scale) { h.AvgTimePerFrame = (10000000I64*num_units_in_tick)/time_scale; } } if (fullscan) { bool nalflag = !!gb.BitRead(1); // nal_hrd_parameters_present_flag if (nalflag) { if (HrdParameters(gb) < 0) { return false; } } bool vlcflag = !!gb.BitRead(1); // vlc_hrd_parameters_present_flag if (vlcflag) { if (HrdParameters(gb) < 0) { return false; } } if (nalflag || vlcflag) { gb.BitRead(1); // low_delay_hrd_flag } gb.BitRead(1); // pic_struct_present_flag if (gb.BitRead(1)) { // bitstream_restriction_flag gb.BitRead(1); // motion_vectors_over_pic_boundaries_flag gb.UExpGolombRead(); // max_bytes_per_pic_denom gb.UExpGolombRead(); // max_bits_per_mb_denom gb.UExpGolombRead(); // log2_max_mv_length_horizontal gb.UExpGolombRead(); // log2_max_mv_length_vertical UINT64 num_reorder_frames = gb.UExpGolombRead(); // num_reorder_frames gb.UExpGolombRead(); // max_dec_frame_buffering if (gb.GetSize() < gb.GetPos()) { num_reorder_frames = 0; } if (num_reorder_frames > 16U) { return false; } } } } if (!h.sar.num) h.sar.num = 1; if (!h.sar.den) h.sar.den = 1; unsigned int mb_Width = (unsigned int)pic_width_in_mbs_minus1 + 1; unsigned int mb_Height = ((unsigned int)pic_height_in_map_units_minus1 + 1) * (2 - !h.interlaced); BYTE CHROMA444 = (chroma_format_idc == 3); h.width = 16 * mb_Width - (2u>>CHROMA444) * min(h.crop_right, (8u<<CHROMA444)-1); if (!h.interlaced) { h.height = 16 * mb_Height - (2u>>CHROMA444) * min(h.crop_bottom, (8u<<CHROMA444)-1); } else {