Ejemplo n.º 1
0
void CHdmvSub::EnqueuePresentationSegment(REFERENCE_TIME rt)
{
    if (m_pCurrentPresentationSegment) {
        if (m_pCurrentPresentationSegment->objectCount > 0) {
            m_pCurrentPresentationSegment->rtStop = rt;
            m_pCurrentPresentationSegment->CLUT = m_CLUTs[m_pCurrentPresentationSegment->CLUT.id];

            // Get the objects' data
            POSITION pos = m_pCurrentPresentationSegment->objects.GetHeadPosition();
            while (pos) {
                CompositionObject* pObject = m_pCurrentPresentationSegment->objects.GetNext(pos);

                CompositionObject& pObjectData = m_compositionObjects[pObject->m_object_id_ref];

                pObject->m_width = pObjectData.m_width;
                pObject->m_height = pObjectData.m_height;

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

            m_pPresentationSegments.AddTail(m_pCurrentPresentationSegment);
            TRACE_HDMVSUB( (_T("CHdmvSub: Enqueue Presentation Segment %d - %lS => %lS\n"), m_pCurrentPresentationSegment->composition_descriptor.nNumber,
                          ReftimeToCString(m_pCurrentPresentationSegment->rtStart), ReftimeToCString(m_pCurrentPresentationSegment->rtStop)) );
        } else {
            TRACE_HDMVSUB( (_T("CHdmvSub: Delete empty Presentation Segment %d\n"), m_pCurrentPresentationSegment->composition_descriptor.nNumber) );
            delete m_pCurrentPresentationSegment;
        }

        m_pCurrentPresentationSegment = NULL;
    }
}
Ejemplo n.º 2
0
void CHdmvSub::ParseObject(CGolombBuffer* pGBuffer, USHORT nUnitSize)
{
	SHORT object_id = pGBuffer->ReadShort();
	if (object_id > _countof(m_ParsedObjects)) {
		TRACE_HDMVSUB(_T("CHdmvSub::ParseObject() : FAILED, object_id = %d\n"), object_id);
		return;
	}

	CompositionObject &pObject = m_ParsedObjects[object_id];

	pObject.m_version_number	= pGBuffer->ReadByte();
	BYTE m_sequence_desc		= pGBuffer->ReadByte();

	if (m_sequence_desc & 0x80) {
		DWORD object_data_length = (DWORD)pGBuffer->BitRead(24);

		pObject.m_width		= pGBuffer->ReadShort();
		pObject.m_height	= pGBuffer->ReadShort();

		pObject.SetRLEData(pGBuffer->GetBufferPos(), nUnitSize-11, object_data_length-4);

		TRACE_HDMVSUB(_T("CHdmvSub::ParseObject() : NewObject - size = %ld, version = %d, total obj = %d, size = %dx%d\n"),
						object_data_length,
						pObject.m_version_number,
						m_pObjects.GetCount(),
						pObject.m_width, pObject.m_height);
	} else {
		pObject.AppendRLEData(pGBuffer->GetBufferPos(), nUnitSize-4);
	}
}
Ejemplo n.º 3
0
void CHdmvSub::Render(SubPicDesc& spd, REFERENCE_TIME rt, RECT& bbox)
{
    HDMV_PRESENTATION_SEGMENT* pPresentationSegment = FindPresentationSegment(rt);

    bbox.left   = LONG_MAX;
    bbox.top    = LONG_MAX;
    bbox.right  = 0;
    bbox.bottom = 0;

    if (pPresentationSegment) {
        POSITION pos = pPresentationSegment->objects.GetHeadPosition();

        TRACE_HDMVSUB(_T("CHdmvSub:Render Presentation segment %d --> %s - %s\n"), pPresentationSegment->composition_descriptor.nNumber,
                      ReftimeToString(pPresentationSegment->rtStart), ReftimeToString(pPresentationSegment->rtStop));

        while (pos) {
            CompositionObject* pObject = pPresentationSegment->objects.GetNext(pos);

            if (pObject->GetRLEDataSize() && pObject->m_width > 0 && pObject->m_height > 0
                    && spd.w >= (pObject->m_horizontal_position + pObject->m_width) && spd.h >= (pObject->m_vertical_position + pObject->m_height)) {
                pObject->SetPalette(pPresentationSegment->CLUT.size, pPresentationSegment->CLUT.palette, pPresentationSegment->video_descriptor.nVideoWidth > 720);

                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);

                TRACE_HDMVSUB(_T(" --> Object %d (Res=%dx%d, SPDRes=%dx%d)\n"), pObject->m_object_id_ref, pObject->m_width, pObject->m_height, spd.w, spd.h);
                pObject->RenderHdmv(spd);
            } else {
                TRACE_HDMVSUB(_T(" --> Invalid object %d\n"), pObject->m_object_id_ref);
            }
        }
    }
}
Ejemplo n.º 4
0
void CHdmvSub::Render(SubPicDesc& spd, REFERENCE_TIME rt, RECT& bbox)
{
    HDMV_PRESENTATION_SEGMENT* pPresentationSegment = FindPresentationSegment(rt);

    bbox.left   = LONG_MAX;
    bbox.top    = LONG_MAX;
    bbox.right  = 0;
    bbox.bottom = 0;

    if (pPresentationSegment) {
        POSITION pos = pPresentationSegment->objects.GetHeadPosition();

        TRACE_HDMVSUB( (_T("CHdmvSub:Render Presentation segment %d --> %lS - %lS\n"), pPresentationSegment->composition_descriptor.nNumber,
                      ReftimeToCString(pPresentationSegment->rtStart), ReftimeToCString(pPresentationSegment->rtStop)) );

        while (pos) {
            CompositionObject* pObject = pPresentationSegment->objects.GetNext(pos);

            if (pObject->GetRLEDataSize() && pObject->m_width > 0 && pObject->m_height > 0
                && spd.w >= (pObject->m_horizontal_position + pObject->m_width) 
                && spd.h >= (pObject->m_vertical_position + pObject->m_height)) 
            {
                CompositionObject::ColorType color_type = m_colorTypeSetting;
                if (color_type==CompositionObject::NONE)
                {
                    color_type = pPresentationSegment->video_descriptor.nVideoWidth > 720 ? 
                        CompositionObject::YUV_Rec709 : CompositionObject::YUV_Rec601;
                }
                pObject->SetPalette(pPresentationSegment->CLUT.size, pPresentationSegment->CLUT.palette, color_type, 
                    m_yuvRangeSetting==CompositionObject::RANGE_NONE ? CompositionObject::RANGE_TV : m_yuvRangeSetting);

                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);

                ASSERT(spd.h>=0);
                bbox.left = bbox.left > 0 ? bbox.left : 0;
                bbox.top = bbox.top > 0 ? bbox.top : 0;
                bbox.right = bbox.right < spd.w ? bbox.right : spd.w;
                bbox.bottom = bbox.bottom < spd.h ? bbox.bottom : spd.h;

                pObject->InitColor(spd);
                TRACE_HDMVSUB( (_T(" --> Object %d (Pos=%dx%d, Res=%dx%d, SPDRes=%dx%d)\n"),
                              pObject->m_object_id_ref, pObject->m_horizontal_position, pObject->m_vertical_position, pObject->m_width, pObject->m_height, spd.w, spd.h) );
                pObject->RenderHdmv(spd);
            } else {
                TRACE_HDMVSUB( (_T(" --> Invalid object %d\n"), pObject->m_object_id_ref) );
            }
        }
    }
}
Ejemplo n.º 5
0
int CHdmvSub::ParsePresentationSegment(CGolombBuffer* pGBuffer)
{
	COMPOSITION_DESCRIPTOR	CompositionDescriptor;
	BYTE					nObjectNumber;
	//bool					palette_update_flag;
	//BYTE					palette_id_ref;

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

	TRACE_HDMVSUB( "CHdmvSub::ParsePresentationSegment Size = %d, nObjectNumber = %d\n", pGBuffer->GetSize(), nObjectNumber);

	if (nObjectNumber > 0) {
		delete m_pCurrentObject;
		m_pCurrentObject = DNew CompositionObject();
		m_pCurrentObject->m_nObjectNumber = nObjectNumber;
		for (int i=0; i<nObjectNumber; i++) {
			ParseCompositionObject (pGBuffer, m_pCurrentObject);
		}
	}

	return nObjectNumber;
}
Ejemplo n.º 6
0
void CHdmvSub::ParseObject(CGolombBuffer* pGBuffer, USHORT nUnitSize)	// #498
{
	SHORT	object_id	= pGBuffer->ReadShort();
	UNUSED_ALWAYS(object_id);
	BYTE	m_sequence_desc;

	ASSERT (m_pCurrentObject != NULL);
	if (m_pCurrentObject) { // && m_pCurrentObject->m_object_id_ref == object_id)
		m_pCurrentObject->m_version_number	= pGBuffer->ReadByte();
		m_sequence_desc						= pGBuffer->ReadByte();

		if (m_sequence_desc & 0x80) {
			DWORD	object_data_length  = (DWORD)pGBuffer->BitRead(24);

			m_pCurrentObject->m_width			= pGBuffer->ReadShort();
			m_pCurrentObject->m_height 			= pGBuffer->ReadShort();

			m_pCurrentObject->SetRLEData (pGBuffer->GetBufferPos(), nUnitSize-11, object_data_length-4);

			TRACE_HDMVSUB ("CHdmvSub:NewObject	size=%ld, total obj=%d, %dx%d\n", object_data_length, m_pObjects.GetCount(),
						   m_pCurrentObject->m_width, m_pCurrentObject->m_height);
		} else {
			m_pCurrentObject->AppendRLEData (pGBuffer->GetBufferPos(), nUnitSize-4);
		}
	}
}
Ejemplo n.º 7
0
void CHdmvSub::RemoveOldSegments(REFERENCE_TIME rt)
{
    // Cleanup the old presentation segments. We keep a 2 min buffer to play nice with the queue.
    while (!m_pPresentationSegments.IsEmpty() && m_pPresentationSegments.GetHead()->rtStop + 120 * 10000000i64 < rt) {
        HDMV_PRESENTATION_SEGMENT* pPresentationSegment = m_pPresentationSegments.RemoveHead();
        TRACE_HDMVSUB(_T("CHdmvSub::RemoveOldSegments Remove presentation segment %d %s => %s (rt=%s)\n"),
                      pPresentationSegment->composition_descriptor.nNumber,
                      ReftimeToString(pPresentationSegment->rtStart), ReftimeToString(pPresentationSegment->rtStop), ReftimeToString(rt));
        delete pPresentationSegment;
    }
}
Ejemplo n.º 8
0
void CHdmvSub::CleanOld(REFERENCE_TIME rt)
{
	CompositionObject* pObject_old;

	while (!m_pObjects.IsEmpty()) {
		pObject_old = m_pObjects.GetHead();
		if (pObject_old->m_rtStop < rt) {
			TRACE_HDMVSUB(_T("CHdmvSub:HDMV remove object, size = %d, %s => %s, (rt = %s)\n"), pObject_old->GetRLEDataSize(),
						   ReftimeToString (pObject_old->m_rtStart), ReftimeToString(pObject_old->m_rtStop),
						   ReftimeToString(rt));
			m_pObjects.RemoveHead();
			delete pObject_old;
		} else {
			break;
		}
	}
}
Ejemplo n.º 9
0
POSITION CHdmvSub::GetStartPosition(REFERENCE_TIME rt, double fps /* = 0*/)
{
    HDMV_PRESENTATION_SEGMENT* pPresentationSegment;

    // Cleanup old PG
    while (m_pPresentationSegments.GetCount() > 0) {
        pPresentationSegment = m_pPresentationSegments.GetHead();
        if (pPresentationSegment->rtStop < rt) {
            TRACE_HDMVSUB( (_T("CHdmvSub:HDMV Remove Presentation segment %d  %lS => %lS (rt=%lS)\n"), pPresentationSegment->composition_descriptor.nNumber,
                          ReftimeToString(pPresentationSegment->rtStart), ReftimeToString(pPresentationSegment->rtStop), ReftimeToString(rt)) );
            m_pPresentationSegments.RemoveHead();
            delete pPresentationSegment;
        } else {
            break;
        }
    }
 // log first 2 objects
 //   {
 //       POSITION pos = m_pPresentationSegments.GetHeadPosition();
 //       for (int i=0;i<2 && pos!=NULL; i++)
 //       {
 //           CompositionObject*	pObject = m_pPresentationSegments.GetNext(pos);
 //           TRACE_HDMVSUB( (_T("CHdmvSub:HDMV cur %d object %d  %lS => %lS\n"), i, pObject->GetRLEDataSize(),
 //               ReftimeToCString (pObject->m_rtStart), ReftimeToCString(pObject->m_rtStop)));
 //       }
 //   }

    POSITION	pos = m_pPresentationSegments.GetHeadPosition();

    while (pos) {
        HDMV_PRESENTATION_SEGMENT* pPresentationSegment = m_pPresentationSegments.GetAt (pos);

        if (rt >= pPresentationSegment->rtStart && rt < pPresentationSegment->rtStop) {
            break;
        }
        else if( rt < pPresentationSegment->rtStart )
        {
            pos = NULL;
            break;
        }

        m_pPresentationSegments.GetNext(pos);
    }
    return pos;
}
Ejemplo n.º 10
0
POSITION CHdmvSub::GetStartPosition(REFERENCE_TIME rt, double fps)
{
	CompositionObject*	pObject;

	// Cleanup old PG
	while (m_pObjects.GetCount()>0) {
		pObject = m_pObjects.GetHead();
		if (pObject->m_rtStop < rt) {
			TRACE_HDMVSUB ("CHdmvSub:HDMV remove object %d  %S => %S (rt=%S)\n", pObject->GetRLEDataSize(),
						   ReftimeToString (pObject->m_rtStart), ReftimeToString(pObject->m_rtStop), ReftimeToString(rt));
			m_pObjects.RemoveHead();
			delete pObject;
		} else {
			break;
		}
	}

	return m_pObjects.GetHeadPosition();
}
Ejemplo n.º 11
0
POSITION CHdmvSub::GetStartPosition(REFERENCE_TIME rt, double fps)
{
    HDMV_PRESENTATION_SEGMENT* pPresentationSegment;

    // Cleanup old PG
    while (m_pPresentationSegments.GetCount() > 0) {
        pPresentationSegment = m_pPresentationSegments.GetHead();
        if (pPresentationSegment->rtStop < rt) {
            TRACE_HDMVSUB(_T("CHdmvSub:HDMV Remove Presentation segment %d  %s => %s (rt=%s)\n"), pPresentationSegment->composition_descriptor.nNumber,
                          ReftimeToString(pPresentationSegment->rtStart), ReftimeToString(pPresentationSegment->rtStop), ReftimeToString(rt));
            m_pPresentationSegments.RemoveHead();
            delete pPresentationSegment;
        } else {
            break;
        }
    }

    return m_pPresentationSegments.GetHeadPosition();
}
Ejemplo n.º 12
0
void CHdmvSub::Render(SubPicDesc& spd, REFERENCE_TIME rt, RECT& bbox)
{
	CompositionObject*	pObject = FindObject (rt);

	ASSERT (pObject!=NULL && spd.w >= pObject->m_width && spd.h >= pObject->m_height);

	if (pObject && spd.w >= pObject->m_width && spd.h >= pObject->m_height) {
		if (!pObject->HavePalette()) {
			pObject->SetPalette (m_nDefaultPaletteNbEntry, m_pDefaultPalette, m_VideoDescriptor.nVideoWidth>720);
		}

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

		bbox.left	= 0;
		bbox.top	= 0;
		bbox.right	= bbox.left + pObject->m_width;
		bbox.bottom	= bbox.top  + pObject->m_height;
	}
}
Ejemplo n.º 13
0
void CHdmvSub::ParseCompositionObject(CGolombBuffer* pGBuffer, CompositionObject* pCompositionObject)
{
	pCompositionObject->m_object_id_ref			= pGBuffer->ReadShort();
	pCompositionObject->m_window_id_ref			= (SHORT)pGBuffer->ReadByte();
	BYTE bTemp									= pGBuffer->ReadByte();
	pCompositionObject->m_object_cropped_flag	= !!(bTemp & 0x80);
	pCompositionObject->m_forced_on_flag		= !!(bTemp & 0x40);
	pCompositionObject->m_horizontal_position	= pGBuffer->ReadShort();
	pCompositionObject->m_vertical_position		= pGBuffer->ReadShort();

	if (pCompositionObject->m_object_cropped_flag) {
		pCompositionObject->m_cropping_horizontal_position	= pGBuffer->ReadShort();
		pCompositionObject->m_cropping_vertical_position	= pGBuffer->ReadShort();
		pCompositionObject->m_cropping_width				= pGBuffer->ReadShort();
		pCompositionObject->m_cropping_height				= pGBuffer->ReadShort();
	}

	TRACE_HDMVSUB(_T("CHdmvSub::ParseCompositionObject() : m_object_id_ref = %d, m_window_id_ref = %d, pos = %d:%d\n"),
					pCompositionObject->m_object_id_ref, pCompositionObject->m_window_id_ref,
					pCompositionObject->m_horizontal_position, pCompositionObject->m_vertical_position);
}
Ejemplo n.º 14
0
void CHdmvSub::ParseObject(CGolombBuffer* pGBuffer, unsigned short nUnitSize)   // #498
{
    short object_id = pGBuffer->ReadShort();
    ASSERT(object_id < _countof(m_compositionObjects));

    CompositionObject& pObject = m_compositionObjects[object_id];

    pObject.m_version_number = pGBuffer->ReadByte();
    BYTE m_sequence_desc = pGBuffer->ReadByte();

    if (m_sequence_desc & 0x80) {
        DWORD object_data_length  = (DWORD)pGBuffer->BitRead(24);

        pObject.m_width = pGBuffer->ReadShort();
        pObject.m_height = pGBuffer->ReadShort();

        pObject.SetRLEData(pGBuffer->GetBufferPos(), nUnitSize - 11, object_data_length - 4);

        TRACE_HDMVSUB( (_T("CHdmvSub:ParseObject %d (size=%ld, %dx%d)\n"), object_id, object_data_length, pObject.m_width, pObject.m_height) );
    } else {
        pObject.AppendRLEData(pGBuffer->GetBufferPos(), nUnitSize - 4);
    }
}
Ejemplo n.º 15
0
int CHdmvSub::ParsePresentationSegment(REFERENCE_TIME rt, CGolombBuffer* pGBuffer)
{
    m_pCurrentPresentationSegment = DEBUG_NEW HDMV_PRESENTATION_SEGMENT();

    m_pCurrentPresentationSegment->rtStart = rt;
    m_pCurrentPresentationSegment->rtStop  = _I64_MAX;

    ParseVideoDescriptor(pGBuffer, &m_pCurrentPresentationSegment->video_descriptor);
    ParseCompositionDescriptor(pGBuffer, &m_pCurrentPresentationSegment->composition_descriptor);
    m_pCurrentPresentationSegment->palette_update_flag = !!(pGBuffer->ReadByte() & 0x80);
    m_pCurrentPresentationSegment->CLUT.id = pGBuffer->ReadByte();
    m_pCurrentPresentationSegment->objectCount = pGBuffer->ReadByte();

    TRACE_HDMVSUB( (_T("CHdmvSub::ParsePresentationSegment Size = %d, state = %#x, nObjectNumber = %d\n"), pGBuffer->GetSize(),
                  m_pCurrentPresentationSegment->composition_descriptor.bState, m_pCurrentPresentationSegment->objectCount) );

    for (int i = 0; i < m_pCurrentPresentationSegment->objectCount; i++) {
        CompositionObject* pCompositionObject = DEBUG_NEW CompositionObject();
        ParseCompositionObject(pGBuffer, pCompositionObject);
        m_pCurrentPresentationSegment->objects.AddTail(pCompositionObject);
    }

    return m_pCurrentPresentationSegment->objectCount;
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
0
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;
}
Ejemplo n.º 18
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;
}
Ejemplo n.º 19
0
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);
}
Ejemplo n.º 20
0
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]);
		}
	}
}