DirectShow + HAP implementation


#1

Hello again,

It has been some time I was playing around with hap blocks. The< all work fine with quicktime, but since there is no support, I went for a DirectShow solution. Openframeworks did it and it is working and since the implementation is pretty straight forward, I went and implemented a cinderHap player. The source is almost the same. After I almost finished with it, a wild error appeared.

I can’t use “glPushClientAttrib”, “GL_CLIENT_PIXEL_STORE_BIT” or “glPopClientAttrib”. They are in glew.h, but including it caused a few headaches. Can it be done? How?

Here is the snippet from openframeworks. Cinder implementation is almost the same.

if (!ofIsGLProgrammableRenderer())
{
    glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
    glEnable(GL_TEXTURE_2D);
}

glBindTexture(GL_TEXTURE_2D, texData.textureID);

GLint dataLength = 0;

if (textureFormat == HapTextureFormat_RGB_DXT1){

    dataLength = width * height / 2;
}
else {

    //dataLength = player->getBufferSize(); 
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &dataLength);
}
glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, texData.glInternalFormat, dataLength, pix.getPixels());

GLenum err = glGetError();

if (err != GL_NO_ERROR){

    // printf("error %s\n", gluErrorString(err));
	int error = 1;
}

if (!ofIsGLProgrammableRenderer())
{
    glPopClientAttrib();
    glDisable(GL_TEXTURE_2D);
}

I tried creating / updating current texture vid Surface (data gets fulled via STDMETHODIMP SampleCB(long Time, IMediaSample *pSample). The result is not ok:

Comparing both implementations side by side there were no differences whatsoever. Except those three defines so the solution probably lies in including glew.h without redefinitions, missing implementations, right? Or is there an alternative way to fix this.

I’ve used the samples from here.

Thank you


HAPQ alpha support
#2

As far as I know OF’s programmable renderer is what Cinder has: modern OpenGL. glPushClientAttrib/glPopClientAttrib are legacy OpenGL, so you cannot use them. Because of this you don’t need to add them to the Cinder port.


#3

I see. How can I achieve the same result inside cinder then?

I thought declaring all formats and sizes for cinders Surface would work, but it seems I missed something. Buffer is clearly updating, all events (end if video file) and controllers work (play, pause, stop, start), but created end texture is not as expected.

What am I missing here?


#4

I should have been more clear. I just meant that I think OF is not using that part of the code either, so you should not worry about porting them. The issue is probably somewhere else.


#5

Here is an update - glGetError is generated in this line:

glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, texData.getInternalFormat() , dataLength, mSurface->getData());

where width = 1920, height = 1080 (sample video), internal format is GL_COMPRESSED_RGB_S3TC_DXT1_EXT (33776), dataLength = 1036800.

mSurface data is updated like so:

memcpy(dstBuffer, rawBuffer, videoSize);

where rawBuffer gets updated @ STDMETHODIMP SampleCB(long Time, IMediaSample *pSample) with memcpy(rawBuffer, ptrBuffer + 4, sz);

As said before all buffers side by side look the same. But in cinder environment glCompressedTexSubImage2D throws an exception/error (GL_INVALID_ENUM). But they both (format and target) look the same as on of side.


#6

Hi,

With the help of these guys I’ve managed to overcome this issue. The large majority of the port was done by @dave, I am basically responsible just for overcoming the hurdle he talks about above.

A working sample can be downloaded on HAP-Cinder repo.


OpenGL Extensions (Glew,Glee,Gloader)