summaryrefslogtreecommitdiff
path: root/pjmedia
diff options
context:
space:
mode:
authorLiong Sauw Ming <ming@teluu.com>2014-09-22 07:03:25 +0000
committerLiong Sauw Ming <ming@teluu.com>2014-09-22 07:03:25 +0000
commit74e9fd84c72a87cc00e659eddb34b4f8f970a7b8 (patch)
tree511b7b83ad86f8e38d193d03428a5cbbb6d846ae /pjmedia
parent7e466f2b480ba0120aa15e9ca63edd18f7364af6 (diff)
Re #1790: Use OpenGL textures instead of platform dependent textures.
This revision contains: * remove the generation of iOS texture (instead directly use OpenGL textures) * add iOS and Android window type git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4925 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia')
-rw-r--r--pjmedia/include/pjmedia-videodev/opengl_dev.h7
-rw-r--r--pjmedia/include/pjmedia-videodev/videodev.h15
-rw-r--r--pjmedia/src/pjmedia-videodev/ios_opengl_dev.m89
-rw-r--r--pjmedia/src/pjmedia-videodev/opengl_dev.c94
4 files changed, 87 insertions, 118 deletions
diff --git a/pjmedia/include/pjmedia-videodev/opengl_dev.h b/pjmedia/include/pjmedia-videodev/opengl_dev.h
index 750df8e5..3763b2f0 100644
--- a/pjmedia/include/pjmedia-videodev/opengl_dev.h
+++ b/pjmedia/include/pjmedia-videodev/opengl_dev.h
@@ -40,14 +40,13 @@ pjmedia_vid_dev_opengl_imp_create_stream(pj_pool_t *pool,
typedef struct gl_buffers gl_buffers;
/* Create OpenGL buffers. */
-void pjmedia_vid_dev_opengl_create_buffers(pj_pool_t *pool,
+void pjmedia_vid_dev_opengl_create_buffers(pj_pool_t *pool, pj_bool_t direct,
gl_buffers **glb);
/* Initialize OpenGL buffers. */
pj_status_t pjmedia_vid_dev_opengl_init_buffers(gl_buffers *glb);
/* Render a texture. */
-pj_status_t pjmedia_vid_dev_opengl_draw(gl_buffers *glb,
- unsigned int texture,
- unsigned int name);
+pj_status_t pjmedia_vid_dev_opengl_draw(gl_buffers *glb,unsigned int width,
+ unsigned int height, void *pixels);
/* Destroy OpenGL buffers. */
void pjmedia_vid_dev_opengl_destroy_buffers(gl_buffers *glb);
diff --git a/pjmedia/include/pjmedia-videodev/videodev.h b/pjmedia/include/pjmedia-videodev/videodev.h
index d7def15b..0bcb1686 100644
--- a/pjmedia/include/pjmedia-videodev/videodev.h
+++ b/pjmedia/include/pjmedia-videodev/videodev.h
@@ -58,7 +58,17 @@ typedef enum pjmedia_vid_dev_hwnd_type
/**
* Native window handle on Windows.
*/
- PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS
+ PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS,
+
+ /**
+ * Native view on iOS.
+ */
+ PJMEDIA_VID_DEV_HWND_TYPE_IOS,
+
+ /**
+ * Native window handle on Android.
+ */
+ PJMEDIA_VID_DEV_HWND_TYPE_ANDROID
} pjmedia_vid_dev_hwnd_type;
@@ -90,6 +100,9 @@ typedef struct pjmedia_vid_dev_hwnd
struct {
void *window; /**< Window */
} ios;
+ struct {
+ void *window; /**< Native window */
+ } android;
void *window;
} info;
diff --git a/pjmedia/src/pjmedia-videodev/ios_opengl_dev.m b/pjmedia/src/pjmedia-videodev/ios_opengl_dev.m
index 77ad6ba2..150fcad5 100644
--- a/pjmedia/src/pjmedia-videodev/ios_opengl_dev.m
+++ b/pjmedia/src/pjmedia-videodev/ios_opengl_dev.m
@@ -34,13 +34,12 @@
typedef struct iosgl_fmt_info
{
pjmedia_format_id pjmedia_format;
- UInt32 iosgl_format;
} iosgl_fmt_info;
/* Supported formats */
static iosgl_fmt_info iosgl_fmts[] =
{
- {PJMEDIA_FORMAT_BGRA, kCVPixelFormatType_32BGRA} ,
+ {PJMEDIA_FORMAT_BGRA} ,
};
@interface GLView : UIView
@@ -65,14 +64,11 @@ struct iosgl_stream
pj_timestamp frame_ts;
unsigned ts_inc;
pjmedia_rect_size vid_size;
+ const pjmedia_frame *frame;
gl_buffers *gl_buf;
GLView *gl_view;
EAGLContext *ogl_context;
- CVOpenGLESTextureCacheRef vid_texture;
- CVImageBufferRef pb;
- void *pb_addr;
- CVOpenGLESTextureRef texture;
};
@@ -153,7 +149,8 @@ static iosgl_fmt_info* get_iosgl_format_info(pjmedia_format_id id)
}
/* Create GL buffers */
- pjmedia_vid_dev_opengl_create_buffers(stream->pool, &stream->gl_buf);
+ pjmedia_vid_dev_opengl_create_buffers(stream->pool, PJ_FALSE,
+ &stream->gl_buf);
[stream->ogl_context renderbufferStorage:GL_RENDERBUFFER
fromDrawable:(CAEAGLLayer *)[stream->gl_view layer]];
@@ -174,9 +171,8 @@ static iosgl_fmt_info* get_iosgl_format_info(pjmedia_format_id id)
return;
}
- pjmedia_vid_dev_opengl_draw(stream->gl_buf,
- (unsigned int)CVOpenGLESTextureGetTarget(stream->texture),
- (unsigned int)CVOpenGLESTextureGetName(stream->texture));
+ pjmedia_vid_dev_opengl_draw(stream->gl_buf, stream->vid_size.w, stream->vid_size.h,
+ stream->frame->buf);
}
@end
@@ -193,7 +189,6 @@ pjmedia_vid_dev_opengl_imp_create_stream(pj_pool_t *pool,
const pjmedia_video_format_detail *vfd;
pj_status_t status = PJ_SUCCESS;
CGRect rect;
- CVReturn err;
strm = PJ_POOL_ZALLOC_T(pool, struct iosgl_stream);
pj_memcpy(&strm->param, param, sizeof(*param));
@@ -230,17 +225,6 @@ pjmedia_vid_dev_opengl_imp_create_stream(pj_pool_t *pool,
goto on_error;
}
- /* Create a new CVOpenGLESTexture cache */
- err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL,
- strm->ogl_context, NULL,
- &strm->vid_texture);
- if (err) {
- PJ_LOG(3, (THIS_FILE, "Unable to create OpenGL texture cache %d",
- err));
- status = PJMEDIA_EVID_SYSERR;
- goto on_error;
- }
-
/* Apply the remaining settings */
if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
iosgl_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW,
@@ -343,13 +327,7 @@ static pj_status_t iosgl_stream_set_cap(pjmedia_vid_dev_stream *s,
pj_memcpy(&strm->vid_size, &vfd->size, sizeof(vfd->size));
if (strm->param.disp_size.w == 0 || strm->param.disp_size.h == 0)
pj_memcpy(&strm->param.disp_size, &vfd->size, sizeof(vfd->size));
-
- /* Invalidate the buffer */
- if (strm->pb) {
- CVPixelBufferRelease(strm->pb);
- strm->pb = NULL;
- }
-
+
return PJ_SUCCESS;
} else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
UIView *view = (UIView *)pval;
@@ -410,45 +388,8 @@ static pj_status_t iosgl_stream_put_frame(pjmedia_vid_dev_stream *strm,
const pjmedia_frame *frame)
{
struct iosgl_stream *stream = (struct iosgl_stream*)strm;
- CVReturn err;
-
- /* Pixel buffer will only create a wrapper for the frame's buffer,
- * so if the frame buffer changes, we have to recreate pb
- */
- if (!stream->pb || (frame->buf && stream->pb_addr != frame->buf)) {
- if (stream->pb) {
- CVPixelBufferRelease(stream->pb);
- stream->pb = NULL;
- }
- err = CVPixelBufferCreateWithBytes(kCFAllocatorDefault,
- stream->vid_size.w,
- stream->vid_size.h,
- kCVPixelFormatType_32BGRA,
- frame->buf,
- stream->vid_size.w * 4,
- NULL, NULL, NULL, &stream->pb);
- if (err) {
- PJ_LOG(3, (THIS_FILE, "Unable to create pixel buffer %d", err));
- return PJMEDIA_EVID_SYSERR;
- }
- stream->pb_addr = frame->buf;
- }
-
- /* Create a CVOpenGLESTexture from the CVImageBuffer */
- err=CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
- stream->vid_texture,
- stream->pb, NULL,
- GL_TEXTURE_2D, GL_RGBA,
- stream->vid_size.w,
- stream->vid_size.h,
- GL_BGRA,
- GL_UNSIGNED_BYTE,
- 0, &stream->texture);
- if (!stream->texture || err) {
- PJ_LOG(3, (THIS_FILE, "Unable to create OpenGL texture %d", err));
- return PJMEDIA_EVID_SYSERR;
- }
+ stream->frame = frame;
/* Perform OpenGL drawing in the main thread. */
[stream->gl_view performSelectorOnMainThread:@selector(render)
withObject:nil waitUntilDone:YES];
@@ -456,10 +397,6 @@ static pj_status_t iosgl_stream_put_frame(pjmedia_vid_dev_stream *strm,
// ^{[stream->gl_view render];});
[stream->ogl_context presentRenderbuffer:GL_RENDERBUFFER];
-
- /* Flush the CVOpenGLESTexture cache and release the texture */
- CVOpenGLESTextureCacheFlush(stream->vid_texture, 0);
- CFRelease(stream->texture);
return PJ_SUCCESS;
}
@@ -486,16 +423,6 @@ static pj_status_t iosgl_stream_destroy(pjmedia_vid_dev_stream *strm)
iosgl_stream_stop(strm);
- if (stream->pb) {
- CVPixelBufferRelease(stream->pb);
- stream->pb = NULL;
- }
-
- if (stream->vid_texture) {
- CFRelease(stream->vid_texture);
- stream->vid_texture = NULL;
- }
-
if ([EAGLContext currentContext] == stream->ogl_context)
[EAGLContext setCurrentContext:nil];
diff --git a/pjmedia/src/pjmedia-videodev/opengl_dev.c b/pjmedia/src/pjmedia-videodev/opengl_dev.c
index 7db7dba4..9dd26d37 100644
--- a/pjmedia/src/pjmedia-videodev/opengl_dev.c
+++ b/pjmedia/src/pjmedia-videodev/opengl_dev.c
@@ -26,8 +26,14 @@
#include <pjmedia-videodev/opengl_dev.h>
#ifdef PJMEDIA_VIDEO_DEV_HAS_OPENGL_ES
-# include <OpenGLES/ES2/gl.h>
-# include <OpenGLES/ES2/glext.h>
+# if PJ_ANDROID
+# include <GLES2/gl2.h>
+# include <GLES2/gl2ext.h>
+# define GL_BGRA GL_RGBA
+# else
+# include <OpenGLES/ES2/gl.h>
+# include <OpenGLES/ES2/glext.h>
+# endif
#else
# include <GL/gl.h>
# include <GL/glext.h>
@@ -39,7 +45,11 @@
#define DEFAULT_HEIGHT 360
#define DEFAULT_FPS 15
-#define LOG(a)
+#if PJ_ANDROID
+# define LOG(a) PJ_LOG(3, (THIS_FILE, a))
+#else
+# define LOG(a)
+#endif
enum {
ATTRIB_VERTEX,
@@ -69,12 +79,14 @@ void main() \
/* OpenGL buffers structure. */
struct gl_buffers {
- GLuint frameBuf;
- GLuint rendBuf;
- GLuint directProg;
-
- int rendBufW;
- int rendBufH;
+ GLuint frameBuf;
+ GLuint rendBuf;
+ GLuint rendTex;
+ GLuint directProg;
+
+ int rendBufW;
+ int rendBufH;
+ pj_bool_t direct;
};
/* Supported formats */
@@ -200,18 +212,23 @@ GLint create_program(const GLchar *vertSource, const GLchar *fragSource,
return status;
}
-void pjmedia_vid_dev_opengl_create_buffers(pj_pool_t *pool, gl_buffers **glb)
+void pjmedia_vid_dev_opengl_create_buffers(pj_pool_t *pool, pj_bool_t direct,
+ gl_buffers **glb)
{
gl_buffers *glbuf = PJ_POOL_ZALLOC_T(pool, gl_buffers);
*glb = glbuf;
glDisable(GL_DEPTH_TEST);
- glGenFramebuffers(1, &glbuf->frameBuf);
- glBindFramebuffer(GL_FRAMEBUFFER, glbuf->frameBuf);
+ if (!(glbuf->direct = direct)) {
+ glGenFramebuffers(1, &glbuf->frameBuf);
+ glBindFramebuffer(GL_FRAMEBUFFER, glbuf->frameBuf);
+
+ glGenRenderbuffers(1, &glbuf->rendBuf);
+ glBindRenderbuffer(GL_RENDERBUFFER, glbuf->rendBuf);
+ }
- glGenRenderbuffers(1, &glbuf->rendBuf);
- glBindRenderbuffer(GL_RENDERBUFFER, glbuf->rendBuf);
+ glGenTextures(1, &glbuf->rendTex);
}
pj_status_t pjmedia_vid_dev_opengl_init_buffers(gl_buffers *glb)
@@ -221,16 +238,18 @@ pj_status_t pjmedia_vid_dev_opengl_init_buffers(gl_buffers *glb)
ATTRIB_TEXTUREPOSITON };
GLchar *attribName[NUM_ATTRIBUTES] = { "position", "texCoord" };
- glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH,
- &glb->rendBufW);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT,
- &glb->rendBufH);
-
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_RENDERBUFFER, glb->rendBuf);
- if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
- LOG("Unable to create frame buffer");
- return -1;
+ if (!glb->direct ) {
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH,
+ &glb->rendBufW);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT,
+ &glb->rendBufH);
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER, glb->rendBuf);
+ if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+ LOG("Unable to create frame buffer");
+ return -1;
+ }
}
create_program(vertSrc, fragSrc, NUM_ATTRIBUTES,
@@ -245,8 +264,8 @@ pj_status_t pjmedia_vid_dev_opengl_init_buffers(gl_buffers *glb)
return PJ_SUCCESS;
}
-pj_status_t pjmedia_vid_dev_opengl_draw(gl_buffers *glb, unsigned int texture,
- unsigned int name)
+pj_status_t pjmedia_vid_dev_opengl_draw(gl_buffers *glb, unsigned int width,
+ unsigned int height, void *pixels)
{
static const GLfloat squareVertices[] = {
-1.0f, -1.0f,
@@ -257,10 +276,8 @@ pj_status_t pjmedia_vid_dev_opengl_draw(gl_buffers *glb, unsigned int texture,
GLfloat textureVertices[] = {
0, 1, 1, 1, 0, 0, 1, 0
};
- GLenum tex = (GLenum) texture;
- GLuint nam = (GLuint) name;
- glBindTexture(tex, nam);
+ glBindTexture(GL_TEXTURE_2D, glb->rendTex);
/* Set texture parameters */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -268,10 +285,17 @@ pj_status_t pjmedia_vid_dev_opengl_draw(gl_buffers *glb, unsigned int texture,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glBindFramebuffer(GL_FRAMEBUFFER, glb->frameBuf);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height,
+ 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)pixels);
+
+ glFlush();
+
+ /* Do we render directly to the screen? */
+ glBindFramebuffer(GL_FRAMEBUFFER, (glb->direct? 0: glb->frameBuf));
/* Set the view port to the entire view */
- glViewport(0, 0, glb->rendBufW, glb->rendBufH);
+ glViewport(0, 0, (glb->direct? width: glb->rendBufW),
+ (glb->direct? height: glb->rendBufH));
/* Draw the texture on the screen with OpenGL ES 2 */
/* Use program */
@@ -288,7 +312,8 @@ pj_status_t pjmedia_vid_dev_opengl_draw(gl_buffers *glb, unsigned int texture,
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
/* Present */
- glBindRenderbuffer(GL_RENDERBUFFER, glb->rendBuf);
+ if (!glb->direct)
+ glBindRenderbuffer(GL_RENDERBUFFER, glb->rendBuf);
return PJ_SUCCESS;
}
@@ -305,6 +330,11 @@ void pjmedia_vid_dev_opengl_destroy_buffers(gl_buffers *glb)
glb->rendBuf = 0;
}
+ if (glb->rendTex) {
+ glDeleteTextures(1, &glb->rendTex);
+ glb->rendTex = 0;
+ }
+
if (glb->directProg) {
glDeleteProgram(glb->directProg);
glb->directProg = 0;