예제 #1
0
//----------------------------------------------------------------------------
//! @brief	  	レンダリング前にコールされる
//!
//! メディアサンプルにメディアタイムを記録する。
//! メディアタイムは開始フレームに現在のストリーム時間を加算したものになる。
//! もし、フィルタのIMediaSeekingインターフェイスが利用できない場合は、
//! このレンダーフィルタが描画したフレーム数とドロップしたフレーム数を加算する。
//! この場合、より上位のフィルタでドロップしたフレーム数はわからないので、
//! 若干精度が落ちる。
//! @param		pMediaSample : メディアサンプル
//----------------------------------------------------------------------------
void TBufferRenderer::OnRenderStart( IMediaSample *pMediaSample )
{
	CBaseVideoRenderer::OnRenderStart(pMediaSample);

	HRESULT		hr;
	bool		bGetTime = false;
	LONGLONG	Current = 0, Stop = 0;
	IMediaSeeking	*mediaSeeking = NULL;
	if( GetMediaPositionInterface( IID_IMediaSeeking, (void**)&mediaSeeking) == S_OK )
	{
		GUID	Format;
		if( SUCCEEDED(hr = mediaSeeking->GetTimeFormat( &Format ) ) )
		{
			if( SUCCEEDED(hr = mediaSeeking->GetCurrentPosition( &Current )) &&
				SUCCEEDED(hr = mediaSeeking->GetStopPosition( &Stop )) )
			{
				if( IsEqualGUID( TIME_FORMAT_MEDIA_TIME, Format ) )
				{
					double	renderTime = Current / 10000000.0;
					double	stopTime = Stop / 10000000.0;
					REFTIME	AvgTimePerFrame;	// REFTIME :  秒数を示す小数を表す倍精度浮動小数点数。
					if( SUCCEEDED( hr = get_AvgTimePerFrame( &AvgTimePerFrame ) ) )
					{
						Current = (LONGLONG)(renderTime / AvgTimePerFrame + 0.5);
						Stop = (LONGLONG)(stopTime / AvgTimePerFrame + 0.5);
						bGetTime = true;
					}
				}
				else if( IsEqualGUID( TIME_FORMAT_FRAME, Format ) )
				{
					bGetTime = true;
				}
			}
		}
		mediaSeeking->Release();
		mediaSeeking = NULL;
	}
	LONGLONG	TimeStart = m_StartFrame + m_cFramesDrawn + m_cFramesDropped;;
	LONGLONG	TimeEnd = m_StartFrame + m_cFramesDrawn + m_cFramesDropped;;
	if( bGetTime == true )
	{
		TimeStart = m_StartFrame + Current;
		TimeEnd = m_StartFrame + Current;
		m_StopFrame = m_StartFrame + static_cast<LONG>(Stop);
	}
	else
	{
		TimeStart = m_StartFrame + m_cFramesDrawn + m_cFramesDropped;;
		TimeEnd = m_StartFrame + m_cFramesDrawn + m_cFramesDropped;;
		m_StopFrame = 0;
	}
	pMediaSample->SetMediaTime( &TimeStart, &TimeEnd );
}
예제 #2
0
long video_get_seek(int id) {
	get_videor(videoStruct, id, -1);
	IMediaSeeking* pSeek;
	HRESULT hr = videoStruct->pGraph->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);
	DWORD dwCap = 0;
	hr = pSeek->GetCapabilities(&dwCap);
	
	long long position = 0;
	if (AM_SEEKING_CanSeekAbsolute & dwCap)
	{
		hr = pSeek->GetCurrentPosition(&position);
	}

	pSeek->Release();
	
	return position;
}
예제 #3
0
int main(int argc, char* argv[])
{
    ICaptureGraphBuilder2   *pCaptureGraphBuilder = NULL;
    IGraphBuilder           *pGraphBuilder = NULL;
    IBaseFilter             *pSource = NULL;
    IBaseFilter             *pMux = NULL;
    IBaseFilter             *pVideoCompressor = NULL;
    IBaseFilter             *pAudioCompressor = NULL;

    IAMStreamConfig         *pAMStreamConfig = NULL;
    IAMVideoCompression     *pAMVideoCompression = NULL;

    IMediaControl           *pControl = NULL;
    IMediaSeeking           *pSeek = NULL;
    IMediaEvent             *pEvent = NULL;

    HRESULT hr;

    DWORD pdwRegister=0;
    CoInitialize(NULL);

    // Create the capture graph builder.
    CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
                     IID_ICaptureGraphBuilder2, (void **)&pCaptureGraphBuilder);

    // Make the rendering section of the graph.
    pCaptureGraphBuilder->SetOutputFileName(
        &MEDIASUBTYPE_Avi,  // File type.
        L"C:\\STDIUE1.avi",  // File name.
        &pMux,              // pointer to the multiplexer.
        NULL);              // pointer to the file writer.

    // Load the source file.
    pCaptureGraphBuilder->GetFiltergraph(&pGraphBuilder);
    pGraphBuilder->AddSourceFilter(L"C:\\Program Files\\Microsoft Money\\Media\\STDIUE1.avi", L"Source Filter", &pSource);

    // Add the compressor filter.
    CoCreateInstance(CLSID_AVICo, NULL, CLSCTX_INPROC,
                     IID_IBaseFilter, (void **)&pVideoCompressor);
    pGraphBuilder->AddFilter(pVideoCompressor, L"Video Compressor");

    // Render the video stream, through the compressor.
    pCaptureGraphBuilder->RenderStream(
        NULL,       // Output pin category
        NULL,       // Media type
        pSource,       // Source filter
        pVideoCompressor,     // Compressor filter
        pMux);      // Sink filter (the AVI Mux)

    /* CoCreateInstance(CLSID_GSM, NULL, CLSCTX_INPROC,
             IID_IBaseFilter, (void **)&pAudioCompressor);
     pGraphBuilder->AddFilter(pAudioCompressor, L"Audio Compressor");*/

    // Render the audio stream.
    pCaptureGraphBuilder->RenderStream(
        NULL,
        NULL,
        pSource,
        pAudioCompressor,
        pMux);

    // Compress at 100k/second data rate.
    AM_MEDIA_TYPE *pmt;
    pCaptureGraphBuilder->FindInterface(NULL, NULL, pVideoCompressor, IID_IAMStreamConfig, (void **)&pAMStreamConfig);

    pAMStreamConfig->GetFormat(&pmt);

    if (pmt->formattype == FORMAT_VideoInfo)
    {

        ((VIDEOINFOHEADER *)(pmt->pbFormat))->dwBitRate = 100000;

        pAMStreamConfig->SetFormat(pmt);
    }


    // Request key frames every four frames.
    pAMStreamConfig->QueryInterface(IID_IAMVideoCompression, (void **)&pAMVideoCompression);
    pAMVideoCompression->put_KeyFrameRate(4);
    pAMVideoCompression->Release();
    pAMStreamConfig->Release();

    // Run the graph.

    pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&pControl);
    pGraphBuilder->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

    hr = pMux->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);


    pControl->Run();
    printf("Recompressing... \n");

    long evCode;
    if (SUCCEEDED(hr))
    {
        REFERENCE_TIME rtTotal, rtNow = 0;
        pSeek->GetDuration(&rtTotal);
        while ((pEvent->WaitForCompletion(1000, &evCode)) == E_ABORT)
        {
            pSeek->GetCurrentPosition(&rtNow);
            printf("%d%%\n", (rtNow * 100)/rtTotal);
        }
        pSeek->Release();
    }
    else  // Cannot update the progress.
    {
        pEvent->WaitForCompletion(INFINITE, &evCode);
    }
    pControl->Stop();
    printf("All done\n");

    pSource->Release();
    pMux->Release();
    pVideoCompressor->Release();
    pAudioCompressor->Release ();
    pControl->Release();
    pEvent->Release();
    pCaptureGraphBuilder->Release();
    pGraphBuilder->Release();
    CoUninitialize();

    return 0;
}
예제 #4
0
STDMETHODIMP CTsReaderFilter::Pause()
{
  //m_ShowBufferVideo = INIT_SHOWBUFFERVIDEO;
  //m_ShowBufferAudio = INIT_SHOWBUFFERAUDIO;

  LogDebug("CTsReaderFilter::Pause() - IsTimeShifting = %d - state = %d", IsTimeShifting(), m_State);
  CAutoLock cObjectLock(m_pLock);

  if (m_State == State_Running)
  {
    m_lastPause = GetTickCount();
    m_RandomCompensation = 0;
  }

  //pause filter
  HRESULT hr=CSource::Pause();

  if (!m_bPauseOnClockTooFast)
  {
    //are we using rtsp?
    if (m_fileDuration==NULL)
    {
    //yes, are we busy seeking?
    if (!IsSeeking())
    {
      //not seeking, is rtsp streaming at the moment?
      if (!m_rtspClient.IsRunning())
      {
        //not streaming atm
        double startTime=m_seekTime.Millisecs();
        startTime/=1000.0;

        long Old_rtspDuration = m_rtspClient.Duration() ;
        //clear buffers
        LogDebug("  -- Pause()  ->start rtsp from %f", startTime);
        m_buffer.Clear();
        m_demultiplexer.Flush();

        //start streaming
        m_buffer.Run(true);
        m_rtspClient.Play(startTime,0.0);
//        m_tickCount = GetTickCount();
        LogDebug("  -- Pause()  ->rtsp started");

        //update the duration of the stream
        CPcr pcrStart, pcrEnd, pcrMax ;
        double duration = m_rtspClient.Duration() / 1000.0f ;

        if (m_bTimeShifting)
        {
          // EndPcr is continuously increasing ( until ~26 hours for rollover that will fail ! )
          // So, we refer duration to End, and just update start.
          pcrEnd   = m_duration.EndPcr() ;
          double start  = pcrEnd.ToClock() - duration;
	        if (start<0) start=0 ;
          pcrStart.FromClock(start) ;
          m_duration.Set( pcrStart, pcrEnd, pcrMax) ;     // Pause()-RTSP
        }
        else
        {
          // It's a record, eventually end can increase if recording is in progress, let the end virtually updated by ThreadProc()
          //m_bRecording = (Old_rtspDuration != m_rtspClient.Duration()) ;
          m_bRecording = true; // duration may have not increased in such a short time
        }
        LogDebug("Timeshift %d, Recording %d, StartPCR %f, EndPcr %f, Duration %f",m_bTimeShifting,m_bRecording,m_duration.StartPcr().ToClock(),m_duration.EndPcr().ToClock(),(float)m_duration.Duration().Millisecs()/1000.0f) ;
      }
      else
      {
        //we are streaming at the moment.
       
        //query the current position, so it can resume on un-pause at this position
        //can be required in multiseat with rtsp when changing audio streams 
        IMediaSeeking * ptrMediaPos;
        if (SUCCEEDED(GetFilterGraph()->QueryInterface(IID_IMediaSeeking, (void**)&ptrMediaPos)))
        {
          ptrMediaPos->GetCurrentPosition(&m_seekTime.m_time);
          ptrMediaPos->Release();
        }
        //pause the streaming
        LogDebug("  -- Pause()  ->pause rtsp at position: %f", (m_seekTime.Millisecs() / 1000.0f));
        m_rtspClient.Pause();
      }
    }
    else //we are seeking
    {
      IMediaSeeking * ptrMediaPos;

      if (SUCCEEDED(GetFilterGraph()->QueryInterface(IID_IMediaSeeking, (void**)&ptrMediaPos)))
      {
        LONGLONG currentPos;
        ptrMediaPos->GetCurrentPosition(&currentPos);
        ptrMediaPos->Release();
        double clock = currentPos;clock /= 10000000.0;
        float clockEnd = m_duration.EndPcr().ToClock() ;
        if (clock >= clockEnd && clockEnd > 0 )
        {
          LogDebug("End of rtsp stream...");
          m_demultiplexer.SetEndOfFile(true);
        }
      }
    }
    }
    m_demultiplexer.m_LastDataFromRtsp = GetTickCount() ;
  }

  //is the duration update thread running?
  if (!IsThreadRunning())
  {
    //nop? then start it
    //LogDebug("  CTsReaderFilter::Pause()->start duration thread");
    StartThread();
  }

  LogDebug("CTsReaderFilter::Pause() - END - state = %d", m_State);
  return hr;
}
예제 #5
0
void 
recChannel_t::posReaderThread(void)
{
    __int64 position = 0;
    __int64 duration = 0;

    Sleep(1000);
    while (!fControl)
    {
        Sleep(1000);
    }

    fControl->slideMoved = true;

    IMediaSeeking * pSeek = NULL;
    while(true)
    {
        int hr = pGraph->QueryInterface(IID_IMediaSeeking,(void **)&pSeek);
        //read file pos and put at slicer 
        if (pSeek && hr == S_OK)
        {
            if (!fControl->play & fControl->event)
            {
                pControl->StopWhenReady();
                fControl->event = false;
                continue;
            }

            if (fControl->play & fControl->event)
            {
                pControl->Run();
                fControl->event = false;
            }
                
            if (fControl->slideMoved)
            {
                position = fControl->m_slide.GetPos();
                position *=1000000;
                fControl->slideMoved = false;
                pSeek->SetPositions(&position,
                                     AM_SEEKING_AbsolutePositioning,
                                     NULL,
                                     AM_SEEKING_NoPositioning);
            }else{

                if (!duration)
                {
                    pSeek->GetDuration(&duration);
                    duration /= 1000000;
                    fControl->m_slide.SetRangeMin(0,true);
                    fControl->m_slide.SetRangeMax(duration,true);
                }
                pSeek->GetCurrentPosition(&position);
                position /= 1000000;
                fControl->m_slide.SetPos(position);
            }
        }
        pSeek->Release();
        Sleep(1000);
    }
}