FFMPEG (ayrı bir iş parçacığında) kullanarak video dosyasını çözen ve bu dokuyu başka bir PBO kullanarak oluşturan bir uygulamaya sahibim. Tüm PBO do-Hickey aşağıdaki fonksiyonu olur:Birden çok Piksel Tamponu Nesnesi kullanarak Video Texture güncellenirken kesinti
kod çözme threadvoid DynamicTexture::update()
{
if(!_isDirty)
{
return;
}
/// \todo Check to make sure that PBOs are supported
if(_usePbo)
{
// In multi PBO mode, we keep swapping between the PBOs
// We use one PBO to actually set the texture data that we will upload
// and the other we use to update/modify. Once modification is complete,
// we simply swap buffers
// Unmap the PBO that was updated last so that it can be released for rendering
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _pboIds[_currentPboIndex]);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
Util::GLErrorAssert();
// bind the texture
glBindTexture(GL_TEXTURE_2D, _textureId);
Util::GLErrorAssert();
// copy pixels from PBO to texture object
// Use offset instead of pointer.
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _width, _height,
(_channelCount==4)?GL_RGBA:GL_RGB,
GL_UNSIGNED_BYTE, 0);
Util::GLErrorAssert();
// Now swap the pbo index
_currentPboIndex = (++_currentPboIndex) % _numPbos;
// bind PBO to update pixel values
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _pboIds[_currentPboIndex]);
Util::GLErrorAssert();
// map the next buffer object into client's memory
// Note that glMapBuffer() causes sync issue.
// If GPU is working with this buffer, glMapBuffer() will wait(stall)
// for GPU to finish its job
GLubyte* ptr = (GLubyte*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
Util::GLErrorAssert();
if(ptr)
{
// update data directly on the mapped buffer
_currentBuffer = ptr;
Util::GLErrorAssert();
}
else
{
printf("Unable to map PBO!");
assert(false);
}
// It is good idea to release PBOs with ID 0 after use.
// Once bound with 0, all pixel operations behave normal ways.
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
Util::GLErrorAssert();
// If a callback was registered, call it
if(_renderCallback)
{
(*_renderCallback)(this);
}
}
else
{
glBindTexture(GL_TEXTURE_2D, _textureId);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
_width, _height, (_channelCount==4)?GL_RGBA:GL_RGB,
GL_UNSIGNED_BYTE,
&(_buffer[0])
);
Util::GLErrorAssert();
}
// Reset the dirty flag after updating
_isDirty = false;
}
, ben sadece _currentBuffer güncelleme ve true _isDirty bayrağını ayarlayın. Bu işlev render iş parçacığında çağrılır.
Tek bir PBO kullandığımda, yani yukarıdaki kodda _numPbos = 1 olduğunda, oluşturma herhangi bir kesiklik olmadan düzgün çalışır. Bununla birlikte, birden fazla PBO kullandığımda, videoda görünür bir kekem var. _numPbos = 2 here ile 5 video görüntüleyen bir örnek bulabilirsiniz. Kullandığım daha fazla sayıda PBO'lar, daha da kötüsü olur.
Teorik olarak, güncelleştirdiğim arabellek ve arabellek için kullanıyorumdan daha farklı olan arabellek farklıdır, bu nedenle bu tür bir aksaklık olmamalıdır. Oluşturma performansını artırmak için çift/üçlü tamponlamayı kullanmak istiyorum.
Neyin yanlış gidebileceği konusunda bazı ipuçları/ipuçları arıyorum.
Hayır, bu değildi Sorun. GlUnmapBuffer çağrılması, arabellek nesnesinin artık geçerli olmadığı anlamına gelmez. Sadece sürücünün arabayı GPU belleğinde hareket ettirmesine izin verir. İstemci alanında yalnızca eşlemesi geçersiz kılınacaktır. – balajeerc