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