"varying vec2 out_block_edge;\n"\r
"varying vec4 out_block_types;\n"\r
\r
+ "varying float out_unsupported;\n"\r
+\r
"const float one=1.0;\n"\r
"const float c1024=1024.0;\n"\r
"const float c32=32.0;\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
+ // " if (block_types.y!=0.) {\n"\r
+ // " out_unsupported=1.;\n"\r
+ // "} else {\n"\r
+ // " out_unsupported=0.;\n"\r
+ // "}\n"\r
+\r
\r
" out_block_edge=block_edge;\n"\r
" out_block_types=block_types;\n"\r
const GLchar moco_frag_shader[] =\r
"precision mediump float;\n"\r
"uniform sampler2D blocks;\n"\r
+ "uniform sampler2D forward_pic;\n"\r
+ "uniform sampler2D backward_pic;\n"\r
"varying vec4 out_yblockpos_x;\n"\r
"varying vec4 out_yblockpos_y;\n"\r
"varying vec4 out_uvblockpos_xy;\n"\r
"varying vec2 out_block_edge;\n"\r
- "varying vec4 out_block_types;\n"\r
+ "varying vec4 out_block_types;\n" // change this we need so far only the dct type\r
+ "varying float out_unsupported;\n"\r
\r
"const float halfst=0.5;\n"\r
"const float ctwo=2.0;\n"\r
" ypos_temp2.xy=ypos_temp1.xy;\n"\r
" }\n"\r
" gl_FragColor.b=unpack_short(ypos_temp2.rg);\n"\r
+ " if (out_unsupported!=0.) {\n"\r
+ " gl_FragColor.rgb=vec3(cone,cone,0.0);\n"\r
+ "}\n"\r
\r
\r
//" ypos_temp2=mix(ypos_temp1.rg,ypos_temp1.ba,step(c1over2047,mod(ypos_temp2.x,c1over1023)));\n" //activate this\r
}\r
loc_pict_scale = glGetUniformLocation(shad_program, "pict_scale");\r
blocks_loc = glGetUniformLocation(shad_program, "blocks");\r
+ forward_pic_loc = glGetUniformLocation(shad_program, "forward_pic");\r
+ backward_pic_loc = glGetUniformLocation(shad_program, "backward_pic");\r
\r
// frame_sampler_locY = glGetUniformLocation(shad_program, "textureY");\r
// Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",frame_sampler_locY,glGetError());\r
\r
\r
\r
- Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark1 glerror %x %d",glGetError(),height);\r
+// Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark1 glerror %x %d",glGetError(),height);\r
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,\r
BLOCK_TEXTURE_WIDTH>>1,height,\r
GL_RGBA,GL_UNSIGNED_BYTE,\r
blocks);\r
- Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark2 glerror %x",glGetError());\r
+// Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark2 glerror %x",glGetError());\r
glTexSubImage2D(GL_TEXTURE_2D,0,0,height+1,\r
(num_blocks%BLOCK_PER_ROW)>>1,1,\r
GL_RGBA,GL_UNSIGNED_BYTE,\r
blocks);\r
\r
- Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark2 glerror %x",glGetError());\r
+ //Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark2 glerror %x",glGetError());\r
\r
\r
\r
\r
}\r
\r
-int GLMocoShader::doMoCo(VPEOGLFrame *target)\r
+int GLMocoShader::doMoCo(VPEOGLFrame *target,VPEOGLFrame *forward,VPEOGLFrame *backward)\r
{\r
\r
// Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark-2 glerror %x %x",glGetError(),frame_buf);\r
\r
//Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark-1 glerror %x %x",glGetError(),frame_buf);\r
glBindFramebuffer(GL_FRAMEBUFFER, frame_buf);\r
- Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark1 glerror %x %x %x",glGetError(),target->textures[0],target->textures[1]);\r
+ //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark1 glerror %x %x %x",glGetError(),target->textures[0],target->textures[1]);\r
\r
\r
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,\r
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);\r
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);\r
\r
+ if (forward) {\r
+ glActiveTexture(GL_TEXTURE1);\r
+ glBindTexture(GL_TEXTURE_2D,forward->textures[0]);\r
+ glUniform1i(forward_pic_loc,1);\r
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);\r
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);\r
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);\r
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);\r
+ }\r
+\r
+ if (backward) {\r
+ glActiveTexture(GL_TEXTURE2);\r
+ glBindTexture(GL_TEXTURE_2D,backward->textures[1]);\r
+ glUniform1i(backward_pic_loc,2);\r
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);\r
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);\r
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);\r
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);\r
+ }\r
+\r
glDrawElements(GL_TRIANGLE_STRIP, valid_macro_blocks*6,\r
GL_UNSIGNED_SHORT, NULL);\r
\r
//Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark6 glerror %x",glGetError());\r
\r
// glDrawElements(GL_TRIANGLE_STRIP,/*valid_macro_blocks*/4,GL_UNSIGNED_SHORT,0);\r
- Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark7 glerror %x %x",glGetError(),valid_macro_blocks);\r
+ //Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark7 glerror %x %x",glGetError(),valid_macro_blocks);\r
//cleanup\r
\r
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);\r
moco_shader=NULL;
#endif
+ ogl_forward_ref_frame_num=0;
+ ogl_backward_ref_frame_num=0;
+ ogl_forward_ref_frame=NULL;
+ ogl_backward_ref_frame=NULL;
+
#ifdef BENCHMARK_FPS
time_in_decoder=0;
num_frames=0;
ogl_frame_mutex.Lock();
if (frame) {
ogl_frame_outside=false;
- free_ogl_frames.push_back(frame);
+ //Log::getInstance()->log("Video", Log::WARN, "returnOGLRFrame mark incoming num: %d",frame->pict_num);
+ if (frame->pict_num==ogl_forward_ref_frame_num ||
+ frame->pict_num==ogl_backward_ref_frame_num ) {
+ recycle_ref_ogl_frames.push_back(frame);
+ } else {
+ free_ogl_frames.push_back(frame);
+ }
+ }
+ ogl_frame_mutex.Unlock();
+}
+
+void VideoVPEOGL::recycleOGLRefFrames()
+{
+ // This function recycles frames formerly used as reference frame
+ ogl_frame_mutex.Lock();
+ list<VPEOGLFrame*> keep;
+ list<VPEOGLFrame*>::iterator itty=recycle_ref_ogl_frames.begin();
+ while (itty!=recycle_ref_ogl_frames.end()) {
+ Log::getInstance()->log("Video", Log::WARN, "recycleOGLRefFrame mark3");
+ if ((*itty)->pict_num==ogl_forward_ref_frame_num
+ || (*itty)->pict_num==ogl_backward_ref_frame_num)
+ {
+ // ok we have to keep this
+ keep.push_back(*itty);
+ } else {
+ free_ogl_frames.push_back(*itty);
+ }
+ itty++;
}
+ recycle_ref_ogl_frames.clear();
+ recycle_ref_ogl_frames=keep;
+
ogl_frame_mutex.Unlock();
+
+
}
void VideoVPEOGL::threadMethod()
}
while (1) {
bool sleep=true;
+ bool upload=false;
+ bool view=false;
#ifdef VPE_LIBAV_SUPPORT
dec_frame_libav_mutex.Lock();
- if (dec_frame_libav_upload_pending.size()>0) {
- dec_frame_libav_uploading=dec_frame_libav_upload_pending.front();
- dec_frame_libav_upload_pending.pop_front();
- if (dec_frame_libav_upload_pending.size()>0) sleep=false;
+
+
+ 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_upload_and_view_pending.pop_front();
+ upload=view=true;
+ if (decoding_mode!=VPE_NO_XVMC) upload=false;
+ } else {
+ dec_frame_libav_uploading=NULL;
+ }
+ }
+
+ if (!view && dec_frame_libav_upload_only_pending.size()>0) {
+
+ 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_upload_only_pending.pop_front();
+ view=false;
+ upload=true;
}
+
+
+ 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) {
- int width,height,pixfmt;
- //First get a free ogl image
- VPEOGLFrame* out_frame=NULL;
- while (!out_frame) {
- ogl_frame_mutex.Lock();
- if (all_ogl_frames.size()==0) {
- ogl_frame_mutex.Unlock(); break;
- }
- if (free_ogl_frames.size()>0) {
- width=libavwidth;
- height=libavheight;
- pixfmt=libavpixfmt;
- out_frame=free_ogl_frames.front();
- free_ogl_frames.pop_front();
- } else MILLISLEEP(2);
- ogl_frame_mutex.Unlock();
- }
- bool failed=false;
- if (out_frame) {
- if (out_frame->textures[0]==0 || out_frame->width!=width ||
- out_frame->height!=height || out_frame->stride!=dec_frame_libav_uploading->linesize[0]) {
- if (out_frame->textures[0]!=0) {
- glDeleteTextures(1,&out_frame->textures[0]);
- out_frame->textures[0]=0;
- }
- if (out_frame->textures[1]!=0) {
- glDeleteTextures(1,&out_frame->textures[1]);
- out_frame->textures[1]=0;
- }
- if (out_frame->textures[2]!=0) {
- glDeleteTextures(1,&out_frame->textures[2]);
- out_frame->textures[2]=0;
+ if (upload) {
+ int width,height,pixfmt;
+ //First get a free ogl image
+ VPEOGLFrame* out_frame=NULL;
+ while (!out_frame) {
+ ogl_frame_mutex.Lock();
+ // Log::getInstance()->log("Video", Log::WARN, "threadMethod mark upload 1a %d %d %d %d %d",all_ogl_frames.size(),free_ogl_frames.size(),
+ // recycle_ref_ogl_frames.size(),ready_ogl_frames.size(),ogl_frame_outside);
+ if (all_ogl_frames.size()==0) {
+ ogl_frame_mutex.Unlock(); break;
}
- if (decoding_mode==VPE_NO_XVMC) {
- if (!AllocateYUV400OglTexture(out_frame,width,height,dec_frame_libav_uploading->linesize[0])) failed=true;
- }else {
- if (!AllocateYUV444OglTexture(out_frame,width,height)) failed=true; //We use a YUV 444 texture in this case
- // the shaders are easier to implement
- }
+ if (free_ogl_frames.size()>0) {
+ width=libavwidth;
+ height=libavheight;
+ pixfmt=libavpixfmt;
+ out_frame=free_ogl_frames.front();
+ free_ogl_frames.pop_front();
+ } else MILLISLEEP(2);
+ ogl_frame_mutex.Unlock();
}
- 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) {
- glBindTexture(GL_TEXTURE_2D, out_frame->textures[0]);
- glPixelStorei(GL_UNPACK_ALIGNMENT,1);
- glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
- out_frame->stride,out_frame->height,
- GL_LUMINANCE,GL_UNSIGNED_BYTE,
- dec_frame_libav_uploading->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]);
-
- 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]);
- } else {
- //XVMC case
- xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading->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 );
- if (decoding_mode==VPE_XVMC_MOCOMP)
- {
- //DCT Blocks upload
-
- } else {
- //DCT Blocks upload
- }
- moco_shader->doMoCo(out_frame);
+ bool failed=false;
+ if (out_frame) {
+ if (out_frame->textures[0]==0 || out_frame->width!=width ||
+ out_frame->height!=height || out_frame->stride!=dec_frame_libav_uploading->linesize[0]) {
+ if (out_frame->textures[0]!=0) {
+ glDeleteTextures(1,&out_frame->textures[0]);
+ out_frame->textures[0]=0;
+ }
+ if (out_frame->textures[1]!=0) {
+ glDeleteTextures(1,&out_frame->textures[1]);
+ out_frame->textures[1]=0;
+ }
+ if (out_frame->textures[2]!=0) {
+ glDeleteTextures(1,&out_frame->textures[2]);
+ out_frame->textures[2]=0;
+ }
- // Excute motion compensation
+ if (decoding_mode==VPE_NO_XVMC) {
+ if (!AllocateYUV400OglTexture(out_frame,width,height,dec_frame_libav_uploading->linesize[0])) failed=true;
+ } else {
+ if (!AllocateYUV444OglTexture(out_frame,width,height)) 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;
+ 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) {
+ glBindTexture(GL_TEXTURE_2D, out_frame->textures[0]);
+ glPixelStorei(GL_UNPACK_ALIGNMENT,1);
+ glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
+ out_frame->stride,out_frame->height,
+ GL_LUMINANCE,GL_UNSIGNED_BYTE,
+ dec_frame_libav_uploading->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]);
+
+ 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]);
+ } else {
+ //XVMC case
+ xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading->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);
+
+ if (((int)pix_fmt->p_future_surface)!=0 && ogl_forward_ref_frame_num!=((int)pix_fmt->p_future_surface))
+ {
+ //Now determine the frame, that fits
+ ogl_frame_mutex.Lock();
+ for (int i=0;i<all_ogl_frames.size();i++) {
+ if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_future_surface))
+ {
+ ogl_backward_ref_frame=ogl_forward_ref_frame; //mpeg life time axioms
+ ogl_backward_ref_frame_num=ogl_forward_ref_frame_num;
+ ogl_forward_ref_frame=all_ogl_frames[i];
+ ogl_forward_ref_frame_num=(int)pix_fmt->p_future_surface;
+ break;
+ }
+ }
+
+ ogl_frame_mutex.Unlock();
+ recycleOGLRefFrames(); //needed for recycling of reference frames
+ }
+
+
+ if (((int)pix_fmt->p_past_surface)!=0 && ogl_backward_ref_frame_num!=((int)pix_fmt->p_past_surface))
+ {
+ //Now determine the frame, that fits
+ ogl_frame_mutex.Lock();
+ for (int i=0;i<all_ogl_frames.size();i++) {
+ if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_past_surface))
+ {
+ ogl_backward_ref_frame=all_ogl_frames[i];
+ ogl_backward_ref_frame_num=(int)pix_fmt->p_past_surface; // This should not happen, or for DMV, who knows
+ break;
+ }
+ }
+
+ ogl_frame_mutex.Unlock();
+ recycleOGLRefFrames(); //needed for recycling of reference frames
+
+ }
+
+ if (decoding_mode==VPE_XVMC_MOCOMP)
+ {
+ //DCT Blocks upload
+
+ } else {
+ //DCT Blocks upload
+ }
+ out_frame->pict_num=((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->pict_num;
+
+ moco_shader->doMoCo(out_frame,ogl_forward_ref_frame,ogl_backward_ref_frame);
+
+ // Excute motion compensation
+ }
+ }
- releaseFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_uploading->base[0]);
+ }
+ }
- 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
+ }
- }
+
+
+ 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);
+
+ releaseFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_uploading->base[0]);
+ 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_uploading=NULL;
dec_frame_libav_mutex.Unlock();
+ }
+ dec_frame_libav_mutex.Lock();
+ dec_frame_libav_uploading=NULL;
+ 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();
}
#endif
- if (sleep) threadWaitForSignal();
+ if (sleep) {
+ threadWaitForSignal();
+ Log::getInstance()->log("Video", Log::WARN, "threadMethod signalled");
+ }
threadCheckExit();
}
return ret_pix;
}
+// we use this function to push the data to ogl out before hand, this is only useful for xvmc
+void VideoVPEOGL::draw_horiz_band_libav(struct AVCodecContext *s, const AVFrame *src, int offset[4], int y, int type, int height)
+{
+ if ((y+height)==src->height) {
+ //Log::getInstance()->log("Video", Log::NOTICE, "draw_horiz_band %d %d %d %d!",y,type,height,((xvmc_pix_fmt *)src->data[2])->p_surface);
+ ((VideoVPEOGL*)Video::getInstance())->add_dec_frame_upload_only(s,src);
+ }
+
+}
+
int VideoVPEOGL::reget_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
{
Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!Not Implemented!");
if (decoding_mode==VPE_XVMC_MOCOMP) mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_MC;
else mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_IDCT;
mpeg2codec_context_libav->get_format=get_format_libav;
+ mpeg2codec_context_libav->draw_horiz_band=draw_horiz_band_libav;
}
mpeg2codec_context_libav->get_buffer=get_buffer_libav;
mpeg2codec_context_libav->release_buffer=release_buffer_libav;
+
int avc_ret=avcodec_open(mpeg2codec_context_libav, mpeg2codec_libav);
if (avc_ret<0) {
Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec failed ");
ogl_frame_mutex.Lock();
//Allocate texture structs, since we do not know the sizes, we do not allocate the textures yet
- for (int i=0;i<3;i++) {
+ for (int i=0;i<5;i++) {
VPEOGLFrame *new_frame=(VPEOGLFrame *)malloc(sizeof(VPEOGLFrame));
new_frame->type=1; //1 = YUV, 2 RGB
new_frame->textures[0]=0;
libav_running=false;
Log::getInstance()->log("Video", Log::NOTICE, "DeAllocateCodecslibav");
dec_frame_libav_mutex.Lock();
- dec_frame_libav_upload_pending.clear();
+ dec_frame_libav_upload_and_view_pending.clear();
+ dec_frame_libav_upload_only_pending.clear();
dec_frame_libav_free.clear();
dec_frame_libav_mutex.Unlock();
while (dec_frame_libav_uploading) {
all_ogl_frames.clear();
free_ogl_frames.clear();
ready_ogl_frames.clear();
+ recycle_ref_ogl_frames.clear();
+ ogl_forward_ref_frame_num=0;
+ ogl_backward_ref_frame_num=0;
+ ogl_forward_ref_frame=NULL;
+ ogl_backward_ref_frame=NULL;
+
ogl_frame_mutex.Unlock();
((OsdOpenGL*)Osd::getInstance())->EndPainting();
vpe_framebuf_mutex.Unlock();
}
+void VideoVPEOGL::add_dec_frame_upload_only(struct AVCodecContext *s,const AVFrame* data)
+{
+ dec_frame_libav_mutex.Lock();
+ 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);
+
+ dec_frame_libav_upload_only_pending.push_back((AVFrame*)data); // we are only uploading
+ dec_frame_libav_mutex.Unlock();
+ threadSignal();
+}
// Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",libavwidth,libavheight,libavpixfmt);
- dec_frame_libav_upload_pending.push_back(dec_frame_libav_decoding);
+ dec_frame_libav_upload_and_view_pending.push_back(dec_frame_libav_decoding);
dec_frame_libav_decoding=NULL;
if (dec_frame_libav_free.size()>0) {
dec_frame_libav_decoding=dec_frame_libav_free.front();
} else {
libav_hastime=false;
dec_frame_libav_mutex.Unlock();
+ threadSignal();
// No free buffers
return 0;
}