gpt4 book ai didi

ios - EAGLContexts 共享 EAGLSharegroup 在子类化 GLKView 时给出错误

转载 作者:行者123 更新时间:2023-12-04 23:28:24 25 4
gpt4 key购买 nike

我正在尝试使用 FFMPEG 创建一个播放器,该播放器可以使用 OpenGL 显示帧。 player类有三个线程:一个用于渲染(运行一个 runloop 并处理每 N 毫秒触发的渲染事件。) - 它获取 GLKTextureInfo存储在图片队列中并渲染。
第一个用于从 VideoStream 中读取数据包并将它们放入 videoQueue,第三个用于从 videoQueue 中获取数据包并对其进行解码并创建一个 GLKTextureInfo并将其存储在图片队列中。

案例一:player类子类 GLKView并创建一个 EAGLContext将其设置为其上下文,并在渲染线程中设置为 currentContext(它是第一个启动的线程)。

EAGLContext *mycontext = [self createBestEaglContext];
if (!self.mycontext || ![EAGLContext setCurrentContext:mycontext]) {
NSLog(@"Could not create Base EAGLContext");
return;
}
[self setContext:mycontext];

然后启动 stream decoding thread进而启动 Video Packet Decoding Thread如果它找到一个视频流。那么
// set's the params for the GLKBaseEffect
// set's up VBO's
// run's runloop
Video Packet Decoding Thread还创建 EAGLContext共享先前创建的上下文 EAGLSharegroup .
self.videoPacketDecodeThreadContext = [self createEaglContextForOtherThread];
if (!self.videoPacketDecodeThreadContext || ![EAGLContext setCurrentContext:self.videoPacketDecodeThreadContext])
{
NSLog(@"Could not create video packet decode thread context");
}

纹理部分
UIImage* image = [self ImageFromAVPicture:*(AVPicture*)pFrameRGB width:self.is.video_stream->codec->width height:self.is.video_stream->codec->height];

NSError *error = nil;
GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithCGImage:image.CGImage
options:nil
error:&error];
if (error)
{
NSLog(@"Texture loading Error: %@\n", error.description);
//return -1;
}
else
{
[self.is.pictQueue_lock lock];
[self.is.pictQueue enqueue:textureInfo];
[self.is.pictQueue_lock unlock];
}

我得到一个 错误 说: Failed to bind EAGLDrawable: <CAEAGLLayer: 0x156f7e50> to GL_RENDERBUFFER 1Failed to make complete framebuffer object 8cd6glerror 1280 .

案例二: Player不子类 GLKView相反,它被设置为 GLKView 的委托(delegate)。在 Storyboard 中创建。
-(void)initPlayerWithView:(GLKView*)v
{
self.view = v;
}

并按上述方式设置everyThing(将 self.view 上下文设置为 mycontext)一切运行良好。
-(void)drawRect:(CGRect)rect-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect都在 Rendering Thread 上调用.渲染代码:
    {
[self.is.pictQueue_lock lock];
GLKTextureInfo *textureInfo = (GLKTextureInfo*)[self.is.pictQueue dequeue];
[self.is.pictQueue_lock unlock];

// delete the previous texture
GLuint index = self.baseEffect.texture2d0.name;
glDeleteTextures(1, &index);

self.baseEffect.texture2d0.name = textureInfo.name;
self.baseEffect.texture2d0.target = textureInfo.target;

[self.baseEffect prepareToDraw];
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

// Enable vertex buffer
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glEnableVertexAttribArray(GLKVertexAttribPosition);

//Enable texture buffer
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, textureCoords));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);

glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);
}

如何解决案例 1 中的错误?另外,如果他们是我可以以不同方式做的其他事情,请建议如下:
  • 我使用了很多线程吗?
  • 我将解码的帧转换为 UIImage,然后从中创建纹理。可以做得不同吗?
  • 最佳答案

    我不关心 GLKView,我在 OSX 中使用 NSOpenGLView 编写了一个播放器,子类化在那里工作得很好,但我让它为我创建上下文。

    Am i using to many threads ?



    默认情况下,对于大多数编解码器,ffmpeg 使用 frame multithreading ,这意味着主解码线程什么都不做,它创建子线程并等待它们完成解码帧。 (对于实时通信,您还可以使用切片多线程,它可以减少延迟,但扩展性较差,并且需要比特流支持。)如果您没有做任何具体的说明,ffmpeg 使用帧多线程,而您的帧解码线程什么也没做。所以你不需要它。播放器线程可以直接解码视频。

    I am converting the decoded frame to a UIImage and then creating a texture from it. can it be done differently ?



    UIImage 是 RGB 格式,大多数视频解码器输出 YUV,所以这表明其他一些代码正在做软件 YUV-RGB 转换。这种RGB转换会很慢,很慢。

    相反,考虑一下openGL可以直接绘制YUV。所以我不会使用 UIImage,而是直接使用着色器绘制 YUV 平面,在硬件内部进行 YUV-RGB 转换。

    关于ios - EAGLContexts 共享 EAGLSharegroup 在子类化 GLKView 时给出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32247957/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com