Example #1
0
HRESULT CNutSplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader)
{
	CheckPointer(pAsyncReader, E_POINTER);

	HRESULT hr = E_FAIL;

	m_pFile.Free();

	m_pFile.Attach(new CNutFile(pAsyncReader, hr));
	if(!m_pFile) return E_OUTOFMEMORY;
	if(FAILED(hr)) {m_pFile.Free(); return hr;}

	m_rtNewStart = m_rtCurrent = 0;
	m_rtNewStop = m_rtStop = m_rtDuration = 0;

	// pins

	POSITION pos = m_pFile->m_streams.GetHeadPosition();
	while(pos)
	{
		CNutFile::stream_header* sh = m_pFile->m_streams.GetNext(pos);

		CAtlArray<CMediaType> mts;
		CMediaType mt;

		if(sh->stream_class == CNutFile::SC_VIDEO)
		{
			CNutFile::video_stream_header& vsh = sh->vsh;

			mt.majortype = MEDIATYPE_Video;
			mt.subtype = FOURCCMap(*(DWORD*)sh->fourcc.GetData());
			mt.formattype = FORMAT_VideoInfo;

			VIDEOINFOHEADER vih;
			memset(&vih, 0, sizeof(vih));
			vih.dwBitRate = (DWORD)sh->average_bitrate;
			vih.AvgTimePerFrame = 10000000i64 * sh->time_base_nom / sh->time_base_denom;
			vih.bmiHeader.biSize = sizeof(vih.bmiHeader);
			vih.bmiHeader.biCompression = mt.subtype.Data1;
			vih.bmiHeader.biWidth = (LONG)vsh.width;
			vih.bmiHeader.biHeight = (LONG)vsh.height;
			mt.SetFormat((BYTE*)&vih, sizeof(vih));

			mts.Add(mt);

			if(vsh.sample_width && vsh.sample_height)
			{
				VIDEOINFOHEADER2 vih2;
				memset(&vih2, 0, sizeof(vih2));
				vih2.dwBitRate = vih.dwBitRate;
				vih2.AvgTimePerFrame = vih.AvgTimePerFrame;
				vih2.dwPictAspectRatioX = (DWORD)vsh.sample_width;
				vih2.dwPictAspectRatioY = (DWORD)vsh.sample_height;
				vih2.bmiHeader = vih.bmiHeader;
				mt.SetFormat((BYTE*)&vih2, sizeof(vih2));

				mts.InsertAt(0, mt);
			}
		}
		else if(sh->stream_class == CNutFile::SC_AUDIO)
		{
			CNutFile::audio_stream_header& ash = sh->ash;
			// TODO
		}
		else if(sh->stream_class == CNutFile::SC_SUBTITLE)
		{
			// TODO
		}

		if(mts.GetCount() > 0)
		{
			CAutoPtr<CBaseSplitterOutputPin> pPinOut(new CBaseSplitterOutputPin(mts, L"Video", this, this, &hr));
			AddOutputPin((DWORD)sh->stream_id, pPinOut);
		}
	}

	// TODO
	m_rtNewStop = m_rtStop = m_rtDuration = 0;

	return m_pOutputs.GetCount() > 0 ? S_OK : E_FAIL;
}