コード例 #1
0
ファイル: HdmvSub.cpp プロジェクト: DieBagger/MediaPortal-1
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;
}
コード例 #2
0
ファイル: HdmvSub.cpp プロジェクト: Tphive/mpc-be
void CHdmvSub::ParsePresentationSegment(CGolombBuffer* pGBuffer, REFERENCE_TIME rtTime)
{
	COMPOSITION_DESCRIPTOR	CompositionDescriptor;
	BYTE					nObjectNumber;
	bool					palette_update_flag;
	BYTE					palette_id_ref;

	ParseVideoDescriptor(pGBuffer, &m_VideoDescriptor);
	ParseCompositionDescriptor(pGBuffer, &CompositionDescriptor);
	palette_update_flag	= !!(pGBuffer->ReadByte() & 0x80);
	UNREFERENCED_PARAMETER(palette_update_flag);
	palette_id_ref		= pGBuffer->ReadByte();
	nObjectNumber		= pGBuffer->ReadByte();

	TRACE_HDMVSUB(_T("CHdmvSub::ParsePresentationSegment() : Size = %d, nObjectNumber = %d, palette_id_ref = %d, compositionNumber = %d\n"),
					pGBuffer->GetSize(), nObjectNumber, palette_id_ref, CompositionDescriptor.nNumber);

	if (m_pCurrentWindow && m_pCurrentWindow->m_nObjectNumber && m_pCurrentWindow->m_compositionNumber != -1) {
		for (int i = 0; i < m_pCurrentWindow->m_nObjectNumber; i++) {
			if (m_pCurrentWindow->Objects[i]) {
				CompositionObject* pObject		= m_pCurrentWindow->Objects[i];
				CompositionObject& pObjectData	= m_ParsedObjects[pObject->m_object_id_ref];
				if (pObjectData.m_width) {
					pObject->m_rtStop	= rtTime;
					pObject->m_width	= pObjectData.m_width;
					pObject->m_height	= pObjectData.m_height;

					pObject->SetRLEData(pObjectData.GetRLEData(), pObjectData.GetRLEDataSize(), pObjectData.GetRLEDataSize());

					if (!pObject->HavePalette() && m_CLUT[palette_id_ref].Palette) {
						pObject->SetPalette(m_CLUT[palette_id_ref].pSize, m_CLUT[palette_id_ref].Palette, m_VideoDescriptor.nVideoWidth > 720);
					}

					TRACE_HDMVSUB(_T("			store Segment : m_object_id_ref = %d, m_window_id_ref = %d, compositionNumber = %d, [%10I64d -> %10I64d], [%s -> %s]\n"),
									m_pCurrentWindow->Objects[i]->m_object_id_ref,
									m_pCurrentWindow->Objects[i]->m_window_id_ref,
									m_pCurrentWindow->Objects[i]->m_compositionNumber,
									m_pCurrentWindow->Objects[i]->m_rtStart, m_pCurrentWindow->Objects[i]->m_rtStop,
									ReftimeToString(m_pCurrentWindow->Objects[i]->m_rtStart), ReftimeToString(m_pCurrentWindow->Objects[i]->m_rtStop));

					m_pObjects.AddTail (m_pCurrentWindow->Objects[i]);
				} else {
					delete m_pCurrentWindow->Objects[i];
				}
			}
			m_pCurrentWindow->Objects[i] = NULL;
		}
	}

	if (!m_pCurrentWindow) {
		m_pCurrentWindow = DNew HDMV_WindowDefinition();
	} else {
		m_pCurrentWindow->Reset();
	}

	if (nObjectNumber > 0) {
		m_pCurrentWindow->m_nObjectNumber		= nObjectNumber;
		m_pCurrentWindow->m_palette_id_ref		= (SHORT)palette_id_ref;
		m_pCurrentWindow->m_compositionNumber	= CompositionDescriptor.nNumber;

		for (int i = 0; i < nObjectNumber; i++) {
			m_pCurrentWindow->Objects[i]						= DNew CompositionObject();
			m_pCurrentWindow->Objects[i]->m_rtStart				= rtTime;
			m_pCurrentWindow->Objects[i]->m_rtStop				= _I64_MAX;
			m_pCurrentWindow->Objects[i]->m_compositionNumber	= CompositionDescriptor.nNumber;

			ParseCompositionObject(pGBuffer, m_pCurrentWindow->Objects[i]);
		}
	}
}
コード例 #3
0
ファイル: DVBSub.cpp プロジェクト: finalpatch/mpc-hc
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);
    }

    //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) {
                TRACE_DVB("DVB - ParseSample\n");

                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) {
                        if (m_pCurrentPage != NULL) {
                            m_pCurrentPage->rtStop = max(m_pCurrentPage->rtStop, m_rtStart);
                            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 * 1000000;

                        TRACE_DVB("DVB - Page started %S, TimeOut = %d\n", ReftimeToString(m_rtStart), m_pCurrentPage->PageTimeOut);
                    } else {
                        TRACE_DVB("DVB - Page update\n");

                        if (m_pCurrentPage && !m_pCurrentPage->RegionCount) {
                            m_pCurrentPage = pPage;
                            m_pCurrentPage->rtStart = m_rtStart;
                            m_pCurrentPage->rtStop  = m_pCurrentPage->rtStart + m_pCurrentPage->PageTimeOut * 1000000;

                            TRACE_DVB("DVB - Page started[update] %S, TimeOut = %d\n", ReftimeToString(m_rtStart), m_pCurrentPage->PageTimeOut);
                        }
                    }
                }
                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);
                    TRACE_DVB("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("DVB - End display %S - %S\n", ReftimeToString(m_pCurrentPage->rtStart), ReftimeToString(m_pCurrentPage->rtStop));
                        m_Pages.AddTail(m_pCurrentPage.Detach());
                    }
                    break;
                default:
                    break;
                }
                nLastPos = gb.GetPos();
            }
        }
        m_nBufferReadPos += nLastPos;
    }

    return hr;
}
コード例 #4
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;
}
コード例 #5
0
ファイル: HdmvSub.cpp プロジェクト: Tphive/mpc-be
void CHdmvSub::Render(SubPicDesc& spd, REFERENCE_TIME rt, RECT& bbox)
{
	bbox.left	= LONG_MAX;
	bbox.top	= LONG_MAX;
	bbox.right	= 0;
	bbox.bottom	= 0;

	POSITION pos = m_pObjects.GetHeadPosition();
	while (pos) {
		CompositionObject* pObject = m_pObjects.GetAt (pos);

		if (pObject && rt >= pObject->m_rtStart && rt < pObject->m_rtStop) {
			if (pObject->GetRLEDataSize() && pObject->m_width > 0 && pObject->m_height > 0 &&
					m_VideoDescriptor.nVideoWidth >= (pObject->m_horizontal_position + pObject->m_width) &&
					m_VideoDescriptor.nVideoHeight >= (pObject->m_vertical_position + pObject->m_height)) {

				if (g_bForcedSubtitle && !pObject->m_forced_on_flag) {
					TRACE_HDMVSUB(_T("CHdmvSub::Render() : skip non forced subtitle - forced = %d, %I64d = %s"), pObject->m_forced_on_flag, rt, ReftimeToString(rt));
					return;
				}

				if (!pObject->HavePalette() && m_DefaultCLUT.Palette) {
					pObject->SetPalette(m_DefaultCLUT.pSize, m_DefaultCLUT.Palette, m_VideoDescriptor.nVideoWidth > 720);
				}

				if (!pObject->HavePalette()) {
					TRACE_HDMVSUB(_T("CHdmvSub::Render() : The palette is missing - cancel rendering\n"));
					return;
				}

				bbox.left	= min(pObject->m_horizontal_position, bbox.left);
				bbox.top	= min(pObject->m_vertical_position, bbox.top);
				bbox.right	= max(pObject->m_horizontal_position + pObject->m_width, bbox.right);
				bbox.bottom	= max(pObject->m_vertical_position + pObject->m_height, bbox.bottom);

				bbox.left	= bbox.left > 0 ? bbox.left : 0;
				bbox.top	= bbox.top > 0 ? bbox.top : 0;
				if (m_VideoDescriptor.nVideoWidth > spd.w) {
					bbox.left	= MulDiv(bbox.left, spd.w, m_VideoDescriptor.nVideoWidth);
					bbox.right	= MulDiv(bbox.right, spd.w, m_VideoDescriptor.nVideoWidth);
				}
				if (m_VideoDescriptor.nVideoHeight > spd.h) {
					bbox.top	= MulDiv(bbox.top, spd.h, m_VideoDescriptor.nVideoHeight);
					bbox.bottom	= MulDiv(bbox.bottom, spd.h, m_VideoDescriptor.nVideoHeight);
				}

				TRACE_HDMVSUB(_T("CHdmvSub::Render() : size = %ld, ObjRes = %dx%d, SPDRes = %dx%d, %I64d = %s\n"),
								pObject->GetRLEDataSize(),
								pObject->m_width, pObject->m_height, spd.w, spd.h,
								rt, ReftimeToString(rt));

				InitSpd(spd, m_VideoDescriptor.nVideoWidth, m_VideoDescriptor.nVideoHeight);
				pObject->RenderHdmv(spd, m_bResizedRender ? &m_spd : NULL);
			}
		}

		m_pObjects.GetNext(pos);
	}

	FinalizeRender(spd);
}
コード例 #6
0
ファイル: MpegSplitterFile.cpp プロジェクト: GenomeXP/mpc-hc
HRESULT CMpegSplitterFile::SearchStreams(__int64 start, __int64 stop, IAsyncReader* pAsyncReader, BOOL CalcDuration)
{
    Seek(start);
    stop = min(stop, GetLength());

    while (GetPos() < stop) {
        BYTE b;

        if (m_type == mpeg_ps || m_type == mpeg_es) {
            if (!NextMpegStartCode(b)) {
                continue;
            }

            if (b == 0xba) { // program stream header
                pshdr h;
                if (!Read(h)) {
                    continue;
                }
                m_rate = int(h.bitrate / 8);
            } else if (b == 0xbb) { // program stream system header
                pssyshdr h;
                if (!Read(h)) {
                    continue;
                }
            } else if ((b >= 0xbd && b < 0xf0) || (b == 0xfd)) { // pes packet
                peshdr h;
                if (!Read(h, b) || !h.len) {
                    continue;
                }

                if (h.type == mpeg2 && h.scrambling) {
                    ASSERT(0);
                    return E_FAIL;
                }

                if (h.fpts) {
                    if (m_rtMin == _I64_MAX) {
                        m_rtMin = h.pts;
                        m_posMin = GetPos();
                        TRACE(_T("m_rtMin(SearchStreams)=%s\n"), ReftimeToString(m_rtMin));
                    }
                    if (m_rtMin < h.pts && m_rtMax < h.pts) {
                        m_rtMax = h.pts;
                        m_posMax = GetPos();
                        TRACE(_T("m_rtMax(SearchStreams)=%s\n"), ReftimeToString(m_rtMax));
                    }
                }

                __int64 pos = GetPos();
                AddStream(0, b, h.id_ext, h.len);
                if (h.len) {
                    Seek(pos + h.len);
                }
            }
        } else if (m_type == mpeg_ts) {
            tshdr h;
            if (!Read(h)) {
                continue;
            }

            __int64 pos = GetPos();

            //UpdatePrograms(h);

            if (h.payload && ISVALIDPID(h.pid)) {
                peshdr h2;
                if (h.payloadstart && NextMpegStartCode(b, 4) && Read(h2, b)) { // pes packet
                    if (h2.type == mpeg2 && h2.scrambling) {
                        ASSERT(0);
                        return E_FAIL;
                    }

                    if (h2.fpts && CalcDuration && (m_AlternativeDuration || (GetMasterStream() && GetMasterStream()->GetHead() == h.pid))) {
                        if (m_rtPrec != _I64_MIN && abs(h2.pts - m_rtPrec) >= PTS_MAX_BEFORE_WRAP / 2) {
                            m_bPTSWrap = true;
                            m_rtMax = h2.pts;
                            m_posMax = GetPos();
                            TRACE(_T("PTS Wrap detected --> m_rtMax(SearchStreams)=%s\n"), ReftimeToString(m_rtMax));
                        }
                        m_rtPrec = h2.pts;

                        if ((m_rtMin == _I64_MAX) || (m_rtMin > h2.pts && m_rtMax > h2.pts && !m_bPTSWrap)) {
                            m_rtMin = h2.pts;
                            m_posMin = GetPos();
                            TRACE(_T("m_rtMin(SearchStreams)=%s, PID=%d\n"), ReftimeToString(m_rtMin), h.pid);
                        }

                        if (m_rtMax < h2.pts && (m_rtMin < h2.pts || m_bPTSWrap)) {
                            m_rtMax = h2.pts;
                            m_posMax = GetPos();
                            TRACE(_T("m_rtMax(SearchStreams)=%s, PID=%d\n"), ReftimeToString(m_rtMax), h.pid);
                            // Ugly code : to support BRD H264 seamless playback, CMultiFiles need to update m_rtPTSOffset variable
                            // each time a new part is open...
                            // use this code only if Blu-ray is detected
                            if (m_ClipInfo.IsHdmv()) {
                                for (size_t i = 0; i < m_ClipInfo.GetStreamNumber(); i++) {
                                    CHdmvClipInfo::Stream* stream = m_ClipInfo.GetStreamByIndex(i);
                                    if (stream->m_Type == VIDEO_STREAM_H264 && m_rtMin == 116506666) {
                                        CComQIPtr<ISyncReader>  pReader = pAsyncReader;
                                        if (pReader) {
                                            pReader->SetPTSOffset(&m_rtPTSOffset);
                                        }
                                        //TRACE(_T("UPDATE m_rtPTSOffset(SearchStreams)=%s\n"), ReftimeToString(m_rtPTSOffset));
                                        //TRACE(_T("m_rtMin(Boucle)=%s\n"), ReftimeToString(m_rtMin));
                                        //TRACE(_T("stream=%d\n"), stream->m_Type);
                                        //TRACE(_T("m_rtMax(Boucle)=%s\n"), ReftimeToString(m_rtMax));
                                        //TRACE(_T("m_rtMax - m_rtMin(Boucle)=%s\n"), ReftimeToString(m_rtMax - m_rtMin));
                                    }
                                }
                            }
                        }
                    }
                } else {
                    b = 0;
                }

                if (!CalcDuration) {
                    AddStream(h.pid, b, 0, DWORD(h.bytes - (GetPos() - pos)));
                }
            }

            Seek(h.next);
        } else if (m_type == mpeg_pva) {
            pvahdr h;
            if (!Read(h)) {
                continue;
            }

            if (h.fpts) {
                if (m_rtMin == _I64_MAX) {
                    m_rtMin = h.pts;
                    m_posMin = GetPos();
                }

                if (m_rtMin < h.pts && m_rtMax < h.pts) {
                    m_rtMax = h.pts;
                    m_posMax = GetPos();
                }
            }

            __int64 pos = GetPos();

            if (h.streamid == 1) {
                AddStream(h.streamid, 0xe0, 0, h.length);
            } else if (h.streamid == 2) {
                AddStream(h.streamid, 0xc0, 0, h.length);
            }

            if (h.length) {
                Seek(pos + h.length);
            }
        }
    }

    return S_OK;
}
コード例 #7
0
ファイル: DVBSub.cpp プロジェクト: anxocruel/mpc-hc
HRESULT CDVBSub::ParseSample(IMediaSample* pSample)
{
    CheckPointer(pSample, E_POINTER);
    HRESULT hr;
    BYTE* pData = nullptr;
    int nSize;
    DVB_SEGMENT_TYPE nCurSegment;

    hr = pSample->GetPointer(&pData);
    if (FAILED(hr) || pData == nullptr) {
        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.RemainingSize() >= 6) { // Ensure there is enough data to parse the entire segment header
            if (gb.ReadByte() == 0x0F) {
                TRACE_DVB(_T("DVB - ParseSample\n"));

                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: {
                        if (m_pCurrentPage != nullptr) {
                            TRACE_DVB(_T("DVB - Force End display"));
                            EnqueuePage(m_rtStart);
                        }
                        UpdateTimeStamp(m_rtStart);

                        CAutoPtr<DVB_PAGE> pPage;
                        ParsePage(gb, wSegLength, pPage);

                        if (pPage->pageState == DPS_ACQUISITION || pPage->pageState == DPS_MODE_CHANGE) {
                            m_pCurrentPage = pPage;
                            m_pCurrentPage->rtStart = m_rtStart;
                            m_pCurrentPage->rtStop  = m_pCurrentPage->rtStart + m_pCurrentPage->pageTimeOut * 10000000;

                            TRACE_DVB(_T("DVB - Page started [pageState = %d] %s, TimeOut = %ds\n"), m_pCurrentPage->pageState, ReftimeToString(m_rtStart), m_pCurrentPage->pageTimeOut);
                        } else if (!m_Pages.IsEmpty()) {
                            m_pCurrentPage = pPage;
                            m_pCurrentPage->rtStart = m_rtStart;
                            m_pCurrentPage->rtStop  = m_pCurrentPage->rtStart + m_pCurrentPage->pageTimeOut * 10000000;

                            // Copy data from the previous page
                            DVB_PAGE* pPrevPage = m_Pages.GetTail();

                            memcpy(m_pCurrentPage->regions, pPrevPage->regions, sizeof(m_pCurrentPage->regions));

                            for (POSITION pos = pPrevPage->objects.GetHeadPosition(); pos;) {
                                m_pCurrentPage->objects.AddTail(pPrevPage->objects.GetNext(pos)->Copy());
                            }

                            for (POSITION pos = pPrevPage->CLUTs.GetHeadPosition(); pos;) {
                                m_pCurrentPage->CLUTs.AddTail(DEBUG_NEW DVB_CLUT(*pPrevPage->CLUTs.GetNext(pos)));
                            }

                            TRACE_DVB(_T("DVB - Page started [update] %s, TimeOut = %ds\n"), ReftimeToString(m_rtStart), m_pCurrentPage->pageTimeOut);
                        } else {
                            TRACE_DVB(_T("DVB - Page update ignored %s\n"), ReftimeToString(m_rtStart));
                        }
                    }
                    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 == nullptr) {
                            TRACE_DVB(_T("DVB - Ignored End display %s: no current page\n"), ReftimeToString(m_rtStart));
                        } else if (m_pCurrentPage->rtStart < m_rtStart) {
                            TRACE_DVB(_T("DVB - End display"));
                            EnqueuePage(m_rtStart);
                        } else {
                            TRACE_DVB(_T("DVB - Ignored End display %s: no information on page duration\n"), ReftimeToString(m_rtStart));
                        }
                        break;
                    default:
                        break;
                }
                nLastPos = gb.GetPos();
            }
        }
        m_nBufferReadPos += nLastPos;
    }

    return hr;
}
コード例 #8
0
ファイル: PGSSub.cpp プロジェクト: Blitzker/mpc-hc
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;
}
コード例 #9
0
CString CClip::GetOut() const
{
    return (m_rtOut == _I64_MIN) ? _T("") : ReftimeToString(m_rtOut);
}
コード例 #10
0
CString CClip::GetIn() const
{
    return (m_rtIn == _I64_MIN) ? _T("") : ReftimeToString(m_rtIn);
}
コード例 #11
0
ファイル: HdmvClipInfo.cpp プロジェクト: Tphive/mpc-be
HRESULT CHdmvClipInfo::ReadPlaylist(CString strPlaylistFile, REFERENCE_TIME& rtDuration, CPlaylist& Playlist, BOOL bFullInfoRead)
{

	BYTE	Buff[5];
	CPath	Path (strPlaylistFile);
	bool	bDuplicate = false;
	rtDuration  = 0;

	// Get BDMV folder
	Path.RemoveFileSpec();
	Path.RemoveFileSpec();

	m_hFile = CreateFile(strPlaylistFile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
							OPEN_EXISTING, FILE_ATTRIBUTE_READONLY|FILE_FLAG_SEQUENTIAL_SCAN, NULL);

	if (m_hFile != INVALID_HANDLE_VALUE) {
		DbgLog((LOG_TRACE, 3, _T("CHdmvClipInfo::ReadPlaylist() : %s"), strPlaylistFile));

		ReadBuffer(Buff, 4);
		if (memcmp(Buff, "MPLS", 4)) {
			return CloseFile(VFW_E_INVALID_FILE_FORMAT);
		}

		ReadBuffer(Buff, 4);
		if ((memcmp(Buff, "0200", 4)) && (memcmp(Buff, "0100", 4))) {
			return CloseFile(VFW_E_INVALID_FILE_FORMAT);
		}

		LARGE_INTEGER	Pos = {0, 0};
		DWORD			dwTemp;
		USHORT			nPlaylistItems;

		Pos.QuadPart = ReadDword();	// PlayList_start_address
		ReadDword();				// PlayListMark_start_address

		// PlayList()
		SetFilePointerEx(m_hFile, Pos, NULL, FILE_BEGIN);
		ReadDword();						// length
		ReadShort();						// reserved_for_future_use
		nPlaylistItems = ReadShort();		// number_of_PlayItems
		ReadShort();						// number_of_SubPaths

		Pos.QuadPart += 10;
		__int64 TotalSize = 0;
		for (size_t i = 0; i < nPlaylistItems; i++) {
			CAutoPtr<PlaylistItem> Item(DNew PlaylistItem);
			SetFilePointerEx(m_hFile, Pos, NULL, FILE_BEGIN);
			Pos.QuadPart += ReadShort() + 2;
			ReadBuffer(Buff, 5);
			Item->m_strFileName.Format(_T("%s\\STREAM\\%c%c%c%c%c.M2TS"), CString(Path), Buff[0], Buff[1], Buff[2], Buff[3], Buff[4]);

			ReadBuffer(Buff, 4);
			if (memcmp(Buff, "M2TS", 4)) {
				return CloseFile(VFW_E_INVALID_FILE_FORMAT);
			}

			if (!::PathFileExists(Item->m_strFileName)) {
				DbgLog((LOG_TRACE, 3, _T("		==> %s is missing, skip it"), Item->m_strFileName));
				continue;
			}
			ReadBuffer(Buff, 3);

			dwTemp				= ReadDword();
			Item->m_rtIn		= REFERENCE_TIME(20000.0f*dwTemp/90);

			dwTemp				= ReadDword();
			Item->m_rtOut		= REFERENCE_TIME(20000.0f*dwTemp/90);

			Item->m_rtStartTime	= rtDuration;

			rtDuration += (Item->m_rtOut - Item->m_rtIn);

			if (bFullInfoRead) {
				LARGE_INTEGER size = {0, 0};
				HANDLE hFile = CreateFile(Item->m_strFileName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
											OPEN_EXISTING, FILE_ATTRIBUTE_READONLY|FILE_FLAG_SEQUENTIAL_SCAN, NULL);
				if (hFile != INVALID_HANDLE_VALUE) {
					GetFileSizeEx(hFile, &size);
					CloseHandle(hFile);
				}

				Item->m_SizeIn	= TotalSize;
				TotalSize		+= size.QuadPart;
				Item->m_SizeOut	= TotalSize;
			}

			POSITION pos = Playlist.GetHeadPosition();
			while (pos) {
				PlaylistItem* pItem = Playlist.GetNext(pos);
				if (*pItem == *Item) {
					bDuplicate = true;
					break;
				}

			}

			DbgLog((LOG_TRACE, 3, _T("	==> %s, Duration : %s [%15I64d], Total duration : %s, Size : %I64d"), Item->m_strFileName, ReftimeToString(Item->Duration()), Item->Duration(), ReftimeToString(rtDuration), Item->Size()));

			Playlist.AddTail(Item);
		}

		CloseFile(S_OK);

		if (bFullInfoRead) {
			POSITION pos = Playlist.GetHeadPosition();
			while (pos) {
				PlaylistItem* pItem = Playlist.GetNext(pos);
				CString fname = pItem->m_strFileName;
				fname.Replace(L"\\STREAM\\", L"\\CLIPINF\\");
				fname.Replace(L".M2TS", L".CLPI");

				ReadInfo(fname, &pItem->m_sps);
			}
		}

		return Playlist.IsEmpty() ? E_FAIL : bDuplicate ? S_FALSE : S_OK;
	}

	return AmHresultFromWin32(GetLastError());
}
コード例 #12
0
ファイル: DVBSub.cpp プロジェクト: chinajeffery/MPC-BE--1.2.3
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;
}