]> git.vomp.tv Git - vompclient-marten.git/blob - videovpeogl.cc
Motion Compensation, all implemented, all buggy
[vompclient-marten.git] / videovpeogl.cc
1 /*
2     Copyright 2004-2005 Chris Tallon, 2009 Marten Richter
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #include "videovpeogl.h"
22 #include "audiovpe.h"
23 #include "mtdraspberry.h"
24 #include "demuxer.h"
25 #include "osdopengl.h"
26
27 // temp
28 #include "log.h"
29
30 //A lot of parts of this file are heavily inspired by xbmc omx implementations
31
32 VideoVPEOGL::VideoVPEOGL()
33 {
34   lastpacketnum=-1;
35
36 #ifdef VPE_OMX_SUPPORT
37   omx_running=false;
38
39   omx_vid_dec=0;
40   cur_input_buf_omx=NULL;
41   omx_h264=omx_mpeg2=true;
42 #endif
43
44 #ifdef VPE_LIBAV_SUPPORT
45   mpeg2codec_context_libav=NULL;
46   libav_running=false;
47   dec_frame_libav_uploading=NULL;
48   dec_frame_libav_decoding=NULL;
49   ogl_frame_outside=false;
50   //decoding_mode=VPE_NO_XVMC;
51   decoding_mode=VPE_XVMC_MOCOMP;
52   //decoding_mode=VPE_XVMC_IDCT;
53   framebuf_framenum=0;
54   moco_shader=NULL;
55 #endif
56
57   ogl_forward_ref_frame_num=0;
58   ogl_backward_ref_frame_num=0;
59   ogl_forward_ref_frame=NULL;
60   ogl_backward_ref_frame=NULL;
61
62 #ifdef BENCHMARK_FPS
63         time_in_decoder=0;
64     num_frames=0;
65 #endif
66
67 }
68
69 VideoVPEOGL::~VideoVPEOGL()
70 {
71   instance = NULL;
72 }
73
74 int VideoVPEOGL::init(UCHAR tformat)
75 {
76   if (initted) return 0;
77   initted = 1;
78
79 //  if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
80
81   if (!setFormat(tformat))           { shutdown(); return 0; }
82   if (!setConnection(COMPOSITERGB))  { shutdown(); return 0; }
83   if (!setAspectRatio(ASPECT4X3))    { shutdown(); return 0; }
84   if (!setMode(NORMAL))              { shutdown(); return 0; }
85   if (!setSource())                  { shutdown(); return 0; }
86   if (!attachFrameBuffer())          { shutdown(); return 0; }
87
88   setTVsize(ASPECT4X3);
89
90 /*  if (format == PAL) setLetterboxBorder("38");
91   else setLetterboxBorder("31");*/
92
93   /* new stulibav */
94
95
96
97
98   //stop();
99
100
101
102   return 1;
103 }
104
105 int VideoVPEOGL::initUsingOSDObjects()
106 {
107         EGLDisplay i_egl_display;
108         EGLSurface i_egl_surface;
109         EGLContext i_egl_context;
110         EGLConfig i_egl_config;
111         OsdOpenGL *osd=(OsdOpenGL*)osd->getInstance();
112         osd->getEGLObjs(&i_egl_display,&i_egl_surface,&i_egl_context, &i_egl_config);
113         const EGLint attr_context[]={
114                         EGL_CONTEXT_CLIENT_VERSION,2,
115                 EGL_NONE
116         };
117
118         egl_display=i_egl_display;
119         egl_context=eglCreateContext(egl_display,i_egl_config,i_egl_context,attr_context);
120         if (egl_context==EGL_NO_CONTEXT) {
121                  Log::getInstance()->log("Video", Log::WARN, "Creating egl context failed! %x",eglGetError());
122                  return 0;
123         }
124         // We create a dummy surface here, in order to allow two contexts
125         const EGLint attr_pbuffer[]={
126                         EGL_WIDTH, 1, EGL_HEIGHT,1,
127                     EGL_NONE
128         };
129         egl_surface=eglCreatePbufferSurface(egl_display,i_egl_config,attr_pbuffer);
130         if (egl_surface==EGL_NO_SURFACE) {
131                  Log::getInstance()->log("Video", Log::WARN, "Creating egl pbuffer failed! %x",eglGetError());
132                  return 0;
133         }
134
135
136
137
138         //egl_surface=i_egl_surface;
139         //egl_context=i_egl_context;
140
141
142 #ifdef VPE_OMX_SUPPORT
143 // we are called before the audio
144         OMX_ERRORTYPE error;
145         error=OMX_Init();
146         if (error!=OMX_ErrorNone) {
147                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error);
148                 return 0;
149         }
150
151         //our callbacks move to play?
152
153 #endif
154
155 #ifdef VPE_LIBAV_SUPPORT
156
157         av_register_all();
158         if (decoding_mode==VPE_NO_XVMC) {
159                 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
160         } else {
161                 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_XVMC);
162         }
163         if (mpeg2codec_libav==NULL) {
164                 Log::getInstance()->log("Video", Log::DEBUG, "Find libav mpeg2 codec failed");
165                 return 0;
166         }
167
168 #endif
169         threadStart();
170         return 1;
171 }
172
173
174 #ifdef VPE_OMX_SUPPORT
175
176 OMX_ERRORTYPE VideoVPEOGL::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
177            OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
178            OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
179
180         Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
181
182         struct VPE_OMX_EVENT  new_event;
183         new_event.handle=handle;
184         new_event.appdata=appdata;
185         new_event.event_type=event_type;
186         new_event.data1=data1;
187         new_event.data2=data2;
188         new_event.event_data=event_data;
189
190         VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
191         video->AddOmxEvent(new_event);
192
193 /*      switch (event_type) {
194         case OMX_EventCmdComplete: {
195
196         } break;
197         }*/
198
199         return OMX_ErrorNone;
200
201 }
202
203 void VideoVPEOGL::AddOmxEvent(VPE_OMX_EVENT  new_event)
204 {
205         omx_event_mutex.Lock();
206     omx_events.push_back(new_event);
207         omx_event_mutex.Unlock();
208 }
209
210
211 OMX_ERRORTYPE VideoVPEOGL::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
212
213         Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
214         VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
215         video->ReturnEmptyOMXBuffer(buffer);
216         return OMX_ErrorNone;
217
218 }
219
220 void VideoVPEOGL::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
221         input_bufs_omx_mutex.Lock();
222         Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
223         input_bufs_omx_free.push_back(buffer);
224         Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
225         input_bufs_omx_mutex.Unlock();
226 }
227
228  OMX_ERRORTYPE VideoVPEOGL::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
229          Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
230         return OMX_ErrorNone;
231 }
232
233 #endif
234
235 int VideoVPEOGL::shutdown()
236 {
237   if (!initted) return 0;
238   initted = 0;
239   threadCancel();
240
241   decoding_backend=0;
242 #ifdef VPE_OMX_SUPPORT
243   DeAllocateCodecsOMX();
244   OMX_Deinit();
245 #endif
246 #ifdef VPE_LIBAV_SUPPORT
247   DeAllocateCodecsLibav();
248 #endif
249   eglDestroyContext(egl_display,egl_context);
250 //  close(fdVideo);
251   return 1;
252 }
253
254 int VideoVPEOGL::AllocateYUV400OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
255 {
256         Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 400");
257         // Y
258         glGenTextures(1, &outframe->textures[0]);
259         glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
260         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride, height, 0, GL_LUMINANCE,
261                                 GL_UNSIGNED_BYTE, NULL);
262         // U
263         glGenTextures(1, &outframe->textures[1]);
264         glBindTexture(GL_TEXTURE_2D, outframe->textures[1]);
265         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
266                                 GL_UNSIGNED_BYTE, NULL);
267         // V
268         glGenTextures(1, &outframe->textures[2]);
269         glBindTexture(GL_TEXTURE_2D, outframe->textures[2]);
270         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
271                         GL_UNSIGNED_BYTE, NULL);
272         outframe->height=height;
273         outframe->width=width;
274         outframe->stride=stride;
275         outframe->type=1;
276         return 1;
277 }
278
279 int VideoVPEOGL::AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
280 {
281         Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 444");
282         // Y
283         glGenTextures(1, &outframe->textures[0]);
284         glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
285         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
286                                 GL_UNSIGNED_BYTE, NULL);
287         outframe->textures[1]=outframe->textures[2]=0; // no handles here
288
289
290
291
292         outframe->type=2;
293         outframe->height=height;
294         outframe->width=width;
295         outframe->stride=stride;// does not make any sense otherwise, just to prevent reallocating
296         return 1;
297 }
298
299
300 VPEOGLFrame *VideoVPEOGL::getReadyOGLFrame(){
301         VPEOGLFrame *return_obj=NULL;
302         ogl_frame_mutex.Lock();
303         if (ready_ogl_frames.size()>0) {
304                 return_obj=ready_ogl_frames.front();
305                 ready_ogl_frames.pop_front();
306                 ogl_frame_outside=true;
307         }
308         ogl_frame_mutex.Unlock();
309         return return_obj;
310 }
311
312 void VideoVPEOGL::returnOGLFrame(VPEOGLFrame *frame)
313 {
314         ogl_frame_mutex.Lock();
315         if (frame) {
316                 ogl_frame_outside=false;
317                 //Log::getInstance()->log("Video", Log::WARN, "returnOGLRFrame mark incoming num: %d",frame->pict_num);
318                 if (frame->pict_num==ogl_forward_ref_frame_num ||
319                                 frame->pict_num==ogl_backward_ref_frame_num ) {
320                         recycle_ref_ogl_frames.push_back(frame);
321                 } else {
322                         free_ogl_frames.push_back(frame);
323                 }
324         }
325         ogl_frame_mutex.Unlock();
326 }
327
328 void VideoVPEOGL::recycleOGLRefFrames()
329 {
330         // This function recycles frames formerly used as reference frame
331         ogl_frame_mutex.Lock();
332         list<VPEOGLFrame*> keep;
333         list<VPEOGLFrame*>::iterator itty=recycle_ref_ogl_frames.begin();
334         while (itty!=recycle_ref_ogl_frames.end()) {
335                 Log::getInstance()->log("Video", Log::WARN, "recycleOGLRefFrame mark3");
336                 if ((*itty)->pict_num==ogl_forward_ref_frame_num
337                                 || (*itty)->pict_num==ogl_backward_ref_frame_num)
338                 {
339                         // ok we have to keep this
340                         keep.push_back(*itty);
341                 } else {
342                         free_ogl_frames.push_back(*itty);
343                 }
344                 itty++;
345         }
346         recycle_ref_ogl_frames.clear();
347         recycle_ref_ogl_frames=keep;
348
349         ogl_frame_mutex.Unlock();
350
351
352 }
353
354 void VideoVPEOGL::threadMethod()
355 {
356         if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
357                 Log::getInstance()->log("Video", Log::WARN, "Making egl Current failed in thread %d",eglGetError());
358                 return;
359         }
360         while (1) {
361                 bool sleep=true;
362                 bool upload=false;
363                 bool view=false;
364 #ifdef VPE_LIBAV_SUPPORT
365                 dec_frame_libav_mutex.Lock();
366
367
368                 if (dec_frame_libav_upload_and_view_pending.size()>0  ) {
369                         bool blocked=false;
370                         dec_frame_libav_uploading=dec_frame_libav_upload_and_view_pending.front();
371                 //      Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view %d",((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->pict_num);
372                 //      if (dec_frame_libav_upload_only_pending.size()>0) Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view %d",
373                 //                      ((VPE_FrameBuf*)dec_frame_libav_upload_only_pending.front()->base[0])->pict_num);
374                         list<AVFrame*>::iterator itty=dec_frame_libav_upload_only_pending.begin();
375                         while (itty!=dec_frame_libav_upload_only_pending.end())
376                         {
377                                 if (*itty==dec_frame_libav_uploading) {
378                                         blocked=true;
379                                         break;
380                                 }
381                                 itty++;
382                         }
383                         if (!blocked) { // this assures that no frame without an upload is pushed out to rendering
384                                 dec_frame_libav_upload_and_view_pending.pop_front();
385                                 upload=view=true;
386                                 if (decoding_mode!=VPE_NO_XVMC) upload=false;
387                         } else {
388                                 dec_frame_libav_uploading=NULL;
389                         }
390                 }
391
392                 if (!view && dec_frame_libav_upload_only_pending.size()>0) {
393
394                         dec_frame_libav_uploading=dec_frame_libav_upload_only_pending.front();
395                         //Log::getInstance()->log("Video", Log::WARN, "threadMethod u  %d",((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->pict_num);
396                         dec_frame_libav_upload_only_pending.pop_front();
397                         view=false;
398                         upload=true;
399                 }
400
401
402                 if (dec_frame_libav_upload_and_view_pending.size()>0
403                         ||dec_frame_libav_upload_only_pending.size()>0) sleep=false;
404
405                 dec_frame_libav_mutex.Unlock();
406
407
408                 if (dec_frame_libav_uploading) {
409
410                         if (upload) {
411                                 int width,height,pixfmt;
412                                 //First get a free ogl image
413                                 VPEOGLFrame* out_frame=NULL;
414                                 while (!out_frame) {
415                                         ogl_frame_mutex.Lock();
416                                 //      Log::getInstance()->log("Video", Log::WARN, "threadMethod mark upload 1a %d %d %d %d %d",all_ogl_frames.size(),free_ogl_frames.size(),
417                                         //                                                              recycle_ref_ogl_frames.size(),ready_ogl_frames.size(),ogl_frame_outside);
418                                         if (all_ogl_frames.size()==0) {
419                                                 ogl_frame_mutex.Unlock(); break;
420                                         }
421
422                                         if (free_ogl_frames.size()>0) {
423                                                 width=libavwidth;
424                                                 height=libavheight;
425                                                 pixfmt=libavpixfmt;
426                                                 out_frame=free_ogl_frames.front();
427                                                 free_ogl_frames.pop_front();
428                                         } else MILLISLEEP(2);
429                                         ogl_frame_mutex.Unlock();
430                                 }
431                                 bool failed=false;
432                                 if (out_frame) {
433                                         if (out_frame->textures[0]==0 || out_frame->width!=width ||
434                                                         out_frame->height!=height || out_frame->stride!=dec_frame_libav_uploading->linesize[0]) {
435                                                 if (out_frame->textures[0]!=0) {
436                                                         glDeleteTextures(1,&out_frame->textures[0]);
437                                                         out_frame->textures[0]=0;
438                                                 }
439                                                 if (out_frame->textures[1]!=0) {
440                                                         glDeleteTextures(1,&out_frame->textures[1]);
441                                                         out_frame->textures[1]=0;
442                                                 }
443                                                 if (out_frame->textures[2]!=0) {
444                                                         glDeleteTextures(1,&out_frame->textures[2]);
445                                                         out_frame->textures[2]=0;
446                                                 }
447
448                                                 if (decoding_mode==VPE_NO_XVMC) {
449                                                         if (!AllocateYUV400OglTexture(out_frame,width,height,dec_frame_libav_uploading->linesize[0])) failed=true;
450                                                 } else {
451                                                         if (!AllocateYUV444OglTexture(out_frame,width,height,dec_frame_libav_uploading->linesize[0])) failed=true; //We use a YUV 444 texture in this case
452                                                         // the shaders are easier to implement
453                                                 }
454                                         }
455                                         ((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->ogl_ref=out_frame;
456                                         if (!failed) {
457                                                 //up to now only YUV data, this is for reference only, since the pi is too slow.
458                                                 if (decoding_mode==VPE_NO_XVMC) {
459                                                         glBindTexture(GL_TEXTURE_2D, out_frame->textures[0]);
460                                                         glPixelStorei(GL_UNPACK_ALIGNMENT,1);
461                                                         glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
462                                                                         out_frame->stride,out_frame->height,
463                                                                         GL_LUMINANCE,GL_UNSIGNED_BYTE,
464                                                                         dec_frame_libav_uploading->data[0]);
465
466                                                         glBindTexture(GL_TEXTURE_2D, out_frame->textures[1]);
467                                                         glPixelStorei(GL_UNPACK_ALIGNMENT,1);
468                                                         glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
469                                                                         out_frame->stride>>1,out_frame->height>>1,
470                                                                         GL_LUMINANCE,GL_UNSIGNED_BYTE,
471                                                                         dec_frame_libav_uploading->data[1]);
472
473                                                         glBindTexture(GL_TEXTURE_2D, out_frame->textures[2]);
474                                                         glPixelStorei(GL_UNPACK_ALIGNMENT,1);
475                                                         glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
476                                                                         out_frame->stride>>1,out_frame->height>>1,
477                                                                         GL_LUMINANCE,GL_UNSIGNED_BYTE,
478                                                                         dec_frame_libav_uploading->data[2]);
479                                                 } else {
480                                                         //XVMC case
481                                                         xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading->data[2];
482                                                         if (moco_shader && pix_fmt) {
483
484                                                                 moco_shader->uploadDataBlocks(pix_fmt->data_blocks,pix_fmt->next_free_data_block_num,
485                                                                                 pix_fmt->mv_blocks , pix_fmt->filled_mv_blocks_num );
486                                                                 Log::getInstance()->log("Video", Log::WARN, "Pictnum %d Forward %d Backward %d pict_type%d",pix_fmt->p_surface,
487                                                                                                                         pix_fmt->p_past_surface,pix_fmt->p_future_surface,dec_frame_libav_uploading->pict_type);
488
489                                                                 if (((int)pix_fmt->p_future_surface)!=0 && ogl_backward_ref_frame_num!=((int)pix_fmt->p_future_surface))
490                                                                 {
491                                                                         //Now determine the frame, that fits
492                                                                         ogl_frame_mutex.Lock();
493                                                                         for (int i=0;i<all_ogl_frames.size();i++) {
494                                                                                 if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_future_surface))
495                                                                                 {
496                                                                                         ogl_forward_ref_frame=ogl_backward_ref_frame; //mpeg life time axioms
497                                                                                         ogl_forward_ref_frame_num=ogl_backward_ref_frame_num;
498                                                                                         ogl_backward_ref_frame=all_ogl_frames[i];
499                                                                                         ogl_backward_ref_frame_num=(int)pix_fmt->p_future_surface;
500                                                                                         break;
501                                                                                 }
502                                                                         }
503
504                                                                         ogl_frame_mutex.Unlock();
505                                                                         recycleOGLRefFrames(); //needed for recycling of reference frames
506                                                                 }
507
508
509                                                                 if (((int)pix_fmt->p_past_surface)!=0 && ogl_forward_ref_frame_num!=((int)pix_fmt->p_past_surface))
510                                                                 {
511                                                                         //Now determine the frame, that fits
512                                                                         ogl_frame_mutex.Lock();
513                                                                         for (int i=0;i<all_ogl_frames.size();i++) {
514                                                                                 if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_past_surface))
515                                                                                 {
516                                                                                         ogl_forward_ref_frame=all_ogl_frames[i];
517                                                                                         ogl_forward_ref_frame_num=(int)pix_fmt->p_past_surface; // This should not happen, or for DMV, who knows
518                                                                                         break;
519                                                                                 }
520                                                                         }
521
522                                                                         ogl_frame_mutex.Unlock();
523                                                                         recycleOGLRefFrames(); //needed for recycling of reference frames
524
525                                                                 }
526
527                                                                 if (decoding_mode==VPE_XVMC_MOCOMP)
528                                                                 {
529                                                                         //DCT Blocks upload
530
531                                                                 } else {
532                                                                         //DCT Blocks upload
533                                                                 }
534                                                                 out_frame->pict_num=((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->pict_num;
535
536
537                                                                 moco_shader->doMoCo(out_frame,(((int)pix_fmt->p_past_surface)!=0)? ogl_forward_ref_frame:NULL,
538                                                                                 (((int)pix_fmt->p_future_surface)!=0)? ogl_backward_ref_frame:NULL);
539
540                                                                 // Excute motion compensation
541                                                         }
542                                                 }
543
544
545
546                                         }
547                                 }
548
549                         }
550
551
552
553                         if (view) {
554
555                                 //Log::getInstance()->log("Video", Log::WARN, "threadMethod mark view");
556                                 VPEOGLFrame* out_frame=((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->ogl_ref;
557                                 xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading->data[2];
558                                 Log::getInstance()->log("Video", Log::WARN, "View Pictnum %d Forward %d Backward %d pict_type%d",pix_fmt->p_surface,
559                                                                                                                         pix_fmt->p_past_surface,pix_fmt->p_future_surface,dec_frame_libav_uploading->pict_type);
560
561                                 releaseFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_uploading->base[0]);
562                                 ogl_frame_mutex.Lock();
563                                 ready_ogl_frames.push_back(out_frame);
564                                 ogl_frame_mutex.Unlock();
565                                 ((OsdOpenGL*)Osd::getInstance())->AdviseAboutNewFrame(); //Tell him, that we have a frame waiting
566
567                                 dec_frame_libav_mutex.Lock();
568                                 dec_frame_libav_free.push_back(dec_frame_libav_uploading);
569                                 dec_frame_libav_mutex.Unlock();
570                         }
571
572
573                         dec_frame_libav_mutex.Lock();
574                         dec_frame_libav_uploading=NULL;
575
576                         if (dec_frame_libav_upload_and_view_pending.size()>0
577                                         ||dec_frame_libav_upload_only_pending.size()>0) sleep=false;
578
579                         dec_frame_libav_mutex.Unlock();
580
581
582
583                 }
584 #endif
585
586                 if (sleep) {
587                         threadWaitForSignal();
588                         Log::getInstance()->log("Video", Log::WARN, "threadMethod signalled");
589                 }
590                 threadCheckExit();
591         }
592
593 }
594
595 void VideoVPEOGL::threadPostStopCleanup()
596 {
597         eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
598 #ifdef VPE_LIBAV_SUPPORT
599         dec_frame_libav_uploading=NULL;
600 #endif
601 }
602
603
604
605
606 int VideoVPEOGL::setTVsize(UCHAR ttvsize)
607 {
608 /*  tvsize = ttvsize;
609
610   // Override the aspect ratio usage, temporarily use to set the video chip mode
611   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
612   close(fdVideo);
613   if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
614   if (!setSource())                  { shutdown(); return 0; }
615   if (!attachFramebuffer())          { shutdown(); return 0; }
616
617   // Reopening the fd causes the scart aspect line to go back to 4:3
618   // Set this again to the same as the tv screen size
619   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
620
621   // mode == LETTERBOX is invalid if the TV is widescreen
622   if (tvsize == ASPECT16X9) setMode(NORMAL);
623 */
624   return 1;
625 }
626
627 int VideoVPEOGL::setDefaultAspect()
628 {
629   return setAspectRatio(tvsize);
630 }
631
632
633
634 int VideoVPEOGL::setFormat(UCHAR tformat)
635 {
636   if (!initted) return 0;
637   if ((tformat != PAL) && (tformat != NTSC)) return 0;
638   format = tformat;
639
640 //  if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
641
642   if (format == NTSC)
643   {
644     screenWidth = 720;
645     screenHeight = 480;
646   }
647   if (format == PAL)
648   {
649     screenWidth = 720;
650     screenHeight = 576;
651   }
652
653   return 1;
654 }
655
656 int VideoVPEOGL::setConnection(UCHAR tconnection)
657 {
658   if (!initted) return 0;
659   if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
660   connection = tconnection;
661
662 //  if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
663   return 1;
664 }
665
666 int VideoVPEOGL::setAspectRatio(UCHAR taspectRatio)
667 {
668   if (!initted) return 0;
669   if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
670   aspectRatio = taspectRatio;
671
672   Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
673
674 //  if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
675   return 1;
676 }
677
678 int VideoVPEOGL::setMode(UCHAR tmode)
679 {
680   if (!initted) return 0;
681
682   if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
683
684   if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
685       && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
686   mode = tmode;
687
688 //  if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
689   return 1;
690 }
691
692 int VideoVPEOGL::signalOff()
693 {
694 //  if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
695   return 1;
696 }
697
698 int VideoVPEOGL::signalOn()
699 {
700 //  if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
701   return 1;
702 }
703
704 int VideoVPEOGL::setSource()
705 {
706   if (!initted) return 0;
707
708   // What does this do...
709 //  if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
710   return 1;
711 }
712
713 int VideoVPEOGL::setPosition(int x, int y)
714 {
715   if (!initted) return 0;
716
717 //  vid_pos_regs_t pos_d;
718 //  pos_d.x = x;
719 //  pos_d.y = y;
720
721 /*  vid_pos_regs_t pos_d;
722
723   memset(&pos_d, 0, sizeof(pos_d));
724
725   pos_d.dest.y = y;
726   pos_d.dest.x = x;
727 /*
728 typedef struct {
729   int w;
730   int h;
731   int scale;
732   int x1;
733   int y;
734   int x;
735   int y2;
736   int x3;
737   int y3;
738   int x4;
739   int y4;
740 } vid_pos_regs_t;
741 */
742
743 /*
744   pos_d.w = 100;
745   pos_d.h = 30;
746   pos_d.scale = 2;
747   pos_d.x1 = 0;
748   pos_d.y = 100;            // Top left X
749   pos_d.x = 50;            // Top left Y
750   pos_d.y2 = 30;
751   pos_d.x3 = 60;
752   pos_d.y3 = 90;
753   pos_d.x4 = 120;
754   pos_d.y4 = 150;
755 */
756
757 //  if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
758   return 1;
759 }
760
761 int VideoVPEOGL::sync()
762 {
763   if (!initted) return 0;
764
765 //  if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
766   return 1;
767 }
768
769
770
771
772 int VideoVPEOGL::play()
773 {
774   if (!initted) return 0;
775   decoding_backend=0;
776 #ifdef VPE_OMX_SUPPORT
777   bool doomx=true;
778   if (h264) {
779           if (!omx_h264) doomx=false;
780   } else {
781           if (!omx_mpeg2) doomx=false;
782   }
783   if (doomx) {
784           if (AllocateCodecsOMX()) {
785                   decoding_backend=VPE_DECODER_OMX;
786                   return 1;
787                   // Otherwise fall back to libav
788           } else {
789                   if (h264) {
790                           omx_h264=false;
791                           Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume h264 unsupported");
792                   } else {
793                           omx_mpeg2=false;
794                           Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume mpeg2 unsupported");
795                   }
796           }
797   }
798 #endif
799 #ifdef VPE_LIBAV_SUPPORT
800   if (AllocateCodecsLibav()) {
801           decoding_backend=VPE_DECODER_libav;
802           return 1;
803                   // Otherwise fall back to libav
804   }
805 #endif
806   return 0;
807
808
809
810 }
811
812 #ifdef VPE_OMX_SUPPORT
813 int VideoVPEOGL::AllocateCodecsOMX()
814 {
815         OMX_ERRORTYPE error;
816         static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
817
818         Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
819         //Clock, move later to audio
820
821         omx_events.clear();
822
823         error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
824
825
826         if (error!=OMX_ErrorNone){
827                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
828                 DeAllocateCodecsOMX();
829                 return 0;
830         }
831
832
833
834         OMX_PORT_PARAM_TYPE p_param;
835         memset(&p_param,0,sizeof(p_param));
836         p_param.nSize=sizeof(p_param);
837         p_param.nVersion.nVersion=OMX_VERSION;
838         error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
839         if (error!=OMX_ErrorNone){
840                 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
841                 DeAllocateCodecsOMX();
842                 return 0;
843         }
844         omx_clock_output_port=p_param.nStartPortNumber;
845
846         for (unsigned int i=0;i<p_param.nPorts;i++) {
847                 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i) ) {
848                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
849                         DeAllocateCodecsOMX();
850                         return 0;
851                 }
852         }
853
854
855         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
856         memset(&clock_conf,0,sizeof(clock_conf));
857         clock_conf.nSize=sizeof(clock_conf);
858         clock_conf.nVersion.nVersion=OMX_VERSION;
859         clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
860         clock_conf.nStartTime=0;
861         clock_conf.nOffset=0;
862         clock_conf.nWaitMask=OMX_CLOCKPORT0;
863         error=OMX_SetParameter(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
864         if (error!=OMX_ErrorNone){
865                 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
866                 DeAllocateCodecsOMX();
867                 return 0;
868         }
869
870
871
872         if (h264) {
873                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
874         } else {
875                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
876         }
877
878         if (error!=OMX_ErrorNone){
879                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
880                 DeAllocateCodecsOMX();
881                 return 0;
882         }
883
884
885
886         memset(&p_param,0,sizeof(p_param));
887         p_param.nSize=sizeof(p_param);
888         p_param.nVersion.nVersion=OMX_VERSION;
889         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
890         if (error!=OMX_ErrorNone){
891                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
892                 DeAllocateCodecsOMX();
893             return 0;
894         }
895         omx_codec_input_port=p_param.nStartPortNumber;
896         omx_codec_output_port=p_param.nStartPortNumber+1;
897
898         if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
899                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
900                 DeAllocateCodecsOMX();
901                 return 0;
902         }
903
904
905         OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
906         memset(&conceal,0,sizeof(conceal));
907         conceal.nSize=sizeof(conceal);
908         conceal.nVersion.nVersion=OMX_VERSION;
909         conceal.bStartWithValidFrame=OMX_FALSE;
910
911         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
912         if (error!=OMX_ErrorNone){
913                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
914                 DeAllocateCodecsOMX();
915                 return 0;
916         }
917
918
919         error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
920         if (error!=OMX_ErrorNone){
921                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
922                 DeAllocateCodecsOMX();
923                 return 0;
924         }
925
926
927
928         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
929         if (error!=OMX_ErrorNone){
930                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
931                 DeAllocateCodecsOMX();
932                 return 0;
933         }
934         omx_shed_input_port=p_param.nStartPortNumber;
935         omx_shed_output_port=p_param.nStartPortNumber+1;
936
937
938         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
939         if (error!=OMX_ErrorNone){
940                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
941                 DeAllocateCodecsOMX();
942                 return 0;
943         }
944         omx_shed_clock_port=p_param.nStartPortNumber;
945
946
947         if (!DisablePort(omx_vid_sched,omx_shed_input_port) || !DisablePort(omx_vid_sched,omx_shed_output_port)
948                         || !DisablePort(omx_vid_sched,omx_shed_clock_port)) {
949                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
950                 DeAllocateCodecsOMX();
951                 return 0;
952         }
953
954
955         error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
956         if (error!=OMX_ErrorNone){
957                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
958                 DeAllocateCodecsOMX();
959                 return 0;
960         }
961
962         error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
963         if (error!=OMX_ErrorNone){
964                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
965                 DeAllocateCodecsOMX();
966                 return 0;
967         }
968         omx_rend_input_port=p_param.nStartPortNumber;
969         //omx_rend_output_port=p_param.nStartPortNumber+1;
970
971
972         if (!DisablePort(omx_vid_rend,omx_rend_input_port) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
973                                 ) {
974                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
975                 DeAllocateCodecsOMX();
976                 return 0;
977         }
978
979         //Setuo chain
980
981
982
983
984
985
986
987
988 /*      error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
989         if (error!=OMX_ErrorNone){
990                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
991                 return 0;
992         }*/
993
994
995
996
997         OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
998         memset(&ft_type,0,sizeof(ft_type));
999         ft_type.nSize=sizeof(ft_type);
1000         ft_type.nVersion.nVersion=OMX_VERSION;
1001
1002         ft_type.nPortIndex=omx_codec_input_port;
1003         if (h264) {
1004                 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
1005         } else {
1006                 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
1007         }
1008
1009         Demuxer* demux=Demuxer::getInstance();
1010
1011     ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
1012     Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
1013         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
1014         if (error!=OMX_ErrorNone){
1015                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
1016                 DeAllocateCodecsOMX();
1017                 return 0;
1018         }
1019
1020
1021         if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1022                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1023                 DeAllocateCodecsOMX();
1024                 return 0;
1025         }
1026
1027
1028         if (!PrepareInputBufsOMX()) {
1029                 DeAllocateCodecsOMX();
1030                 return 0;
1031         }
1032
1033
1034         if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1035                 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle");
1036                 DeAllocateCodecsOMX();
1037                 return 0;
1038         }
1039
1040         error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
1041         if (error!=OMX_ErrorNone){
1042                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel clock to sched failed %x %d %d", error,omx_clock_output_port,omx_shed_clock_port);
1043                 DeAllocateCodecsOMX();
1044                 return 0;
1045         }
1046
1047         if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
1048                                         ) {
1049                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
1050                 DeAllocateCodecsOMX();
1051                 return 0;
1052         }
1053
1054         if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
1055                 DeAllocateCodecsOMX();
1056                 return 0;
1057         }
1058
1059         error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
1060         if (error!=OMX_ErrorNone){
1061                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
1062                 DeAllocateCodecsOMX();
1063                 return 0;
1064         }
1065
1066
1067
1068         if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1069                                                 ) {
1070                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
1071                 DeAllocateCodecsOMX();
1072                 return 0;
1073         }
1074
1075         if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1076                 return 0;
1077         }
1078         if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1079                 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
1080                 DeAllocateCodecsOMX();
1081                 return 0;
1082         }
1083         if (!CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)
1084                         ||!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port)){
1085                 DeAllocateCodecsOMX();
1086                 return 0;
1087         }
1088
1089         if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
1090                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
1091                 DeAllocateCodecsOMX();
1092                 return 0;
1093         }
1094
1095         error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
1096         if (error!=OMX_ErrorNone){
1097                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel  sched to rend failed %x", error);
1098                 DeAllocateCodecsOMX();
1099                 return 0;
1100         }
1101
1102         if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
1103                                                         ) {
1104                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX  shed rend failed");
1105                 DeAllocateCodecsOMX();
1106                 return 0;
1107         }
1108
1109         if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
1110                                         || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1111                 DeAllocateCodecsOMX();
1112                 return 0;
1113         }
1114
1115         if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1116                 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1117                 DeAllocateCodecsOMX();
1118                 return 0;
1119         }
1120
1121
1122         if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
1123                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
1124                 DeAllocateCodecsOMX();
1125                 return 0;
1126         }
1127
1128         if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
1129                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
1130                 DeAllocateCodecsOMX();
1131                 return 0;
1132         }
1133
1134         //raspbi specifif
1135         OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1136         memset(&dispconf,0,sizeof(dispconf));
1137         dispconf.nSize=sizeof(dispconf);
1138         dispconf.nVersion.nVersion=OMX_VERSION;
1139
1140         dispconf.nPortIndex=omx_rend_input_port;
1141
1142         dispconf.set=OMX_DISPLAY_SET_LAYER ;
1143         dispconf.layer=1;
1144         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1145         if (error!=OMX_ErrorNone){
1146                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1147                 DeAllocateCodecsOMX();
1148                 return 0;
1149         }
1150
1151 /*      dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1152         dispconf.fullscreen=OMX_FALSE;
1153         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1154         if (error!=OMX_ErrorNone){
1155                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1156                 DeAllocateCodecsOMX();
1157                 return 0;
1158         }
1159
1160         dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1161         dispconf.dest_rect.x_offset=100;
1162         dispconf.dest_rect.y_offset=100;
1163         dispconf.dest_rect.width=640;
1164         dispconf.dest_rect.height=480;
1165         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1166         if (error!=OMX_ErrorNone){
1167                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1168                 DeAllocateCodecsOMX();
1169                 return 0;
1170         }*/
1171
1172
1173
1174
1175         if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1176                         Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Exccute");
1177                         DeAllocateCodecsOMX();
1178                         return 0;
1179         }
1180
1181         omx_running=true;
1182
1183         return 1;
1184 }
1185
1186
1187 int VideoVPEOGL::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type)
1188 {
1189         OMX_ERRORTYPE error;
1190         error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1191         if (error!=OMX_ErrorNone){
1192                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1193                 return 0;
1194         }
1195
1196         if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1197                 return 0;
1198         }
1199
1200         return 1;
1201 }
1202
1203
1204 int VideoVPEOGL::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1205 {
1206         OMX_ERRORTYPE error;
1207         error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1208         if (error!=OMX_ErrorNone){
1209                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1210                 return 0;
1211         }
1212
1213         if (!wait) return 1;
1214         if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1215                 return 0;
1216         }
1217
1218         return 1;
1219 }
1220
1221
1222 int VideoVPEOGL::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1223 {
1224         OMX_ERRORTYPE error;
1225         error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1226         if (error!=OMX_ErrorNone){
1227                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1228                 return 0;
1229         }
1230
1231         if (!wait) return 1;
1232         if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1233                 return 0;
1234         }
1235
1236
1237         return 1;
1238 }
1239
1240
1241
1242
1243 int VideoVPEOGL::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2)
1244 {
1245         int i=0;
1246         while (i<1000) {
1247                 omx_event_mutex.Lock();
1248                 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1249                 while (itty!=omx_events.end()) {
1250
1251                         VPE_OMX_EVENT current=*itty;
1252                         if (current.handle==handle) { //this is ours
1253                                 if (current.event_type==OMX_EventError) {
1254                                         omx_events.erase(itty);
1255                                         omx_event_mutex.Unlock();
1256                                         return 0;
1257
1258                                 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1259                                         omx_events.erase(itty);
1260                                         omx_event_mutex.Unlock();
1261                                         return 1;
1262                                 }
1263                         }
1264                         itty++;
1265
1266                 }
1267                 omx_event_mutex.Unlock();
1268                 MILLISLEEP(2);
1269                 i++;
1270
1271         }
1272         Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1273         return 0;
1274
1275 }
1276
1277
1278
1279
1280
1281 int VideoVPEOGL::PrepareInputBufsOMX()
1282 {
1283         OMX_ERRORTYPE error;
1284         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1285         memset(&port_def_type,0,sizeof(port_def_type));
1286         port_def_type.nSize=sizeof(port_def_type);
1287         port_def_type.nVersion.nVersion=OMX_VERSION;
1288         port_def_type.nPortIndex=omx_codec_input_port;
1289
1290         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1291
1292         if (error!=OMX_ErrorNone){
1293                         Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1294         }
1295 /*      Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1296                         port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1297                         port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1298
1299         port_def_type.nBufferCountActual=60;
1300
1301         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1302
1303         if (error!=OMX_ErrorNone){
1304                         Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1305         }
1306
1307
1308         error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1309         if (error!=OMX_ErrorNone){
1310                 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1311                 return 0;
1312         }
1313
1314         input_bufs_omx_mutex.Lock();
1315         for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1316
1317         //      unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1318                 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1319         /*      error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1320                 if (error!=OMX_ErrorNone){
1321                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1322                         input_bufs_omx_mutex.Unlock();
1323                         return 0;
1324                 }*/
1325                 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1326                 if (error!=OMX_ErrorNone){
1327                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1328                                 input_bufs_omx_mutex.Unlock();
1329                         return 0;
1330                 }
1331                 input_bufs_omx_all.push_back(buf_head);
1332                 input_bufs_omx_free.push_back(buf_head);
1333         }
1334         omx_first_frame=true;
1335
1336         firstsynched=false;
1337         cur_input_buf_omx=NULL;
1338         input_bufs_omx_mutex.Unlock();
1339
1340
1341         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1342         if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1343                 return 0;
1344         }
1345         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1346
1347         return 1;
1348 }
1349
1350 int VideoVPEOGL::DestroyInputBufsOMX()
1351 {
1352         OMX_ERRORTYPE error;
1353
1354         cur_input_buf_omx=NULL;
1355         input_bufs_omx_mutex.Lock();
1356         for (int i=0; i< input_bufs_omx_all.size();i++) {
1357         //      free(input_bufs_omx_all[i]->pBuffer);
1358         //      input_bufs_omx_all[i]->pBuffer=NULL;
1359                 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1360                 if (error!=OMX_ErrorNone){
1361                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1362                         input_bufs_omx_mutex.Unlock();
1363                         return 0;
1364                 }
1365         }
1366         input_bufs_omx_all.clear();
1367         input_bufs_omx_free.clear();
1368         input_bufs_omx_mutex.Unlock();
1369
1370 }
1371
1372
1373
1374
1375 int VideoVPEOGL::DeAllocateCodecsOMX()
1376 {
1377         OMX_ERRORTYPE error;
1378         omx_running=false;
1379         if (omx_vid_dec) {
1380                 // first flush all buffers
1381
1382                 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_output_port, NULL);
1383                 if (error!=OMX_ErrorNone){
1384                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1385
1386                 }
1387
1388                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_input_port, NULL);
1389                 if (error!=OMX_ErrorNone){
1390                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed in failed %x", error);
1391
1392                 }
1393
1394                 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_output_port) ||
1395                                 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_input_port)) {
1396                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec shed failed");
1397                 }
1398
1399                 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1400                 if (error!=OMX_ErrorNone){
1401                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1402
1403                 }
1404
1405                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
1406                 if (error!=OMX_ErrorNone){
1407                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
1408
1409                 }
1410
1411                 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1412                         !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
1413                                 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
1414                 }
1415
1416                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_output_port, NULL);
1417                 if (error!=OMX_ErrorNone) {
1418                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed out failed %x", error);
1419
1420                 }
1421
1422                 error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1423                 if (error!=OMX_ErrorNone) {
1424                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1425
1426                 }
1427
1428                 if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ||
1429                                 !CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
1430                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
1431                 }
1432
1433
1434
1435
1436                 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1437                 if (error!=OMX_ErrorNone){
1438                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1439
1440                 }
1441
1442
1443                 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_input_port)) {
1444                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec input failed");
1445                 }
1446
1447                 DestroyInputBufsOMX();
1448
1449                 //todo flushing
1450                 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
1451                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
1452                 }
1453                 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
1454                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
1455                 }
1456
1457                 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
1458                 if (error!=OMX_ErrorNone){
1459                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1460
1461                 }
1462
1463                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
1464                 if (error!=OMX_ErrorNone){
1465                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1466
1467                 }
1468
1469                 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
1470                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
1471                 }
1472
1473                 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1474                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
1475                 }
1476
1477                 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
1478                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
1479                 }
1480                 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
1481                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
1482                 }
1483
1484
1485
1486                 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
1487                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
1488                 }
1489
1490
1491                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
1492                 if (error!=OMX_ErrorNone){
1493                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1494
1495                 }
1496                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
1497                 if (error!=OMX_ErrorNone){
1498                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1499
1500                 }
1501
1502                 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1503                 if (error!=OMX_ErrorNone){
1504                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1505
1506                 }
1507
1508                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
1509                 if (error!=OMX_ErrorNone){
1510                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1511
1512                 }
1513
1514
1515
1516
1517
1518                 error=OMX_FreeHandle(omx_vid_dec);
1519                 error=OMX_FreeHandle(omx_vid_sched);
1520                 error=OMX_FreeHandle(omx_vid_rend);
1521                 error=OMX_FreeHandle(omx_clock);
1522                 omx_vid_dec=NULL;
1523                 if (error!=OMX_ErrorNone) {
1524                         Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1525                 }
1526         }
1527
1528         return 1;
1529 }
1530
1531 #endif
1532
1533
1534 #ifdef VPE_LIBAV_SUPPORT
1535
1536 enum PixelFormat VideoVPEOGL::get_format_libav(struct AVCodecContext *s, const enum PixelFormat *fmt)
1537 {
1538         int dec_mode=((VideoVPEOGL*)getInstance())->getlibavDecodingMode();
1539         enum PixelFormat ret_pix=PIX_FMT_NONE;
1540         if (dec_mode==VPE_NO_XVMC) return PIX_FMT_NONE;
1541         while (*fmt!=PIX_FMT_NONE) {
1542                 if (*fmt== PIX_FMT_XVMC_MPEG2_IDCT && dec_mode==VPE_XVMC_IDCT) {
1543                         ret_pix=PIX_FMT_XVMC_MPEG2_IDCT;
1544                 } else if (*fmt== PIX_FMT_XVMC_MPEG2_MC && dec_mode==VPE_XVMC_MOCOMP) {
1545                         ret_pix=PIX_FMT_XVMC_MPEG2_MC;
1546                 }
1547                 fmt++;
1548         }
1549         return ret_pix;
1550 }
1551
1552 // we use this function to push the data to ogl out before hand, this is only useful for xvmc
1553 void VideoVPEOGL::draw_horiz_band_libav(struct AVCodecContext *s, const AVFrame *src, int offset[4], int y, int type, int height)
1554 {
1555         if ((y+height)==src->height) {
1556         /*      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,
1557                                 ((xvmc_pix_fmt *)src->data[2])->picture_structure);*/
1558                 if (((xvmc_pix_fmt *)src->data[2])->picture_structure!=3) {
1559                         Log::getInstance()->log("Video", Log::ERR, "Non frame pict supported! Yet! Please send sample to authors!"); exit(0);
1560                 }
1561                 ((VideoVPEOGL*)Video::getInstance())->add_dec_frame_upload_only(s,src);
1562         }
1563
1564 }
1565
1566 int VideoVPEOGL::reget_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1567 {
1568         Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!Not Implemented!");
1569         return -1;
1570 }
1571
1572 int VideoVPEOGL::get_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1573 {
1574         unsigned int want_sizes[4]={0,0,0,0};
1575         AVPicture pict;
1576         bool normal_pixs=false;
1577         int num_blocks=0;
1578         int num_dct_blocks=0;
1579
1580         int s_a[4];
1581         //reget logic from mplayer
1582         if (pic->opaque && pic->data[0] && (!pic->buffer_hints ||pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE )){
1583                 Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!");
1584                 return 0;
1585         }
1586
1587
1588         if (c->pix_fmt!=PIX_FMT_XVMC_MPEG2_IDCT &&c->pix_fmt!=PIX_FMT_XVMC_MPEG2_MC) {
1589                 normal_pixs=true;
1590                 // standard pixel format
1591                 // this is written using much inspiration from libav util.c, so portions from there
1592                 int width,height;
1593
1594                 width=c->width;
1595                 height=c->height;
1596
1597                 avcodec_align_dimensions2(c, &width, &height, s_a);
1598                 if ((c->flags & CODEC_FLAG_EMU_EDGE)==0) {
1599                         width+=2*16;
1600                         height+=2*16;
1601                 }
1602                 // Now we have to determine alignment size
1603                 bool unaligned=true;
1604                 while (unaligned) {
1605                         av_image_fill_linesizes(pict.linesize, c->pix_fmt, width); //linesizes are derived
1606                         width+=width & ~(width-1); //trick from libav, now determine, if the alignment is ok
1607                         unaligned=false;
1608                         for (int i=0;i<4;i++) {
1609                                 if ((pict.linesize[i]%s_a[i])!=0) {
1610                                         unaligned=true;
1611                                         break;
1612                                 }
1613                         }
1614                 }
1615                 int tot_size=av_image_fill_pointers(pict.data, c->pix_fmt, height, NULL, pict.linesize); //get sizes
1616                 for (int i=0;i<4 ;i++) {
1617                         if (i<3 && pict.data[i+1]) {
1618                                 want_sizes[i]=pict.data[i+1]-pict.data[i];
1619                                 want_sizes[i]+=16;
1620                         } else {
1621                                 want_sizes[i]=(tot_size-(pict.data[i]-pict.data[0]));
1622                                 want_sizes[i]+=16;
1623                                 break;
1624                         }
1625                 }
1626
1627         } else {
1628                 //TODO set linesizes!
1629
1630                 num_blocks=((c->width+15)/16)*((c->height+15)/16);
1631                 num_dct_blocks=num_blocks*6; //6 blocks per macroblock
1632
1633                 want_sizes[2]=sizeof(xvmc_pix_fmt);
1634                 want_sizes[1]=sizeof(short)*num_dct_blocks*8*8;
1635                 want_sizes[0]=sizeof(XvMCMacroBlock)*num_blocks;
1636                 pict.linesize[0]=pict.linesize[1]=pict.linesize[2]=pict.linesize[3]=0;
1637
1638         }
1639
1640         VPE_FrameBuf *frame_buf=((VideoVPEOGL*)Video::getInstance())->getFrameBuf(want_sizes);
1641
1642         //Log::getInstance()->log("Video", Log::NOTICE, "get buffer %x",frame_buf);
1643         if (!frame_buf) {
1644                 Log::getInstance()->log("Video", Log::ERR, "Getting buffer libav failed");
1645                 return -1;
1646         }
1647
1648
1649         //populate pict
1650         pic->type=FF_BUFFER_TYPE_USER; // we are controlling the buffers
1651         int hchr_shift,vchr_shift;
1652         avcodec_get_chroma_sub_sample(c->pix_fmt,&hchr_shift,&vchr_shift);
1653         const int pixel_size = av_pix_fmt_descriptors[c->pix_fmt].comp[0].step_minus1+1;
1654         for (int i=0;i<4;i++) {
1655                 pic->data[i]=(uint8_t*)frame_buf->data[i];
1656                 pic->linesize[i]=pict.linesize[i];
1657                 if (normal_pixs) {
1658
1659                         int edge_width=16;
1660                         int edge_height=16;
1661                         if (i!=0) {
1662                                 edge_width>>=hchr_shift;
1663                                 edge_height>>=vchr_shift;
1664                         }
1665                         pic->data[i]+=FFALIGN((pic->linesize[i]*16) + (pixel_size*edge_width), s_a[i]);
1666                 }
1667         }
1668
1669         pic->base[0]=(uint8_t*)frame_buf; // our structure
1670         //pic->extended_data=pic->data;
1671         if(c->pkt) pic->pkt_pts=c->pkt->pts;
1672         else pic->pkt_pts=AV_NOPTS_VALUE;
1673         pic->width=c->width;
1674         pic->height=c->height;
1675         pic->format=c->pix_fmt;
1676         pic->sample_aspect_ratio=c->sample_aspect_ratio;
1677         pic->reordered_opaque= c->reordered_opaque;
1678         pic->age=INT_MAX;
1679         if (!normal_pixs) {
1680                 xvmc_pix_fmt *pix_xvmc=(xvmc_pix_fmt *)pic->data[2];
1681                 pix_xvmc->xvmc_id=AV_XVMC_ID;
1682                 pix_xvmc->data_blocks=(short*)pic->data[1];
1683                 pix_xvmc->mv_blocks=(XvMCMacroBlock*)pic->data[0];
1684                 pix_xvmc->allocated_mv_blocks=num_blocks;
1685                 pix_xvmc->allocated_data_blocks=num_dct_blocks;
1686                 if (c->pix_fmt==PIX_FMT_XVMC_MPEG2_IDCT) pix_xvmc->idct=1;
1687                 else pix_xvmc->idct=0;
1688                 pix_xvmc->unsigned_intra=1; // let see what happens
1689                 pix_xvmc->p_surface=(XvMCSurface*)frame_buf->pict_num;
1690                 pix_xvmc->start_mv_blocks_num=0;
1691                 pix_xvmc->filled_mv_blocks_num=0;
1692                 pix_xvmc->next_free_data_block_num=0;
1693                 //that is all folks
1694
1695
1696         }
1697
1698         return 0;
1699
1700 }
1701
1702 void VideoVPEOGL::release_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1703 {
1704 //      Log::getInstance()->log("Video", Log::NOTICE, "release buffer %x",pic->base[0]);
1705         ((VideoVPEOGL*)Video::getInstance())->releaseFrameBufLibav((VPE_FrameBuf*) pic->base[0]);
1706         pic->base[0]=NULL;
1707         pic->data[0]=pic->data[1]=pic->data[2]=pic->data[3]=NULL;
1708
1709
1710 }
1711
1712 int VideoVPEOGL::AllocateCodecsLibav()
1713 {
1714         libav_hastime=false;
1715         Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecslibav");
1716         mpeg2codec_context_libav=avcodec_alloc_context();
1717         if (mpeg2codec_context_libav==NULL) {
1718                 Log::getInstance()->log("Video", Log::DEBUG, "Creating libav codec context failed");
1719                 return 0;
1720         }
1721         if (decoding_mode!=VPE_NO_XVMC) {
1722                 mpeg2codec_context_libav->slice_flags=SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD;
1723                 if (decoding_mode==VPE_XVMC_MOCOMP) mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_MC;
1724                 else mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_IDCT;
1725                 mpeg2codec_context_libav->get_format=get_format_libav;
1726                 mpeg2codec_context_libav->draw_horiz_band=draw_horiz_band_libav;
1727
1728         }
1729         mpeg2codec_context_libav->get_buffer=get_buffer_libav;
1730         mpeg2codec_context_libav->reget_buffer=reget_buffer_libav;
1731         mpeg2codec_context_libav->release_buffer=release_buffer_libav;
1732
1733
1734
1735         int avc_ret=avcodec_open(mpeg2codec_context_libav, mpeg2codec_libav);
1736         if (avc_ret<0) {
1737                 Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec  failed ");
1738                 return 0;
1739         }
1740         memset(&incom_packet_libav,0,sizeof(incom_packet_libav));
1741         incom_packet_libav_size=200000;
1742         incom_packet_libav.data=(uint8_t*)av_malloc(incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
1743
1744         dec_frame_libav_mutex.Lock();
1745         for (int i=0;i<3;i++) {
1746                         AVFrame *dec_frame_libav=avcodec_alloc_frame(); // may be we need multiple frames, if we want to use async texture upload
1747                         if (!dec_frame_libav) {
1748                                 Log::getInstance()->log("Video", Log::DEBUG, "Allocating dec_frame  failed");
1749                                 return 0;
1750                         }
1751                         dec_frame_libav_all.push_back(dec_frame_libav);
1752                         dec_frame_libav_free.push_back(dec_frame_libav);
1753         }
1754         dec_frame_libav_decoding=NULL;
1755         dec_frame_libav_mutex.Unlock();
1756
1757         ogl_frame_mutex.Lock();
1758         //Allocate texture structs, since we do not know the sizes, we do not allocate the textures yet
1759         for (int i=0;i<5;i++) {
1760                 VPEOGLFrame *new_frame=(VPEOGLFrame *)malloc(sizeof(VPEOGLFrame));
1761                 new_frame->type=1; //1 = YUV, 2 RGB
1762                 new_frame->textures[0]=0;
1763                 new_frame->textures[1]=0;
1764                 new_frame->textures[2]=0;
1765                 new_frame->width=new_frame->height=0;
1766                 all_ogl_frames.push_back(new_frame);
1767                 free_ogl_frames.push_back(new_frame);
1768
1769         }
1770         ogl_frame_outside=false;
1771
1772         ogl_frame_mutex.Unlock();
1773
1774         if (decoding_mode==VPE_XVMC_MOCOMP) {
1775                 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
1776                 osd->BeginPainting(); // get OpenGl context
1777                 moco_shader=new GLMocoShader();
1778                 moco_shader->init();
1779                 osd->EndPainting();
1780         }
1781
1782         libav_running=true;
1783
1784         return 1;
1785
1786 }
1787
1788 int VideoVPEOGL::DeAllocateCodecsLibav()
1789 {
1790         libav_running=false;
1791         Log::getInstance()->log("Video", Log::NOTICE, "DeAllocateCodecslibav");
1792         dec_frame_libav_mutex.Lock();
1793         dec_frame_libav_upload_and_view_pending.clear();
1794         dec_frame_libav_upload_only_pending.clear();
1795         dec_frame_libav_free.clear();
1796         dec_frame_libav_mutex.Unlock();
1797         while (dec_frame_libav_uploading) {
1798                 Log::getInstance()->log("Video", Log::NOTICE, "Wait for uploading to finish");
1799                 MILLISLEEP(20);
1800         }
1801         dec_frame_libav_mutex.Lock();
1802         for (int i=0; i< dec_frame_libav_all.size();i++) {
1803                 av_free(dec_frame_libav_all[i]);
1804         }
1805
1806         dec_frame_libav_all.clear();
1807
1808         av_free(incom_packet_libav.data);
1809         incom_packet_libav.data=NULL;
1810         incom_packet_libav_size=0;
1811
1812         dec_frame_libav_mutex.Unlock();
1813         dec_frame_libav_decoding=NULL;
1814         while (ogl_frame_outside) {
1815                 Log::getInstance()->log("Video", Log::NOTICE, "Wait for ogl frame from outside");
1816                 MILLISLEEP(20);
1817         }
1818
1819         ((OsdOpenGL*)Osd::getInstance())->BeginPainting(); // get osd's context
1820         ogl_frame_mutex.Lock();
1821         for (int i=0; i< dec_frame_libav_all.size();i++) {
1822                 VPEOGLFrame * del_frame=all_ogl_frames[i];
1823                 if (del_frame->textures[0]==0) {
1824                         glDeleteTextures(1,&del_frame->textures[0]);
1825                         del_frame->textures[0]=0;
1826                 }
1827                 if (del_frame->textures[1]==0) {
1828                         glDeleteTextures(1,&del_frame->textures[1]);
1829                         del_frame->textures[1]=0;
1830                 }
1831                 if (del_frame->textures[2]==0) {
1832                         glDeleteTextures(1,&del_frame->textures[2]);
1833                         del_frame->textures[2]=0;
1834                 }
1835
1836                 free(all_ogl_frames[i]);
1837         }
1838         all_ogl_frames.clear();
1839         free_ogl_frames.clear();
1840         ready_ogl_frames.clear();
1841         recycle_ref_ogl_frames.clear();
1842         ogl_forward_ref_frame_num=0;
1843         ogl_backward_ref_frame_num=0;
1844         ogl_forward_ref_frame=NULL;
1845         ogl_backward_ref_frame=NULL;
1846
1847         ogl_frame_mutex.Unlock();
1848         ((OsdOpenGL*)Osd::getInstance())->EndPainting();
1849
1850
1851         if (mpeg2codec_context_libav) {
1852                 avcodec_close(mpeg2codec_context_libav);
1853                 av_free(mpeg2codec_context_libav);
1854                 mpeg2codec_context_libav=NULL;
1855
1856         }
1857
1858
1859
1860         vpe_framebuf_mutex.Lock();
1861
1862         for (int i=0;i<all_frame_bufs.size();i++) {
1863                 VPE_FrameBuf* current=all_frame_bufs[i];
1864                 for (int x=0;x<4;x++) {
1865                         if (current->data[x]) {
1866                                 av_free(current->data[x]);
1867                         }
1868                 }
1869                 free(current);
1870         }
1871         all_frame_bufs.clear();
1872         free_frame_bufs.clear();
1873         locked_libav_frame_buf.clear();
1874         locked_uploading_frame_buf.clear();
1875
1876         vpe_framebuf_mutex.Unlock();
1877
1878
1879
1880         if (moco_shader) {
1881                 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
1882                 osd->BeginPainting(); // get OpenGl context
1883                 moco_shader->deinit();
1884                 delete moco_shader;
1885                 moco_shader=NULL;
1886                 osd->EndPainting();
1887         }
1888
1889
1890
1891
1892
1893         return 1;
1894 }
1895
1896
1897 VPE_FrameBuf *VideoVPEOGL::getFrameBuf(unsigned int *size)
1898 { //for libav
1899         VPE_FrameBuf* current=NULL;
1900         vpe_framebuf_mutex.Lock();
1901         if (free_frame_bufs.size()>0) {
1902                 current=free_frame_bufs.front();
1903                 free_frame_bufs.pop_front();
1904         } else if (all_frame_bufs.size()<6) {
1905                 current=(VPE_FrameBuf*)malloc(sizeof(VPE_FrameBuf));
1906                 memset(current,0,sizeof(VPE_FrameBuf));
1907         } else {
1908                 Log::getInstance()->log("Video", Log::NOTICE, "Framebuffer underrun!");
1909                 vpe_framebuf_mutex.Unlock();
1910                 return NULL; // We do not have a frame buffer
1911         }
1912         locked_libav_frame_buf.push_back(current);
1913         vpe_framebuf_mutex.Unlock();
1914         //check if we need reallocation
1915         for (int x=0;x<4;x++) {
1916                 if (current->size[x]!=size[x]) {
1917                         current->data[x]=av_realloc(current->data[x],size[x]);
1918                         current->size[x]=size[x];
1919                 }
1920         }
1921         framebuf_framenum++;
1922         current->pict_num=framebuf_framenum; //This is used for tracking reference frames through the conversion pipeline
1923         return current;
1924
1925 }
1926
1927 void VideoVPEOGL::lockFrameBufUpload(VPE_FrameBuf* buf)
1928 {
1929         // first find frame_buf memory
1930
1931         //Log::getInstance()->log("Video", Log::NOTICE, "lock buffer upload %x",buf);
1932         VPE_FrameBuf* current=buf;
1933         vpe_framebuf_mutex.Lock();
1934         if (current) locked_uploading_frame_buf.push_back(current); //locked
1935         vpe_framebuf_mutex.Unlock();
1936
1937 }
1938
1939
1940 void VideoVPEOGL::releaseFrameBufLibav(VPE_FrameBuf* buf)
1941 {
1942         // first find frame_buf memory
1943         //Log::getInstance()->log("Video", Log::NOTICE, "release buffer libav %x",buf);
1944         VPE_FrameBuf* current=buf;
1945         vpe_framebuf_mutex.Lock();
1946         if (current) {
1947                 locked_libav_frame_buf.remove(current); //unlocked
1948                 list<VPE_FrameBuf*>::iterator itty=locked_uploading_frame_buf.begin();
1949                 bool inlist=false;
1950                 while (itty!=locked_uploading_frame_buf.end()) {
1951                         if (*itty==current) {
1952                                 inlist=true;
1953                                 break;
1954                         }
1955                         itty++;
1956                 }
1957                 if (!inlist) {
1958                         free_frame_bufs.push_back(current);
1959                 }
1960         }
1961         vpe_framebuf_mutex.Unlock();
1962 }
1963
1964 void VideoVPEOGL::releaseFrameBufUpload(VPE_FrameBuf* buf)
1965 {
1966         // first find frame_buf memory
1967         VPE_FrameBuf* current=buf;
1968         //Log::getInstance()->log("Video", Log::NOTICE, "release buffer upload %x",buf);
1969         vpe_framebuf_mutex.Lock();
1970         if (current) {
1971                 locked_uploading_frame_buf.remove(current); //unlocked
1972                 list<VPE_FrameBuf*>::iterator itty=locked_libav_frame_buf.begin();
1973                 bool inlist=false;
1974                 while (itty!=locked_libav_frame_buf.end()) {
1975                         if (*itty==current) {
1976                                 inlist=true;
1977                                 break;
1978                         }
1979                         itty++;
1980                 }
1981                 if (!inlist) {
1982                         free_frame_bufs.push_back(current);
1983                 }
1984         }
1985         vpe_framebuf_mutex.Unlock();
1986 }
1987
1988 void VideoVPEOGL::add_dec_frame_upload_only(struct AVCodecContext *s,const AVFrame* data)
1989 {
1990         dec_frame_libav_mutex.Lock();
1991         libavwidth=s->width;
1992         libavheight=s->height;
1993         libavpixfmt=s->pix_fmt;
1994         Log::getInstance()->log("Video", Log::DEBUG, "add_dec Frame info %d %d %d %d",libavwidth,libavheight,libavpixfmt,((VPE_FrameBuf*)data->base[0])->pict_num);
1995
1996         dec_frame_libav_upload_only_pending.push_back((AVFrame*)data); // we are only uploading
1997         dec_frame_libav_mutex.Unlock();
1998         threadSignal();
1999 }
2000
2001
2002
2003
2004
2005 #endif
2006
2007 int VideoVPEOGL::stop()
2008 {
2009   if (!initted) return 0;
2010
2011 #ifdef VPE_OMX_SUPPORT
2012   //Check if libav mode
2013   if (decoding_backend==VPE_DECODER_OMX) DeAllocateCodecsOMX();
2014   decoding_backend=0;
2015
2016 #endif
2017
2018
2019
2020 //  if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2021   return 1;
2022 }
2023
2024 int VideoVPEOGL::reset()
2025 {
2026   if (!initted) return 0;
2027
2028 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2029   return 1;
2030 }
2031
2032 int VideoVPEOGL::pause()
2033 {
2034   if (!initted) return 0;
2035
2036 //  if (ioctl(fdVideo, AV_SET_VID_PAUSE, 0) != 0) return 0;
2037   return 1;
2038 }
2039
2040 int VideoVPEOGL::unPause() // FIXME get rid - same as play!!
2041 {
2042   if (!initted) return 0;
2043 //  if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2044   return 1;
2045 }
2046
2047 int VideoVPEOGL::fastForward()
2048 {
2049   if (!initted) return 0;
2050
2051 //  if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2052   return 1;
2053 }
2054
2055 int VideoVPEOGL::unFastForward()
2056 {
2057   if (!initted) return 0;
2058
2059 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2060
2061  //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2062   return 1;
2063 }
2064
2065 int VideoVPEOGL::attachFrameBuffer()
2066 {
2067   if (!initted) return 0;
2068
2069 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2070   return 1;
2071 }
2072
2073 int VideoVPEOGL::blank(void)
2074 {
2075 //  if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2076 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2077   return 1;
2078 }
2079
2080 ULLONG VideoVPEOGL::getCurrentTimestamp()
2081 {
2082 /*  sync_data_t timestamps;
2083   if (ioctl(fdVideo, AV_GET_VID_TIMESTAMPS, &timestamps) == 0)
2084   {
2085     // FIXME are these the right way around?
2086
2087     timestamps.stc = (timestamps.stc >> 31 ) | (timestamps.stc & 1);
2088     timestamps.pts = (timestamps.pts >> 31 ) | (timestamps.pts & 1);
2089
2090     return timestamps.stc;
2091   }
2092   else
2093   {
2094     return 0;
2095   }*/
2096   return 0;
2097 }
2098
2099 ULONG VideoVPEOGL::timecodeToFrameNumber(ULLONG timecode)
2100 {
2101   if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
2102   else               return (ULONG)(((double)timecode / (double)90000) * (double)30);
2103 }
2104
2105 #ifdef DEV
2106 int VideoVPEOGL::test()
2107 {
2108   return 0;
2109
2110 //  ULLONG stc = 0;
2111 //  return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2112 /*
2113  // reset();
2114   return 1;
2115 */
2116 }
2117
2118 int VideoVPEOGL::test2()
2119 {
2120   return 0;
2121 }
2122 #endif
2123
2124 void VideoVPEOGL::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
2125 {
2126   mediapacket = mplist.front();
2127 }
2128
2129 UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
2130 {
2131   DeliverMediaPacket(mediapacket, buffer, samplepos);
2132   if (*samplepos == mediapacket.length) {
2133     *samplepos = 0;
2134     return 1;
2135   }
2136   else return 0;
2137 }
2138
2139 UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
2140                 const UCHAR* buffer,
2141                 UINT *samplepos)
2142 {
2143         if (packet.type == MPTYPE_VIDEO_H264)
2144         {
2145                 h264=true;
2146         }
2147         else
2148         {
2149                 h264=false;
2150         }
2151         switch (decoding_backend) {
2152         default: case 0: return 0; // no backend runnigng
2153 #ifdef VPE_OMX_SUPPORT
2154         case VPE_DECODER_OMX: return DeliverMediaPacketOMX(packet,buffer,samplepos);
2155 #endif
2156 #ifdef VPE_LIBAV_SUPPORT
2157         case VPE_DECODER_libav: return DeliverMediaPacketlibav(packet,buffer,samplepos);
2158 #endif
2159         }
2160 }
2161
2162 #ifdef VPE_OMX_SUPPORT
2163 UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
2164                 const UCHAR* buffer,
2165                 UINT *samplepos)
2166 {
2167
2168
2169         //Later add fail back code for libav
2170         /*if (!videoon) {
2171                 *samplepos+=packet.length;
2172                 return packet.length;
2173         }*/
2174
2175
2176         if (!omx_running) return 0; // if we are not runnig do not do this
2177
2178
2179         OMX_ERRORTYPE error;
2180
2181 /*      OMX_PARAM_PORTDEFINITIONTYPE port_image;
2182         memset(&port_image,0,sizeof(port_image));
2183         port_image.nSize=sizeof(port_image);
2184         port_image.nVersion.nVersion=OMX_VERSION;
2185         port_image.nPortIndex =omx_codec_output_port;
2186         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_image);
2187         if (error!= OMX_ErrorNone){
2188                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_GetParameter failed %x", error);
2189         }
2190         Log::getInstance()->log("Video", Log::DEBUG, "Image port %d %d", port_image.format.video.nFrameWidth , port_image.format.video.nFrameHeight);*/
2191
2192         /*First Check, if we have an audio sample*/
2193         if (iframemode) {
2194                 //samplepos=0;
2195                 MILLISLEEP(10);
2196                 return 0; //Not in iframe mode!
2197         }
2198
2199         UINT headerstrip=0;
2200         if (packet.disconti) {
2201                 firstsynched=false;
2202                 if (cur_input_buf_omx) {
2203                         OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2204                         if (error!=OMX_ErrorNone){
2205                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2206                         }
2207                         cur_input_buf_omx=NULL;
2208                 }
2209         }
2210
2211         /*Inspect PES-Header */
2212
2213 //      OMX_STATETYPE temp_state;
2214 //      OMX_GetState(omx_vid_dec,&temp_state);
2215
2216         if (*samplepos==0) {//stripheader
2217                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2218                 *samplepos+=headerstrip;
2219                 if ( packet.synched ) {
2220
2221                         if (cur_input_buf_omx) {
2222                                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2223                                 if (error!=OMX_ErrorNone){
2224                                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2225                                 }
2226
2227                                 cur_input_buf_omx=NULL;//write out old data
2228                         }
2229                 //      reftime1=packet.presentation_time;
2230                 //      reftime2=reftime1+1;
2231                         firstsynched=true;
2232                 } else {
2233                         if (!firstsynched) {//
2234                                 *samplepos=packet.length;//if we have not processed at least one
2235                                 return packet.length;//synched packet ignore it!
2236                         }
2237                 }
2238         }
2239
2240         if (!cur_input_buf_omx) {
2241                 input_bufs_omx_mutex.Lock();
2242                 if (input_bufs_omx_free.size()==0) {
2243                         input_bufs_omx_mutex.Unlock();
2244                         Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2245                         return 0; // we do not have a free media sample
2246
2247                 }
2248                 cur_input_buf_omx=input_bufs_omx_free.front();
2249                 cur_input_buf_omx->nFilledLen=0;
2250                 cur_input_buf_omx->nOffset=0;
2251                 cur_input_buf_omx->nTimeStamp=0;
2252                 input_bufs_omx_free.pop_front();
2253                 input_bufs_omx_mutex.Unlock();
2254         }
2255
2256
2257
2258
2259         if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2260                 /*if (packet.disconti) {
2261                         ms->SetDiscontinuity(TRUE);
2262                 } else {
2263                         ms->SetDiscontinuity(FALSE);
2264                 }*/
2265                 //if (packet.synched) {
2266
2267                         //lastreftimePTS=packet.pts;
2268                    if (omx_first_frame) { // TODO time
2269                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2270                            omx_first_frame=false;
2271                    } else
2272
2273                 //}
2274                 //else
2275                 //{
2276                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2277
2278
2279                         //  ms->SetSyncPoint(TRUE);
2280                 //}
2281
2282         }
2283         unsigned int haveToCopy=packet.length-*samplepos;
2284
2285         while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
2286                 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
2287                 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
2288                 haveToCopy-=cancopy;
2289                 cur_input_buf_omx->nFilledLen+=cancopy;
2290                 *samplepos+=cancopy;
2291                 // push old buffer out
2292
2293                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2294                 if (error!=OMX_ErrorNone){
2295                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2296                 }
2297                 // get5 new buffer
2298                 input_bufs_omx_mutex.Lock();
2299                 if (input_bufs_omx_free.size()==0) {
2300                         input_bufs_omx_mutex.Unlock();
2301                         //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2302                         return *samplepos; // we do not have a free media sample
2303                 }
2304                 cur_input_buf_omx=input_bufs_omx_free.front();
2305                 cur_input_buf_omx->nFilledLen=0;
2306                 cur_input_buf_omx->nOffset=0;
2307                 cur_input_buf_omx->nTimeStamp=0;
2308                 input_bufs_omx_free.pop_front();
2309                 input_bufs_omx_mutex.Unlock();
2310
2311                 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2312
2313         }
2314         memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
2315                         buffer+packet.pos_buffer+*samplepos,haveToCopy);
2316         cur_input_buf_omx->nFilledLen+=haveToCopy;
2317
2318
2319
2320         *samplepos+=haveToCopy;
2321
2322         return *samplepos;
2323
2324 }
2325
2326 #endif
2327
2328
2329 #ifdef VPE_LIBAV_SUPPORT
2330 int VideoVPEOGL::DecodePacketlibav()
2331 {
2332         unsigned int haveToCopy=incom_packet_libav.size;
2333         if (incom_packet_libav.size==0) return 1; // we are already empty
2334         while (haveToCopy>0) {
2335                 int dec_bytes=0;
2336                 int frame_ready=0;
2337
2338         //      Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
2339
2340 #ifdef BENCHMARK_FPS
2341             int cur_time=getTimeMS();
2342 #endif
2343                 dec_bytes=avcodec_decode_video2(mpeg2codec_context_libav, dec_frame_libav_decoding,
2344                                 &frame_ready, &incom_packet_libav);
2345 #ifdef BENCHMARK_FPS
2346                 time_in_decoder+=getTimeMS()-cur_time;
2347                 if (frame_ready) num_frames++;
2348                 if ((num_frames%100)==0) {
2349                         float fps=1000./(float)(time_in_decoder);
2350                         fps*=((float)num_frames);
2351                         Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
2352                 }
2353 #endif
2354                 if (dec_bytes<0) {
2355                         Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
2356                         return 0;
2357                 }
2358                 haveToCopy-=dec_bytes;
2359                 if (frame_ready) {
2360                 //      Log::getInstance()->log("Video", Log::DEBUG, "We have a frame push it to osd");
2361
2362                         lockFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_decoding->base[0]); //lock for upload, so that ffmpeg does not reuse
2363                         dec_frame_libav_mutex.Lock();
2364                         libavwidth=mpeg2codec_context_libav->width;
2365                         libavheight=mpeg2codec_context_libav->height;
2366                         libavpixfmt=mpeg2codec_context_libav->pix_fmt;
2367                 //      Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",libavwidth,libavheight,libavpixfmt);
2368
2369
2370                         dec_frame_libav_upload_and_view_pending.push_back(dec_frame_libav_decoding);
2371                         dec_frame_libav_decoding=NULL;
2372                         if (dec_frame_libav_free.size()>0) {
2373                                 dec_frame_libav_decoding=dec_frame_libav_free.front();
2374                                 dec_frame_libav_free.pop_front();
2375                                 dec_frame_libav_mutex.Unlock();
2376                                 threadSignal();
2377                                 libav_hastime=false;
2378                         } else {
2379                                 libav_hastime=false;
2380                                 dec_frame_libav_mutex.Unlock();
2381                                 threadSignal();
2382                                 // No free buffers
2383                                 return 0;
2384                         }
2385
2386
2387                 }
2388
2389         }
2390         incom_packet_libav.size=0;
2391         return 1;
2392
2393 }
2394
2395
2396 UINT VideoVPEOGL::DeliverMediaPacketlibav(MediaPacket packet,
2397                 const UCHAR* buffer,
2398                 UINT *samplepos)
2399 {
2400         //Later add fail back code for libav
2401         /*if (!videoon) {
2402                 *samplepos+=packet.length;
2403                 return packet.length;
2404         }*/
2405
2406         if (!libav_running) return 0; // if we are not runnig do not do this
2407
2408
2409         if (iframemode) {
2410                 //samplepos=0;
2411                 MILLISLEEP(10);
2412                 return 0; //Not in iframe mode!
2413         }
2414
2415         UINT headerstrip=0;
2416         if (packet.disconti) {
2417                 firstsynched=false;
2418                 if (!DecodePacketlibav()) return 0;
2419         }
2420
2421         /*Inspect PES-Header */
2422         if (!dec_frame_libav_decoding) {
2423                 dec_frame_libav_mutex.Lock();
2424                 if (dec_frame_libav_free.size()>0) {
2425                         dec_frame_libav_decoding=dec_frame_libav_free.front();
2426                         dec_frame_libav_free.pop_front();
2427                         dec_frame_libav_mutex.Unlock();
2428                 } else {
2429                         Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers");
2430                         dec_frame_libav_mutex.Unlock();
2431                         // No free buffers
2432                         return 0;
2433                 }
2434         }
2435
2436
2437
2438         if (*samplepos==0) {//stripheader
2439                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2440                 *samplepos+=headerstrip;
2441                 if ( packet.synched ) {
2442
2443                         if (!DecodePacketlibav()) return 0; // WriteOut old Data
2444
2445                         libav_time=packet.presentation_time;
2446                         libav_hastime=true;
2447                 //      reftime1=packet.presentation_time;
2448                 //      reftime2=reftime1+1;
2449                         firstsynched=true;
2450                 } else {
2451                         if (!firstsynched) {//
2452                                 *samplepos=packet.length;//if we have not processed at least one
2453                                 return packet.length;//synched packet ignore it!
2454                         }
2455                 }
2456         }
2457
2458
2459
2460
2461
2462
2463         /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2464                 /*if (packet.disconti) {
2465                         ms->SetDiscontinuity(TRUE);
2466                 } else {
2467                         ms->SetDiscontinuity(FALSE);
2468                 }*
2469                 //if (packet.synched) {
2470
2471                         //lastreftimePTS=packet.pts;
2472                    if (omx_first_frame) { // TODO time
2473                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2474                            omx_first_frame=false;
2475                    } else
2476
2477                 //}
2478                 //else
2479                 //{
2480                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2481
2482
2483                         //  ms->SetSyncPoint(TRUE);
2484                 //}
2485
2486         }*/
2487         unsigned int haveToCopy=packet.length-*samplepos;
2488
2489         if  ((incom_packet_libav_size-incom_packet_libav.size)< haveToCopy) {
2490                 // if the buffer is to small reallocate
2491                 incom_packet_libav_size+=haveToCopy;
2492                 incom_packet_libav.data=(uint8_t*)av_realloc(incom_packet_libav.data,incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
2493                 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_libav_size);
2494         }
2495         memcpy(incom_packet_libav.data+incom_packet_libav.size,buffer+packet.pos_buffer+*samplepos,haveToCopy);
2496         incom_packet_libav.size+=haveToCopy;
2497
2498         *samplepos+=haveToCopy;
2499
2500
2501         return *samplepos;
2502
2503
2504 }
2505
2506 #endif
2507
2508
2509
2510
2511
2512
2513 void VideoVPEOGL::ResetTimeOffsets()
2514 {
2515 }
2516
2517 bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length)
2518 {
2519   //write(fdVideo, buffer, length);
2520         if (!iframemode) EnterIframePlayback();
2521 //      WriteOutTS(buffer,length, h264?MPTYPE_VIDEO_H264 :MPTYPE_VIDEO_MPEG2 );
2522
2523   lastpacketnum=-1;
2524   return true;
2525 }
2526
2527 int VideoVPEOGL::EnterIframePlayback()
2528 {
2529
2530         return 0;
2531 }
2532