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); } } }
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(" ", " "); str.Replace(" ", " "); 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()); }
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); } }
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); } }
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); } } } }