我正在制作一个也有视频支持的voip应用程序,
对于视频,我将数据作为YUV格式获取并解码我正在使用libvpx,
然后我将RGB数据,
现在显示我正在使用NSImageView我将更改NSImage,请参考下面的代码
-(void)gotNewRGBBuffer:(void *)imageData Height:(int)height Width:(int)width Scan:(int)scan VideoId:(const char *)pId{
@autoreleasepool {
// display the image (on the UI thread)
NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:(unsigned char **)&imageData
pixelsWide:width pixelsHigh:height
bitsPerSample:8
samplesPerPixel:3 // or 4 with alpha
hasAlpha:NO
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bitmapFormat:0
bytesPerRow:scan // 0 == determine automatically
bitsPerPixel:24]; // 0 == determine automatically
NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
[image addRepresentation:bitmap];
if ( ![NSThread isMainThread]){
[self performSelectorOnMainThread:@selector(updateImage:) withObject:image waitUntilDone:NO];
}else{
[self updateImage:image];
}
}
}
并在此处更新图像的功能,
-(void)updateImage:(NSImage *)pNewLocalImage{
[self pImageView].image = pNewLocalImage;
[[self pImageView] setNeedsDisplay:YES];
NSLog(@" Updating the image ");
}
这是有效的,但是需要相当多的内存,所以我的问题是,有没有其他方法来优化它!
答案 0 :(得分:0)
感谢您查看此内容,
我现在转移到OpenGL NSOpenGLView,它可以快速渲染并消耗更少的CPU和内存,
参考代码:
在给定的例子中,它将绘制PNG图像,但我需要有YUV缓冲区,所以你需要像这样调整顶点和着色器,
- (BOOL)setupProgram {
NSAssert(!_program, @"program already set up");
GLuint vertexShader = CreateShader(GL_VERTEX_SHADER, kVertexShaderSource);
NSAssert(vertexShader, @"failed to create vertex shader");
GLuint fragmentShader =
CreateShader(GL_FRAGMENT_SHADER, kFragmentShaderSource);
NSAssert(fragmentShader, @"failed to create fragment shader");
_program = CreateProgram(vertexShader, fragmentShader);
// Shaders are created only to generate program.
if (vertexShader) {
glDeleteShader(vertexShader);
}
if (fragmentShader) {
glDeleteShader(fragmentShader);
}
if (!_program) {
return NO;
}
_position = glGetAttribLocation(_program, "position");
_texcoord = glGetAttribLocation(_program, "texcoord");
_ySampler = glGetUniformLocation(_program, "s_textureY");
_uSampler = glGetUniformLocation(_program, "s_textureU");
_vSampler = glGetUniformLocation(_program, "s_textureV");
if (_position < 0 || _texcoord < 0 || _ySampler < 0 || _uSampler < 0 ||
_vSampler < 0) {
return NO;
}
return YES;
}
顶点和着色器源,
// Vertex shader doesn't do anything except pass coordinates through.
static const char kVertexShaderSource[] =
SHADER_VERSION
VERTEX_SHADER_IN " vec2 position;\n"
VERTEX_SHADER_IN " vec2 texcoord;\n"
VERTEX_SHADER_OUT " vec2 v_texcoord;\n"
"void main() {\n"
" gl_Position = vec4(position.x, position.y, 0.0, 1.0);\n"
" v_texcoord = texcoord;\n"
"}\n";
// Fragment shader converts YUV values from input textures into a final RGB
// pixel. The conversion formula is from http://www.fourcc.org/fccyvrgb.php.
static const char kFragmentShaderSource[] =
SHADER_VERSION
"precision highp float;"
FRAGMENT_SHADER_IN " vec2 v_texcoord;\n"
"uniform lowp sampler2D s_textureY;\n"
"uniform lowp sampler2D s_textureU;\n"
"uniform lowp sampler2D s_textureV;\n"
FRAGMENT_SHADER_OUT
"void main() {\n"
" float y, u, v, r, g, b;\n"
" y = " FRAGMENT_SHADER_TEXTURE "(s_textureY, v_texcoord).r;\n"
" u = " FRAGMENT_SHADER_TEXTURE "(s_textureU, v_texcoord).r;\n"
" v = " FRAGMENT_SHADER_TEXTURE "(s_textureV, v_texcoord).r;\n"
" u = u - 0.5;\n"
" v = v - 0.5;\n"
" r = y + 1.403 * v;\n"
" g = y - 0.344 * u - 0.714 * v;\n"
" b = y + 1.770 * u;\n"
" " FRAGMENT_SHADER_COLOR " = vec4(r, g, b, 1.0);\n"
" }\n";