• AnyStream is having some DRM issues currently, Netflix is not available in HD for the time being.
    Situations like this will always happen with AnyStream: streaming providers are continuously improving their countermeasures while we try to catch up, it's an ongoing cat-and-mouse game. Please be patient and don't flood our support or forum with requests, we are working on it 24/7 to get it resolved. Thank you.

How to feed reclock for TrueHD, DTSHD, EAC3 bitstream?

Come on James :bang: :)

Good Lord, give the man a break! He puts in more hours than I do, and that's saying a lot!! :D He'll get to it as soon as he can, I'm sure. Patience brings great rewards. ;)
 
vladd (whurlston above) got his TrueHD light to show up but with the Realtek drivers. Do they work on the 5000 series?

I haven't tested that yet. I'm hopeful that they release an HDMI driver with PAP for the 5xxx series, but, it seems rather unlikely. We'll see. I've been using the ATI driver, which does in fact have the issue that it loses what audio mode it's in if the signal stops at all. For instance, pausing a movie. It then has to change back. So, this is still an issue in the RC7 driver. :(
 
Hi James,

I am stuck with the Wasapi implementation. Could give me a little help ?

Whenever I initialize the IAudioClient object once, it works fine : it accepts the waveformatex and initialize correctly.

However, if I release the object and reactivate one and supply the same waveformatex structure, the "IAudioClient.isFormatsupported" method will refuse it (E_INVALIDARG) and also Initialize method.

Of course, this is a real need that corresponds to a change of format : for example, the parser detected an AC3 stream but it was a TrueHD stream. So the waveformatex needs to be updated

I wonder if this is not the audio driver's fault.

How do you handle input formats change ?

Thank you

Regards

Damien BT
 
Ah, so that's why I haven't seen a new build this morning. :D Ok, that's fine. I hope you get this worked out. Ideally, a ReClock version that supports your bitstreaming efforts would be better. Then you could focus on bitstreaming and leave the rendering work to James. ;)
 
Hi again, I really don't understand why wasapi fails on this one
It says that the format is supported but then it says E_INVALIDARG for the initialization

Code:
[4020] CMpcAudioRenderer::InitAudioClient
[4020] 
[4020]  WAVEFORMATEXTENSIBLE :
[4020]  subFormat : {00000000-0000-0000-0000-000000000000}
[4020]  
[4020] 
[4020]  wSamplesPerBlock : 0 
[4020] Valid bits per sample : 0
[4020]  
[4020] 
[4020]  WAVEFORMATEX :
[4020]  wFormatTag : 
[4020] PCM
[4020] 
[4020]  
[4020] cbSize : 22 
[4020] nAvgBytesPerSec : 176400 
[4020] Channels : 2 
[4020] Bits per sample : 16 
[4020]  Samples per second : 44100 
[4020]  nBlockAlign : 4
[4020]  
[4020] CMpcAudioRenderer::InitAudioClient format supported
[4020] CMpcAudioRenderer::InitAudioClient [COLOR="Red"][B]failed (80070057)[/B][/COLOR]
 
Hi again, I really don't understand why wasapi fails on this one
It says that the format is supported but then it says E_INVALIDARG for the initialization

Code:
[4020] CMpcAudioRenderer::InitAudioClient
[4020] 
[4020]  WAVEFORMATEXTENSIBLE :
[4020]  subFormat : {00000000-0000-0000-0000-000000000000}
[4020]  
[4020] 
[4020]  wSamplesPerBlock : 0 
[4020] Valid bits per sample : 0
[4020]  
[4020] 
[4020]  WAVEFORMATEX :
[4020]  wFormatTag : 
[4020] PCM
[4020] 
[4020]  
[4020] cbSize : 22 
[4020] nAvgBytesPerSec : 176400 
[4020] Channels : 2 
[4020] Bits per sample : 16 
[4020]  Samples per second : 44100 
[4020]  nBlockAlign : 4
[4020]  
[4020] CMpcAudioRenderer::InitAudioClient format supported
[4020] CMpcAudioRenderer::InitAudioClient [COLOR="Red"][B]failed (80070057)[/B][/COLOR]
I have seen "format supported" but InitAudioClient failed, but the error code was different, not E_INVALIDARG, which is strange. Other formats work with the same code? Buffer size too small/large? Don't trust most of the Wasapi functions like GetDevicePeriod() or others which "suggest" something for you. Never trust anyone, especially hardware manufacturers writing drivers. Or Microsoft. ;)
 
OK, I have made it !

This nearly works now : I have modified FFDShow to parse the stream enough to detect if it is real AC3 or TrueHD in order to initialize the audio client once.

However, clearly the driver is in fault because I don't get the same result from 1 PC to another.

SamuriHL tested it (cause I don't have any radeon 4xxx or 5xxx) and he "saw the light" on his receiver (true HD light)

But he didn't get any sound.

To summarize : I think that the header is correct, I followed the IEC guidlines that I sent to you (15360 bytes for each IEC frame)
So I have :
[ 15360 bytes ]
<IEC header><MLP frame>< silence >

To do that, I also stripped of the AC3 frames from the TrueHD stream in order to get only a MLP frame.

One weird thing about Wasapi is that he thinks by frame and not by bytes when you feed the buffer. So I try to feed the buffer frame by frame but shouldn't I feed it byte by byte without taking care if half a frame is filled in ?

Another weird thing where you could help me is the sleep duration.
MS says to sleep half the duration of the frames filled in. Is this correct or do you use another approach (I saw that you could work with events instead but I am not sure this would work on vista or on directshow)
Code:
// Sleep for half the buffer duration.
  hnsActualDuration=(double)10000000 * numFramesAvailable / m_pWaveFileFormat->nSamplesPerSec;
  Sleep((DWORD)(hnsActualDuration/10000/2));


Here is our code which works fine for AC3 and DTS
length is the length of the IEC frame
size is the length of the compressed (MLP) frame
type is the type of stream according to IEC table

Code:
    DWORD type = 0x0001;
    short subDataType = 0; // TODO : 0 for all these formats (but different for AAC and WMA Pro)
    short errorFlag = 0;
    short datatypeInfo = 0;
    short bitstreamNumber = 0;
    switch (codecId)
    {
     case CODEC_ID_SPDIF_AC3:type=1;length=2048;break;
     case CODEC_ID_BITSTREAM_TRUEHD:type=22;length=15360;break;
     case CODEC_ID_BITSTREAM_EAC3:type=21;length=6144;break;
...

    }

   DWORD Pc=type | (subDataType << 5) | (errorFlag << 7) | (datatypeInfo << 8) | (bitstreamNumber << 13);

   // TODO : insert pause between data bursts for audio/video syncs according to each format recommandations

   memset(pDataOut + 16 + size, 0, length -16 - size);
   WORD *pDataOutW=(WORD*)pDataOut;
   pDataOutW[0] = pDataOutW[1] = pDataOutW[2] = pDataOutW[3] = 0;
   pDataOutW[4]=0xf872;
   pDataOutW[5]=0x4e1f;
   pDataOutW[6]=Pc;
   pDataOutW[7]=WORD(size*8);
   _swab((char*)buf,(char*)&pDataOutW[8],(int)(size & ~1));
   if (size & 1) // _swab doesn't like odd number.
    {
     pDataOut[16 + size] = ((BYTE*)buf)[size - 1];
     pDataOut[15 + size] = 0;
    }

On the renderer side :
Code:
 pInputBufferPointer=&pMediaBuffer[0];

 UINT frameSize = m_pWaveFileFormat->nChannels * 
	 		    m_pWaveFileFormat->wBitsPerSample / 8;

	// Each loop fills one of the two buffers.
 while (flags != AUDCLNT_BUFFERFLAGS_SILENT)
 {
  UINT32 numFramesPadding;
  pAudioClient->GetCurrentPadding(&numFramesPadding);
  UINT32 numFramesAvailable = bufferFrameCount - numFramesPadding;

  // If remaining input bytes < output size of buffer, reduce the size to write
  if (&pMediaBuffer[0]+lSize-pInputBufferPointer < numFramesAvailable*frameSize)
  {
   numFramesAvailable = (&pMediaBuffer[0]+lSize-pInputBufferPointer)/frameSize;
  }

  // Grab the next empty buffer from the audio device.
  hr = pRenderClient->GetBuffer(numFramesAvailable, &pData);
  if (FAILED (hr)) return hr;


  // Load the buffer with data from the audio source.
  if (pData != NULL)
		{
			memcpy(&pData[0], pInputBufferPointer, numFramesAvailable*frameSize);
			pInputBufferPointer += numFramesAvailable*frameSize;
		}
  hr = pRenderClient->ReleaseBuffer(numFramesAvailable, flags);
  if (FAILED (hr)) return hr;

  // Sleep for half the buffer duration.
  hnsActualDuration=(double)10000000 * numFramesAvailable / m_pWaveFileFormat->nSamplesPerSec;
  Sleep((DWORD)(hnsActualDuration/10000/2));

  if (pInputBufferPointer >= &pMediaBuffer[0] + lSize)
   break;
 }

I know this is a big post, but we are really close to the solution, so any hint would be helpful

Thanks

Damien
 
Correct. I can see the TrueHD light come on but I get no sound. So if this remaining problem can be overcome, I think we've got TrueHD bitstreaming in the bag. That'd rock!
 
A TrueHD stream is composed of Major sync frames and non major frames, maybe I have to feed the driver with series of
Major1-non major 11-non major 12-...-nonmajor 1N

Major2-non major 21...

Because otherwise each frame is less than 200 bytes
 
I have some experience on sending TrueHD, DTSHD, EAC3 bitstream to the receiver. (It works here.) I want to provide some help on this.

Did you swap the bytes of the MAT/MLP file?
 
Which environment you are testing on?
5870 on Vista?

I want to try it on my side.
 
Oh, seriously?! SWEET! I'm sure albain would appreciate the help. PM him here or on doom9 and see what he needs help with. He's working on a tool right now that will see what the driver supports and possibly capture truehd/dts-hd ma/etc as it's being bitstreamed to the receiver. If you have knowledge that can help him get past the current issues, I'm sure he'd be very interested. Thanks!!

P.S. I'm testing with my 5870 on W7 x64.
 
I have some experience on sending TrueHD, DTSHD, EAC3 bitstream to the receiver. (It works here.) I want to provide some help on this.

Did you swap the bytes of the MAT/MLP file?

Great, thanks !

Yes I swapped the bytes. I also sent the major frame with all the non major in a whole IEC frame

Concerning the size : I coded it in bytes (instead of bits for AC3/DTS)

Also what I am not sure about is the length of each IEC frames : should it be fixed or a multiple of something ?

If I send you an m2ts file could you be able to get me the stream in bytes in a file ?

Otherwise I am working on another option to get this format
 
Back
Top