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