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