From 6c3233ddfd41c4ca22c62a4c60daec651fd9c29c Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Sat, 7 Jul 2012 23:47:40 +0200 Subject: [PATCH] Bugfixes Reference Frame Handling, CBP shader handling, but still buggy --- glmocoshader.cc | 50 +++++++++----- osdopengl.cc | 2 +- videovpeogl.cc | 178 +++++++++++++++++++++++++++++++++++------------- videovpeogl.h | 8 ++- 4 files changed, 171 insertions(+), 67 deletions(-) diff --git a/glmocoshader.cc b/glmocoshader.cc index af5a1fb..5f0cd6c 100755 --- a/glmocoshader.cc +++ b/glmocoshader.cc @@ -23,7 +23,7 @@ #define BLOCK_TEXTURE_WIDTH 2048 #define BLOCK_TEXTURE_HEIGHT 1024 #define BLOCK_SIZE 64 -#define BLOCK_PER_ROW 32 +#define BLOCK_PER_ROW (32) // This implementation is for framed coded pictures only! // I did not find any DVB recording with field coded pictures @@ -68,18 +68,27 @@ const GLchar moco_vertex_shader[] = "const vec4 y_cbp=vec4(1.0,2.0,4.0,8.0);\n" - "const vec2 uv_cbp=vec2(16.0,32.0);\n" + "const vec3 uv_cbp=vec3(16.0,32.0,64.0);\n" "void main()\n" "{\n" // calculate cbp " vec4 cbp_vec=vec4(cbp,cbp,cbp,cbp);\n" - " vec4 fmod_cbp_y=mod(cbp_vec,y_cbp);\n" - " vec2 fmod_cbp_uv=mod(cbp_vec.xy,uv_cbp);\n" - " fmod_cbp_y.x=0.;\n" - " fmod_cbp_y=sign(vec4(fmod_cbp_y.yzw,fmod_cbp_uv.x)-fmod_cbp_y);\n" - " fmod_cbp_uv=sign(vec2(fmod_cbp_uv.y,cbp)-fmod_cbp_uv);\n" + + // old cbp code + // " vec4 fmod_cbp_y=mod(cbp_vec,y_cbp);\n" + // " vec2 fmod_cbp_uv=mod(cbp_vec.xy,uv_cbp);\n" + // " fmod_cbp_y.x=0.;\n" + // " fmod_cbp_y=sign(vec4(fmod_cbp_y.yzw,fmod_cbp_uv.x)-fmod_cbp_y);\n" + // " fmod_cbp_uv=sign(vec2(fmod_cbp_uv.y,cbp)-fmod_cbp_uv);\n" // resulting vector should indicate with block is present // now transform it to a sum (TODO vectorize this) + + + " vec4 fmod_cbp_y=mod(cbp_vec,vec4(uv_cbp.zyx,y_cbp.w));\n" + " vec2 fmod_cbp_uv=mod(cbp_vec.xy,y_cbp.zy);\n" + " fmod_cbp_y=vec4(lessThanEqual(vec4(uv_cbp.yx,y_cbp.wz),fmod_cbp_y));\n" + " fmod_cbp_uv=vec2(lessThanEqual(y_cbp.yx,fmod_cbp_uv));\n" + " vec4 fmod_cbp_y2=fmod_cbp_y;\n" " vec2 fmod_cbp_uv2=fmod_cbp_uv;\n" " fmod_cbp_y2.y+=fmod_cbp_y2.x;\n" @@ -105,8 +114,12 @@ const GLchar moco_vertex_shader[] = //Kick out uncoded blocks - " out_yblockpos_y-=sign(fmod_cbp_y-one)*c1024;\n" - " out_uvblockpos_xy.zw-=sign(fmod_cbp_uv-one)*c1024;\n" + // " out_yblockpos_y-=sign(fmod_cbp_y-one)*c1024;\n" + // " out_uvblockpos_xy.zw-=sign(fmod_cbp_uv-one)*c1024;\n" + + " out_yblockpos_y=mix(vec4(c1024,c1024,c1024,c1024)-one,out_yblockpos_y,fmod_cbp_y);\n" + " out_uvblockpos_xy.zw=mix(vec2(c1024,c1024)-one,out_uvblockpos_xy.zw,fmod_cbp_uv);\n" + // set start positions " vec4 motion_vertical=vec4(block_types.z,block_types.z,block_types.z,block_types.z);\n" @@ -137,8 +150,8 @@ const GLchar moco_vertex_shader[] = " out_moco_backward=vec4(PMV1.zw,PMV1.zw);\n" //" out_unsupported=2.;\n" " } else if (block_types.y==y_cbp.x /*1*/) {" //Field - " out_moco_forward=vec4(PMV1.xy,PMV2.xy);\n" - " out_moco_backward=vec4(PMV1.zw,PMV2.zw);\n" + " out_moco_forward=vec4(PMV1.xy,PMV1.xy);\n" + " out_moco_backward=vec4(PMV1.zw,PMV1.zw);\n" " out_moco_forward.y+=mod_motion_vertical.x;\n" " out_moco_backward.y+=mod_motion_vertical.y;\n" " out_moco_forward.w-=one-mod_motion_vertical.z;\n" @@ -151,6 +164,8 @@ const GLchar moco_vertex_shader[] = " }\n" + + " out_block_edge=block_edge;\n" " out_misc_info.x=block_types.w;\n" " vec4 out_pos=block_pos;\n" @@ -284,7 +299,7 @@ const GLchar moco_frag_shader[] = // now we handle the y fetching " vec4 moco_temp;\n" " vec4 subpixel=floor(mod(moco_work,ctwo))*halfst; \n" - " moco_temp=floor(moco_work*halfst+halfst)+floor(vec4(out_moco_pos.xy,out_moco_pos.xy));\n" + " moco_temp=floor(moco_work*halfst)+floor(vec4(out_moco_pos.xy,out_moco_pos.xy));\n" " vec4 c00,c01,c10,c11;\n" " c00=texture2D(forward_pic,moco_temp.xy*pict_size);\n" @@ -374,11 +389,11 @@ int GLMocoShader::init() { glBindTexture(GL_TEXTURE_2D, data_blocks); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, BLOCK_TEXTURE_WIDTH >>1, BLOCK_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - char buffer[BLOCK_TEXTURE_WIDTH*4]; - memset(buffer,0,BLOCK_TEXTURE_WIDTH*4); // the last line is black, simplifies the shader algorithms + char buffer[BLOCK_TEXTURE_WIDTH*2]; + memset(buffer,0,BLOCK_TEXTURE_WIDTH*2); // the last line is black, simplifies the shader algorithms glTexSubImage2D(GL_TEXTURE_2D,0,0,BLOCK_TEXTURE_HEIGHT-1, - 1024,1, + BLOCK_TEXTURE_WIDTH>>1,1, GL_RGBA,GL_UNSIGNED_BYTE, buffer); @@ -545,6 +560,7 @@ int GLMocoShader::doMoCo(VPEOGLFrame *target,VPEOGLFrame *forward,VPEOGLFrame *b + //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark2 glerror %x",glGetError()); //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark2a glerror %x",glGetError()); @@ -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); + if (forward) { Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo forward %x",forward->textures[0]); glActiveTexture(GL_TEXTURE1); @@ -637,8 +654,9 @@ int GLMocoShader::doMoCo(VPEOGLFrame *target,VPEOGLFrame *forward,VPEOGLFrame *b } + glDrawElements(GL_TRIANGLE_STRIP, valid_macro_blocks*6, - GL_UNSIGNED_SHORT, NULL); + GL_UNSIGNED_SHORT, NULL); /* diff --git a/osdopengl.cc b/osdopengl.cc index b425ffc..f0bc96b 100755 --- a/osdopengl.cc +++ b/osdopengl.cc @@ -420,7 +420,7 @@ void OsdOpenGL::threadMethod() if (!frame) frame=video->getReadyOGLFrame(); if (frame) { InternalRendering(frame); - // MILLISLEEP(1500); + // MILLISLEEP(1000); lastrendertime=getTimeMS(); video->returnOGLFrame(frame); //please recycle it frame=NULL; diff --git a/videovpeogl.cc b/videovpeogl.cc index 3b80eaa..1035ec2 100755 --- a/videovpeogl.cc +++ b/videovpeogl.cc @@ -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::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::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;ipict_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;ipict_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); diff --git a/videovpeogl.h b/videovpeogl.h index 4357df2..f76c5c2 100755 --- a/videovpeogl.h +++ b/videovpeogl.h @@ -88,6 +88,9 @@ struct VPE_FrameBuf unsigned int size[4]; unsigned int pict_num; VPEOGLFrame *ogl_ref; + bool ogl_uploaded; + int width, height; + int stride; }; #endif @@ -269,8 +272,9 @@ class VideoVPEOGL : public Video, public Thread_TYPE vector dec_frame_libav_all; list dec_frame_libav_free; list dec_frame_libav_upload_and_view_pending; - list dec_frame_libav_upload_only_pending; - AVFrame* dec_frame_libav_uploading; + list dec_frame_libav_upload_only_pending; + //AVFrame* dec_frame_libav_uploading; + VPE_FrameBuf* dec_frame_libav_uploading_framebuf; AVFrame* dec_frame_libav_decoding; void add_dec_frame_upload_only(struct AVCodecContext *s,const AVFrame* data); -- 2.39.2