Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you switch the pixel format from <code>kCVPixelFormatType_420YpCbCr8BiPlanarFullRange</code> to <code>kCVPixelFormatType_32BGRA</code> (at line 315 of RippleViewController) then <code>captureOutput:didOutputSampleBuffer:fromConnection:</code> will receive a sample buffer in which the image buffer can be uploaded straight to OpenGL via <code>glTexImage2D</code> (or <code>glTexSubImage2D</code> if you want to keep your texture sized as a power of two). That works because all iOS devices to date support the <code>GL_APPLE_texture_format_BGRA8888</code> extension, allowing you to specify an otherwise non-standard format of <code>GL_BGRA</code>.</p> <p>So you'd create a texture somewhere in advance with <code>glGenTextures</code> and replace line 235 with something like:</p> <pre><code>glBindTexture(GL_TEXTURE_2D, myTexture); CVPixelBufferLockBaseAddress(pixelBuffer); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer), GL_BGRA, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddress(pixelBuffer)); CVPixelBufferUnlockBaseAddress(pixelBuffer); </code></pre> <p>You may want to check that the result of <code>CVPixelBufferGetBytesPerRow</code> is four times the result of <code>CVPixelBufferGetWidth</code>; I'm uncertain from the documentation whether it's guaranteed always to be (which, pragmatically, probably means that it isn't), but as long as it's a multiple of four you can just supply <code>CVPixelBufferGetBytesPerRow</code> divided by four as your pretend width, given that you're uploading a sub image anyway.</p> <p>EDIT: in response to the follow-on question posted below as a comment, if you wanted to stick with receiving frames and making them available to the GPU in YUV then the code becomes visually ugly because what you're returned is a structure pointing to the various channel components but you'd want something like this:</p> <pre><code>// lock the base address, pull out the struct that'll show us where the Y // and CbCr information is actually held CVPixelBufferLockBaseAddress(pixelBuffer); CVPlanarPixelBufferInfo_YCbCrBiPlanar *info = CVPixelBufferGetBaseAddress(imageBuffer); // okay, upload Y. You'll want to communicate this texture to the // SamplerY uniform within the fragment shader. glBindTexture(GL_TEXTURE_2D, yTexture); uint8_t *yBaseAddress = (uint8_t *)info + EndianU32_BtoN(info-&gt;componentInfoY.offset); uint32_t yRowBytes = EndianU32_BtoN(info-&gt;componentInfoY.rowBytes); /* TODO: check that yRowBytes is equal to CVPixelBufferGetWidth(pixelBuffer); otherwise you'll need to shuffle memory a little */ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer), GL_LUMINANCE, GL_UNSIGNED_BYTE, yBaseAddress); // we'll also need to upload the CbCr part of the buffer, as a two-channel // (ie, luminance + alpha) texture. This texture should be supplied to // the shader for the SamplerUV uniform. glBindTexture(GL_TEXTURE_2D, uvTexture); uint8_t *uvBaseAddress = (uint8_t *)info + EndianU32_BtoN(info-&gt;componentInfoCbCr.offset); uint32_t uvRowBytes = EndianU32_BtoN(info-&gt;componentInfoCbCr.rowBytes); /* TODO: a check on uvRowBytes, as above */ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, CVPixelBufferGetWidth(pixelBuffer)/2, CVPixelBufferGetHeight(pixelBuffer)/2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, uvBaseAddress); CVPixelBufferUnlockBaseAddress(pixelBuffer); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload