]> git.vomp.tv Git - vompclient-marten.git/commitdiff
Bugfixes Reference Frame Handling, CBP shader handling, but still buggy
authorMarten Richter <marten.richter@freenet.de>
Sat, 7 Jul 2012 21:47:40 +0000 (23:47 +0200)
committerMarten Richter <marten.richter@freenet.de>
Sat, 7 Jul 2012 21:47:40 +0000 (23:47 +0200)
glmocoshader.cc
osdopengl.cc
videovpeogl.cc
videovpeogl.h

index af5a1fb756d0a6e13587bf596acd02d62464ab5c..5f0cd6c6d0cd07288aa051ad6622de9c7928607f 100755 (executable)
@@ -23,7 +23,7 @@
 #define BLOCK_TEXTURE_WIDTH 2048\r
 #define BLOCK_TEXTURE_HEIGHT 1024\r
 #define BLOCK_SIZE 64\r
-#define BLOCK_PER_ROW 32\r
+#define BLOCK_PER_ROW (32)\r
 \r
 // This implementation is for framed coded pictures only!\r
 // I did not find any DVB recording with field coded pictures\r
@@ -68,18 +68,27 @@ const GLchar moco_vertex_shader[] =
 \r
 \r
                "const vec4  y_cbp=vec4(1.0,2.0,4.0,8.0);\n"\r
-               "const vec2  uv_cbp=vec2(16.0,32.0);\n"\r
+               "const vec3  uv_cbp=vec3(16.0,32.0,64.0);\n"\r
                "void main()\n"\r
                "{\n"\r
                // calculate cbp\r
                "  vec4 cbp_vec=vec4(cbp,cbp,cbp,cbp);\n"\r
-               "  vec4 fmod_cbp_y=mod(cbp_vec,y_cbp);\n"\r
-               "  vec2 fmod_cbp_uv=mod(cbp_vec.xy,uv_cbp);\n"\r
-               "  fmod_cbp_y.x=0.;\n"\r
-               "  fmod_cbp_y=sign(vec4(fmod_cbp_y.yzw,fmod_cbp_uv.x)-fmod_cbp_y);\n"\r
-               "  fmod_cbp_uv=sign(vec2(fmod_cbp_uv.y,cbp)-fmod_cbp_uv);\n"\r
+\r
+               // old cbp code\r
+       //      "  vec4 fmod_cbp_y=mod(cbp_vec,y_cbp);\n"\r
+       //      "  vec2 fmod_cbp_uv=mod(cbp_vec.xy,uv_cbp);\n"\r
+       //      "  fmod_cbp_y.x=0.;\n"\r
+       //      "  fmod_cbp_y=sign(vec4(fmod_cbp_y.yzw,fmod_cbp_uv.x)-fmod_cbp_y);\n"\r
+       //      "  fmod_cbp_uv=sign(vec2(fmod_cbp_uv.y,cbp)-fmod_cbp_uv);\n"\r
                // resulting vector should indicate with block is present\r
                // now transform it to a sum (TODO vectorize this)\r
+\r
+\r
+               "  vec4 fmod_cbp_y=mod(cbp_vec,vec4(uv_cbp.zyx,y_cbp.w));\n"\r
+               "  vec2 fmod_cbp_uv=mod(cbp_vec.xy,y_cbp.zy);\n"\r
+               "  fmod_cbp_y=vec4(lessThanEqual(vec4(uv_cbp.yx,y_cbp.wz),fmod_cbp_y));\n"\r
+           "  fmod_cbp_uv=vec2(lessThanEqual(y_cbp.yx,fmod_cbp_uv));\n"\r
+\r
                "  vec4 fmod_cbp_y2=fmod_cbp_y;\n"\r
                "  vec2 fmod_cbp_uv2=fmod_cbp_uv;\n"\r
                "  fmod_cbp_y2.y+=fmod_cbp_y2.x;\n"\r
@@ -105,8 +114,12 @@ const GLchar moco_vertex_shader[] =
 \r
 \r
                //Kick out uncoded blocks\r
-               "  out_yblockpos_y-=sign(fmod_cbp_y-one)*c1024;\n"\r
-               "  out_uvblockpos_xy.zw-=sign(fmod_cbp_uv-one)*c1024;\n"\r
+       //      "  out_yblockpos_y-=sign(fmod_cbp_y-one)*c1024;\n"\r
+       //      "  out_uvblockpos_xy.zw-=sign(fmod_cbp_uv-one)*c1024;\n"\r
+\r
+               "  out_yblockpos_y=mix(vec4(c1024,c1024,c1024,c1024)-one,out_yblockpos_y,fmod_cbp_y);\n"\r
+               "  out_uvblockpos_xy.zw=mix(vec2(c1024,c1024)-one,out_uvblockpos_xy.zw,fmod_cbp_uv);\n"\r
+\r
 \r
                // set start positions\r
                "  vec4 motion_vertical=vec4(block_types.z,block_types.z,block_types.z,block_types.z);\n"\r
@@ -137,8 +150,8 @@ const GLchar moco_vertex_shader[] =
                "        out_moco_backward=vec4(PMV1.zw,PMV1.zw);\n"\r
                //"          out_unsupported=2.;\n"\r
                "     } else if (block_types.y==y_cbp.x /*1*/) {" //Field\r
-               "        out_moco_forward=vec4(PMV1.xy,PMV2.xy);\n"\r
-               "        out_moco_backward=vec4(PMV1.zw,PMV2.zw);\n"\r
+               "        out_moco_forward=vec4(PMV1.xy,PMV1.xy);\n"\r
+               "        out_moco_backward=vec4(PMV1.zw,PMV1.zw);\n"\r
                "        out_moco_forward.y+=mod_motion_vertical.x;\n"\r
                "        out_moco_backward.y+=mod_motion_vertical.y;\n"\r
                "        out_moco_forward.w-=one-mod_motion_vertical.z;\n"\r
@@ -151,6 +164,8 @@ const GLchar moco_vertex_shader[] =
                "  }\n"\r
 \r
 \r
+\r
+\r
                "  out_block_edge=block_edge;\n"\r
                "  out_misc_info.x=block_types.w;\n"\r
                "  vec4 out_pos=block_pos;\n"\r
@@ -284,7 +299,7 @@ const GLchar moco_frag_shader[] =
                // now we handle the y fetching\r
                " vec4 moco_temp;\n"\r
                " vec4 subpixel=floor(mod(moco_work,ctwo))*halfst; \n"\r
-               " moco_temp=floor(moco_work*halfst+halfst)+floor(vec4(out_moco_pos.xy,out_moco_pos.xy));\n"\r
+               " moco_temp=floor(moco_work*halfst)+floor(vec4(out_moco_pos.xy,out_moco_pos.xy));\n"\r
                " vec4 c00,c01,c10,c11;\n"\r
 \r
                " c00=texture2D(forward_pic,moco_temp.xy*pict_size);\n"\r
@@ -374,11 +389,11 @@ int GLMocoShader::init() {
        glBindTexture(GL_TEXTURE_2D, data_blocks);\r
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, BLOCK_TEXTURE_WIDTH >>1, BLOCK_TEXTURE_HEIGHT, 0, GL_RGBA,\r
                                GL_UNSIGNED_BYTE, NULL);\r
-       char buffer[BLOCK_TEXTURE_WIDTH*4];\r
-       memset(buffer,0,BLOCK_TEXTURE_WIDTH*4); // the last line is black, simplifies the shader algorithms\r
+       char buffer[BLOCK_TEXTURE_WIDTH*2];\r
+       memset(buffer,0,BLOCK_TEXTURE_WIDTH*2); // the last line is black, simplifies the shader algorithms\r
 \r
        glTexSubImage2D(GL_TEXTURE_2D,0,0,BLOCK_TEXTURE_HEIGHT-1,\r
-                       1024,1,\r
+                       BLOCK_TEXTURE_WIDTH>>1,1,\r
                        GL_RGBA,GL_UNSIGNED_BYTE,\r
                        buffer);\r
 \r
@@ -545,6 +560,7 @@ int GLMocoShader::doMoCo(VPEOGLFrame *target,VPEOGLFrame *forward,VPEOGLFrame *b
 \r
 \r
 \r
+\r
        //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark2 glerror %x",glGetError());\r
 \r
        //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark2a glerror %x",glGetError());\r
@@ -612,6 +628,7 @@ int GLMocoShader::doMoCo(VPEOGLFrame *target,VPEOGLFrame *forward,VPEOGLFrame *b
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);\r
 \r
 \r
+\r
                if (forward) {\r
                        Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo forward %x",forward->textures[0]);\r
                        glActiveTexture(GL_TEXTURE1);\r
@@ -637,8 +654,9 @@ int GLMocoShader::doMoCo(VPEOGLFrame *target,VPEOGLFrame *forward,VPEOGLFrame *b
                }\r
 \r
 \r
+\r
                glDrawElements(GL_TRIANGLE_STRIP, valid_macro_blocks*6,\r
-                       GL_UNSIGNED_SHORT, NULL);\r
+                               GL_UNSIGNED_SHORT, NULL);\r
 \r
 \r
                /*\r
index b425ffcba4257b2db760d98fc35ff7631aa26572..f0bc96b4ce67f524b552239bb0a1ddc712019b4f 100755 (executable)
@@ -420,7 +420,7 @@ void OsdOpenGL::threadMethod()
                        if (!frame) frame=video->getReadyOGLFrame();\r
                        if (frame) {\r
                                InternalRendering(frame);\r
-                       //      MILLISLEEP(1500);\r
+                       //      MILLISLEEP(1000);\r
                                lastrendertime=getTimeMS();\r
                                video->returnOGLFrame(frame); //please recycle it\r
                                frame=NULL;\r
index 3b80eaa8cc61b05506e816eea3eb18dd5d58e316..1035ec2c28d77197ff240ac57633549cf790a5f9 100755 (executable)
@@ -44,7 +44,7 @@ VideoVPEOGL::VideoVPEOGL()
 #ifdef VPE_LIBAV_SUPPORT
   mpeg2codec_context_libav=NULL;
   libav_running=false;
-  dec_frame_libav_uploading=NULL;
+  dec_frame_libav_uploading_framebuf=NULL;
   dec_frame_libav_decoding=NULL;
   ogl_frame_outside=false;
   //decoding_mode=VPE_NO_XVMC;
@@ -303,6 +303,7 @@ VPEOGLFrame *VideoVPEOGL::getReadyOGLFrame(){
        if (ready_ogl_frames.size()>0) {
                return_obj=ready_ogl_frames.front();
                ready_ogl_frames.pop_front();
+               //Log::getInstance()->log("Video", Log::WARN, "readyOGLRFrame markoutgoing  num: %d",return_obj->pict_num);
                ogl_frame_outside=true;
        }
        ogl_frame_mutex.Unlock();
@@ -357,55 +358,89 @@ void VideoVPEOGL::threadMethod()
                Log::getInstance()->log("Video", Log::WARN, "Making egl Current failed in thread %d",eglGetError());
                return;
        }
+       long long run=0;
        while (1) {
                bool sleep=true;
                bool upload=false;
                bool view=false;
+               run++;
 #ifdef VPE_LIBAV_SUPPORT
                dec_frame_libav_mutex.Lock();
+               AVFrame* dec_frame_libav_uploading_int=NULL;
 
 
                if (dec_frame_libav_upload_and_view_pending.size()>0  ) {
-                       bool blocked=false;
-                       dec_frame_libav_uploading=dec_frame_libav_upload_and_view_pending.front();
-               //      Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view %d",((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->pict_num);
-               //      if (dec_frame_libav_upload_only_pending.size()>0) Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view %d",
-               //                      ((VPE_FrameBuf*)dec_frame_libav_upload_only_pending.front()->base[0])->pict_num);
-                       list<AVFrame*>::iterator itty=dec_frame_libav_upload_only_pending.begin();
-                       while (itty!=dec_frame_libav_upload_only_pending.end())
-                       {
-                               if (*itty==dec_frame_libav_uploading) {
-                                       blocked=true;
-                                       break;
-                               }
-                               itty++;
-                       }
-                       if (!blocked) { // this assures that no frame without an upload is pushed out to rendering
+
+                       dec_frame_libav_uploading_int=dec_frame_libav_upload_and_view_pending.front();
+                       dec_frame_libav_uploading_framebuf=(VPE_FrameBuf*)dec_frame_libav_uploading_int->base[0];
+                       //Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view %d %lld %x",(dec_frame_libav_uploading_framebuf)->pict_num,run,
+               //                      dec_frame_libav_uploading_framebuf);
+               //      if (dec_frame_libav_upload_only_pending.size()>0) Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view2 %d",
+               //                      ((VPE_FrameBuf*)dec_frame_libav_upload_only_pending.front())->pict_num);
+
+                       view=true;
+                       if ((dec_frame_libav_uploading_framebuf)->ogl_uploaded || decoding_mode==VPE_NO_XVMC  ) {
                                dec_frame_libav_upload_and_view_pending.pop_front();
-                               upload=view=true;
-                               if (decoding_mode!=VPE_NO_XVMC) upload=false;
+                               if (decoding_mode==VPE_NO_XVMC) upload=true;
                        } else {
-                               dec_frame_libav_uploading=NULL;
+                               dec_frame_libav_uploading_framebuf=NULL;
+                               dec_frame_libav_uploading_int=NULL; // if not uploaded do not do it yet
+                               view=false; //do the upload
+                       //      Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view view canceled");
                        }
                }
 
-               if (!view && dec_frame_libav_upload_only_pending.size()>0) {
+               if (!view && dec_frame_libav_upload_only_pending.size()>0) { //this is for uploading reference frames ahead
 
-                       dec_frame_libav_uploading=dec_frame_libav_upload_only_pending.front();
-                       //Log::getInstance()->log("Video", Log::WARN, "threadMethod u  %d",((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->pict_num);
+                       dec_frame_libav_uploading_framebuf=dec_frame_libav_upload_only_pending.front();
+                       //Log::getInstance()->log("Video", Log::WARN, "threadMethod u  %d %lld %x",((VPE_FrameBuf*)dec_frame_libav_uploading_framebuf)->pict_num,run,
+                               //      dec_frame_libav_uploading_framebuf);
                        dec_frame_libav_upload_only_pending.pop_front();
                        view=false;
                        upload=true;
+               /*      if (((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->ogl_uploaded) {
+                               upload=false;
+                               dec_frame_libav_uploading=NULL; //do not upload again
+                       }*/
                }
 
 
+
+
+
+
                if (dec_frame_libav_upload_and_view_pending.size()>0
                        ||dec_frame_libav_upload_only_pending.size()>0) sleep=false;
 
                dec_frame_libav_mutex.Unlock();
 
 
-               if (dec_frame_libav_uploading) {
+               if (dec_frame_libav_uploading_framebuf) {
+
+                       //Code Block for debugging if needed
+               /*      Log::getInstance()->log("Video", Log::WARN, "Iterate all free ogl frames");
+                       ogl_frame_mutex.Lock();
+                       list<VPEOGLFrame*>::iterator itty=free_ogl_frames.begin();
+                       while (itty!=free_ogl_frames.end()) {
+                               Log::getInstance()->log("Video", Log::WARN, "free ogl pict num %d",(*itty)->pict_num);
+
+                               itty++;
+                       }
+
+                       itty=recycle_ref_ogl_frames.begin();
+                       while (itty!=recycle_ref_ogl_frames.end()) {
+                               Log::getInstance()->log("Video", Log::WARN, "recycle ogl pict num %d",(*itty)->pict_num);
+
+                               itty++;
+                       }
+                       itty=ready_ogl_frames.begin();
+                       while (itty!=ready_ogl_frames.end()) {
+                               Log::getInstance()->log("Video", Log::WARN, "ready ogl pict num %d",(*itty)->pict_num);
+
+                               itty++;
+                       }
+                       ogl_frame_mutex.Unlock();*/
+
 
                        if (upload) {
                                int width,height,pixfmt;
@@ -430,8 +465,9 @@ void VideoVPEOGL::threadMethod()
                                }
                                bool failed=false;
                                if (out_frame) {
+                               //      Log::getInstance()->log("Video", Log::WARN, "outframes old pict num: %d",out_frame->pict_num);
                                        if (out_frame->textures[0]==0 || out_frame->width!=width ||
-                                                       out_frame->height!=height || out_frame->stride!=dec_frame_libav_uploading->linesize[0]) {
+                                                       out_frame->height!=height || out_frame->stride!=dec_frame_libav_uploading_framebuf->stride) {
                                                if (out_frame->textures[0]!=0) {
                                                        glDeleteTextures(1,&out_frame->textures[0]);
                                                        out_frame->textures[0]=0;
@@ -446,13 +482,16 @@ void VideoVPEOGL::threadMethod()
                                                }
 
                                                if (decoding_mode==VPE_NO_XVMC) {
-                                                       if (!AllocateYUV400OglTexture(out_frame,width,height,dec_frame_libav_uploading->linesize[0])) failed=true;
+                                                       if (!AllocateYUV400OglTexture(out_frame,width,height,dec_frame_libav_uploading_framebuf->stride)) failed=true;
                                                } else {
-                                                       if (!AllocateYUV444OglTexture(out_frame,width,height,dec_frame_libav_uploading->linesize[0])) failed=true; //We use a YUV 444 texture in this case
+                                                       if (!AllocateYUV444OglTexture(out_frame,width,height,dec_frame_libav_uploading_framebuf->stride)) failed=true; //We use a YUV 444 texture in this case
                                                        // the shaders are easier to implement
                                                }
                                        }
-                                       ((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->ogl_ref=out_frame;
+                                       dec_frame_libav_uploading_framebuf->ogl_ref=out_frame;
+                                       dec_frame_libav_uploading_framebuf->ogl_uploaded=true;
+
+
                                        if (!failed) {
                                                //up to now only YUV data, this is for reference only, since the pi is too slow.
                                                if (decoding_mode==VPE_NO_XVMC) {
@@ -461,35 +500,36 @@ void VideoVPEOGL::threadMethod()
                                                        glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
                                                                        out_frame->stride,out_frame->height,
                                                                        GL_LUMINANCE,GL_UNSIGNED_BYTE,
-                                                                       dec_frame_libav_uploading->data[0]);
+                                                                       dec_frame_libav_uploading_framebuf->data[0]);
 
                                                        glBindTexture(GL_TEXTURE_2D, out_frame->textures[1]);
                                                        glPixelStorei(GL_UNPACK_ALIGNMENT,1);
                                                        glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
                                                                        out_frame->stride>>1,out_frame->height>>1,
                                                                        GL_LUMINANCE,GL_UNSIGNED_BYTE,
-                                                                       dec_frame_libav_uploading->data[1]);
+                                                                       dec_frame_libav_uploading_framebuf->data[1]);
 
                                                        glBindTexture(GL_TEXTURE_2D, out_frame->textures[2]);
                                                        glPixelStorei(GL_UNPACK_ALIGNMENT,1);
                                                        glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
                                                                        out_frame->stride>>1,out_frame->height>>1,
                                                                        GL_LUMINANCE,GL_UNSIGNED_BYTE,
-                                                                       dec_frame_libav_uploading->data[2]);
+                                                                       dec_frame_libav_uploading_framebuf->data[2]);
                                                } else {
                                                        //XVMC case
-                                                       xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading->data[2];
+                                                       xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading_framebuf->data[2];
                                                        if (moco_shader && pix_fmt) {
 
                                                                moco_shader->uploadDataBlocks(pix_fmt->data_blocks,pix_fmt->next_free_data_block_num,
                                                                                pix_fmt->mv_blocks , pix_fmt->filled_mv_blocks_num );
-                                                               Log::getInstance()->log("Video", Log::WARN, "Pictnum %d Forward %d Backward %d pict_type%d",pix_fmt->p_surface,
-                                                                                                                       pix_fmt->p_past_surface,pix_fmt->p_future_surface,dec_frame_libav_uploading->pict_type);
+                                                       //      Log::getInstance()->log("Video", Log::WARN, "Pictnum %d Forward %d Backward %d ",pix_fmt->p_surface,
+                                                               //                                                      pix_fmt->p_past_surface,pix_fmt->p_future_surface);
 
                                                                if (((int)pix_fmt->p_future_surface)!=0 && ogl_backward_ref_frame_num!=((int)pix_fmt->p_future_surface))
                                                                {
                                                                        //Now determine the frame, that fits
                                                                        ogl_frame_mutex.Lock();
+                                                                       bool found=false;
                                                                        for (int i=0;i<all_ogl_frames.size();i++) {
                                                                                if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_future_surface))
                                                                                {
@@ -497,32 +537,51 @@ void VideoVPEOGL::threadMethod()
                                                                                        ogl_forward_ref_frame_num=ogl_backward_ref_frame_num;
                                                                                        ogl_backward_ref_frame=all_ogl_frames[i];
                                                                                        ogl_backward_ref_frame_num=(int)pix_fmt->p_future_surface;
+                                                                                       found=true;
                                                                                        break;
                                                                                }
                                                                        }
+                                                               //      if (!found) {// for debugging
+                                                               //              Log::getInstance()->log("Video", Log::WARN, "Emergency reference frame not found");
+                                                               //              exit(0);
+                                                               //      }
 
                                                                        ogl_frame_mutex.Unlock();
                                                                        recycleOGLRefFrames(); //needed for recycling of reference frames
                                                                }
+                                                       //      Log::getInstance()->log("Video", Log::WARN, "Pictnum mark1");
 
+/*
+                                                               if ( ((int)pix_fmt->p_past_surface)==ogl_backward_ref_frame_num)
+                                                               {
+
+                                                               }*/
 
                                                                if (((int)pix_fmt->p_past_surface)!=0 && ogl_forward_ref_frame_num!=((int)pix_fmt->p_past_surface))
                                                                {
                                                                        //Now determine the frame, that fits
                                                                        ogl_frame_mutex.Lock();
+                                                                       bool found=false;
                                                                        for (int i=0;i<all_ogl_frames.size();i++) {
                                                                                if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_past_surface))
                                                                                {
                                                                                        ogl_forward_ref_frame=all_ogl_frames[i];
                                                                                        ogl_forward_ref_frame_num=(int)pix_fmt->p_past_surface; // This should not happen, or for DMV, who knows
+                                                                                       found=true;
                                                                                        break;
                                                                                }
                                                                        }
+                                                               //      if (!found) {
+                                                               //              Log::getInstance()->log("Video", Log::WARN, "Emergency reference frame not found %d %d",ogl_forward_ref_frame_num,
+                                                               //                              ((int)pix_fmt->p_past_surface));
+                                                               //              exit(0);
+                                                               //      }
 
                                                                        ogl_frame_mutex.Unlock();
                                                                        recycleOGLRefFrames(); //needed for recycling of reference frames
 
                                                                }
+                                                               //Log::getInstance()->log("Video", Log::WARN, "Pictnum mark2");
 
                                                                if (decoding_mode==VPE_XVMC_MOCOMP)
                                                                {
@@ -531,13 +590,18 @@ void VideoVPEOGL::threadMethod()
                                                                } else {
                                                                        //DCT Blocks upload
                                                                }
-                                                               out_frame->pict_num=((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->pict_num;
+                                                               out_frame->pict_num=dec_frame_libav_uploading_framebuf->pict_num;
 
+                                                       //      Log::getInstance()->log("Video", Log::WARN, "Pictnum mark3");
 
                                                                moco_shader->doMoCo(out_frame,(((int)pix_fmt->p_past_surface)!=0)? ogl_forward_ref_frame:NULL,
                                                                                (((int)pix_fmt->p_future_surface)!=0)? ogl_backward_ref_frame:NULL);
 
+                                                               //Log::getInstance()->log("Video", Log::WARN, "Pictnum mark4");
                                                                // Excute motion compensation
+                                                       } else {
+                                                               //Log::getInstance()->log("Video", Log::WARN, "moco pixfmt error abort");
+                                                               //                                      exit(0);
                                                        }
                                                }
 
@@ -553,25 +617,26 @@ void VideoVPEOGL::threadMethod()
                        if (view) {
 
                                //Log::getInstance()->log("Video", Log::WARN, "threadMethod mark view");
-                               VPEOGLFrame* out_frame=((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->ogl_ref;
-                               xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading->data[2];
-                               Log::getInstance()->log("Video", Log::WARN, "View Pictnum %d Forward %d Backward %d pict_type%d",pix_fmt->p_surface,
-                                                                                                                       pix_fmt->p_past_surface,pix_fmt->p_future_surface,dec_frame_libav_uploading->pict_type);
+                               VPEOGLFrame* out_frame=dec_frame_libav_uploading_framebuf->ogl_ref;
+                               xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading_framebuf->data[2];
+                       /*      Log::getInstance()->log("Video", Log::WARN, "View Pictnum %d Forward %d Backward %d pict_num %d",pix_fmt->p_surface,
+                                                                                                                       pix_fmt->p_past_surface,pix_fmt->p_future_surface,out_frame->pict_num);
+                               Log::getInstance()->log("Video", Log::WARN, "Real Pictnum %d ",out_frame->pict_num);*/
 
-                               releaseFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_uploading->base[0]);
+                               releaseFrameBufUpload(dec_frame_libav_uploading_framebuf);
                                ogl_frame_mutex.Lock();
                                ready_ogl_frames.push_back(out_frame);
                                ogl_frame_mutex.Unlock();
                                ((OsdOpenGL*)Osd::getInstance())->AdviseAboutNewFrame(); //Tell him, that we have a frame waiting
 
                                dec_frame_libav_mutex.Lock();
-                               dec_frame_libav_free.push_back(dec_frame_libav_uploading);
+                               dec_frame_libav_free.push_back(dec_frame_libav_uploading_int);
                                dec_frame_libav_mutex.Unlock();
                        }
 
 
                        dec_frame_libav_mutex.Lock();
-                       dec_frame_libav_uploading=NULL;
+                       dec_frame_libav_uploading_framebuf=NULL;
 
                        if (dec_frame_libav_upload_and_view_pending.size()>0
                                        ||dec_frame_libav_upload_only_pending.size()>0) sleep=false;
@@ -584,19 +649,28 @@ void VideoVPEOGL::threadMethod()
 #endif
 
                if (sleep) {
-                       threadWaitForSignal();
-                       Log::getInstance()->log("Video", Log::WARN, "threadMethod signalled");
+                       struct timespec target_time;
+                       int ts=20; //20 ms
+                       clock_gettime(CLOCK_REALTIME,&target_time);
+                       target_time.tv_nsec+=1000000LL*ts;
+                       if (target_time.tv_nsec>999999999) {
+                               target_time.tv_nsec-=1000000000L;
+                               target_time.tv_sec+=1;
+                       }
+                       threadWaitForSignalTimed(&target_time);
+                       //Log::getInstance()->log("Video", Log::WARN, "threadMethod signalled");
                }
                threadCheckExit();
        }
 
 }
 
+
 void VideoVPEOGL::threadPostStopCleanup()
 {
        eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
 #ifdef VPE_LIBAV_SUPPORT
-       dec_frame_libav_uploading=NULL;
+       dec_frame_libav_uploading_framebuf=NULL;
 #endif
 }
 
@@ -1556,7 +1630,7 @@ void VideoVPEOGL::draw_horiz_band_libav(struct AVCodecContext *s, const AVFrame
        /*      Log::getInstance()->log("Video", Log::NOTICE, "draw_horiz_band %d %d %d %d %d!",y,type,height,((xvmc_pix_fmt *)src->data[2])->p_surface,
                                ((xvmc_pix_fmt *)src->data[2])->picture_structure);*/
                if (((xvmc_pix_fmt *)src->data[2])->picture_structure!=3) {
-                       Log::getInstance()->log("Video", Log::ERR, "Non frame pict supported! Yet! Please send sample to authors!"); exit(0);
+                       Log::getInstance()->log("Video", Log::ERR, "Non frame pict not supported! Yet! Please send sample to authors!"); exit(0);
                }
                ((VideoVPEOGL*)Video::getInstance())->add_dec_frame_upload_only(s,src);
        }
@@ -1638,6 +1712,11 @@ int VideoVPEOGL::get_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
        }
 
        VPE_FrameBuf *frame_buf=((VideoVPEOGL*)Video::getInstance())->getFrameBuf(want_sizes);
+       frame_buf->ogl_ref=NULL; //do not use old references, crash instead!
+       frame_buf->ogl_uploaded=false; //not uploaded yet
+       frame_buf->width=pic->width;
+       frame_buf->height=pic->height;
+       frame_buf->stride=pic->linesize[0];
 
        //Log::getInstance()->log("Video", Log::NOTICE, "get buffer %x",frame_buf);
        if (!frame_buf) {
@@ -1711,6 +1790,7 @@ void VideoVPEOGL::release_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
 
 int VideoVPEOGL::AllocateCodecsLibav()
 {
+       if (libav_running) DeAllocateCodecsLibav();
        libav_hastime=false;
        Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecslibav");
        mpeg2codec_context_libav=avcodec_alloc_context();
@@ -1794,7 +1874,7 @@ int VideoVPEOGL::DeAllocateCodecsLibav()
        dec_frame_libav_upload_only_pending.clear();
        dec_frame_libav_free.clear();
        dec_frame_libav_mutex.Unlock();
-       while (dec_frame_libav_uploading) {
+       while (dec_frame_libav_uploading_framebuf) {
                Log::getInstance()->log("Video", Log::NOTICE, "Wait for uploading to finish");
                MILLISLEEP(20);
        }
@@ -1991,9 +2071,9 @@ void VideoVPEOGL::add_dec_frame_upload_only(struct AVCodecContext *s,const AVFra
        libavwidth=s->width;
        libavheight=s->height;
        libavpixfmt=s->pix_fmt;
-       Log::getInstance()->log("Video", Log::DEBUG, "add_dec Frame info %d %d %d %d",libavwidth,libavheight,libavpixfmt,((VPE_FrameBuf*)data->base[0])->pict_num);
+       //Log::getInstance()->log("Video", Log::DEBUG, "add_dec Frame info %d %d %d %d %x",libavwidth,libavheight,libavpixfmt,((VPE_FrameBuf*)data->base[0])->pict_num,data->base[0]);
 
-       dec_frame_libav_upload_only_pending.push_back((AVFrame*)data); // we are only uploading
+       dec_frame_libav_upload_only_pending.push_back((VPE_FrameBuf*)data->base[0]); // we are only uploading
        dec_frame_libav_mutex.Unlock();
        threadSignal();
 }
@@ -2365,6 +2445,8 @@ int VideoVPEOGL::DecodePacketlibav()
                        libavheight=mpeg2codec_context_libav->height;
                        libavpixfmt=mpeg2codec_context_libav->pix_fmt;
                //      Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",libavwidth,libavheight,libavpixfmt);
+               //      Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d %d %x",libavwidth,libavheight,libavpixfmt,
+                       //              ((VPE_FrameBuf*)dec_frame_libav_decoding->base[0])->pict_num,dec_frame_libav_decoding->base[0]);
 
 
                        dec_frame_libav_upload_and_view_pending.push_back(dec_frame_libav_decoding);
index 4357df2d1001b6f04895f240c9ee0335d161ae3f..f76c5c2354f6a4fdd2d4a3a36a504bdc6115d5d6 100755 (executable)
@@ -88,6 +88,9 @@ struct VPE_FrameBuf
        unsigned int size[4];\r
        unsigned int pict_num;\r
        VPEOGLFrame *ogl_ref;\r
+       bool ogl_uploaded;\r
+       int width, height;\r
+       int stride;\r
 };\r
 \r
 #endif\r
@@ -269,8 +272,9 @@ class VideoVPEOGL : public Video, public Thread_TYPE
        vector<AVFrame*> dec_frame_libav_all;\r
        list<AVFrame*> dec_frame_libav_free;\r
        list<AVFrame*> dec_frame_libav_upload_and_view_pending;\r
-       list<AVFrame*> dec_frame_libav_upload_only_pending;\r
-       AVFrame* dec_frame_libav_uploading;\r
+       list<VPE_FrameBuf*> dec_frame_libav_upload_only_pending;\r
+       //AVFrame* dec_frame_libav_uploading;\r
+       VPE_FrameBuf* dec_frame_libav_uploading_framebuf;\r
        AVFrame* dec_frame_libav_decoding;\r
 \r
        void add_dec_frame_upload_only(struct AVCodecContext *s,const AVFrame* data);\r