Exemple #1
0
void CDSMMuxerFilter::MuxStreamInfo(IBitStream* pBS, CBaseMuxerInputPin* pPin)
{
	int len = 1;
	CSimpleMap<CStringA, CStringA> si;

	for(int i = 0; i < pPin->GetSize(); i++)
	{
		CStringA key = CStringA(CString(pPin->GetKeyAt(i))), value = UTF16To8(pPin->GetValueAt(i));
		if(key.GetLength() != 4) continue;
		si.Add(key, value);
		len += 4 + value.GetLength() + 1;
	}

	if(len > 1)
	{
		MuxPacketHeader(pBS, DSMP_STREAMINFO, len);
		pBS->BitWrite(pPin->GetID(), 8);
		for(int i = 0; i < si.GetSize(); i++)
		{
			CStringA key = si.GetKeyAt(i), value = si.GetValueAt(i);
			pBS->ByteWrite((LPCSTR)key, 4);
			pBS->ByteWrite((LPCSTR)value, value.GetLength()+1);
		}
	}
}
Exemple #2
0
void CDSMMuxerFilter::MuxPacket(IBitStream* pBS, const MuxerPacket* pPacket)
{
    if (pPacket->IsEOS()) {
        return;
    }

    if (pPacket->pPin->CurrentMediaType().majortype == MEDIATYPE_Text) {
        CStringA str((char*)pPacket->pData.GetData(), (int)pPacket->pData.GetCount());
        str.Replace("\xff", " ");
        str.Replace("&nbsp;", " ");
        str.Replace("&nbsp", " ");
        str.Trim();
        if (str.IsEmpty()) {
            return;
        }
    }

    ASSERT(!pPacket->IsSyncPoint() || pPacket->IsTimeValid());

    REFERENCE_TIME rtTimeStamp = _I64_MIN, rtDuration = 0;
    int iTimeStamp = 0, iDuration = 0;

    if (pPacket->IsTimeValid()) {
        rtTimeStamp = pPacket->rtStart;
        rtDuration = max(pPacket->rtStop - pPacket->rtStart, 0);

        iTimeStamp = GetByteLength(myabs(rtTimeStamp));
        ASSERT(iTimeStamp <= 7);

        iDuration = GetByteLength(rtDuration);
        ASSERT(iDuration <= 7);

        IndexSyncPoint(pPacket, pBS->GetPos());
    }

    UINT64 len = 2 + iTimeStamp + iDuration + pPacket->pData.GetCount(); // id + flags + data

    MuxPacketHeader(pBS, DSMP_SAMPLE, len);
    pBS->BitWrite(pPacket->pPin->GetID(), 8);
    pBS->BitWrite(pPacket->IsSyncPoint(), 1);
    pBS->BitWrite(rtTimeStamp < 0, 1);
    pBS->BitWrite(iTimeStamp, 3);
    pBS->BitWrite(iDuration, 3);
    pBS->BitWrite(myabs(rtTimeStamp), iTimeStamp << 3);
    pBS->BitWrite(rtDuration, iDuration << 3);
    pBS->ByteWrite(pPacket->pData.GetData(), (int)pPacket->pData.GetCount());
}
Exemple #3
0
void CDSMMuxerFilter::MuxFooter(IBitStream* pBS)
{
    // syncpoints

    int len = 0;
    CAtlList<IndexedSyncPoint> isps;
    REFERENCE_TIME rtPrev = 0, rt;
    UINT64 fpPrev = 0, fp;

    POSITION pos = m_isps.GetHeadPosition();
    while (pos) {
        IndexedSyncPoint& isp = m_isps.GetNext(pos);
        TRACE(_T("sp[%d]: %I64d %I64x\n"), isp.id, isp.rt, isp.fp);

        rt = isp.rt - rtPrev;
        rtPrev = isp.rt;
        fp = isp.fp - fpPrev;
        fpPrev = isp.fp;

        IndexedSyncPoint isp2;
        isp2.fp = fp;
        isp2.rt = rt;
        isps.AddTail(isp2);

        len += 1 + GetByteLength(myabs(rt)) + GetByteLength(fp); // flags + rt + fp
    }

    MuxPacketHeader(pBS, DSMP_SYNCPOINTS, len);

    pos = isps.GetHeadPosition();
    while (pos) {
        IndexedSyncPoint& isp = isps.GetNext(pos);

        int irt = GetByteLength(myabs(isp.rt));
        int ifp = GetByteLength(isp.fp);

        pBS->BitWrite(isp.rt < 0, 1);
        pBS->BitWrite(irt, 3);
        pBS->BitWrite(ifp, 3);
        pBS->BitWrite(0, 1); // reserved
        pBS->BitWrite(myabs(isp.rt), irt << 3);
        pBS->BitWrite(isp.fp, ifp << 3);
    }
}
Exemple #4
0
void CDSMMuxerFilter::MuxFileInfo(IBitStream* pBS)
{
    int len = 1;
    CSimpleMap<CStringA, CStringA> si;

    for (int i = 0; i < GetSize(); i++) {
        CStringA key = CStringA(CString(GetKeyAt(i))), value = UTF16To8(GetValueAt(i));
        if (key.GetLength() != 4) {
            continue;
        }
        si.Add(key, value);
        len += 4 + value.GetLength() + 1;
    }

    MuxPacketHeader(pBS, DSMP_FILEINFO, len);
    pBS->BitWrite(DSMF_VERSION, 8);
    for (int i = 0; i < si.GetSize(); i++) {
        CStringA key = si.GetKeyAt(i), value = si.GetValueAt(i);
        pBS->ByteWrite((LPCSTR)key, 4);
        pBS->ByteWrite((LPCSTR)value, value.GetLength() + 1);
    }

}
Exemple #5
0
void CDSMMuxerFilter::MuxHeader(IBitStream* pBS)
{
    CString muxer;
    muxer.Format(_T("DSM Muxer (%s)"), CString(__TIMESTAMP__));

    SetProperty(L"MUXR", CStringW(muxer));
    SetProperty(L"DATE", CStringW(CTime::GetCurrentTime().FormatGmt(_T("%Y-%m-%d %H:%M:%S"))));

    MuxFileInfo(pBS);

    POSITION pos = m_pPins.GetHeadPosition();
    while (pos) {
        CBaseMuxerInputPin* pPin = m_pPins.GetNext(pos);
        const CMediaType& mt = pPin->CurrentMediaType();

        ASSERT((mt.lSampleSize >> 30) == 0); // you don't need >1GB samples, do you?

        MuxPacketHeader(pBS, DSMP_MEDIATYPE, 5 + sizeof(GUID) * 3 + mt.FormatLength());
        pBS->BitWrite(pPin->GetID(), 8);
        pBS->ByteWrite(&mt.majortype, sizeof(mt.majortype));
        pBS->ByteWrite(&mt.subtype, sizeof(mt.subtype));
        pBS->BitWrite(mt.bFixedSizeSamples, 1);
        pBS->BitWrite(mt.bTemporalCompression, 1);
        pBS->BitWrite(mt.lSampleSize, 30);
        pBS->ByteWrite(&mt.formattype, sizeof(mt.formattype));
        pBS->ByteWrite(mt.Format(), mt.FormatLength());

        MuxStreamInfo(pBS, pPin);
    }

    // resources & chapters

    CInterfaceList<IDSMResourceBag> pRBs;
    pRBs.AddTail(this);

    CComQIPtr<IDSMChapterBag> pCB = (IUnknown*)(INonDelegatingUnknown*)this;

    pos = m_pPins.GetHeadPosition();
    while (pos) {
        for (CComPtr<IPin> pPin = m_pPins.GetNext(pos)->GetConnected(); pPin; pPin = GetUpStreamPin(GetFilterFromPin(pPin))) {
            if (m_fAutoRes) {
                CComQIPtr<IDSMResourceBag> pPB = GetFilterFromPin(pPin);
                if (pPB && !pRBs.Find(pPB)) {
                    pRBs.AddTail(pPB);
                }
            }

            if (m_fAutoChap) {
                if (!pCB || pCB->ChapGetCount() == 0) {
                    pCB = GetFilterFromPin(pPin);
                }
            }
        }
    }

    // resources

    pos = pRBs.GetHeadPosition();
    while (pos) {
        IDSMResourceBag* pRB = pRBs.GetNext(pos);

        for (DWORD i = 0, j = pRB->ResGetCount(); i < j; i++) {
            CComBSTR name, desc, mime;
            BYTE* pData = NULL;
            DWORD len = 0;
            if (SUCCEEDED(pRB->ResGet(i, &name, &desc, &mime, &pData, &len, NULL))) {
                CStringA utf8_name = UTF16To8(name);
                CStringA utf8_desc = UTF16To8(desc);
                CStringA utf8_mime = UTF16To8(mime);

                MuxPacketHeader(pBS, DSMP_RESOURCE,
                                1 +
                                utf8_name.GetLength() + 1 +
                                utf8_desc.GetLength() + 1 +
                                utf8_mime.GetLength() + 1 +
                                len);

                pBS->BitWrite(0, 2);
                pBS->BitWrite(0, 6); // reserved
                pBS->ByteWrite(utf8_name, utf8_name.GetLength() + 1);
                pBS->ByteWrite(utf8_desc, utf8_desc.GetLength() + 1);
                pBS->ByteWrite(utf8_mime, utf8_mime.GetLength() + 1);
                pBS->ByteWrite(pData, len);

                CoTaskMemFree(pData);
            }
        }
    }

    // chapters

    if (pCB) {
        CAtlList<CDSMChapter> chapters;
        REFERENCE_TIME rtPrev = 0;
        int len = 0;

        pCB->ChapSort();

        for (DWORD i = 0; i < pCB->ChapGetCount(); i++) {
            CDSMChapter c;
            CComBSTR name;
            if (SUCCEEDED(pCB->ChapGet(i, &c.rt, &name))) {
                REFERENCE_TIME rtDiff = c.rt - rtPrev;
                rtPrev = c.rt;
                c.rt = rtDiff;
                c.name = name;
                len += 1 + GetByteLength(myabs(c.rt)) + UTF16To8(c.name).GetLength() + 1;
                chapters.AddTail(c);
            }
        }

        if (chapters.GetCount()) {
            MuxPacketHeader(pBS, DSMP_CHAPTERS, len);

            pos = chapters.GetHeadPosition();
            while (pos) {
                CDSMChapter& c = chapters.GetNext(pos);
                CStringA name = UTF16To8(c.name);
                int irt = GetByteLength(myabs(c.rt));
                pBS->BitWrite(c.rt < 0, 1);
                pBS->BitWrite(irt, 3);
                pBS->BitWrite(0, 4);
                pBS->BitWrite(myabs(c.rt), irt << 3);
                pBS->ByteWrite((LPCSTR)name, name.GetLength() + 1);
            }
        }
    }
}