From cf91c9ba00195c0c8c6cfe07612a74b946c821c1 Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Tue, 5 Jun 2012 08:48:12 +0200 Subject: [PATCH] FFMPEG decoding in color at 7 fps --- defines.h | 3 ++ main.cc | 6 +++ osdopengl.cc | 73 ++++++++++++++++++++++-------------- osdopengl.h | 2 +- shaders/frame__frag_shader.h | 63 +++++++++++++++++++++++++++++++ shaders/osd__frag_shader.h | 2 +- videovpeogl.cc | 26 +++++++++++-- videovpeogl.h | 6 ++- 8 files changed, 146 insertions(+), 35 deletions(-) mode change 100644 => 100755 main.cc create mode 100755 shaders/frame__frag_shader.h mode change 100644 => 100755 shaders/osd__frag_shader.h diff --git a/defines.h b/defines.h index c640c1b..c04928e 100755 --- a/defines.h +++ b/defines.h @@ -30,9 +30,12 @@ typedef unsigned long long ULLONG; #define OPTIONTYPE_TEXT 1 #define OPTIONTYPE_INT 2 +#define BENCHMARK_FPS + //ULLONG htonll(ULLONG a); //ULLONG ntohll(ULLONG a); void MILLISLEEP(ULONG a); +long long getTimeMS(); #ifdef WIN32 diff --git a/main.cc b/main.cc old mode 100644 new mode 100755 index 226f3e2..b91b671 --- a/main.cc +++ b/main.cc @@ -565,6 +565,12 @@ void MILLISLEEP(ULONG a) #endif } +long long getTimeMS() { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return ts.tv_sec*1000+ts.tv_nsec/1000000LL; +} + int min(UINT a, int b) { if (a > b) return b; diff --git a/osdopengl.cc b/osdopengl.cc index 682a4e9..fe19214 100755 --- a/osdopengl.cc +++ b/osdopengl.cc @@ -37,11 +37,7 @@ -long long getTimeMS() { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return ts.tv_sec*1000+ts.tv_nsec/1000000LL; -} + @@ -205,6 +201,7 @@ int OsdOpenGL::init(void* device) + //Now we will create the Screen screen = (Surface*) new SurfaceOpenGL(Surface::SCREEN); @@ -231,11 +228,14 @@ int OsdOpenGL::init(void* device) glBindAttribLocation(osd_program,0,"vec_pos"); glBindAttribLocation(osd_program,1,"tex_coord"); - osd_sampler_loc=glGetUniformLocation(osd_program,"texture"); + glLinkProgram(osd_program); + + + GLint link_status; - glGetShaderiv(osd_program,GL_LINK_STATUS, &link_status); + glGetProgramiv(osd_program,GL_LINK_STATUS, &link_status); if (!link_status) { char buffer[1024]; @@ -245,6 +245,10 @@ int OsdOpenGL::init(void* device) glDeleteProgram(osd_program); return 0; } + + osd_sampler_loc=glGetUniformLocation(osd_program,"texture"); + // Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",osd_sampler_loc,glGetError()); + // create the program for yuv frame rendering frame_shader=CreateShader(frame_frag_shader, GL_FRAGMENT_SHADER); @@ -258,13 +262,11 @@ int OsdOpenGL::init(void* device) glBindAttribLocation(frame_program,0,"vec_pos"); glBindAttribLocation(frame_program,1,"tex_coord"); - frame_sampler_locY=glGetUniformLocation(frame_program,"textureY"); - //frame_sampler_locU=glGetUniformLocation(frame_program,"textureU"); - // frame_sampler_locV=glGetUniformLocation(frame_program,"textureV"); + glLinkProgram(frame_program); //GLint link_status; - glGetShaderiv(frame_program,GL_LINK_STATUS, &link_status); + glGetProgramiv(frame_program,GL_LINK_STATUS, &link_status); if (!link_status) { char buffer[1024]; @@ -275,6 +277,12 @@ int OsdOpenGL::init(void* device) return 0; } + frame_sampler_locY=glGetUniformLocation(frame_program,"textureY"); + // Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",frame_sampler_locY,glGetError()); + frame_sampler_locU=glGetUniformLocation(frame_program,"textureU"); + //Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",frame_sampler_locU,glGetError()); + frame_sampler_locV=glGetUniformLocation(frame_program,"textureV"); + glClearColor(0.0f,0.0f,0.0f,1.f); @@ -569,8 +577,9 @@ void OsdOpenGL::InternalRendering(VPEOGLFrame* frame){ if (frame) { + //Log::getInstance()->log("OSD", Log::WARN, "mark1 glerror %x",glGetError()); glUseProgram(frame_program); - // Log::getInstance()->log("OSD", Log::WARN, "mark1 glerror %x",glGetError()); + //Log::getInstance()->log("OSD", Log::WARN, "mark1 glerror %x",glGetError()); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX), osdvertices); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX), &(osdvertices[0].u)); @@ -580,26 +589,34 @@ void OsdOpenGL::InternalRendering(VPEOGLFrame* frame){ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX), &(osdvertices[0].u)); glEnableVertexAttribArray(1); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D,frame->textures[0]); + //Log::getInstance()->log("OSD", Log::WARN, "mark2 glerror %x",glGetError()); - // glActiveTexture(GL_TEXTURE1); - // Log::getInstance()->log("OSD", Log::WARN, "mark3 glerror %x",glGetError()); - // glBindTexture(GL_TEXTURE_2D,frame->textures[1]); - // Log::getInstance()->log("OSD", Log::WARN, "mark4 glerror %x",glGetError()); - // glActiveTexture(GL_TEXTURE2); - // Log::getInstance()->log("OSD", Log::WARN, "mark5 glerror %x",glGetError()); - // glBindTexture(GL_TEXTURE_2D,frame->textures[2]); - - // Log::getInstance()->log("OSD", Log::WARN, "mark6 glerror %x",glGetError()); + + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D,frame->textures[2]); + glUniform1i(frame_sampler_locV,2); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D,frame->textures[1]); + glUniform1i(frame_sampler_locU,1); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D,frame->textures[0]); + glUniform1i(frame_sampler_locY,0); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - // Log::getInstance()->log("OSD", Log::WARN, "mark7 glerror %x",glGetError()); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - //Log::getInstance()->log("OSD", Log::WARN, "mark8 glerror %x",glGetError()); - glUniform1i(frame_sampler_locY,0); - //glUniform1i(frame_sampler_locU,1); - //glUniform1i(frame_sampler_locV,2); + + + //Log::getInstance()->log("OSD", Log::WARN, "mark8 glerror %x %x",glGetError(),osd_sampler_loc); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); diff --git a/osdopengl.h b/osdopengl.h index f92cadc..3bd5def 100755 --- a/osdopengl.h +++ b/osdopengl.h @@ -36,7 +36,7 @@ #include "mutex.h" #include "videovpeogl.h" -#define BENCHMARK_FPS + diff --git a/shaders/frame__frag_shader.h b/shaders/frame__frag_shader.h new file mode 100755 index 0000000..4671f0e --- /dev/null +++ b/shaders/frame__frag_shader.h @@ -0,0 +1,63 @@ +/* + Copyright 2012 Marten Richter + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef FRAME_FRAG_SHADER_H +#define FRAME_FRAG_SHADER_H + +const GLchar frame_frag_shader[] = + "precision mediump float;\n" + "uniform sampler2D textureU;\n" + "uniform sampler2D textureV;\n" + "uniform sampler2D textureY;\n" + "const float uv_corr=0.5;\n" + "const float y_corr=0.0625;\n" + "const mat3 yuvtransform= mat3( 1.164 ,0.0 ,1.596 ,\n" + " 1.164 ,-0.391,-0.813 ,\n" + " 1.164,2.018 , 0.0 );\n" +// "const mat3 yuvtransform= mat3( 1. ,1. ,1. ,\n" +// " 0.0 ,-0.3960,2.029 ,\n" +// " 1.140,-0.581 , 0.0 );\n" +// "const mat3 yuvtransform= mat3( 1. ,0 ,0. ,\n" +// " 0.0 ,1.,0. ,\n" +// " 0.,0. , 1.0 );\n" +// "const mat3 yuvtransform= mat3( 1. ,1. ,1. ,\n" +// " 0.0 ,-0.03960,0.2029 ,\n" +// " 0.1140,-0.0581 , 0.0 );\n" + "varying vec2 out_texCoord;\n" + "void main()\n" + "{\n" + // " vec3 inputcoloryuv=vec3(texture2D(textureY,out_texCoord).r-y_corr,0,0);\n" + //" texture2D(textureU,out_texCoord)-uv_corr," + //" texture2D(textureV,out_texCoord)-uv_corr);" + // " gl_FragColor.rgb=yuvtransform*inputcoloryuv;\n" + " vec3 help;\n" + "help.x=texture2D(textureY,out_texCoord).r-y_corr;\n" + "help.y=texture2D(textureU,out_texCoord).r-uv_corr;\n" + "help.z=texture2D(textureV,out_texCoord).r-uv_corr;\n" //-uv_corr;\n" + " gl_FragColor.rgb=help*yuvtransform;\n" + //" gl_FragColor.g=texture2D(textureU,out_texCoord).r;\n" + //" gl_FragColor.b=texture2D(textureV,out_texCoord).r;\n" + " gl_FragColor.a=1.;\n" +// " gl_FragColor=texture2D(texture,out_texCoord);\n" + //" vec4 temp=vec4(0.3,0.4,0.5,0.5);\n" + //"gl_FragColor=temp;\n" + "}\n"; +#endif + diff --git a/shaders/osd__frag_shader.h b/shaders/osd__frag_shader.h old mode 100644 new mode 100755 index 50421e8..d7fb2b8 --- a/shaders/osd__frag_shader.h +++ b/shaders/osd__frag_shader.h @@ -23,7 +23,7 @@ const GLchar osd_frag_shader[] = "precision mediump float;\n" - "uniform sampler2D texture;" + "uniform sampler2D texture;\n" "varying vec2 out_texCoord;\n" "void main()\n" "{\n" diff --git a/videovpeogl.cc b/videovpeogl.cc index 1ef6d93..1a0b03f 100755 --- a/videovpeogl.cc +++ b/videovpeogl.cc @@ -46,8 +46,14 @@ VideoVPEOGL::VideoVPEOGL() ffmpeg_running=false; dec_frame_ff_uploading=NULL; dec_frame_ff_decoding=NULL; + ogl_frame_outside=false; #endif +#ifdef BENCHMARK_FPS + time_in_decoder=0; + num_frames=0; +#endif + } VideoVPEOGL::~VideoVPEOGL() @@ -338,7 +344,7 @@ void VideoVPEOGL::threadMethod() glPixelStorei(GL_UNPACK_ALIGNMENT,1); glTexSubImage2D(GL_TEXTURE_2D,0,0,0, - dec_frame_ff_uploading->linesize[0],height, + out_frame->stride,out_frame->height, GL_LUMINANCE,GL_UNSIGNED_BYTE, dec_frame_ff_uploading->data[0]); @@ -346,14 +352,14 @@ void VideoVPEOGL::threadMethod() glBindTexture(GL_TEXTURE_2D, out_frame->textures[1]); glPixelStorei(GL_UNPACK_ALIGNMENT,1); glTexSubImage2D(GL_TEXTURE_2D,0,0,0, - dec_frame_ff_uploading->linesize[1],height>>1, + out_frame->stride>>1,out_frame->height>>1, GL_LUMINANCE,GL_UNSIGNED_BYTE, dec_frame_ff_uploading->data[1]); glBindTexture(GL_TEXTURE_2D, out_frame->textures[2]); glPixelStorei(GL_UNPACK_ALIGNMENT,1); glTexSubImage2D(GL_TEXTURE_2D,0,0,0, - dec_frame_ff_uploading->linesize[2],height>>1, + out_frame->stride>>1,out_frame->height>>1, GL_LUMINANCE,GL_UNSIGNED_BYTE, dec_frame_ff_uploading->data[2]); ogl_frame_mutex.Lock(); @@ -1879,8 +1885,22 @@ UINT VideoVPEOGL::DeliverMediaPacketFFMPEG(MediaPacket packet, int frame_ready=0; // Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder"); + +#ifdef BENCHMARK_FPS + int cur_time=getTimeMS(); +#endif + dec_bytes=avcodec_decode_video(mpeg2codec_context_ff, dec_frame_ff_decoding, &frame_ready, buffer+packet.pos_buffer+*samplepos, haveToCopy); +#ifdef BENCHMARK_FPS + time_in_decoder+=getTimeMS()-cur_time; + if (frame_ready) num_frames++; + if ((num_frames%100)==0) { + float fps=1000./(float)(time_in_decoder); + fps*=((float)num_frames); + Log::getInstance()->log("OSD", Log::NOTICE, "Current Pure Decoding FPS %g", fps); + } +#endif if (dec_bytes<0) { Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes); return *samplepos; diff --git a/videovpeogl.h b/videovpeogl.h index aab1590..3c722e6 100755 --- a/videovpeogl.h +++ b/videovpeogl.h @@ -271,8 +271,10 @@ class VideoVPEOGL : public Video, public Thread_TYPE EGLDisplay egl_display; EGLSurface egl_surface; EGLContext egl_context; - - +#ifdef BENCHMARK_FPS + unsigned int time_in_decoder; + unsigned int num_frames; +#endif MediaPacket mediapacket; -- 2.39.5