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