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