Пример #1
0
HRESULT CTSParserOutputPin::SendOut( DWORD nGroupFlag, const BYTE* pData, DWORD dwBytes, DWORD* dwUsedBytes )
{
    IMediaSample *pSample;
    BYTE *pSampleData;
    DWORD cbData;
	*dwUsedBytes = 0;

    HRESULT hr = GetDeliveryBuffer(&pSample,NULL,NULL,0);
    if (FAILED(hr)) 
        return E_FAIL;

    pSample->GetPointer(&pSampleData);
    cbData = pSample->GetSize();
	if ( cbData < dwBytes )
	{
		dwBytes = cbData;
		ASSERT( 0 );
	}

	memcpy( pSampleData, pData, dwBytes );
	pSample->SetActualDataLength( dwBytes );
	*dwUsedBytes = dwBytes;

	hr = Deliver(pSample);
    pSample->Release();

	return S_OK;
}
Пример #2
0
HRESULT
CPullPin::QueueSample(
    __inout REFERENCE_TIME& tCurrent,
    REFERENCE_TIME tAlignStop,
    BOOL bDiscontinuity
    )
{
    IMediaSample* pSample;

    HRESULT hr = m_pAlloc->GetBuffer(&pSample, NULL, NULL, 0);
    if (FAILED(hr)) {
	return hr;
    }

    LONGLONG tStopThis = tCurrent + (pSample->GetSize() * UNITS);
    if (tStopThis > tAlignStop) {
	tStopThis = tAlignStop;
    }
    pSample->SetTime(&tCurrent, &tStopThis);
    tCurrent = tStopThis;

    pSample->SetDiscontinuity(bDiscontinuity);

    hr = m_pReader->Request(
			pSample,
			0);
    if (FAILED(hr)) {
	pSample->Release();

	CleanupCancelled();
	OnError(hr);
    }
    return hr;
}
Пример #3
0
HRESULT OutputPin::Push(void *buf, long size)
{
    HRESULT hr;
    IMediaSample *pSample;
    VIDEOINFOHEADER *vi;
    AM_MEDIA_TYPE *pmt;
    BYTE *dst_buf;

    /**
     * Hold the critical section here as the pin might get disconnected
     * during the Deliver() method call.
     */
    m_pLock->Lock();

    hr = GetDeliveryBuffer(&pSample, NULL, NULL, 0);
    if (FAILED(hr))
        goto on_error;

    pSample->GetMediaType(&pmt);
    if (pmt) {
        mediaType.Set(*pmt);
        bufSize = pmt->lSampleSize;
    }

    pSample->GetPointer(&dst_buf);
    vi = (VIDEOINFOHEADER *)mediaType.pbFormat;
    if (vi->rcSource.right == vi->bmiHeader.biWidth) {
        assert(pSample->GetSize() >= size);
        memcpy(dst_buf, buf, size);
    } else {
        unsigned i, bpp;
        unsigned dststride, srcstride;
        BYTE *src_buf = (BYTE *)buf;

        bpp = size / abs(vi->bmiHeader.biHeight) / vi->rcSource.right;
        dststride = vi->bmiHeader.biWidth * bpp;
        srcstride = vi->rcSource.right * bpp;
        for (i = abs(vi->bmiHeader.biHeight); i > 0; i--) {
            memcpy(dst_buf, src_buf, srcstride);
            dst_buf += dststride;
            src_buf += srcstride;
        }
    }
    pSample->SetActualDataLength(size);

    hr = Deliver(pSample);

    pSample->Release();

on_error:
    m_pLock->Unlock();
    return hr;
}
Пример #4
0
int StreamOutputPin::WritePackets(void * opaque, uint8_t * buf, int buf_size)
{
	HRESULT hr = S_OK;
	BYTE * pBuffer = NULL;
	IMediaSample * pSample = NULL;

	StreamOutputPin * pThis = (StreamOutputPin *)opaque;
	REFERENCE_TIME newOffset = pThis->m_offset;

	hr = pThis->GetDeliveryBuffer(&pSample, NULL, NULL, 0);
	if (hr != S_OK)
	{
		//Pokusi sa zapisat buffer cez IStream - allocator je dealokovany
		if (pThis->m_stream)
		{
			ULONG written;
			LARGE_INTEGER move;
			move.QuadPart = pThis->m_offset;

			CHECK_HR(hr = pThis->m_stream->Seek(move, STREAM_SEEK_SET, NULL));
			CHECK_HR(hr = pThis->m_stream->Write(buf, buf_size, &written));

			pThis->m_offset += written;
		}

		goto done;
	}

	buf_size = min(pSample->GetSize(), buf_size);
	newOffset += buf_size;
	
	CHECK_HR(hr = pSample->GetPointer(&pBuffer));

	//Pozor ak sa velkost nezhoduje
	memcpy(pBuffer, buf, buf_size);

	CHECK_HR(hr = pSample->SetActualDataLength(buf_size));
	CHECK_HR(hr = pSample->SetTime(&pThis->m_offset, &newOffset));

	pThis->m_offset = newOffset;

	CHECK_HR(hr = pThis->Deliver(pSample));

done:
	SAFE_RELEASE(pSample);

	return buf_size;
}
Пример #5
0
HRESULT CAMROutputPin::DeliverDataPacketAMR(DataPacketAMR &packet)
{
	IMediaSample *sample;
	HRESULT hr = GetDeliveryBuffer(&sample, NULL, NULL, 0);
	if (FAILED(hr)) {
		return E_FAIL;
	}

	// we should have enough space in there
	long lsize = sample->GetSize();
	ASSERT(lsize >= packet.size);

	BYTE *buf;
	sample->GetPointer(&buf);

	memcpy(buf, packet.buf, packet.size);
	sample->SetActualDataLength(packet.size);

	// sync point, discontinuity ?
	if (packet.sync_point) {
		sample->SetSyncPoint(TRUE);
	} else {
		sample->SetSyncPoint(FALSE);
	}

	if (packet.discontinuity) { 
		sample->SetDiscontinuity(TRUE); 
	} else { 
		sample->SetDiscontinuity(FALSE); 
	}

	// do we have a time stamp ?
	if (packet.has_time) { 
		sample->SetTime(&packet.rtStart, &packet.rtStop); 
	}

	// dorucime
	hr = Deliver(sample);	
	sample->Release();
	return hr;
}
Пример #6
0
HRESULT TheoraEncodeInputPin::deliverData(LONGLONG inStart, LONGLONG inEnd, unsigned char* inBuf, unsigned long inNumBytes) {
	//debugLog <<" deliverData : "<<inStart<<" - "<<inEnd<<"  :: size = "<<inNumBytes<<endl;
	//Get a pointer to a new sample stamped with our time
	IMediaSample* locSample;
	HRESULT locHR = mOutputPin->GetDeliveryBuffer(&locSample, &inStart, &inEnd, NULL);

	if (locHR != S_OK) {
		//We get here when the application goes into stop mode usually.
		return locHR;
	}	
	
	BYTE* locBuffer = NULL;

	
	//Make our pointers set to point to the samples buffer
	locSample->GetPointer(&locBuffer);

	if (locSample->GetSize() >= inNumBytes) {

		memcpy((void*)locBuffer, (const void*)inBuf, inNumBytes);
		
		//Set the sample parameters.
		SetSampleParams(locSample, inNumBytes, &inStart, &inEnd);

		{
			CAutoLock locLock(m_pLock);

			HRESULT locHR = ((TheoraEncodeOutputPin*)mOutputPin)->mDataQueue->Receive(locSample);						//->DownstreamFilter()->Receive(locSample);
			if (locHR != S_OK) {
				return locHR;	
			} else {
			}
		}
		//debugLog<<"deliverData : SUCCESS"<<endl;
		return S_OK;
	} else {
		//debugLog<<"Buffer too small !!!! FATALITY !"<<endl;
		throw 0;
	}

}
Пример #7
0
HRESULT CMPIptvSourceStream::DoBufferProcessingLoop(void) 
{
  Command com;

  OnThreadStartPlay();

  WSADATA wsaData;
  WSAStartup(MAKEWORD(2, 2), &wsaData);

#ifdef logging
  LogDebug("Starting grabber thread");
#endif
  sockaddr_in addr;
  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  if (localip) {
    addr.sin_addr.s_addr = inet_addr(localip);
  } else {
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
  }
  addr.sin_port = htons((u_short)port);

  ip_mreq imr; 
  imr.imr_multiaddr.s_addr = inet_addr(ip);
  if (localip) {
    imr.imr_interface.s_addr = inet_addr(localip);
  } else {
    imr.imr_interface.s_addr = INADDR_ANY;
  }
  unsigned long nonblocking = 1;

  if((m_socket = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
  {
    /*		u_long argp = 1;
    ioctlsocket(m_socket, FIONBIO, &argp);
    */
    DWORD dw = TRUE;
    int dwLen = sizeof(dw);
    if(setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&dw, sizeof(dw)) < 0)
    {
      closesocket(m_socket);
      m_socket = -1;
    }

    if(setsockopt(m_socket, SOL_SOCKET, SO_BROADCAST, (const char*)&dw, sizeof(dw)) < 0)
    {
      closesocket(m_socket);
      m_socket = -1;
    }

    getsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (char *)&dw, &dwLen);
#ifdef logging
    LogDebug("Socket receive buffer is: %d (%d)", dw, dwLen);

    LogDebug("Trying to set receive buffer to %d", IPTV_SOCKET_BUFFER_SIZE);
#endif
    dw = IPTV_SOCKET_BUFFER_SIZE;
    if(setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (const char*)&dw, sizeof(dw)) < 0)
    {
      closesocket(m_socket);
      m_socket = -1;
    }

    dwLen = sizeof(dw);
    getsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (char *)&dw, &dwLen);
#ifdef logging
    LogDebug("New socket receive buffer is: %d (%d)", dw, dwLen);
#endif
    if (ioctlsocket(m_socket, FIONBIO, &nonblocking) != 0) {
      closesocket(m_socket);
      m_socket = -1;
    }

    if(bind(m_socket, (struct sockaddr*)&addr, sizeof(addr)) < 0)
    {
      closesocket(m_socket);
      m_socket = -1;
    }

    if(IN_MULTICAST(htonl(imr.imr_multiaddr.s_addr)))
    {
      int ret = setsockopt(m_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&imr, sizeof(imr));
      if(ret < 0) ret = ::WSAGetLastError();
      ret = ret;
    }
  }

  SetThreadPriority(m_hThread, THREAD_PRIORITY_TIME_CRITICAL);

  int fromlen = sizeof(addr);

  m_buffsize = 0;
  timeval tv; //Will be used for select() below
  tv.tv_sec = 0;
  tv.tv_usec = 100000; //100 msec
  do 
  {
    BOOL requestAvail;
    while ((requestAvail = CheckRequest(&com)) == FALSE) 
    {
      DWORD startRecvTime;
      startRecvTime = GetTickCount();
#ifdef FILL_DIRECTLY_INTO_BUFFER
      IMediaSample *pSample;
      char *pData;
      long cbData;

      HRESULT hr = GetDeliveryBuffer(&pSample,NULL,NULL,0);
      if (FAILED(hr))
        continue;	
      CheckPointer(pSample, E_POINTER);
    // Access the sample's data buffer
      pSample->GetPointer((BYTE **)&pData);
      cbData = pSample->GetSize();
#endif
      do 
      {
        //Try to read the complete remaining buffer size
        //But stop reading after 100ms have passed (slow streams like internet radio)
#ifdef FILL_DIRECTLY_INTO_BUFFER
        int len = recvfrom(m_socket, &pData[m_buffsize], cbData - m_buffsize, 0, (SOCKADDR*)&addr, &fromlen);
#else
        int len = recvfrom(m_socket, &m_buffer[m_buffsize], IPTV_BUFFER_SIZE - m_buffsize, 0, (SOCKADDR*)&addr, &fromlen);
#endif
        if(len <= 0)
        {
          //Wait until there's something in the receive buffer
          fd_set myFDsocket;
          myFDsocket.fd_count = 1;
          myFDsocket.fd_array[0] = m_socket;
          int selectRet = select(0, &myFDsocket, NULL, NULL, &tv);
#ifdef logging
          LogDebug("select return code: %d", selectRet);
#endif
          continue; //On error or nothing read just repeat the loop
        }
#ifdef logging
        LogDebug("Read %d bytes at pos %d of %d", len, m_buffsize, IPTV_BUFFER_SIZE); 
#endif
        m_buffsize += len;
#ifdef FILL_DIRECTLY_INTO_BUFFER
      } while ((requestAvail = CheckRequest(&com)) == FALSE && m_buffsize < (cbData           * 3 / 4) && abs((signed long)(GetTickCount() - startRecvTime)) < 100);
#else
      } while ((requestAvail = CheckRequest(&com)) == FALSE && m_buffsize < (IPTV_BUFFER_SIZE * 3 / 4) && abs((signed long)(GetTickCount() - startRecvTime)) < 100);
#endif
      if (requestAvail) break;
#ifndef FILL_DIRECTLY_INTO_BUFFER
      if (m_buffsize == 0) continue; //100ms passed but no buffer received
      IMediaSample *pSample;
      HRESULT hr = GetDeliveryBuffer(&pSample,NULL,NULL,0);
      if (FAILED(hr))
      {
        continue;	
        // go round again. Perhaps the error will go away
        // or the allocator is decommited & we will be asked to
        // exit soon.
      }
#endif
      // fill buffer
      hr = FillBuffer(pSample);

      if (hr == S_OK) 
      {
        hr = Deliver(pSample);
        pSample->Release();

        // downstream filter returns S_FALSE if it wants us to
        // stop or an error if it's reporting an error.
        if(hr != S_OK)
        {
#ifdef logging
          LogDebug("Deliver() returned %08x; stopping", hr);
#endif
          if(m_socket >= 0) {closesocket(m_socket); m_socket = -1;}
          WSACleanup();
          return S_OK;
        }

      } else if (hr == S_FALSE) {
        // derived class wants us to stop pushing data
        pSample->Release();
        DeliverEndOfStream();
        if(m_socket >= 0) {closesocket(m_socket); m_socket = -1;}
        WSACleanup();
        return S_OK;
      } else {
        // derived class encountered an error
        pSample->Release();
#ifdef logging
        LogDebug("Error %08lX from FillBuffer!!!", hr);
#endif
        DeliverEndOfStream();
        m_pFilter->NotifyEvent(EC_ERRORABORT, hr, 0);
        if(m_socket >= 0) {closesocket(m_socket); m_socket = -1;}
        WSACleanup();
        return hr;
      }

      // all paths release the sample
    }

    // For all commands sent to us there must be a Reply call!

    if (com == CMD_RUN || com == CMD_PAUSE) {
      Reply(NOERROR);
    } else if (com != CMD_STOP) {
      Reply((DWORD) E_UNEXPECTED);
#ifdef logging
      LogDebug("Unexpected command %d!!!", com);
#endif
    }
  } while (com != CMD_STOP);
Пример #8
0
//
// Copy
//
// return a pointer to an identical copy of pSample
IMediaSample * CTransInPlaceFilter::Copy(IMediaSample *pSource)
{
    IMediaSample * pDest;

    HRESULT hr;
    REFERENCE_TIME tStart, tStop;
    const BOOL bTime = S_OK == pSource->GetTime( &tStart, &tStop);

    // this may block for an indeterminate amount of time
    hr = OutputPin()->PeekAllocator()->GetBuffer(
              &pDest
              , bTime ? &tStart : NULL
              , bTime ? &tStop : NULL
              , m_bSampleSkipped ? AM_GBF_PREVFRAMESKIPPED : 0
              );

    if (FAILED(hr)) {
        return NULL;
    }

    ASSERT(pDest);
    IMediaSample2 *pSample2;
    if (SUCCEEDED(pDest->QueryInterface(IID_IMediaSample2, (void **)&pSample2))) {
        HRESULT hr = pSample2->SetProperties(
            FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, pbBuffer),
            (PBYTE)m_pInput->SampleProps());
        pSample2->Release();
        if (FAILED(hr)) {
            pDest->Release();
            return NULL;
        }
    } else {
        if (bTime) {
            pDest->SetTime(&tStart, &tStop);
        }

        if (S_OK == pSource->IsSyncPoint()) {
            pDest->SetSyncPoint(TRUE);
        }
        if (S_OK == pSource->IsDiscontinuity() || m_bSampleSkipped) {
            pDest->SetDiscontinuity(TRUE);
        }
        if (S_OK == pSource->IsPreroll()) {
            pDest->SetPreroll(TRUE);
        }

        // Copy the media type
        AM_MEDIA_TYPE *pMediaType;
        if (S_OK == pSource->GetMediaType(&pMediaType)) {
            pDest->SetMediaType(pMediaType);
            DeleteMediaType( pMediaType );
        }

    }

    m_bSampleSkipped = FALSE;

    // Copy the sample media times
    REFERENCE_TIME TimeStart, TimeEnd;
    if (pSource->GetMediaTime(&TimeStart,&TimeEnd) == NOERROR) {
        pDest->SetMediaTime(&TimeStart,&TimeEnd);
    }

    // Copy the actual data length and the actual data.
    {
        const long lDataLength = pSource->GetActualDataLength();
        pDest->SetActualDataLength(lDataLength);

        // Copy the sample data
        {
            BYTE *pSourceBuffer, *pDestBuffer;
            long lSourceSize  = pSource->GetSize();
            long lDestSize = pDest->GetSize();

            ASSERT(lDestSize >= lSourceSize && lDestSize >= lDataLength);

            pSource->GetPointer(&pSourceBuffer);
            pDest->GetPointer(&pDestBuffer);
            ASSERT(lDestSize == 0 || pSourceBuffer != NULL && pDestBuffer != NULL);

            CopyMemory( (PVOID) pDestBuffer, (PVOID) pSourceBuffer, lDataLength );
        }
    }

    return pDest;

} // Copy
Пример #9
0
void
CPullPin::Process(void)
{
    // is there anything to do?
    if (m_tStop <= m_tStart) {
	EndOfStream();
	return;
    }

    BOOL bDiscontinuity = TRUE;

    // if there is more than one sample at the allocator,
    // then try to queue 2 at once in order to overlap.
    // -- get buffer count and required alignment
    ALLOCATOR_PROPERTIES Actual;
    HRESULT hr = m_pAlloc->GetProperties(&Actual);

    // align the start position downwards
    REFERENCE_TIME tStart = AlignDown(m_tStart / UNITS, Actual.cbAlign) * UNITS;
    REFERENCE_TIME tCurrent = tStart;

    REFERENCE_TIME tStop = m_tStop;
    if (tStop > m_tDuration) {
	tStop = m_tDuration;
    }

    // align the stop position - may be past stop, but that
    // doesn't matter
    REFERENCE_TIME tAlignStop = AlignUp(tStop / UNITS, Actual.cbAlign) * UNITS;


    DWORD dwRequest;

    if (!m_bSync) {

	//  Break out of the loop either if we get to the end or we're asked
	//  to do something else
	while (tCurrent < tAlignStop) {

	    // Break out without calling EndOfStream if we're asked to
	    // do something different
	    if (CheckRequest(&dwRequest)) {
		return;
	    }

	    // queue a first sample
	    if (Actual.cBuffers > 1) {

		hr = QueueSample(tCurrent, tAlignStop, TRUE);
		bDiscontinuity = FALSE;

		if (FAILED(hr)) {
		    return;
		}
	    }



	    // loop queueing second and waiting for first..
	    while (tCurrent < tAlignStop) {

		hr = QueueSample(tCurrent, tAlignStop, bDiscontinuity);
		bDiscontinuity = FALSE;

		if (FAILED(hr)) {
		    return;
		}

		hr = CollectAndDeliver(tStart, tStop);
		if (S_OK != hr) {

		    // stop if error, or if downstream filter said
		    // to stop.
		    return;
		}
	    }

	    if (Actual.cBuffers > 1) {
		hr = CollectAndDeliver(tStart, tStop);
		if (FAILED(hr)) {
		    return;
		}
	    }
	}
    } else {

	// sync version of above loop
	while (tCurrent < tAlignStop) {

	    // Break out without calling EndOfStream if we're asked to
	    // do something different
	    if (CheckRequest(&dwRequest)) {
		return;
	    }

	    IMediaSample* pSample;

	    hr = m_pAlloc->GetBuffer(&pSample, NULL, NULL, 0);
	    if (FAILED(hr)) {
		OnError(hr);
		return;
	    }

	    LONGLONG tStopThis = tCurrent + (pSample->GetSize() * UNITS);
	    if (tStopThis > tAlignStop) {
		tStopThis = tAlignStop;
	    }
	    pSample->SetTime(&tCurrent, &tStopThis);
	    tCurrent = tStopThis;

	    if (bDiscontinuity) {
		pSample->SetDiscontinuity(TRUE);
		bDiscontinuity = FALSE;
	    }

	    hr = m_pReader->SyncReadAligned(pSample);

	    if (FAILED(hr)) {
		pSample->Release();
		OnError(hr);
		return;
	    }

	    hr = DeliverSample(pSample, tStart, tStop);
	    if (hr != S_OK) {
		if (FAILED(hr)) {
		    OnError(hr);
		}
		return;
	    }
	}
    }

    EndOfStream();
}
Пример #10
0
DWORD WINAPI ReceiveThread(PVOID param)
{
	HRESULT hr;
	ReceiveParam *receiveParam = (ReceiveParam*)param;
	HANDLE PushSemaphore = receiveParam->PushSemaphore;
	HANDLE PushDataMutex = receiveParam->PushDataMutex;
	std::map<REFERENCE_TIME,IMediaSample*>& SampleList = *receiveParam->SampleList;
	NetReceiveFilter* filter = receiveParam->filter;
	SOCKET socket ;
	delete receiveParam;

	LONG packSize;
	//	CMediaSample *tmpSample = (CMediaSample*) malloc(sizeof(CMediaSample));
	REFERENCE_TIME startTime = 0,endTime = 0; //马上播放
	REFERENCE_TIME mediaStartTime = 0,mediaEndTime = 0;
	AM_SAMPLE2_PROPERTIES sample2Properties;

	NetReceiveOutputPin* outputPin = reinterpret_cast<NetReceiveOutputPin*>(filter->GetPin(0));
	assert(outputPin != NULL);

	filter->waitForNewSocket();

	while(true)
	{

		IMediaSample *sample = filter->GetFreeSample();
		if (sample == NULL)
		{
			ErrorPrint("Get free sample error");
			return 1;
		}

		PBYTE dataPointer = NULL;
		hr = sample->GetPointer(&dataPointer);
		if (FAILED(hr))
		{
			ErrorPrint("Get data pointer error",hr);
			sample->Release();
			return 1;
		}

		CAutoLock lock(filter->getSocketLock());
		socket = filter->getSocket();

		if (!receiveData(socket, (char*)&sample2Properties, sizeof(sample2Properties)))
		{
			ErrorPrint("Get pack Properties error");
			sample->Release();
			filter->waitForNewSocket();
			continue;
		}
		packSize = sample2Properties.lActual;

		if (packSize > 100 * 1024)
		{
			std::cout<<"Exceed 100K:"<<packSize/1024<<std::endl;
		}

		AM_MEDIA_TYPE mediaType;
		filter->GetPin(0)->ConnectionMediaType(&mediaType);

		if (filter->getPlayMode() == 1)
		{
// 			static const unsigned long  offset = 10000000; //将延迟增加,尽量缓冲一些
// 			sample2Properties.tStart +=offset;
// 			sample2Properties.tStop += offset;

			sample2Properties.cbData = sizeof(sample2Properties) - 9;
			sample2Properties.pbBuffer= dataPointer;

			IMediaSample2 *mediaSample2;
			hr = sample->QueryInterface(IID_IMediaSample2, (void**)&mediaSample2);
			if (FAILED(hr))
			{
				ErrorPrint("Get media sample2 interface error",hr);
				sample->Release();
				return 1;
			}
			ComReleaser mediaSample2Releaser(mediaSample2);

			hr = mediaSample2->SetProperties(sample2Properties.cbData, (BYTE*)&sample2Properties);
			if (FAILED(hr))
			{
				ErrorPrint("Set sample properties error");
			}
			sample->SetTime(&sample2Properties.tStart, &sample2Properties.tStop);

			sample->GetTime(&startTime,&endTime);
		}
		else
		{
			startTime = 0;
			endTime = 0;
		}

		ASSERT(packSize <= sample->GetSize());
		sample->SetActualDataLength(packSize);
		sample->SetTime(&startTime, &endTime);

		if(!receiveData(socket, (char*)dataPointer, packSize))
		{
			ErrorPrint("Receive pack errors");
			sample->Release();
			filter->waitForNewSocket();
			continue;
		}

		//通知PUSH线程进行数据传送
		WaitForSingleObject(PushDataMutex, INFINITE);
		SampleList.insert(std::make_pair(startTime, sample));
		if(filter->getPlayMode() == 0) //如果尽快播放,则只要有一个sample就通知push线程
		{
			if (SampleList.size() == 1)
			{
				ReleaseSemaphore(PushSemaphore, 1, NULL);
			}
		}
		else if (filter->getPlayMode() == 1)//如果考虑时间戳,我们则缓冲尽量多的sample,但也不能太多
		{
			if (SampleList.size() >= 24 * 10)
			{
				ReleaseSemaphore(PushSemaphore, 1, NULL);
			}
		}
		ReleaseMutex(PushDataMutex);

		outputPin->newTransSample(sample2Properties, dataPointer); //通知进行sample的转发
	}

	return 0;
}
Пример #11
0
HRESULT CLAVOutputPin::DeliverPacket(Packet *pPacket)
{
  HRESULT hr = S_OK;
  IMediaSample *pSample = NULL;

  long nBytes = (long)pPacket->GetDataSize();

  if(nBytes == 0) {
    goto done;
  }

  CHECK_HR(hr = GetDeliveryBuffer(&pSample, NULL, NULL, 0));

  if (m_bPacketAllocator) {
    ILAVMediaSample *pLAVSample = NULL;
    CHECK_HR(hr = pSample->QueryInterface(&pLAVSample));
    CHECK_HR(hr = pLAVSample->SetPacket(pPacket));
    SafeRelease(&pLAVSample);
  } else {
    // Resize buffer if it is too small
    // This can cause a playback hick-up, we should avoid this if possible by setting a big enough buffer size
    if(nBytes > pSample->GetSize()) {
      SafeRelease(&pSample);
      ALLOCATOR_PROPERTIES props, actual;
      CHECK_HR(hr = m_pAllocator->GetProperties(&props));
      // Give us 2 times the requested size, so we don't resize every time
      props.cbBuffer = nBytes*2;
      if(props.cBuffers > 1) {
        CHECK_HR(hr = __super::DeliverBeginFlush());
        CHECK_HR(hr = __super::DeliverEndFlush());
      }
      CHECK_HR(hr = m_pAllocator->Decommit());
      CHECK_HR(hr = m_pAllocator->SetProperties(&props, &actual));
      CHECK_HR(hr = m_pAllocator->Commit());
      CHECK_HR(hr = GetDeliveryBuffer(&pSample, NULL, NULL, 0));
    }

    // Fill the sample
    BYTE* pData = NULL;
    if(FAILED(hr = pSample->GetPointer(&pData)) || !pData) goto done;

    memcpy(pData, pPacket->GetData(), nBytes);
  }

  if(pPacket->pmt) {
    DbgLog((LOG_TRACE, 10, L"::DeliverPacket() - sending new media type to decoder"));
    pSample->SetMediaType(pPacket->pmt);
    pPacket->bDiscontinuity = true;

    CAutoLock cAutoLock(m_pLock);
    CMediaType pmt = *(pPacket->pmt);
    m_mts.clear();
    m_mts.push_back(pmt);
    pPacket->pmt = NULL;

    SetMediaType(&pmt);
  }

  bool fTimeValid = pPacket->rtStart != Packet::INVALID_TIME;

  CHECK_HR(hr = pSample->SetActualDataLength(nBytes));
  CHECK_HR(hr = pSample->SetTime(fTimeValid ? &pPacket->rtStart : NULL, fTimeValid ? &pPacket->rtStop : NULL));
  CHECK_HR(hr = pSample->SetMediaTime(NULL, NULL));
  CHECK_HR(hr = pSample->SetDiscontinuity(pPacket->bDiscontinuity));
  CHECK_HR(hr = pSample->SetSyncPoint(pPacket->bSyncPoint));
  CHECK_HR(hr = pSample->SetPreroll(fTimeValid && pPacket->rtStart < 0));
  // Deliver
  CHECK_HR(hr = Deliver(pSample));

done:
  if (!m_bPacketAllocator)
    SAFE_DELETE(pPacket);
  SafeRelease(&pSample);
  return hr;
}
Пример #12
0
HRESULT CLAVOutputPin::DeliverPacket(Packet *pPacket)
{
  HRESULT hr = S_OK;
  IMediaSample *pSample = nullptr;

  long nBytes = (long)pPacket->GetDataSize();

  if(nBytes == 0) {
    goto done;
  }

  CHECK_HR(hr = GetDeliveryBuffer(&pSample, nullptr, nullptr, 0));

  if (m_bPacketAllocator) {
    ILAVMediaSample *pLAVSample = nullptr;
    CHECK_HR(hr = pSample->QueryInterface(&pLAVSample));
    CHECK_HR(hr = pLAVSample->SetPacket(pPacket));
    SafeRelease(&pLAVSample);
  } else {
    // Resize buffer if it is too small
    // This can cause a playback hick-up, we should avoid this if possible by setting a big enough buffer size
    if(nBytes > pSample->GetSize()) {
      SafeRelease(&pSample);
      ALLOCATOR_PROPERTIES props, actual;
      CHECK_HR(hr = m_pAllocator->GetProperties(&props));
      // Give us 2 times the requested size, so we don't resize every time
      props.cbBuffer = nBytes*2;
      if(props.cBuffers > 1) {
        CHECK_HR(hr = __super::DeliverBeginFlush());
        CHECK_HR(hr = __super::DeliverEndFlush());
      }
      CHECK_HR(hr = m_pAllocator->Decommit());
      CHECK_HR(hr = m_pAllocator->SetProperties(&props, &actual));
      CHECK_HR(hr = m_pAllocator->Commit());
      CHECK_HR(hr = GetDeliveryBuffer(&pSample, nullptr, nullptr, 0));
    }

    // Fill the sample
    BYTE* pData = nullptr;
    if(FAILED(hr = pSample->GetPointer(&pData)) || !pData) goto done;

    memcpy(pData, pPacket->GetData(), nBytes);
  }

  if(pPacket->pmt) {
    DbgLog((LOG_TRACE, 10, L"::DeliverPacket() - sending new media type to decoder"));
    pSample->SetMediaType(pPacket->pmt);
    pPacket->bDiscontinuity = true;

    CAutoLock cAutoLock(m_pLock);
    CMediaType pmt = *(pPacket->pmt);
    m_mts.clear();
    m_mts.push_back(pmt);
    pPacket->pmt = nullptr;

    SetMediaType(&pmt);
  }

  bool fTimeValid = pPacket->rtStart != Packet::INVALID_TIME;

  // IBitRateInfo
  m_BitRate.nBytesSinceLastDeliverTime += nBytes;

  if (fTimeValid) {
    if (m_BitRate.rtLastDeliverTime == Packet::INVALID_TIME) {
      m_BitRate.rtLastDeliverTime = pPacket->rtStart;
      m_BitRate.nBytesSinceLastDeliverTime = 0;
    }

    if (m_BitRate.rtLastDeliverTime + 10000000 < pPacket->rtStart) {
      REFERENCE_TIME rtDiff = pPacket->rtStart - m_BitRate.rtLastDeliverTime;

      double dSecs, dBits;

      dSecs = rtDiff / 10000000.0;
      dBits = 8.0 * m_BitRate.nBytesSinceLastDeliverTime;
      m_BitRate.nCurrentBitRate = (DWORD)(dBits / dSecs);

      m_BitRate.rtTotalTimeDelivered += rtDiff;
      m_BitRate.nTotalBytesDelivered += m_BitRate.nBytesSinceLastDeliverTime;

      dSecs = m_BitRate.rtTotalTimeDelivered / 10000000.0;
      dBits = 8.0 * m_BitRate.nTotalBytesDelivered;
      m_BitRate.nAverageBitRate = (DWORD)(dBits / dSecs);

      m_BitRate.rtLastDeliverTime = pPacket->rtStart;
      m_BitRate.nBytesSinceLastDeliverTime = 0;
    }
  }

  CHECK_HR(hr = pSample->SetActualDataLength(nBytes));
  CHECK_HR(hr = pSample->SetTime(fTimeValid ? &pPacket->rtStart : nullptr, fTimeValid ? &pPacket->rtStop : nullptr));
  CHECK_HR(hr = pSample->SetMediaTime(nullptr, nullptr));
  CHECK_HR(hr = pSample->SetDiscontinuity(pPacket->bDiscontinuity));
  CHECK_HR(hr = pSample->SetSyncPoint(pPacket->bSyncPoint));
  CHECK_HR(hr = pSample->SetPreroll(fTimeValid && pPacket->rtStart < 0));
  // Deliver
  CHECK_HR(hr = Deliver(pSample));

done:
  if (!m_bPacketAllocator || !pSample)
    SAFE_DELETE(pPacket);
  SafeRelease(&pSample);
  return hr;
}
Пример #13
0
HRESULT CMPVlcSourceStream::DoBufferProcessingLoop(void)
{
    Command com;
    HRESULT result = S_OK;
    BOOL bStop = false;

    OnThreadStartPlay();

    LogInfo("Starting grabber thread");

    if (m_exec)
    {
        LogInfo("Executing external command: %s %s", m_exec, m_exec_opt);
        ::ShellExecuteA(0, NULL, m_exec, m_exec_opt, NULL, SW_HIDE);
        Sleep(m_exec_wait);
    }

    //libvlc_vlm_seek_media(m_vlc, "vlc_ds_stream", 0);

    if (libvlc_vlm_play_media (m_vlc, "vlc_ds_stream") != 0)
    {
        LogError("libvlc_vlm_play_media failed");
        return S_FALSE;
    }

    OVERLAPPED o;
    o.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
    o.Internal = o.InternalHigh = o.Offset = o.OffsetHigh = 0;

    ConnectNamedPipe(m_hPipe, &o);

    WaitForSingleObject(o.hEvent, 20000);
    BOOL fConnected = HasOverlappedIoCompleted(&o);

    SetThreadPriority(m_hThread, THREAD_PRIORITY_TIME_CRITICAL);

    if (!fConnected)
    {
        LogError("ConnectNamedPipe failed");
        CancelIo(m_hPipe);
        CloseHandle(o.hEvent);
        return S_FALSE;
    }
    else do
        {
            BOOL requestAvail = FALSE;
            while ((requestAvail = CheckRequest(&com)) == FALSE)
            {
                //LogDebug ("Command: %d", com);

                IMediaSample *pSample;

                HRESULT hr = GetDeliveryBuffer(&pSample,NULL,NULL,0);
                if (FAILED(hr))
                    continue;

                // fill buffer
                // ------------------------------------------------------------------------------------
                hr = S_OK;
                BYTE *pData;
                DWORD cbData;

                CheckPointer(pSample, E_POINTER);
                // Access the sample's data buffer
                pSample->GetPointer((BYTE **)&pData);
                cbData = pSample->GetSize();

                DWORD startRecvTime = GetTickCount();
                m_buffsize = 0;

                do
                {
                    DWORD cbBytesRead = 0;
                    ResetEvent(o.hEvent);
                    o.Internal = o.InternalHigh = o.Offset = o.OffsetHigh = 0;
                    BOOL fSuccess = ReadFile( m_hPipe,  pData + m_buffsize,  cbData - m_buffsize,  &cbBytesRead, &o);

                    if (GetLastError() == ERROR_IO_PENDING)
                    {
                        for (int n=0; n < 20; n++)
                        {
                            if ((requestAvail = CheckRequest(&com)) == TRUE)
                                break;
                            if (WaitForSingleObject(o.hEvent, 1000) == WAIT_OBJECT_0)
                                break;
                        }
                        fSuccess = GetOverlappedResult(m_hPipe, &o, &cbBytesRead, false);
                    }

                    if (!fSuccess || cbBytesRead == 0)
                    {
                        CancelIo(m_hPipe);
                        break;
                    }
                    m_buffsize += cbBytesRead;

                } while ( !requestAvail && m_buffsize < (cbData  * 3 / 4)
                          && abs((signed long)(GetTickCount() - startRecvTime)) < 100);

                // ------------------------------------------------------------------------------------

                if (m_buffsize != 0 && !(requestAvail && com == CMD_STOP))
                {
                    LogDebug("Posting %d / %d bytes", m_buffsize, pSample->GetSize());

                    REFERENCE_TIME rtStart = startRecvTime;
                    REFERENCE_TIME rtStop  = GetTickCount();

                    pSample->SetTime(&rtStart, &rtStop);
                    pSample->SetActualDataLength(m_buffsize);
                    pSample->SetSyncPoint(TRUE);

                    hr = Deliver(pSample);
                    // downstream filter returns S_FALSE if it wants us to
                    // stop or an error if it's reporting an error.
                    if(hr != S_OK)
                    {
                        LogInfo("Deliver() returned %08x; stopping", hr);
                        bStop = true;
                    }

                } else
                {
                    // FillBuffer returned false
                    bStop = true;
                    DeliverEndOfStream();
                }

                pSample->Release();

                if (bStop)
                    break;
            }

            if (requestAvail)
            {
                LogInfo("Received command: %d", com);
                if (com == CMD_RUN || com == CMD_PAUSE) {
                    Reply(NOERROR);
                } else if (com != CMD_STOP) {
                    Reply((DWORD) E_UNEXPECTED);
                    LogDebug("Unexpected command %d!!!", com);
                }
            }
        } while (com != CMD_STOP && bStop == false);

    //DeliverEndOfStream();
    LogDebug("end loop");

    HANDLE hSDThread = CreateThread(NULL, 0, &VlcStreamDiscardThread, LPVOID(m_hPipe), 0, 0);

    libvlc_vlm_stop_media(m_vlc, "vlc_ds_stream");
    LogDebug("libvlc_vlm_stop_media");

    if (WaitForSingleObject(hSDThread, 30000) == WAIT_TIMEOUT)
    {
        DWORD ec;
        LogError("Terminating StreamDiscardThread!");
        GetExitCodeThread(hSDThread, &ec);
        TerminateThread(hSDThread, ec);
    }
    DisconnectNamedPipe(m_hPipe);
    LogDebug("DoBufferProcessingLoop end");

    CloseHandle(o.hEvent);
    return result;
}
Пример #14
0
HRESULT CWavPackDSDecoder::Receive(IMediaSample *pSample)
{
    //  Check for other streams and pass them on 
    AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps(); 
    if ((pProps->dwStreamId != AM_STREAM_MEDIA) &&
        (pProps->dwStreamId != AM_STREAM_BLOCK_ADDITIONNAL))
    {
        return m_pOutput->Deliver(pSample);
    }
    
    ASSERT(pSample);
    // If no output to deliver to then no point sending us data 
    ASSERT(m_pOutput != NULL);

    HRESULT hr = S_OK;
    BYTE *pSrc, *pDst;
    DWORD SrcLength = pSample->GetActualDataLength();
    hr = pSample->GetPointer(&pSrc);
    if(FAILED(hr))
        return hr;
    
     // Check for minimal block size
    if(SrcLength < (3 * sizeof(uint32_t)))
    {
        return S_OK;
    }

    WAVEFORMATEX* pwfx = (WAVEFORMATEX*)m_pInput->CurrentMediaType().Format();
    BOOL bSeveralBlocks = (pwfx->nChannels > 2);
 
    if(pProps->dwStreamId == AM_STREAM_MEDIA)
    {
        REFERENCE_TIME rtStop;
        if(pSample->IsSyncPoint() == S_OK)
        {
            pSample->GetTime(&m_rtFrameStart, &rtStop);
            m_TotalSamples = 0;
        }

        m_MainBlockDiscontinuity = (pSample->IsDiscontinuity() == S_OK);

        reconstruct_wavpack_frame(
            m_MainFrame,
            &m_CommonFrameData,
            (char*)pSrc,
            SrcLength,            
            TRUE,
            bSeveralBlocks,
            m_PrivateData.version);

        if(m_HybridMode == TRUE)
        {
            // Stop here and wait for correction data
            return S_OK;
        }
    }
    
    if((m_HybridMode == TRUE) && 
       (pProps->dwStreamId == AM_STREAM_BLOCK_ADDITIONNAL))
    {
        // rebuild correction data block
        reconstruct_wavpack_frame(
            m_CorrectionFrame,
            &m_CommonFrameData,
            (char*)pSrc,
            SrcLength,
            FALSE,
            bSeveralBlocks,
            m_PrivateData.version);
    }

    if(wavpack_buffer_decoder_load_frame(m_Codec, m_MainFrame->data, m_MainFrame->len,
        m_HybridMode ? m_CorrectionFrame->data : NULL, m_CorrectionFrame->len) == 0)
    {
        // Something is wrong
        return S_FALSE;
    }
   
    // We can precise the decoding mode now
    if(m_HybridMode == FALSE)
    {
        if(m_CommonFrameData.array_flags[0] & WV_HYBRID_FLAG)
        {
            m_DecodingMode = DECODING_MODE_LOSSY;
        }
        else
        {
            m_DecodingMode = DECODING_MODE_LOSSLESS;
        }
    }

    uint32_t samplesLeft = m_CommonFrameData.block_samples;
    while(samplesLeft > 0)
    {
        // Set up the output sample
        IMediaSample *pOutSample;
        hr = InitializeOutputSample(pSample, &pOutSample);
        if(FAILED(hr))
        {
            break;
        }
    
        DWORD DstLength = pOutSample->GetSize();
        hr = pOutSample->GetPointer(&pDst);
        if(FAILED(hr))
        {
            pOutSample->Release();
            break;
        }

        DstLength &= 0xFFFFFFF8;
    
        long samples = wavpack_buffer_decoder_unpack(m_Codec,(int32_t *)pDst, m_SamplesPerBuffer);
        if(samples)
        {
            wavpack_buffer_format_samples(m_Codec,
                (uchar *) pDst,
                (long*) pDst,
                samples);
            
            DstLength = samples *
                WavpackGetBytesPerSample(m_Codec->wpc) *
                WavpackGetNumChannels (m_Codec->wpc);

            pOutSample->SetActualDataLength(DstLength);
            
            REFERENCE_TIME rtStart, rtStop;
            rtStart = m_rtFrameStart + (REFERENCE_TIME)(((double)m_TotalSamples / WavpackGetSampleRate(m_Codec->wpc)) * 10000000);
            m_TotalSamples += samples;
            rtStop = m_rtFrameStart + (REFERENCE_TIME)(((double)m_TotalSamples / WavpackGetSampleRate(m_Codec->wpc)) * 10000000);

            if(rtStart < 0 && rtStop < 0)
            {
                // No need to deliver this sample it will be skipped
                pOutSample->Release();
                continue;
            }
            pOutSample->SetTime(&rtStart, &rtStop);
            pOutSample->SetSyncPoint(TRUE);
            pOutSample->SetDiscontinuity(m_MainBlockDiscontinuity);
            if(m_MainBlockDiscontinuity == TRUE)
            {
                m_MainBlockDiscontinuity = FALSE;
            }

            hr = m_pOutput->Deliver(pOutSample);
            if(FAILED(hr))
            {
                pOutSample->Release();
                break;
            }
            pOutSample->Release();
        }
        else
        {
            pOutSample->Release();
            break;
        }
        samplesLeft -= samples;
    }
    
    m_DecodedFrames++;
    m_CrcError = WavpackGetNumErrors(m_Codec->wpc);
    
    return S_OK;
}