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

    技术2025-05-06  12

    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);已经设置了播放声音时间,它与视频保持一致的,前面的上下文也看了多次,没有发现什么异样,不会为什么后半段声音有问题。 若有知情者欢迎留言说明原因。

    最新回复(0)