producersdk 中的mediasinkencoder采样声音为什么时间长度只有一半

来源:互联网 发布:王勇平 知乎 编辑:程序博客网 时间:2024/05/29 15:10

mediasinkencoder样例,是用来生成rmvb文件的,其核心函数是CMediaSinkEncoderApp::EncodeSamples


HX_RESULT CMediaSinkEncoderApp::EncodeSamples()
{
    HX_RESULT res = HXR_OK;
   
    // Create media sample allocator
    IHXTSampleAllocator* pAllocator = NULL;
    res = m_pFactory->CreateInstance(IID_IHXTSampleAllocator, (IUnknown**)&pAllocator);
   
    // simulation:  one pass each second
    UINT32 z=0;
    for (z=0; z < 30 && SUCCEEDED(res); z ++)
    {
 // Encode an event sample
 if (m_bEncodeEvents && SUCCEEDED(res))
 {
     // Send URL event sample
     if ( z == 1000)
     {
  // Create event sample -- note that event sample comes from class factory
  IHXTEventSample* pEventSample = NULL;
  res = m_pFactory->CreateInstance(IID_IHXTEventSample, (IUnknown**)&pEventSample);
  
  // Set target URL
  if (SUCCEEDED(res))
      res = pEventSample->SetAction(HXEventMediaSample_URL, "http://www.real.com", NULL);
  
  // Set start/finish time
  if (SUCCEEDED(res))
      res = pEventSample->SetTime(0, 6000);
  
  // Encode sample
  if (SUCCEEDED(res))
      res = m_pEventPin->EncodeSample( pEventSample );
  
  HX_RELEASE(pEventSample);
  printf( "Sent URL Event/n" );
     }
    
     //Send a custom event sample
     else if ( z == 500 )
     {
  IHXTEventSample* pEventSample = NULL;
  IHXBuffer* pBuffer = NULL;
  IHXValues* pValues = NULL;
  if (SUCCEEDED(res))
      res = m_pFactory->CreateInstance(IID_IHXTEventSample, (IUnknown**)&pEventSample);
  if (SUCCEEDED(res))
      res = m_pFactory->CreateInstance(CLSID_IHXValues, (IUnknown**)&pValues);
  if (SUCCEEDED(res))
      res = m_pFactory->CreateInstance(CLSID_IHXBuffer, (IUnknown**)&pBuffer);
  
  if (SUCCEEDED(res))
  { // load up a IHXValues with name/value pairs to encode
      pValues->SetPropertyULONG32("myulong32prop", 200);
      pBuffer->Set((BYTE *)"my dog spot", 12);
      pValues->SetPropertyCString("mystringprop", pBuffer);
  }
  
  if (SUCCEEDED(res))
      res=pEventSample->SetAction(HXEventMediaSample_Custom, "mycustomevent", pValues);
  if (SUCCEEDED(res))
      res=pEventSample->SetTime( 5000, 15000);
  if (SUCCEEDED(res))
      res = m_pEventPin->EncodeSample( pEventSample );
  
  HX_RELEASE(pBuffer);
  HX_RELEASE(pValues);
  HX_RELEASE(pEventSample);
  printf( "Sent Custom Event/n" );
     }
 }
 
 // Encode on second's worth of audio.
 // Note that in practice it is a better idea to alternate between passing audio and video
 // samples so that one doesn't get too far ahead of the other in terms of sample
 // start times.  Doing otherwise (say passing 5 seconds worth of audio at a time followed by 5 seconds worth
 // of video) may result in higher than expected memory consumption.
 if (m_bEncodeAudio && SUCCEEDED(res))
 { 
     // Get media sample -- sample: 1 channel, 16 bits/sample, 44.1 khz
     // Note that the the size of the buffer being allocated should exactly match the size
     // of the audio chunk (do not allocate a larger buffer).  Since audio start/end timestamps only
     // have millisecond resolution, some portions of the Producer SDK determine the audio chunk size
     // based on the buffer size, not the start/end timestamps.
     IHXTMediaSample* pMediaSample=NULL;
     res = pAllocator->GetMediaSampleOfSize(44100*sizeof(UINT16), &pMediaSample);
    
     if (SUCCEEDED(res))
     {
  // Get the sample data buffer -- note use of GetDataStartForWriting instead of
  // GetDataStartForReading since the buffer is being written to
  UINT16 *y=(UINT16*)pMediaSample->GetDataStartForWriting();
  
  float fifth = 3.0f/2.0f ;
  float minthird = 6.0f/5.0f ;
  float f0 = 440.0f ; // Hz
  float pi = 3.1415926535f;
  
  // Construct a minor chord
  for (int i = 0 ; i < 44100 ; i++)
  {
      float x = (float) (2*pi*i/44100.0 * f0);
      y[i] = (UINT16)(32000 * (1.0/3.0) * (sin(x) + sin(minthird*x)+ sin(fifth*x)));
  }
     }
    
     // Set time
     if (SUCCEEDED(res))
  res = pMediaSample->SetTime(z*1000, (z+1)*1000);
    
     // Encode sample
     // Note: Do NOT reuse (read from or write to the data buffer) the media sample after passing it
     // to the input pin.  The media sample is not automatically memcpy'ed, and some other object may
     // have a refcount on it and modify the buffer on another thread.  Just release the media
     // sample and get another one from the allocator.
     if (SUCCEEDED(res))
  res = m_pAudioPin->EncodeSample( pMediaSample );
    
     printf("Sent audio sample time: %d/n", z*1000);
     HX_RELEASE(pMediaSample);
 }
 
 // Encode one seconds worth of video frames
 // Note that in practice it is a better idea to alternate between passing audio and video
 // samples so that one doesn't get too far ahead of the other in terms of sample
 // start times.  Doing otherwise (say passing 5 seconds worth of audio at a time followed by 5 seconds worth
 // of video) may result in higher than expected memory consumption.
 if (m_bEncodeVideo && SUCCEEDED(res))
 {
     for (UINT32 ulFrameCount=1; ulFrameCount < 30; ulFrameCount++)
     {
  // Get media sample -- kulVideoWidth x kulVideoHeight x HXT_VIDEO_FORMAT_BGRA32_INVERTED
  IHXTMediaSample* pMediaSample=NULL;
  res = pAllocator->GetMediaSampleOfSize( kulVideoWidth * kulVideoHeight * sizeof(UINT32), &pMediaSample);
  
  // Create green/blue colored scrolling frame
  if (SUCCEEDED(res))
  {
      // Get the sample data buffer -- note use of GetDataStartForWriting instead of
      // GetDataStartForReading since the buffer is being written to
      UINT32* pSampleBuffer = (UINT32*)pMediaSample->GetDataStartForWriting();
      for ( int i = 0;  i < kulVideoHeight; i++ )
      {
   static UINT32 ulColorBand = 0;
   ulColorBand++;    
   
   for( int j =0; j < kulVideoWidth; j++ )
   {
       *(pSampleBuffer+(i*kulVideoWidth)+j) = 0x0000FF00 + ulColorBand;
   }
      }
  }
  
  // Set start/end time
  if (SUCCEEDED(res))
      res = pMediaSample->SetTime(z*1000 + ulFrameCount * 33, z*1000 + ulFrameCount * 33 + 10);
  
  // Encode sample
  // Note: Do NOT reuse (read from or write to the data buffer) the media sample after passing it
  // to the input pin.  The media sample is not automatically memcpy'ed, and some other object may
  // have a refcount on it and modify the buffer on another thread.  Just release the media
  // sample and get another one from the allocator.
  if (SUCCEEDED(res))
      res = m_pVideoPin->EncodeSample(pMediaSample);
  
  printf("Sent video sample time: %lu/n", z*1000 + ulFrameCount * 33);
  HX_RELEASE(pMediaSample);
     }
 }  
 //if (m_bEncodeAudio && SUCCEEDED(res))
 //{ 
 // // Get media sample -- sample: 1 channel, 16 bits/sample, 44.1 khz
 // // Note that the the size of the buffer being allocated should exactly match the size
 // // of the audio chunk (do not allocate a larger buffer).  Since audio start/end timestamps only
 // // have millisecond resolution, some portions of the Producer SDK determine the audio chunk size
 // // based on the buffer size, not the start/end timestamps.
 // IHXTMediaSample* pMediaSample=NULL;
 // res = pAllocator->GetMediaSampleOfSize(44100*sizeof(UINT16), &pMediaSample);

 // if (SUCCEEDED(res))
 // {
 //  // Get the sample data buffer -- note use of GetDataStartForWriting instead of
 //  // GetDataStartForReading since the buffer is being written to
 //  UINT16 *y=(UINT16*)pMediaSample->GetDataStartForWriting();

 //  float fifth = 3.0f/2.0f ;
 //  float minthird = 6.0f/5.0f ;
 //  float f0 = 440.0f ; // Hz
 //  float pi = 3.1415926535f;

 //  // Construct a minor chord
 //  for (int i = 0 ; i < 44100 ; i++)
 //  {
 //   float x = (float) (2*pi*i/44100.0 * f0);
 //   y[i] = (UINT16)(24000 * (1.0/3.0) * (sin(x) + sin(minthird*x)+ sin(fifth*x)));
 //  }
 // }

 // // Set time
 // if (SUCCEEDED(res))
 //  res = pMediaSample->SetTime(z*1000, (z+1)*1000);

 // // Encode sample
 // // Note: Do NOT reuse (read from or write to the data buffer) the media sample after passing it
 // // to the input pin.  The media sample is not automatically memcpy'ed, and some other object may
 // // have a refcount on it and modify the buffer on another thread.  Just release the media
 // // sample and get another one from the allocator.
 // if (SUCCEEDED(res))
 //  res = m_pAudioPin->EncodeSample( pMediaSample );

 // printf("Sent audio sample time: %d/n", z*1000);
 // HX_RELEASE(pMediaSample);
 //}
 }
 
 // Signal that all video samples have been sent
 if (m_bEncodeVideo && SUCCEEDED(res))
 {
     // Create media sample
     IHXTMediaSample* pMediaSample = NULL;
     res = pAllocator->GetMediaSampleOfSize(0, &pMediaSample);
    
     // Mark the sample with ENDOFSTREAM flag
     if (SUCCEEDED(res))
  res = pMediaSample->SetSampleFlags(HXT_SAMPLE_ENDOFSTREAM);
    
     // Set time
     if (SUCCEEDED(res))
  res = pMediaSample->SetTime((z+1)*1000, (z+1)*1000);
    
     // Encode sample
     if (SUCCEEDED(res))
  res = m_pVideoPin->EncodeSample(pMediaSample);
    
     HX_RELEASE(pMediaSample);
 }
 
 // Signal that all audio samples have been sent
 if (m_bEncodeAudio && SUCCEEDED(res))
 {
     // Create media sample
     IHXTMediaSample* pMediaSample = NULL;
     res = pAllocator->GetMediaSampleOfSize(0, &pMediaSample);
    
     // Mark the sample with ENDOFSTREAM flag
     if (SUCCEEDED(res))
  res = pMediaSample->SetSampleFlags(HXT_SAMPLE_ENDOFSTREAM);
    
     // Set time
     if (SUCCEEDED(res))
  res = pMediaSample->SetTime((z+1)*1000, (z+1)*1000);
    
     // Encode sample
     if (SUCCEEDED(res))
  res = m_pAudioPin->EncodeSample(pMediaSample);
    
     HX_RELEASE(pMediaSample);
 }
 
 // Signal that all event samples have been sent
 if (m_bEncodeEvents && SUCCEEDED(res))
 {
     // Create event sample
     IHXTEventSample* pEventSample = NULL;
     res = m_pFactory->CreateInstance(IID_IHXTEventSample, (IUnknown**)&pEventSample);
    
     // Mark the sample with ENDOFSTREAM flag
     if (SUCCEEDED(res))
  res = pEventSample->SetSampleFlags(HXT_SAMPLE_ENDOFSTREAM);
    
     // Set time
     if (SUCCEEDED(res))
  res = pEventSample->SetTime(6001, 6001);
    
     // Encode sample
     if (SUCCEEDED(res))
  res = m_pEventPin->EncodeSample(pEventSample);
    
     HX_RELEASE(pEventSample);
 }
 
 HX_RELEASE(pAllocator);
 
 
 
 return res;
}

无论是否打开:m_bEncodeTwoPass,声音只有前半段才有,若把声音采样部分再追加到视频采样后面,这样才正常为,不知为什么?
音频中res = pMediaSample->SetTime(z*1000, (z+1)*1000);已经设置了播放声音时间,它与视频保持一致的,前面的上下文也看了多次,没有发现什么异样,不会为什么后半段声音有问题。

若有知情者欢迎留言说明原因。

原创粉丝点击