]> git.vomp.tv Git - vompclient.git/blob - src/videoomx.cc
Have build.sh deal with cmake
[vompclient.git] / src / videoomx.cc
1 /*
2     Copyright 2004-2005 Chris Tallon, 2009-12 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, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include <algorithm>
21 #include <chrono>
22
23 #include <bcm_host.h>
24 #include <linux/fb.h>
25
26 #include "log.h"
27 #include "audioomx.h"
28 #include "demuxer.h"
29 #include "vdr.h"
30 #include "woptionpane.h"
31 #include "osdopenvg.h"
32 #include "boxstack.h"
33 #include "inputman.h"
34 #include "util.h"
35 #include "config.h"
36
37 #include "videoomx.h"
38
39 //A lot of parts of this file are heavily inspired by xbmc omx implementations
40
41 static const char* TAG = "VideoOMX";
42
43 // Static OMX callbacks
44
45 OMX_ERRORTYPE VideoOMX::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle, OMX_IN OMX_PTR appdata,
46     OMX_IN OMX_EVENTTYPE event_type, OMX_IN OMX_U32 data1,
47     OMX_IN OMX_U32 data2, OMX_IN OMX_PTR event_data)
48 {
49   //LogNT::getInstance()->info(TAG, "eventHandler {:#x} {:#x} {:#x} {:#x} {:#x}",handle,event_type,data1,data2,event_data);
50
51   struct VPE_OMX_EVENT  new_event;
52   new_event.handle = handle;
53   new_event.appdata = appdata;
54   new_event.event_type = event_type;
55   new_event.data1 = data1;
56   new_event.data2 = data2;
57   new_event.event_data = event_data;
58
59   VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
60   video->AddOmxEvent(new_event);
61
62   /*    switch (event_type) {
63         case OMX_EventCmdComplete: {
64
65         } break;
66         }*/
67
68   return OMX_ErrorNone;
69 }
70
71 OMX_ERRORTYPE VideoOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE /*hcomp*/, OMX_IN OMX_PTR /*appdata*/, OMX_IN OMX_BUFFERHEADERTYPE* buffer)
72 {
73   //    LogNT::getInstance()->info(TAG, "EmptyBufferDone");
74   VideoOMX* video = static_cast<VideoOMX*>(Video::getInstance());
75   /*    long long temp =buffer->nTimeStamp.nLowPart
76                                                                 | ((long long) buffer->nTimeStamp.nHighPart << 32);
77         LogNT::getInstance()->info(TAG, "EBD Video %lld  {:#x}",temp,buffer->nFlags);*/
78   video->ReturnEmptyOMXBuffer(buffer);
79   return OMX_ErrorNone;
80 }
81
82 OMX_ERRORTYPE VideoOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE /*hcomp*/, OMX_IN OMX_PTR /*appdata*/, OMX_IN OMX_BUFFERHEADERTYPE* /*buffer*/)
83 {
84   //LogNT::getInstance()->info(TAG, "FillBufferDone");
85   return OMX_ErrorNone;
86 }
87
88 // -----------------------------------
89
90 VideoOMX::VideoOMX()
91 {
92   logger = LogNT::getInstance();
93
94   //cur_pts=0;
95
96   mode = NORMAL;
97   deinterlace = 2; //advanced
98
99   strcpy(L_VPE_OMX_CLOCK, VPE_OMX_CLOCK);
100   strcpy(L_VPE_OMX_H264_DECODER, VPE_OMX_H264_DECODER);
101   strcpy(L_VPE_OMX_MPEG2_DECODER, VPE_OMX_MPEG2_DECODER);
102   strcpy(L_VPE_OMX_VIDEO_SCHED, VPE_OMX_VIDEO_SCHED);
103   strcpy(L_VPE_OMX_VIDEO_REND, VPE_OMX_VIDEO_REND);
104   strcpy(L_VPE_OMX_VIDEO_DEINTERLACE, VPE_OMX_VIDEO_DEINTERLACE);
105 }
106
107 VideoOMX::~VideoOMX()
108 {
109   instance = NULL;
110 }
111
112 int VideoOMX::init(u1 tformat)
113 {
114   if (initted) return 0;
115
116   initted = 1;
117
118   // libcec calls bcm_host_init() - but in case CEC is disabled call it here as well.
119   // Seems safe to call it more than once.
120   bcm_host_init();
121
122   int ret = vc_gencmd_send("codec_enabled MPG2");
123
124   if (ret != 0)
125   {
126     logger->debug(TAG, "vc_gencmd_send failed {:#x}", ret);
127   }
128   else
129   {
130     char buffer[1024];
131     ret = vc_gencmd_read_response(buffer, sizeof(buffer));
132
133     if (ret != 0)
134     {
135       logger->debug(TAG, "vc_gencmd_read_response failed {:#x}", ret);
136     }
137     else
138     {
139       if (STRCASECMP(buffer, "MPG2=enabled") == 0)
140       {
141         mpeg2_supported = true;
142       }
143       else if (STRCASECMP(buffer, "MPG2=disabled") == 0)
144       {
145         mpeg2_supported = false;
146       }
147       else
148       {
149         logger->debug(TAG, "Undefined mpg codec answer {}", buffer);
150       }
151     }
152   }
153
154   if (!setFormat(tformat))           { shutdown(); return 0; }
155   if (!setConnection(HDMI))          { shutdown(); return 0; }
156   if (!setAspectRatio(ASPECT4X3, 12, 11))    { shutdown(); return 0; }
157   if (!setMode(NORMAL))              { shutdown(); return 0; }
158   if (!setSource())                  { shutdown(); return 0; }
159   if (!attachFrameBuffer())          { shutdown(); return 0; }
160
161   setTVsize(ASPECT16X9);
162   selectVideoMode(0);
163
164   OMX_ERRORTYPE error;
165   error = OMX_Init();
166
167   if (error != OMX_ErrorNone)
168   {
169     logger->debug(TAG, "Init OMX failed {:#x}", error);
170     return 0;
171   }
172
173   //stop();
174   return 1;
175 }
176
177 void VideoOMX::signalOmx()
178 {
179   /*
180    * Getting rid of Signal class. It looks like VideoOMX uses a wait-on-condition-variable in WaitForEvent()
181    * and CommandFinished(). These methods both use timed waits and don't use exact thread synchronisation -
182    * i.e. a caught signal will end the wait early but a missed signal doesn't matter. So, I'm just copying
183    * in what the Signal class used to do here and I'll sort it out later.
184    * Q: Are the found places the only synchronisation points? Would it be possible to change this to use
185    * exact sychronisation and remove the wait spin loops? Unknown.
186    *
187    * This omx_event_mutex - is this exactly locking the very thing the condition variable is being used
188    * for? i.e. is omx_event_mutex really the mutex that should be being used with the cond var?
189    *
190    * Callers of signalOmx:
191    *
192    * VideoOMX::AddOmxEvent, VideoOMX::ReturnEmptyOMXBuffer
193    * ImageOMX::ReturnEmptyOMXBuffer, ImageOMX::ReturnFillOMXBuffer
194    * AudioOMX::ReturnEmptyOMXBuffer, AudioOMX::FillBufferDone_OMX
195    *
196    * Surprise: WaitForEvent isn't a long running loop while video is playing.
197    */
198
199   omx_event_ready_signal_mutex.lock();
200   omx_event_ready_signal.notify_one(); // Signal called pthread_cond_signal - unblock one
201   omx_event_ready_signal_mutex.unlock();
202 };
203
204 void VideoOMX::AddOmxEvent(VPE_OMX_EVENT new_event)
205 {
206   omx_event_mutex.lock();
207   omx_events.push_back(new_event);
208   omx_event_mutex.unlock();
209
210   signalOmx();
211 }
212
213 void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer)
214 {
215   input_bufs_omx_mutex.lock();
216   //logger->info(TAG, "ReturnEmptyOMXBuffer {} {}",input_bufs_omx_free.size(),input_bufs_omx_all.size());
217   input_bufs_omx_free.push_back(buffer);
218   //logger->info(TAG, "ReturnEmptyOMXBuffer {}",input_bufs_omx_free.size());
219   input_bufs_omx_mutex.unlock();
220
221   signalOmx();
222 }
223
224 int VideoOMX::shutdown()
225 {
226   if (!initted) return 0;
227
228   initted = 0;
229   logger->info(TAG, "Shutdown video module");
230
231   DeAllocateCodecsOMX();
232   OMX_Deinit();
233   //vc_tv_show_info(0); // back to console
234   // Restore console
235   int fd_fbset = 0;
236   struct fb_var_screeninfo screeninfo;
237   fd_fbset = open("/dev/fb0", O_RDONLY);
238
239   if (fd_fbset < 0)
240   {
241     logger->crit(TAG, "Could not open frame buffer device {}", fd_fbset);
242     return 0;
243   }
244
245   if (ioctl(fd_fbset, FBIOGET_VSCREENINFO, &screeninfo))
246   {
247     close(fd_fbset);
248     logger->crit(TAG, "Could not FBIOGET_VSCREENINFO frame buffer device");
249     return 0;
250   }
251
252   screeninfo.bits_per_pixel = 8;
253
254   if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo))
255   {
256     logger->crit(TAG, "Could not FBIOPUT_VSCREENINFO frame buffer device");
257   }
258
259   screeninfo.bits_per_pixel = 16;
260
261   if (ioctl(fd_fbset, FBIOPUT_VSCREENINFO, &screeninfo))
262   {
263     logger->crit(TAG, "Could not FBIOPUT_VSCREENINFO frame buffer device");
264   }
265
266   close(fd_fbset);
267   return 1;
268 }
269
270 bool VideoOMX::loadOptionsFromServer(VDR* vdr)
271 {
272   logger->debug(TAG, "VideoOMX config load");
273   char* name = vdr->configLoad("VideoOMX", "SDDeinterlacing");
274
275   if (name != NULL)
276   {
277     if (STRCASECMP(name, "None") == 0)
278     {
279       deinterlace = 0;
280     }
281     /* else if (STRCASECMP(name, "LineDouble") == 0)
282     {
283       deinterlace = 1;
284     }*/
285     else if (STRCASECMP(name, "Advanced") == 0)
286     {
287       deinterlace = 2;
288     }
289     /* else if (STRCASECMP(name, "Crazy") == 0)
290     {
291       deinterlace = 3; // this does not activate deinterlacing but a image filter, just for fun
292     }
293     */
294     else if (STRCASECMP(name, "Fast") == 0)
295     {
296       deinterlace = 4;
297     }
298
299     logger->debug(TAG, "Set deinterlacing to {} {}", name, deinterlace);
300     delete[] name;
301   }
302
303   return true;
304
305 }
306
307 bool VideoOMX::handleOptionChanges(Option* option)
308 {
309   if (Video::handleOptionChanges(option))
310     return true;
311
312   switch (option->id)
313   {
314     case 1:
315     {
316       if (STRCASECMP(option->options[option->userSetChoice], "None") == 0)
317       {
318         deinterlace = 0;
319       }
320       /* else if (STRCASECMP(option->options[option->userSetChoice], "LineDouble") == 0)
321       {
322         deinterlace = 1;
323       }*/
324       else if (STRCASECMP(option->options[option->userSetChoice], "Advanced") == 0)
325       {
326         deinterlace = 2;
327       }
328       /* else if (STRCASECMP(option->options[option->userSetChoice], "Crazy") == 0)
329       {
330         deinterlace = 3;
331       }*/
332       else if (STRCASECMP(option->options[option->userSetChoice], "Fast") == 0)
333       {
334         deinterlace = 4;
335       }
336
337       logger->debug(TAG, "Set deinterlacing to {} {}", option->options[option->userSetChoice], deinterlace);
338       return true;
339     }
340   }
341
342   return false;
343 }
344
345 bool VideoOMX::saveOptionstoServer()
346 {
347   switch (deinterlace)
348   {
349     case 0:
350       VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "None");
351       break;
352     /*case 1:
353         VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "LineDouble");
354         break;*/
355     case 2:
356       VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "Advanced");
357       break;
358     /*case 3:
359         VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Crazy");
360         break;*/
361     case 4:
362       VDR::getInstance()->configSave("VideoOMX", "SDDeinterlacing", "Fast");
363       break;
364   }
365
366   return true;
367 }
368
369 /*Option(u4 id, const char* displayText, const char* configSection, const char* configKey, u4 optionType,
370            u4 numChoices, u4 defaultChoice, u4 startInt,
371            const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
372
373 bool VideoOMX::addOptionsToPanes(int panenumber, Options* options, WOptionPane* pane)
374 {
375   if (!Video::addOptionsToPanes(panenumber, options, pane)) return false;
376
377   Option* option;
378
379   if (panenumber == 2)
380   {
381     static const char* deinterlaceopts[] = { "None", "Fast",/*"LineDouble",*/"Advanced"/*,"Crazy"*/ };
382     option = new Option(1, tr("SD Deinterlacing"), "VideoOMX", "SDDeinterlacing", Option::TYPE_TEXT,/*4,2*/3, 2, 0, deinterlaceopts, NULL, false, this);
383     options->push_back(option);
384     pane->addOptionLine(option);
385   }
386
387   return true;
388 }
389
390 int VideoOMX::setTVsize(u1 ttvsize)
391 {
392   if (tvsize != ttvsize) pendingmodechange = true;
393
394   tvsize = ttvsize;
395   return 1;
396 }
397
398 u1 VideoOMX::getTVsize()
399 {
400   /*if (hdmi)*/
401   return ASPECT16X9; // in order that aspect ratio changes are reported
402   //return tvsize;
403 }
404
405 void VideoOMX::executePendingModeChanges()
406 {
407   if (pendingmodechange)
408   {
409     logger->info(TAG, "Execute pending mode change");
410     Osd::getInstance()->shutdown();
411     selectVideoMode(0);
412     Osd::getInstance()->restore();
413     Osd::getInstance()->init();
414     BoxStack::getInstance()->redrawAllBoxes();
415     initted = 1;
416   }
417 }
418
419 int VideoOMX::setDefaultAspect()
420 {
421   return setAspectRatio(tvsize, parx, pary);
422 }
423
424 int VideoOMX::setFormat(u1 tformat)
425 {
426   if (!initted) return 0;
427
428   if ((tformat != PAL) && (tformat != NTSC)
429       && (tformat != PAL_M) && (tformat != NTSC_J)) return 0;
430
431   format = PAL;
432   tvsystem = tformat;
433
434   if (format == PAL)
435   {
436     screenWidth = 720;
437     screenHeight = 576;
438   }
439
440   //  selectVideoMode(0);
441
442   return 1;
443 }
444
445 void VideoOMX::selectVideoMode(int interlaced)
446 {
447   TV_GET_STATE_RESP_T tvstate;
448   vc_tv_get_state(&tvstate);
449
450   if ((tvstate.state & VC_HDMI_UNPLUGGED))
451   {
452     hdmi = false;
453     logger->info(TAG, "HDMI unplugged");
454   }
455   else
456   {
457     hdmi = true;
458     logger->info(TAG, "HDMI plugged");
459
460     if (connection == COMPOSITERGB)
461     {
462       hdmi = false;
463       logger->info(TAG, "SDTV set");
464     }
465     else
466     {
467       hdmi = true;
468       logger->info(TAG, "HDMI set");
469     }
470   }
471
472   if (hdmi)
473   {
474     TV_SUPPORTED_MODE_T all_supp_modes[200];
475     HDMI_RES_GROUP_T pref_group;
476     TV_SUPPORTED_MODE_T*  mymode = NULL;
477     TV_SUPPORTED_MODE_T*  mymode_second_best = NULL;
478     // bool got_optimum=false;
479     uint32_t pref_mode;
480     HDMI_RES_GROUP_T group = HDMI_RES_GROUP_CEA;
481     int all_my_modes = vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_CEA,
482                        all_supp_modes, 200,
483                        &pref_group, &pref_mode);
484
485     if (all_my_modes <= 0)
486     {
487       group = HDMI_RES_GROUP_DMT;
488       all_my_modes = vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_DMT,
489                      all_supp_modes, 200,
490                      &pref_group, &pref_mode);
491       logger->info(TAG, "No CEA fall back to DMT modes ");
492     }
493
494     int target_fps = 50;
495
496     if (format == PAL)target_fps = 50;
497     else if (format == NTSC) target_fps = 60;
498
499     //Now first determine native resolution
500     int native_width = 1920;
501     int native_height = 1080;
502
503     for (int i = 0; i < all_my_modes; i++)
504     {
505       if (all_supp_modes[i].native)
506       {
507         mymode = all_supp_modes + i;
508         logger->info(TAG, "Found native mode {}x{} {} Hz i: {}",
509                      mymode->width, mymode->height, mymode->frame_rate, mymode->scan_mode);
510         native_width = mymode->width;
511         native_height = mymode->height;
512       }
513     }
514
515     //Now find the mode which matches best
516     for (int i = 0; i < all_my_modes; i++)
517     {
518       TV_SUPPORTED_MODE_T*  curmode = all_supp_modes + i;
519
520       if (curmode->width == native_width &&
521           curmode->height == native_height &&
522           curmode->frame_rate == target_fps)
523       {
524         if (curmode->scan_mode == interlaced)
525         {
526           //got_optimum=true;
527           mymode = curmode;
528           logger->info(TAG, "Found optimum mode {}x{} {} Hz i: {}",
529                        mymode->width, mymode->height, mymode->frame_rate, mymode->scan_mode);
530         }
531         else
532         {
533           mymode_second_best = curmode;
534           logger->info(TAG, "Found close to optimum mode {}x{} {} Hz i: {}",
535                        mymode_second_best->width, mymode_second_best->height,
536                        mymode_second_best->frame_rate, mymode_second_best->scan_mode);
537         }
538       }
539     }
540
541     // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run?
542
543     bool disableHDMIModeChange{false};
544     bool confSuccess = Config::getInstance()->getBool("videoomx", "disable-hdmi-modechange", disableHDMIModeChange);
545
546     if (!(confSuccess && disableHDMIModeChange))
547     {
548       vc_tv_power_off();
549
550       if (mymode)
551       {
552         logger->info(TAG, "Switch to optimum mode");
553         vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI, group, mymode->code);
554       }
555       else if (mymode_second_best)
556       {
557         logger->info(TAG, "Switch to close to optimum mode");
558         vc_tv_hdmi_power_on_explicit(HDMI_MODE_HDMI, group, mymode_second_best->code);
559       }
560       else
561       {
562         logger->info(TAG, "Switch to prefered mode");
563         vc_tv_hdmi_power_on_best(1920, 1080, target_fps, interlaced ? HDMI_INTERLACED : HDMI_NONINTERLACED,
564                                  static_cast<EDID_MODE_MATCH_FLAG_T>(HDMI_MODE_MATCH_FRAMERATE | HDMI_MODE_MATCH_RESOLUTION | HDMI_MODE_MATCH_SCANMODE));
565       }
566     }
567
568     hdmi = true;
569     outputinterlaced = interlaced;
570   }
571   else
572   {
573     /* analog tv case */
574     logger->info(TAG, "Analog tv case");
575     // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run?         vc_tv_power_off();
576     SDTV_MODE_T setmode = SDTV_MODE_PAL;
577     SDTV_OPTIONS_T options;
578
579     switch (tvsize)
580     {
581       default:
582       case ASPECT16X9:
583         logger->info(TAG, "SDTV aspect 16:9");
584         options.aspect = SDTV_ASPECT_16_9; break;
585
586       case ASPECT4X3:
587         logger->info(TAG, "SDTV aspect 4:3");
588         options.aspect = SDTV_ASPECT_4_3; break;
589
590       case ASPECT14X9:
591         logger->info(TAG, "SDTV aspect 14:9");
592         options.aspect = SDTV_ASPECT_14_9; break;
593     }
594
595     if (format == PAL) setmode = SDTV_MODE_PAL;
596     else if (format == NTSC) setmode = SDTV_MODE_NTSC;
597     else if (format == PAL_M)setmode = SDTV_MODE_PAL_M;
598     else if (format == NTSC_J) setmode = SDTV_MODE_NTSC_J;
599
600     vc_tv_sdtv_power_on(setmode, &options);
601     hdmi = false;
602   }
603
604   // InputMan::getInstance()->init(); // FIXME complete shutdown and reinit maybe heavy handed. FIXME FIXME FIXME - disabled temp
605   // If this was just to reinit CEC then funcitons should be made to do that
606
607   signalon = true;
608   pendingmodechange = false;
609 }
610
611 int VideoOMX::setConnection(u1 tconnection)
612 {
613   if (!initted) return 0;
614   if ((tconnection != COMPOSITERGB)  && (tconnection != HDMI)) return 0;
615   if (connection != tconnection) pendingmodechange = true;
616   connection = tconnection;
617   //  if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
618   return 1;
619 }
620
621 int VideoOMX::setAspectRatio(u1 taspectRatio, int tparx, int tpary)
622 {
623   if (!initted) return 0;
624
625   //if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
626   aspectRatio = taspectRatio;
627   parx = tparx;
628   pary = tpary;
629
630   logger->debug(TAG, "Setting aspect to {}: PAR {} {}", aspectRatio, parx, pary);
631
632   updateMode();
633   //  if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
634   return 1;
635 }
636
637 int VideoOMX::setMode(u1 tmode)
638 {
639   if (!initted) return 0;
640
641   if (tmode == LETTERBOX || tmode == NORMAL) mode = tmode;
642
643   updateMode();
644   return 1;
645 }
646
647 bool VideoOMX::setVideoDisplay(VideoDisplay display)
648 {
649   if (!initted) return false;
650
651   switch (display.mode)
652   {
653     case None: return true; //??
654
655     case Fullscreen:
656     {
657       windowed = false;
658       break;
659     }
660
661     case Quarter:
662     {
663       windowed = true;
664       xpos = ((float) display.x) / ((float) screenWidth);
665       ypos = ((float) display.y) / ((float) screenHeight);
666       width = 0.5f;
667       height = 0.5f;
668      break;
669     }
670
671     case Eighth:
672     {
673       windowed = true;
674       xpos = ((float) display.x) / ((float) screenWidth);
675       ypos = ((float) display.y) / ((float) screenHeight);
676       width = 0.25f;
677       height = 0.25f;
678       break;
679     }
680
681     case Window:
682     {
683       windowed = true;
684       xpos = ((float) display.x) / ((float) screenWidth);
685       ypos = ((float) display.y) / ((float) screenHeight);
686       width = ((float) display.width) / ((float) screenWidth);
687       height = ((float) display.height) / ((float) screenHeight);
688       break;
689     }
690   }
691
692   updateMode();
693   return true;
694 }
695
696 void VideoOMX::updateMode()
697 {
698   clock_mutex.lock();
699
700   if (omx_running)
701   {
702     int oldcancelstate;
703     int oldcanceltype;
704     pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
705     pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
706     OMX_ERRORTYPE error;
707     OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
708     memset(&dispconf, 0, sizeof(dispconf));
709     dispconf.nSize = sizeof(dispconf);
710     dispconf.nVersion.nVersion = OMX_VERSION;
711     dispconf.nPortIndex = omx_rend_input_port;
712     dispconf.layer = 1;
713     dispconf.set = OMX_DISPLAY_SET_LAYER;
714     error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf);
715
716     if (error != OMX_ErrorNone)
717     {
718       logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion1 failed {:#x}", error);
719       pthread_setcancelstate(oldcancelstate, NULL);
720       pthread_setcanceltype(oldcanceltype, NULL);
721       clock_mutex.unlock();
722       return;
723     }
724
725     dispconf.pixel_x = parx;
726     dispconf.pixel_y = pary;
727     dispconf.set = OMX_DISPLAY_SET_PIXEL;
728     error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf);
729
730     if (error != OMX_ErrorNone)
731     {
732       logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion5 failed {:#x}", error);
733       pthread_setcancelstate(oldcancelstate, NULL);
734       pthread_setcanceltype(oldcanceltype, NULL);
735       clock_mutex.unlock();
736       return;
737     }
738
739     dispconf.set = OMX_DISPLAY_SET_FULLSCREEN;
740
741     if (!windowed)
742     {
743       //Set Fullscreen
744       dispconf.fullscreen = OMX_TRUE;
745     }
746     else
747     {
748       dispconf.fullscreen = OMX_FALSE;
749     }
750
751     error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf);
752     if (error != OMX_ErrorNone)
753     {
754       logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion2 failed {:#x}", error);
755       pthread_setcancelstate(oldcancelstate, NULL);
756       pthread_setcanceltype(oldcanceltype, NULL);
757       clock_mutex.unlock();
758       return;
759     }
760
761     dispconf.set = OMX_DISPLAY_SET_MODE;
762
763     if (!windowed)
764     {
765       dispconf.mode = (mode == NORMAL) ? OMX_DISPLAY_MODE_FILL : OMX_DISPLAY_MODE_LETTERBOX;
766     }
767     else
768     {
769       dispconf.mode = OMX_DISPLAY_MODE_LETTERBOX;
770     }
771
772     error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf);
773
774     if (error != OMX_ErrorNone)
775     {
776       logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion3 failed {:#x}", error);
777       pthread_setcancelstate(oldcancelstate, NULL);
778       pthread_setcanceltype(oldcanceltype, NULL);
779       clock_mutex.unlock();
780       return;
781     }
782
783     if (windowed)
784     {
785       unsigned int display_width, display_height;
786       display_width = display_height = 0;
787
788       if (graphics_get_display_size(0, &display_width, &display_height) < 0)
789       {
790         logger->warn(TAG, "Getting display size failed! (BCM API) ");
791         pthread_setcancelstate(oldcancelstate, NULL);
792         pthread_setcanceltype(oldcanceltype, NULL);
793         clock_mutex.unlock();
794         return;
795       }
796
797       //UnSetFullscreen with window
798       dispconf.set = OMX_DISPLAY_SET_DEST_RECT;
799       dispconf.dest_rect.x_offset = (int) (xpos * ((float) display_width));
800       dispconf.dest_rect.y_offset = (int) (ypos * ((float) display_height));
801       dispconf.dest_rect.width = (int) (width * ((float) display_width));
802       dispconf.dest_rect.height = (int) (height * ((float) display_height));
803       logger->debug(TAG, "Set dest_rect as {} {} {} {}", dispconf.dest_rect.x_offset, dispconf.dest_rect.y_offset,
804                     dispconf.dest_rect.width, dispconf.dest_rect.height);
805
806       error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, &dispconf);
807
808       if (error != OMX_ErrorNone)
809       {
810         logger->debug(TAG, "Set OMX_IndexConfigDisplayRegion failed {:#x}", error);
811         pthread_setcancelstate(oldcancelstate, NULL);
812         pthread_setcanceltype(oldcanceltype, NULL);
813         clock_mutex.unlock();
814         return;
815       }
816     }
817
818     pthread_setcancelstate(oldcancelstate, NULL);
819     pthread_setcanceltype(oldcanceltype, NULL);
820   }
821
822   clock_mutex.unlock();
823 }
824
825 int VideoOMX::signalOff()
826 {
827   //TODO reinit osd
828   logger->info(TAG, "signalOff");
829   Osd::getInstance()->stopUpdate(); // turn off drawing thread
830   // FIXME FIXME FIXME why do this? Probably to do with reinitting CEC, but should refine this
831   InputMan::getInstance()->shutdown();
832   vc_tv_power_off();
833   InputMan::getInstance()->init();
834   signalon = false;
835   return 1;
836 }
837
838 int VideoOMX::signalOn()
839 {
840   if (!signalon)
841   {
842     Osd::getInstance()->shutdown();
843     logger->info(TAG, "signalOn");
844     selectVideoMode(0);
845     Osd::getInstance()->restore();
846     Osd::getInstance()->init();
847     BoxStack::getInstance()->redrawAllBoxes();
848     initted = 1;
849   }
850
851   return 1;
852 }
853
854 int VideoOMX::setSource()
855 {
856   if (!initted) return 0;
857
858   // What does this do...
859   //  if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
860   return 1;
861 }
862
863 int VideoOMX::setPosition(int x, int y)
864 {
865   if (!initted) return 0;
866
867   xpos = ((float) x * 2.f) / ((float) screenWidth);
868   ypos = ((float) y * 2.f) / ((float) screenHeight);
869
870   updateMode();
871   return 1;
872 }
873
874 int VideoOMX::sync()
875 {
876   if (!initted) return 0;
877
878   //  if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
879   return 1;
880 }
881
882 void VideoOMX::interlaceSwitch4Demux()
883 {
884   return;
885   Demuxer* demux = Demuxer::getInstance();
886
887   if (hdmi) // only switch if hdmi and HD or interlaced SD material
888   {
889     //OMX_Deinit();
890     int set_interlaced = 0;
891
892     if (demux->getHorizontalSize() > 720  && demux->getInterlaced())
893     {
894       set_interlaced = 1;
895     }
896
897     logger->info(TAG, "switch interlacing {} {} {}", demux->getInterlaced(), outputinterlaced, set_interlaced);
898
899     if (outputinterlaced != set_interlaced)
900     {
901       selectVideoMode(set_interlaced);
902       Osd::getInstance()->shutdown();
903       Osd::getInstance()->restore();
904       Osd::getInstance()->init();
905       BoxStack::getInstance()->redrawAllBoxes();
906       initted = 1;
907     }
908
909     //OMX_Init();
910   }
911 }
912
913 int VideoOMX::play()
914 {
915   if (!initted) return 0;
916
917   iframemode = false;
918   logger->debug(TAG, "enter play");
919
920   interlaceSwitch4Demux();
921
922   if (AllocateCodecsOMX())
923   {
924     return 1;
925     // Otherwise fall back to libav
926   }
927   else
928   {
929     if (h264)
930     {
931       omx_h264 = false;
932       logger->info(TAG, "Allocate Codecs OMX failed assume h264 unsupported");
933     }
934     else
935     {
936       omx_mpeg2 = false;
937       logger->info(TAG, "Allocate Codecs OMX failed assume mpeg2 unsupported");
938     }
939   }
940
941   return 0;
942 }
943
944 int VideoOMX::initClock()
945 {
946   OMX_ERRORTYPE error;
947   clock_mutex.lock();
948
949   if (clock_references == 0)
950   {
951     static OMX_CALLBACKTYPE callbacks = {&EventHandler_OMX, &EmptyBufferDone_OMX, &FillBufferDone_OMX};
952     omx_event_mutex.lock();
953     omx_events.clear();
954     omx_event_mutex.unlock();
955
956     error = OMX_GetHandle(&omx_clock, L_VPE_OMX_CLOCK, NULL, &callbacks);
957
958     if (error != OMX_ErrorNone)
959     {
960       logger->debug(TAG, "Init OMX clock failed {:#x}", error);
961       clock_mutex.unlock();
962       DeAllocateCodecsOMX();
963       return 0;
964     }
965
966     /* TODO Clock config to separate method */
967     OMX_PORT_PARAM_TYPE p_param;
968     memset(&p_param, 0, sizeof(p_param));
969     p_param.nSize = sizeof(p_param);
970     p_param.nVersion.nVersion = OMX_VERSION;
971     error = OMX_GetParameter(omx_clock, OMX_IndexParamOtherInit, &p_param);
972
973     if (error != OMX_ErrorNone)
974     {
975       logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
976       clock_mutex.unlock();
977       DeAllocateCodecsOMX();
978       return 0;
979     }
980
981     omx_clock_output_port = p_param.nStartPortNumber;
982
983     for (unsigned int i = 0; i < p_param.nPorts; i++)
984     {
985       if (!DisablePort(omx_clock, p_param.nStartPortNumber + i, true) )
986       {
987         logger->debug(TAG, "Disable Ports OMX clock failed {}", i);
988         clock_mutex.unlock();
989         DeAllocateCodecsOMX();
990         return 0;
991       }
992     }
993   }
994
995   logger->debug(TAG, "init omx clock {:p} {}", (void*)this, omx_clock);
996   clock_references++;
997   clock_mutex.unlock();
998   return 1;
999 }
1000
1001 int VideoOMX::getClockAudioandInit(OMX_HANDLETYPE* p_omx_clock, OMX_U32* p_omx_clock_output_port)
1002 {
1003   OMX_ERRORTYPE error;
1004   *p_omx_clock = NULL;
1005   *p_omx_clock_output_port = 0;
1006
1007   if (!initClock()) return 0;
1008
1009   clock_mutex.lock();
1010
1011   OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
1012   memset(&refclock, 0, sizeof(refclock));
1013   refclock.nSize = sizeof(refclock);
1014   refclock.nVersion.nVersion = OMX_VERSION;
1015
1016   refclock.eClock = OMX_TIME_RefClockAudio;
1017
1018   //refclock.eClock=OMX_TIME_RefClockVideo;
1019   error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeActiveRefClock, &refclock);
1020
1021   if (error != OMX_ErrorNone)
1022   {
1023     logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error);
1024     clock_mutex.unlock();
1025     DeAllocateCodecsOMX();
1026     return 0;
1027   }
1028
1029   OMX_PORT_PARAM_TYPE p_param;
1030   memset(&p_param, 0, sizeof(p_param));
1031   p_param.nSize = sizeof(p_param);
1032   p_param.nVersion.nVersion = OMX_VERSION;
1033   error = OMX_GetParameter(omx_clock, OMX_IndexParamOtherInit, &p_param);
1034
1035   if (error != OMX_ErrorNone)
1036   {
1037     logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
1038     clock_mutex.unlock();
1039     DeAllocateCodecsOMX();
1040     return 0;
1041   }
1042
1043   OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1044   memset(&clock_conf, 0, sizeof(clock_conf));
1045   clock_conf.nSize = sizeof(clock_conf);
1046   clock_conf.nVersion.nVersion = OMX_VERSION;
1047   clock_conf.eState = OMX_TIME_ClockStateWaitingForStartTime;
1048   clock_conf.nStartTime = intToOMXTicks(0);
1049   clock_conf.nOffset = intToOMXTicks(0);
1050
1051   if (clock_references == 1) clock_conf.nWaitMask = OMX_CLOCKPORT1;
1052   else clock_conf.nWaitMask = OMX_CLOCKPORT0 | OMX_CLOCKPORT1;
1053
1054   error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf);
1055
1056   if (error != OMX_ErrorNone)
1057   {
1058     logger->debug(TAG, "AuI Clock IndexConfigTimeClockState failed {:#x}", error);
1059   }
1060
1061   *p_omx_clock_output_port = p_param.nStartPortNumber + 1;
1062   *p_omx_clock = omx_clock;
1063   clock_mutex.unlock();
1064   return 1;
1065 }
1066
1067 int VideoOMX::getClockVideoandInit()
1068 {
1069   OMX_ERRORTYPE error;
1070
1071   if (!initClock()) return 0;
1072
1073   clock_mutex.lock();
1074
1075   if (clock_references == 1) // only if no audio is attached to this clock!
1076   {
1077     OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
1078     memset(&refclock, 0, sizeof(refclock));
1079     refclock.nSize = sizeof(refclock);
1080     refclock.nVersion.nVersion = OMX_VERSION;
1081
1082     //refclock.eClock=OMX_TIME_RefClockAudio;
1083
1084     refclock.eClock = OMX_TIME_RefClockVideo;
1085     error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeActiveRefClock, &refclock);
1086
1087     if (error != OMX_ErrorNone)
1088     {
1089       logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error);
1090       clock_mutex.unlock();
1091       DeAllocateCodecsOMX();
1092       return 0;
1093     }
1094   }
1095
1096   OMX_PORT_PARAM_TYPE p_param;
1097   memset(&p_param, 0, sizeof(p_param));
1098   p_param.nSize = sizeof(p_param);
1099   p_param.nVersion.nVersion = OMX_VERSION;
1100   error = OMX_GetParameter(omx_clock, OMX_IndexParamOtherInit, &p_param);
1101
1102   if (error != OMX_ErrorNone)
1103   {
1104     logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
1105     clock_mutex.unlock();
1106     DeAllocateCodecsOMX();
1107     return 0;
1108   }
1109
1110   OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1111   memset(&clock_conf, 0, sizeof(clock_conf));
1112   clock_conf.nSize = sizeof(clock_conf);
1113   clock_conf.nVersion.nVersion = OMX_VERSION;
1114   clock_conf.eState = OMX_TIME_ClockStateStopped;
1115   clock_conf.nStartTime = intToOMXTicks(0);
1116   clock_conf.nOffset = intToOMXTicks(0);
1117   error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf);
1118
1119   if (error != OMX_ErrorNone)
1120   {
1121     logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error);
1122   }
1123
1124   memset(&clock_conf, 0, sizeof(clock_conf));
1125   clock_conf.nSize = sizeof(clock_conf);
1126   clock_conf.nVersion.nVersion = OMX_VERSION;
1127   clock_conf.eState = OMX_TIME_ClockStateWaitingForStartTime;
1128   clock_conf.nStartTime = intToOMXTicks(0);
1129   clock_conf.nOffset = intToOMXTicks(0);
1130
1131   if (clock_references == 1) clock_conf.nWaitMask = OMX_CLOCKPORT0;
1132   else clock_conf.nWaitMask = OMX_CLOCKPORT0 | OMX_CLOCKPORT1;
1133
1134   error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf);
1135
1136   if (error != OMX_ErrorNone)
1137   {
1138     logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error);
1139   }
1140
1141   omx_clock_output_port = p_param.nStartPortNumber;
1142   clock_mutex.unlock();
1143
1144   return 1;
1145 }
1146
1147 void VideoOMX::clockUnpause()
1148 {
1149   OMX_ERRORTYPE error;
1150   logger->info(TAG, "enter Clockunpause");
1151   clock_mutex.lock();
1152
1153   if (clock_references > 0 && clockpaused)
1154   {
1155     OMX_TIME_CONFIG_SCALETYPE scale_type;
1156     memset(&scale_type, 0, sizeof(scale_type));
1157     scale_type.nSize = sizeof(scale_type);
1158     scale_type.nVersion.nVersion = OMX_VERSION;
1159     scale_type.xScale = 1 << 16;
1160     error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeScale, &scale_type);
1161
1162     if (error != OMX_ErrorNone)
1163     {
1164       logger->debug(TAG, "ClockUnpause OMX_IndexConfigTimeScale failed {:#x}", error);
1165     }
1166
1167     logger->info(TAG, "set playback speed ClockUnpause");
1168     clockpaused = false;
1169   }
1170
1171   clock_mutex.unlock();
1172 }
1173
1174
1175 void VideoOMX::clockPause()
1176 {
1177   OMX_ERRORTYPE error;
1178   logger->info(TAG, "enter ClockPause");
1179   clock_mutex.lock();
1180
1181   if (clock_references > 0 && !clockpaused)
1182   {
1183     OMX_TIME_CONFIG_SCALETYPE scale_type;
1184     memset(&scale_type, 0, sizeof(scale_type));
1185     scale_type.nSize = sizeof(scale_type);
1186     scale_type.nVersion.nVersion = OMX_VERSION;
1187     scale_type.xScale = 0;
1188     error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeScale, &scale_type);
1189
1190     if (error != OMX_ErrorNone)
1191     {
1192       logger->debug(TAG, "ClockPause OMX_IndexConfigTimeScale failed {:#x}", error);
1193     }
1194
1195     logger->info(TAG, "set playback speed ClockPause");
1196     clockpaused = true;
1197   }
1198
1199   clock_mutex.unlock();
1200 }
1201
1202 int VideoOMX::AllocateCodecsOMX()
1203 {
1204   OMX_ERRORTYPE error;
1205   static OMX_CALLBACKTYPE callbacks = {&EventHandler_OMX, &EmptyBufferDone_OMX, &FillBufferDone_OMX};
1206
1207   Demuxer* demux = Demuxer::getInstance();
1208
1209   dodeint = false;
1210   first_frame = true;
1211
1212   logger->info(TAG, "Allocate Codecs OMX");
1213   //Clock, move later to audio including events
1214
1215   logger->info(TAG, "Deinter VideoType {} x {} i: {}", demux->getHorizontalSize(), demux->getVerticalSize(), demux->getInterlaced());
1216
1217   if (deinterlace != 0 && /*(demux->getHorizontalSize()<=720 ) &&*/ demux->getInterlaced())
1218   {
1219     dodeint = true;
1220     logger->info(TAG, "Deinterlacing activated {}", deinterlace);
1221   }
1222
1223   if (!getClockVideoandInit())
1224   {
1225     return 0;// get the clock and init it if necessary
1226   }
1227
1228   if (!idleClock())
1229   {
1230     logger->debug(TAG, "idleClock failed");
1231     return 0;
1232   }
1233
1234   /* TODO end */
1235
1236   clock_mutex.lock();
1237
1238   if (h264)
1239   {
1240     error = OMX_GetHandle(&omx_vid_dec, L_VPE_OMX_H264_DECODER, NULL, &callbacks);
1241   }
1242   else
1243   {
1244     error = OMX_GetHandle(&omx_vid_dec, L_VPE_OMX_MPEG2_DECODER, NULL, &callbacks);
1245   }
1246
1247   if (error != OMX_ErrorNone)
1248   {
1249     logger->debug(TAG, "Init OMX video decoder failed {:#x}", error);
1250     clock_mutex.unlock();
1251     DeAllocateCodecsOMX();
1252     return 0;
1253   }
1254
1255   logger->debug(TAG, "Nmark3");
1256   OMX_PORT_PARAM_TYPE p_param;
1257   memset(&p_param, 0, sizeof(p_param));
1258   p_param.nSize = sizeof(p_param);
1259   p_param.nVersion.nVersion = OMX_VERSION;
1260   error = OMX_GetParameter(omx_vid_dec, OMX_IndexParamVideoInit, &p_param);
1261
1262   if (error != OMX_ErrorNone)
1263   {
1264     logger->debug(TAG, "Init OMX h264 decoder OMX_GetParameter failed {:#x}", error);
1265     clock_mutex.unlock();
1266     DeAllocateCodecsOMX();
1267     return 0;
1268   }
1269
1270   omx_codec_input_port = p_param.nStartPortNumber;
1271   omx_codec_output_port = p_param.nStartPortNumber + 1;
1272
1273   if (!DisablePort(omx_vid_dec, omx_codec_input_port) || !DisablePort(omx_vid_dec, omx_codec_output_port))
1274   {
1275     logger->debug(TAG, "Disable Ports OMX video decoder failed");
1276     clock_mutex.unlock();
1277     DeAllocateCodecsOMX();
1278     return 0;
1279   }
1280
1281   logger->debug(TAG, "Nmark4");
1282
1283   OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
1284   memset(&conceal, 0, sizeof(conceal));
1285   conceal.nSize = sizeof(conceal);
1286   conceal.nVersion.nVersion = OMX_VERSION;
1287   conceal.bStartWithValidFrame = OMX_FALSE;
1288
1289   error = OMX_SetParameter(omx_vid_dec, OMX_IndexParamBrcmVideoDecodeErrorConcealment, &conceal);
1290
1291   if (error != OMX_ErrorNone)
1292   {
1293     logger->debug(TAG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed {:#x}", error);
1294     clock_mutex.unlock();
1295     DeAllocateCodecsOMX();
1296     return 0;
1297   }
1298
1299   if (dodeint)
1300   {
1301     error = OMX_GetHandle(&omx_vid_deint, L_VPE_OMX_VIDEO_DEINTERLACE, NULL, &callbacks);
1302
1303     if (error != OMX_ErrorNone)
1304     {
1305       logger->debug(TAG, "Init OMX video deinterlacer failed {:#x}", error);
1306       clock_mutex.unlock();
1307       DeAllocateCodecsOMX();
1308       return 0;
1309     }
1310
1311     error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamImageInit, &p_param);
1312
1313     if (error != OMX_ErrorNone)
1314     {
1315       logger->debug(TAG, "Init OMX video deinterlacer OMX_GetParameter failed {:#x}", error);
1316       clock_mutex.unlock();
1317       DeAllocateCodecsOMX();
1318       return 0;
1319     }
1320
1321     omx_deint_input_port = p_param.nStartPortNumber;
1322     omx_deint_output_port = p_param.nStartPortNumber + 1;
1323
1324     if (!DisablePort(omx_vid_deint, omx_deint_input_port, true)
1325         || !DisablePort(omx_vid_deint, omx_deint_output_port, true))
1326     {
1327       logger->debug(TAG, "Disable Ports OMX video deint failed");
1328       clock_mutex.unlock();
1329       DeAllocateCodecsOMX();
1330       return 0;
1331     }
1332   }
1333
1334   error = OMX_GetHandle(&omx_vid_sched, L_VPE_OMX_VIDEO_SCHED, NULL, &callbacks);
1335
1336   if (error != OMX_ErrorNone)
1337   {
1338     logger->debug(TAG, "Init OMX video scheduler failed {:#x}", error);
1339     clock_mutex.unlock();
1340     DeAllocateCodecsOMX();
1341     return 0;
1342   }
1343
1344   error = OMX_GetParameter(omx_vid_sched, OMX_IndexParamVideoInit, &p_param);
1345
1346   if (error != OMX_ErrorNone)
1347   {
1348     logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error);
1349     clock_mutex.unlock();
1350     DeAllocateCodecsOMX();
1351     return 0;
1352   }
1353
1354   omx_shed_input_port = p_param.nStartPortNumber;
1355   omx_shed_output_port = p_param.nStartPortNumber + 1;
1356
1357   error = OMX_GetParameter(omx_vid_sched, OMX_IndexParamOtherInit, &p_param);
1358
1359   if (error != OMX_ErrorNone)
1360   {
1361     logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error);
1362     clock_mutex.unlock();
1363     DeAllocateCodecsOMX();
1364     return 0;
1365   }
1366
1367   omx_shed_clock_port = p_param.nStartPortNumber;
1368   logger->debug(TAG, "scheduler ports {} {} {}", omx_shed_input_port, omx_shed_output_port, omx_shed_clock_port);
1369
1370   if (!DisablePort(omx_vid_sched, omx_shed_input_port, true) || !DisablePort(omx_vid_sched, omx_shed_output_port, true)
1371       || !DisablePort(omx_vid_sched, omx_shed_clock_port, true))
1372   {
1373     logger->debug(TAG, "Disable Ports OMX video shed failed");
1374     clock_mutex.unlock();
1375     DeAllocateCodecsOMX();
1376     return 0;
1377   }
1378
1379   error = OMX_GetHandle(&omx_vid_rend, L_VPE_OMX_VIDEO_REND, NULL, &callbacks);
1380
1381   if (error != OMX_ErrorNone)
1382   {
1383     logger->debug(TAG, "Init OMX video rend failed {:#x}", error);
1384     clock_mutex.unlock();
1385     DeAllocateCodecsOMX();
1386     return 0;
1387   }
1388
1389   error = OMX_GetParameter(omx_vid_rend, OMX_IndexParamVideoInit, &p_param);
1390
1391   if (error != OMX_ErrorNone)
1392   {
1393     logger->debug(TAG, "Init OMX video rend OMX_GetParameter failed {:#x}", error);
1394     clock_mutex.unlock();
1395     DeAllocateCodecsOMX();
1396     return 0;
1397   }
1398
1399   omx_rend_input_port = p_param.nStartPortNumber;
1400   //omx_rend_output_port=p_param.nStartPortNumber+1;
1401
1402   if (!DisablePort(omx_vid_rend, omx_rend_input_port, true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
1403      )
1404   {
1405     logger->debug(TAG, "Disable Ports OMX video rend failed");
1406     clock_mutex.unlock();
1407     DeAllocateCodecsOMX();
1408     return 0;
1409   }
1410
1411   //Setup chain
1412
1413   error = OMX_SetupTunnel(omx_clock, omx_clock_output_port, omx_vid_sched, omx_shed_clock_port);
1414
1415   if (error != OMX_ErrorNone)
1416   {
1417     logger->debug(TAG, "OMX_Setup tunnel clock to sched failed {:#x} {} {}", error, omx_clock_output_port, omx_shed_clock_port);
1418     clock_mutex.unlock();
1419     DeAllocateCodecsOMX();
1420     return 0;
1421   }
1422
1423   if (!EnablePort(omx_clock, omx_clock_output_port, false) || !EnablePort(omx_vid_sched, omx_shed_clock_port, false)
1424      )
1425   {
1426     logger->debug(TAG, "Enable Ports OMX clock shed failed");
1427     clock_mutex.unlock();
1428     DeAllocateCodecsOMX();
1429     return 0;
1430   }
1431
1432   if (!ChangeComponentState(omx_vid_sched, OMX_StateIdle))
1433   {
1434     logger->debug(TAG, "vid_sched idle ChangeComponentState");
1435     clock_mutex.unlock();
1436     DeAllocateCodecsOMX();
1437     return 0;
1438   }
1439
1440   if (!CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_clock_port))
1441   {
1442     clock_mutex.unlock();
1443     DeAllocateCodecsOMX();
1444     return 0;
1445   }
1446
1447   if (!CommandFinished(omx_clock, OMX_CommandPortEnable, omx_clock_output_port))
1448   {
1449     clock_mutex.unlock();
1450     DeAllocateCodecsOMX();
1451     return 0;
1452   }
1453
1454   /*    error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1455         if (error!=OMX_ErrorNone){
1456                 logger->debug(TAG, "vid_dec Send Command to OMX State Idle {:#x}", error);
1457                 return 0;
1458         }*/
1459
1460   OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1461   memset(&ft_type, 0, sizeof(ft_type));
1462   ft_type.nSize = sizeof(ft_type);
1463   ft_type.nVersion.nVersion = OMX_VERSION;
1464
1465   ft_type.nPortIndex = omx_codec_input_port;
1466
1467   if (h264)
1468     ft_type.eCompressionFormat = OMX_VIDEO_CodingAVC;
1469   else
1470     ft_type.eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1471
1472   ft_type.xFramerate = 0 * (1 << 16); //25*(1<<16);//demux->getFrameRate()*(1<<16);
1473   logger->debug(TAG, "Framerate: {}", demux->getFrameRate());
1474   error = OMX_SetParameter(omx_vid_dec, OMX_IndexParamVideoPortFormat, &ft_type);
1475
1476   if (error != OMX_ErrorNone)
1477   {
1478     logger->debug(TAG, "Init OMX_IndexParamVideoPortFormat failed {:#x}", error);
1479     clock_mutex.unlock();
1480     DeAllocateCodecsOMX();
1481     return 0;
1482   }
1483
1484   if (!ChangeComponentState(omx_vid_dec, OMX_StateIdle))
1485   {
1486     logger->debug(TAG, "vid_dec ChangeComponentState");
1487     clock_mutex.unlock();
1488     DeAllocateCodecsOMX();
1489     return 0;
1490   }
1491
1492   OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
1493   memset(&stall_conf, 0, sizeof(stall_conf));
1494   stall_conf.nSize = sizeof(stall_conf);
1495   stall_conf.nVersion.nVersion = OMX_VERSION;
1496   stall_conf.nPortIndex = omx_codec_output_port;
1497   stall_conf.nDelay = 1500 * 1000;
1498   error = OMX_SetConfig(omx_vid_dec, OMX_IndexConfigBufferStall, &stall_conf);
1499
1500   if (error != OMX_ErrorNone)
1501   {
1502     logger->debug(TAG, "Init OMX_IndexConfigBufferStall failed {:#x}", error);
1503     clock_mutex.unlock();
1504     DeAllocateCodecsOMX();
1505     return 0;
1506   }
1507
1508   omx_vid_stalled = false;
1509
1510   OMX_CONFIG_REQUESTCALLBACKTYPE req_callback;
1511   memset(&req_callback, 0, sizeof(req_callback));
1512   req_callback.nSize = sizeof(req_callback);
1513   req_callback.nVersion.nVersion = OMX_VERSION;
1514   req_callback.nPortIndex = omx_codec_output_port;
1515   req_callback.nIndex = OMX_IndexConfigBufferStall;
1516   req_callback.bEnable = OMX_TRUE;
1517   error = OMX_SetConfig(omx_vid_dec, OMX_IndexConfigRequestCallback, &req_callback);
1518
1519   if (error != OMX_ErrorNone)
1520   {
1521     logger->debug(TAG, "Init OMX_IndexConfigRequestCallback failed {:#x}", error);
1522     clock_mutex.unlock();
1523     DeAllocateCodecsOMX();
1524     return 0;
1525   }
1526
1527   if (!PrepareInputBufsOMX())
1528   {
1529     clock_mutex.unlock();
1530     DeAllocateCodecsOMX();
1531     return 0;
1532   }
1533
1534   if (!dodeint)
1535   {
1536     error = OMX_SetupTunnel(omx_vid_dec, omx_codec_output_port, omx_vid_sched, omx_shed_input_port);
1537
1538     if (error != OMX_ErrorNone)
1539     {
1540       logger->debug(TAG, "OMX_Setup tunnel dec to sched failed {:#x}", error);
1541       clock_mutex.unlock();
1542       DeAllocateCodecsOMX();
1543       return 0;
1544     }
1545
1546     if (!EnablePort(omx_vid_dec, omx_codec_output_port, false) || !EnablePort(omx_vid_sched, omx_shed_input_port, false))
1547     {
1548       logger->debug(TAG, "Enable Ports OMX codec shed failed");
1549       clock_mutex.unlock();
1550       DeAllocateCodecsOMX();
1551       return 0;
1552     }
1553
1554     if (!CommandFinished(omx_vid_dec, OMX_CommandPortEnable, omx_codec_output_port) || !CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_input_port))
1555     {
1556       clock_mutex.unlock();
1557       DeAllocateCodecsOMX();
1558       return 0;
1559     }
1560   }
1561   else
1562   {
1563     error = OMX_SetupTunnel(omx_vid_dec, omx_codec_output_port, omx_vid_deint, omx_deint_input_port);
1564
1565     if (error != OMX_ErrorNone)
1566     {
1567       logger->debug(TAG, "OMX_Setup tunnel dec to deint failed {:#x}", error);
1568       clock_mutex.unlock();
1569       DeAllocateCodecsOMX();
1570       return 0;
1571     }
1572
1573     if (!EnablePort(omx_vid_dec, omx_codec_output_port, false) || !EnablePort(omx_vid_deint, omx_deint_input_port, false))
1574     {
1575       logger->debug(TAG, "Enable Ports OMX codec deint failed");
1576       clock_mutex.unlock();
1577       DeAllocateCodecsOMX();
1578       return 0;
1579     }
1580
1581     if (!CommandFinished(omx_vid_dec, OMX_CommandPortEnable, omx_codec_output_port) || !CommandFinished(omx_vid_deint, OMX_CommandPortEnable, omx_deint_input_port))
1582     {
1583       clock_mutex.unlock();
1584       DeAllocateCodecsOMX();
1585       return 0;
1586     }
1587
1588     if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle))
1589     {
1590       logger->debug(TAG, "vid_deint ChangeComponentState");
1591       clock_mutex.unlock();
1592       DeAllocateCodecsOMX();
1593       return 0;
1594     }
1595
1596     OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter;
1597     memset(&imagefilter, 0, sizeof(imagefilter));
1598     imagefilter.nSize = sizeof(imagefilter);
1599     imagefilter.nVersion.nVersion = OMX_VERSION;
1600
1601     imagefilter.nPortIndex = omx_deint_output_port;
1602     imagefilter.nNumParams = 4;
1603     imagefilter.nParams[0] = 3; //???
1604     imagefilter.nParams[1] = 0; //default frame interval
1605     imagefilter.nParams[2] = 0; // frame rate
1606
1607     if (demux->getHorizontalSize() <= 720)
1608     {
1609       imagefilter.nParams[3] = 1;//use qpus
1610     }
1611     else
1612     {
1613       imagefilter.nParams[3] = 0;//use qpus
1614     }
1615
1616     switch (deinterlace)
1617     {
1618       case 1:
1619         imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceLineDouble; break;
1620
1621       case 2:
1622         imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceAdvanced; break;
1623
1624       case 3:
1625         imagefilter.eImageFilter = OMX_ImageFilterFilm; break;
1626
1627       case 4:
1628         imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceFast; break;
1629     }
1630
1631     error = OMX_SetConfig(omx_vid_deint, OMX_IndexConfigCommonImageFilterParameters, &imagefilter);
1632
1633     if (error != OMX_ErrorNone)
1634     {
1635       logger->debug(TAG, "Init OMX_IndexConfigCommonImageFilterParameters failed {:#x}", error);
1636       clock_mutex.unlock();
1637       DeAllocateCodecsOMX();
1638       return 0;
1639     }
1640
1641     error = OMX_SetupTunnel(omx_vid_deint, omx_deint_output_port, omx_vid_sched, omx_shed_input_port);
1642
1643     if (error != OMX_ErrorNone)
1644     {
1645       logger->debug(TAG, "OMX_Setup tunnel deint to sched failed {:#x}", error);
1646       clock_mutex.unlock();
1647       DeAllocateCodecsOMX();
1648       return 0;
1649     }
1650
1651     if (!EnablePort(omx_vid_deint, omx_deint_output_port, false) || !EnablePort(omx_vid_sched, omx_shed_input_port, false))
1652     {
1653       logger->debug(TAG, "Enable Ports OMX deint shed failed");
1654       clock_mutex.unlock();
1655       DeAllocateCodecsOMX();
1656       return 0;
1657     }
1658
1659     if (!CommandFinished(omx_vid_deint, OMX_CommandPortEnable, omx_deint_output_port) || !CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_input_port))
1660     {
1661       clock_mutex.unlock();
1662       DeAllocateCodecsOMX();
1663       return 0;
1664     }
1665   }
1666
1667   if (!ChangeComponentState(omx_vid_dec, OMX_StateExecuting))
1668   {
1669     logger->debug(TAG, "omx_vid_dec ChangeComponentState Execute");
1670     clock_mutex.unlock();
1671     DeAllocateCodecsOMX();
1672     return 0;
1673   }
1674
1675   error = OMX_SetupTunnel(omx_vid_sched, omx_shed_output_port, omx_vid_rend, omx_rend_input_port);
1676
1677   if (error != OMX_ErrorNone)
1678   {
1679     logger->debug(TAG, "OMX_Setup tunnel sched to rend failed {:#x}", error);
1680     clock_mutex.unlock();
1681     DeAllocateCodecsOMX();
1682     return 0;
1683   }
1684
1685   if (!EnablePort(omx_vid_sched, omx_shed_output_port, false) || !EnablePort(omx_vid_rend, omx_rend_input_port, false))
1686   {
1687     logger->debug(TAG, "Enable Ports OMX shed rend failed");
1688     clock_mutex.unlock();
1689     DeAllocateCodecsOMX();
1690     return 0;
1691   }
1692
1693   if (!CommandFinished(omx_vid_sched, OMX_CommandPortEnable, omx_shed_output_port)
1694       || !CommandFinished(omx_vid_rend, OMX_CommandPortEnable, omx_rend_input_port))
1695   {
1696     clock_mutex.unlock();
1697     DeAllocateCodecsOMX();
1698     return 0;
1699   }
1700
1701   if (!ChangeComponentState(omx_vid_rend, OMX_StateIdle))
1702   {
1703     logger->debug(TAG, "vid_rend ChangeComponentState");
1704     clock_mutex.unlock();
1705     DeAllocateCodecsOMX();
1706     return 0;
1707   }
1708
1709   if (dodeint)
1710   {
1711     if (!ChangeComponentState(omx_vid_deint, OMX_StateExecuting))
1712     {
1713       logger->debug(TAG, "vid_vid_deint ChangeComponentState");
1714       clock_mutex.unlock();
1715       DeAllocateCodecsOMX();
1716       return 0;
1717     }
1718
1719     DisablePort(omx_vid_deint, omx_deint_output_port, false);
1720     DisablePort(omx_vid_deint, omx_deint_input_port, false);
1721   }
1722
1723   if (!ChangeComponentState(omx_vid_sched, OMX_StateExecuting))
1724   {
1725     logger->debug(TAG, "omx_vid_sched ChangeComponentState Execute");
1726     clock_mutex.unlock();
1727     DeAllocateCodecsOMX();
1728     return 0;
1729   }
1730
1731   if (!ChangeComponentState(omx_vid_rend, OMX_StateExecuting))
1732   {
1733     logger->debug(TAG, "omx_vid_rend ChangeComponentState Execute");
1734     clock_mutex.unlock();
1735     DeAllocateCodecsOMX();
1736     return 0;
1737   }
1738
1739   //raspbi specifif
1740   /*OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1741   memset(&dispconf,0,sizeof(dispconf));
1742   dispconf.nSize=sizeof(dispconf);
1743   dispconf.nVersion.nVersion=OMX_VERSION;
1744
1745   dispconf.nPortIndex=omx_rend_input_port;
1746
1747   dispconf.set=OMX_DISPLAY_SET_LAYER ;
1748   dispconf.layer=1;
1749   error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1750   if (error!=OMX_ErrorNone){
1751         logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1752         clock_mutex.unlock();
1753         DeAllocateCodecsOMX();
1754         return 0;
1755   }*/
1756
1757   /*    dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1758         dispconf.fullscreen=OMX_FALSE;
1759         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1760         if (error!=OMX_ErrorNone){
1761                 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1762                 clock_mutex.unlock();
1763                 DeAllocateCodecsOMX();
1764                 return 0;
1765         }
1766
1767         dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1768         dispconf.dest_rect.x_offset=100;
1769         dispconf.dest_rect.y_offset=100;
1770         dispconf.dest_rect.width=640;
1771         dispconf.dest_rect.height=480;
1772         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1773         if (error!=OMX_ErrorNone){
1774                 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1775                 clock_mutex.unlock();
1776                 DeAllocateCodecsOMX();
1777                 return 0;
1778         }*/
1779
1780
1781   //playbacktimeoffset=-GetCurrentSystemTime();
1782
1783   iframemode = false;
1784   omx_running = true;
1785   clock_mutex.unlock();
1786   clockUnpause();
1787   updateMode();
1788
1789   setClockExecutingandRunning();
1790
1791   return 1;
1792 }
1793
1794 int VideoOMX::idleClock()
1795 {
1796   //OMX_ERRORTYPE error;
1797   OMX_STATETYPE temp_state;
1798   clock_mutex.lock();
1799   OMX_GetState(omx_clock, &temp_state);
1800
1801   if (temp_state != OMX_StateIdle)
1802   {
1803     if (!ChangeComponentState(omx_clock, OMX_StateIdle))
1804     {
1805       logger->debug(TAG, "omx_clock ChangeComponentState Idle failed");
1806       clock_mutex.unlock();
1807       return 0;
1808     }
1809   }
1810
1811   clock_mutex.unlock();
1812   return 1;
1813 }
1814
1815 int VideoOMX::setClockExecutingandRunning()
1816 {
1817   OMX_ERRORTYPE error;
1818   OMX_STATETYPE temp_state;
1819   clock_mutex.lock();
1820   OMX_GetState(omx_clock, &temp_state);
1821
1822   if (temp_state != OMX_StateExecuting)
1823   {
1824     if (!ChangeComponentState(omx_clock, OMX_StateExecuting))
1825     {
1826       logger->debug(TAG, "omx_clock ChangeComponentState Execute failed");
1827       clock_mutex.unlock();
1828       DeAllocateCodecsOMX();
1829       return 0;
1830     }
1831   }
1832
1833   OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1834   memset(&clock_conf, 0, sizeof(clock_conf));
1835   clock_conf.nSize = sizeof(clock_conf);
1836   clock_conf.nVersion.nVersion = OMX_VERSION;
1837   clock_conf.eState = OMX_TIME_ClockStateRunning;
1838   error = OMX_SetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf);
1839
1840   if (error != OMX_ErrorNone)
1841   {
1842     logger->debug(TAG, "Clock IndexConfigTimeClockState failed {:#x}", error);
1843     clock_mutex.unlock();
1844     DeAllocateCodecsOMX();
1845     return 0;
1846   }
1847
1848   clock_mutex.unlock();
1849   return 1;
1850 }
1851
1852 int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle, OMX_STATETYPE type, bool wait) //needs to be called with locked mutex
1853 {
1854   OMX_ERRORTYPE error;
1855   error = OMX_SendCommand(handle, OMX_CommandStateSet, type, 0);
1856
1857   if (error != OMX_ErrorNone)
1858   {
1859     logger->debug(TAG, "handle {:#x} Send Command to OMX State {:#x} {:#x}", handle, type, error);
1860     return 0;
1861   }
1862
1863   if (wait)
1864   {
1865     if (!CommandFinished(handle, OMX_CommandStateSet, type)) return 0;
1866   }
1867
1868   return 1;
1869 }
1870
1871
1872 int VideoOMX::EnablePort(OMX_HANDLETYPE handle, OMX_U32 port, bool wait) //needs to be called with locked mutex
1873 {
1874   OMX_ERRORTYPE error;
1875   bool skip = false;
1876
1877   OMX_PARAM_PORTDEFINITIONTYPE pdt;
1878   memset(&pdt, 0, sizeof(pdt));
1879   pdt.nSize = sizeof(pdt);
1880   pdt.nVersion.nVersion = OMX_VERSION;
1881   pdt.nPortIndex = port;
1882   error = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &pdt);
1883
1884   if (error == OMX_ErrorNone)
1885   {
1886     if (pdt.bEnabled == OMX_TRUE)
1887     {
1888       skip = true; //already disabled;
1889     }
1890   }
1891
1892   if (!skip)
1893   {
1894     error = OMX_SendCommand(handle, OMX_CommandPortEnable, port, 0);
1895
1896     if (error != OMX_ErrorNone)
1897     {
1898       logger->debug(TAG, "handle {:#x} Send Command to enable port {:#x} {:#x}", handle, port, error);
1899       return 0;
1900     }
1901
1902     if (!wait) return 1;
1903
1904     if (!CommandFinished(handle, OMX_CommandPortEnable, port))
1905     {
1906       return 0;
1907     }
1908   }
1909
1910   return 1;
1911 }
1912
1913 int VideoOMX::DisablePort(OMX_HANDLETYPE handle, OMX_U32 port, bool wait) //needs to be called with locked mutex
1914 {
1915   OMX_ERRORTYPE error;
1916   bool skip = false;
1917
1918   OMX_PARAM_PORTDEFINITIONTYPE pdt;
1919   memset(&pdt, 0, sizeof(pdt));
1920   pdt.nSize = sizeof(pdt);
1921   pdt.nVersion.nVersion = OMX_VERSION;
1922   pdt.nPortIndex = port;
1923   error = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &pdt);
1924
1925   if (error == OMX_ErrorNone)
1926   {
1927     if (pdt.bEnabled == OMX_FALSE)
1928     {
1929       skip = true; //already disabled;
1930     }
1931   }
1932
1933   if (!skip)
1934   {
1935     error = OMX_SendCommand(handle, OMX_CommandPortDisable, port, 0);
1936
1937     if (error != OMX_ErrorNone)
1938     {
1939       logger->debug(TAG, "handle {:#x} Send Command to disable port {:#x} {:#x}", handle, port, error);
1940       return 0;
1941     }
1942
1943     if (!wait) return 1;
1944
1945     if (!CommandFinished(handle, OMX_CommandPortDisable, port))
1946     {
1947       return 0;
1948     }
1949   }
1950
1951   return 1;
1952 }
1953
1954 int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle, OMX_U32 event, int wait) //needs to be called with locked mutex
1955 {
1956   int i = 0;
1957   int iend = (wait / 5 + 1);
1958
1959   while (i < iend)
1960   {
1961     omx_event_mutex.lock();
1962     std::list<VPE_OMX_EVENT>::iterator itty = omx_events.begin();
1963
1964     while (itty != omx_events.end())
1965     {
1966       VPE_OMX_EVENT current = *itty;
1967
1968       if (current.handle == handle) //this is ours
1969       {
1970         if (current.event_type == OMX_EventError)
1971         {
1972           omx_events.erase(itty);
1973           omx_event_mutex.unlock();
1974           logger->debug(TAG, "WaitForEvent Finished on Error");
1975           return 0;
1976         }
1977         else if (current.event_type == event)
1978         {
1979           omx_events.erase(itty);
1980           omx_event_mutex.unlock();
1981           logger->debug(TAG, "WaitForEvent Finished Completed");
1982           return 1;
1983         }
1984       }
1985
1986       itty++;
1987     }
1988
1989     omx_event_mutex.unlock();
1990
1991     //logger->debug(TAG, "WaitForEvent");
1992     std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
1993     omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
1994     ul.unlock();
1995
1996     i++;
1997   }
1998
1999   logger->debug(TAG, "WaitForEvent waited too long {:p} {:#x}", (void*)handle, event);
2000   return 0;
2001 }
2002
2003 int VideoOMX::clearEvents()
2004 {
2005   omx_event_mutex.lock();
2006   omx_events.clear();
2007   omx_event_mutex.unlock();
2008
2009   return 1;
2010 }
2011
2012 int VideoOMX::clearEventsForComponent(OMX_HANDLETYPE handle)
2013 {
2014   omx_event_mutex.lock();
2015   std::list<VPE_OMX_EVENT>::iterator itty = omx_events.begin();
2016
2017   while (itty != omx_events.end())
2018   {
2019     VPE_OMX_EVENT current = *itty;
2020
2021     if (current.handle == handle) //this is ours
2022     {
2023       itty = omx_events.erase(itty);
2024       continue;
2025     }
2026
2027     itty++;
2028   }
2029
2030   omx_event_mutex.unlock();
2031   return 1;
2032 }
2033
2034 void VideoOMX::checkForStalledBuffers()
2035 {
2036   //logger->debug(TAG, "Check stalled");
2037   clock_mutex.lock();
2038   omx_event_mutex.lock();
2039   std::list<VPE_OMX_EVENT>::iterator itty = omx_events.begin();
2040
2041   while (itty != omx_events.end())
2042   {
2043     VPE_OMX_EVENT current = *itty;
2044
2045     if (current.event_type == OMX_EventParamOrConfigChanged && current.data1 == omx_codec_output_port
2046         && current.handle == omx_vid_dec && current.data2 == OMX_IndexConfigBufferStall)
2047     {
2048       OMX_ERRORTYPE error;
2049       OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
2050       memset(&stall_conf, 0, sizeof(stall_conf));
2051       stall_conf.nSize = sizeof(stall_conf);
2052       stall_conf.nVersion.nVersion = OMX_VERSION;
2053       stall_conf.nPortIndex = omx_codec_output_port;
2054       stall_conf.nDelay = 200000;
2055
2056       error = OMX_GetConfig(omx_vid_dec, OMX_IndexConfigBufferStall, &stall_conf);
2057
2058       if (error != OMX_ErrorNone)
2059       {
2060         logger->debug(TAG, "Get OMX_IndexConfigBufferStall failed {:#x}", error);
2061         clock_mutex.unlock();
2062         omx_event_mutex.unlock();
2063         return ;
2064       }
2065
2066       if (stall_conf.bStalled == OMX_TRUE)
2067       {
2068         omx_vid_stalled = true;
2069         logger->debug(TAG, "Video decoder stalled! {}", stall_conf.nDelay);
2070       }
2071       else
2072       {
2073         omx_vid_stalled = false;
2074         logger->debug(TAG, "Video decoder unstalled! {}", stall_conf.nDelay);
2075       }
2076
2077       omx_events.erase(itty);
2078       break;
2079     }
2080
2081     itty++;
2082   }
2083
2084   omx_event_mutex.unlock();
2085   clock_mutex.unlock();
2086 }
2087
2088 int VideoOMX::CommandFinished(OMX_HANDLETYPE handle, OMX_U32 command, OMX_U32 data2) //needs to be called with locked mutex
2089 {
2090   int i = 0;
2091
2092   while (i < 200/*1000*/)
2093   {
2094     omx_event_mutex.lock();
2095     std::list<VPE_OMX_EVENT>::iterator itty = omx_events.begin();
2096
2097     while (itty != omx_events.end())
2098     {
2099       VPE_OMX_EVENT current = *itty;
2100
2101       if (current.handle == handle) //this is ours
2102       {
2103         if (current.event_type == OMX_EventError)
2104         {
2105           omx_events.erase(itty);
2106           omx_event_mutex.unlock();
2107           logger->debug(TAG, "Command Finished on Error {:#x}", current.data1);
2108           return 0;
2109         }
2110         else if (current.event_type == OMX_EventCmdComplete && current.data1 == command && current.data2 == data2)
2111         {
2112           omx_events.erase(itty);
2113           omx_event_mutex.unlock();
2114           //logger->debug(TAG, "Command Finished Completed");
2115           return 1;
2116         }
2117       }
2118
2119       itty++;
2120     }
2121
2122     omx_event_mutex.unlock();
2123
2124     std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
2125     omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
2126     ul.unlock();
2127
2128     i++;
2129   }
2130
2131   logger->debug(TAG, "CommandFinished waited too long {:#x} {:#x} {:#x}", handle, command, data2);
2132   return 0;
2133 }
2134
2135 int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex
2136 {
2137   OMX_ERRORTYPE error;
2138   OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
2139   memset(&port_def_type, 0, sizeof(port_def_type));
2140   port_def_type.nSize = sizeof(port_def_type);
2141   port_def_type.nVersion.nVersion = OMX_VERSION;
2142   port_def_type.nPortIndex = omx_codec_input_port;
2143
2144   error = OMX_GetParameter(omx_vid_dec, OMX_IndexParamPortDefinition, &port_def_type);
2145
2146   if (error != OMX_ErrorNone)
2147   {
2148     logger->debug(TAG, "Get OMX OMX_IndexParamPortDefinition failed {:#x}", error);
2149   }
2150
2151   /*    logger->debug(TAG, "Port para {} {} {} {} {} {} {}", port_def_type.nBufferCountActual,
2152                         port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
2153                         port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
2154
2155   port_def_type.nBufferCountActual = 100;
2156   port_def_type.nBufferSize = std::max(toi4(port_def_type.nBufferSize), 150000); // for transcoder important
2157
2158   error = OMX_SetParameter(omx_vid_dec, OMX_IndexParamPortDefinition, &port_def_type);
2159
2160   if (error != OMX_ErrorNone)
2161   {
2162     logger->debug(TAG, "Set OMX OMX_IndexParamPortDefinition failed {:#x}", error);
2163   }
2164
2165   error = OMX_SendCommand(omx_vid_dec, OMX_CommandPortEnable, omx_codec_input_port, 0);
2166
2167   if (error != OMX_ErrorNone)
2168   {
2169     logger->debug(TAG, "Prepare Input bufs Send Command to enable port {:#x}", error);
2170     return 0;
2171   }
2172
2173   input_bufs_omx_mutex.lock();
2174
2175   for (unsigned int i = 0; i < port_def_type.nBufferCountActual; i++)
2176   {
2177     //  unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
2178     OMX_BUFFERHEADERTYPE* buf_head = NULL;
2179     /*  error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
2180         if (error!=OMX_ErrorNone){
2181                 logger->debug(TAG, "Use OMX_Usebuffer failed {:#x}", error);
2182                 input_bufs_omx_mutex.unlock();
2183                 return 0;
2184         }*/
2185     error = OMX_AllocateBuffer(omx_vid_dec, &buf_head, omx_codec_input_port, NULL, port_def_type.nBufferSize);
2186
2187     if (error != OMX_ErrorNone)
2188     {
2189       logger->debug(TAG, "Use OMX_AllocateBuffer failed {:#x}", error);
2190       input_bufs_omx_mutex.unlock();
2191       return 0;
2192     }
2193
2194     input_bufs_omx_all.push_back(buf_head);
2195     input_bufs_omx_free.push_back(buf_head);
2196   }
2197
2198   omx_first_frame = true;
2199
2200   firstsynched = false;
2201   cur_input_buf_omx = NULL;
2202   input_bufs_omx_mutex.unlock();
2203
2204   logger->debug(TAG, "PrepareInputBufsOMX mark3");
2205
2206   if (!CommandFinished(omx_vid_dec, OMX_CommandPortEnable, omx_codec_input_port))
2207   {
2208     return 0;
2209   }
2210
2211   logger->debug(TAG, "PrepareInputBufsOMX mark4");
2212
2213   return 1;
2214 }
2215
2216 int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex
2217 {
2218   OMX_ERRORTYPE error;
2219
2220   cur_input_buf_omx = NULL;
2221   input_bufs_omx_mutex.lock();
2222
2223   for (u4 i = 0; i < input_bufs_omx_all.size(); i++)
2224   {
2225     //  free(input_bufs_omx_all[i]->pBuffer);
2226     //  input_bufs_omx_all[i]->pBuffer=NULL;
2227     error = OMX_FreeBuffer(omx_vid_dec, omx_codec_input_port, input_bufs_omx_all[i]);
2228
2229     if (error != OMX_ErrorNone)
2230     {
2231       logger->debug(TAG, "Use OMX_FreeBuffer failed {:#x}", error);
2232       input_bufs_omx_mutex.unlock();
2233       return 0;
2234     }
2235
2236   }
2237
2238   input_bufs_omx_all.clear();
2239   input_bufs_omx_free.clear();
2240   input_bufs_omx_mutex.unlock();
2241
2242   return 1;
2243 }
2244
2245 int VideoOMX::FlushRenderingPipe()
2246 {
2247   OMX_ERRORTYPE error;
2248
2249   if (!dodeint)
2250   {
2251     error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port, NULL);
2252
2253     if (error != OMX_ErrorNone)
2254     {
2255       logger->debug(TAG, "OMX_Flush codec out 1 failed {:#x}", error);
2256     }
2257
2258     error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port, NULL);
2259
2260     if (error != OMX_ErrorNone)
2261     {
2262       logger->debug(TAG, "OMX_Flush shed in 2 failed {:#x}", error);
2263     }
2264
2265     if (!CommandFinished(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port))
2266     {
2267       logger->debug(TAG, "flush cmd codec  3 failed");
2268     }
2269
2270     if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port))
2271     {
2272       logger->debug(TAG, "flush cmd shed 4 failed");
2273     }
2274   }
2275   else
2276   {
2277     error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port, NULL);
2278
2279     if (error != OMX_ErrorNone)
2280     {
2281       logger->debug(TAG, "OMX_Flush codec out 5 failed {:#x}", error);
2282     }
2283
2284     error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush, omx_deint_input_port, NULL);
2285
2286     if (error != OMX_ErrorNone)
2287     {
2288       logger->debug(TAG, "OMX_Flush deint in 6 failed {:#x}", error);
2289     }
2290
2291     if (!CommandFinished(omx_vid_dec, OMX_CommandFlush, omx_codec_output_port))
2292     {
2293       logger->debug(TAG, "flush cmd codec 7 failed");
2294     }
2295
2296     if (!CommandFinished(omx_vid_deint, OMX_CommandFlush, omx_deint_input_port))
2297     {
2298       logger->debug(TAG, "flush cmd deint 8 failed");
2299     }
2300
2301     //m
2302     error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush, omx_deint_output_port, NULL);
2303
2304     if (error != OMX_ErrorNone)
2305     {
2306       logger->debug(TAG, "OMX_Flush deint out 9 failed {:#x}", error);
2307     }
2308
2309     error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port, NULL);
2310
2311     if (error != OMX_ErrorNone)
2312     {
2313       logger->debug(TAG, "OMX_Flush shed in 10 failed {:#x}", error);
2314     }
2315
2316     if (!CommandFinished(omx_vid_deint, OMX_CommandFlush, omx_deint_output_port))
2317     {
2318       logger->debug(TAG, "flush cmd deint 11 failed");
2319     }
2320
2321     if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_input_port))
2322     {
2323       logger->debug(TAG, "flush cmd shed 12 failed");
2324     }
2325   }
2326
2327   error = OMX_SendCommand(omx_vid_rend, OMX_CommandFlush, omx_rend_input_port, NULL);
2328
2329   if (error != OMX_ErrorNone)
2330   {
2331     logger->debug(TAG, "OMX_Flush rend in failed {:#x}", error);
2332
2333   }
2334
2335   error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_output_port, NULL);
2336
2337   if (error != OMX_ErrorNone)
2338   {
2339     logger->debug(TAG, "OMX_Flush shed out failed {:#x}", error);
2340   }
2341
2342   if (!CommandFinished(omx_vid_rend, OMX_CommandFlush, omx_rend_input_port))
2343   {
2344     logger->debug(TAG, "flush cmd shed rend failed");
2345   }
2346
2347   if (!CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_output_port))
2348   {
2349     logger->debug(TAG, "flush cmd shed rend failed");
2350   }
2351
2352   return 1;
2353 }
2354
2355 int VideoOMX::DeAllocateCodecsOMX()
2356 {
2357   OMX_ERRORTYPE error;
2358   omx_running = false;
2359   logger->debug(TAG, "enter deallocatecodecsomx");
2360
2361   if (cur_input_buf_omx)
2362   {
2363     cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_EOS;
2364     error = ProtOMXEmptyThisBuffer(omx_vid_dec, cur_input_buf_omx);
2365
2366     if (error != OMX_ErrorNone)
2367     {
2368       logger->debug(TAG, "OMX_EmptyThisBuffer failed {:#x}", error);
2369     }
2370
2371     cur_input_buf_omx = NULL; //write out old data
2372   }
2373
2374   clock_mutex.lock();
2375   clearEvents();
2376
2377   if (omx_vid_dec)
2378   {
2379     // first stop the omx elements
2380     if (!ChangeComponentState(omx_vid_dec, OMX_StateIdle))
2381     {
2382       logger->debug(TAG, "vid_dec ChangeComponentState");
2383     }
2384
2385     clock_mutex.unlock();
2386
2387     idleClock();
2388     clock_mutex.lock();
2389
2390     if (dodeint)
2391     {
2392       if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle))
2393       {
2394         logger->debug(TAG, "vid_deint ChangeComponentState");
2395       }
2396     }
2397
2398     if (!ChangeComponentState(omx_vid_sched, OMX_StateIdle))
2399     {
2400       logger->debug(TAG, "vid_shed ChangeComponentState");
2401     }
2402
2403     if (!ChangeComponentState(omx_vid_rend, OMX_StateIdle))
2404     {
2405       logger->debug(TAG, "vid_rend ChangeComponentState");
2406     }
2407
2408     // TODO proper deinit sequence
2409     // first flush all buffers
2410     FlushRenderingPipe();
2411
2412     error = OMX_SendCommand(omx_clock, OMX_CommandFlush, omx_clock_output_port, NULL);
2413
2414     if (error != OMX_ErrorNone)
2415     {
2416       logger->debug(TAG, "OMX_Flush clock out failed {:#x}", error);
2417     }
2418
2419     error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush, omx_shed_clock_port, NULL);
2420
2421     if (error != OMX_ErrorNone)
2422     {
2423       logger->debug(TAG, "OMX_Flush shed clock failed {:#x}", error);
2424     }
2425
2426     if (!CommandFinished(omx_clock, OMX_CommandFlush, omx_clock_output_port) ||
2427         !CommandFinished(omx_vid_sched, OMX_CommandFlush, omx_shed_clock_port))
2428     {
2429       logger->debug(TAG, "flush cmd clock shed failed");
2430     }
2431
2432     error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2433                             omx_codec_input_port, NULL);
2434
2435     if (error != OMX_ErrorNone)
2436     {
2437       logger->debug(TAG, "OMX_Flush codec out failed {:#x}", error);
2438     }
2439
2440     DestroyInputBufsOMX();
2441
2442     //todo flushing
2443     if (!DisablePort(omx_vid_sched, omx_shed_output_port, true))
2444     {
2445       logger->debug(TAG, "Disable Tunnel Port failed 2");
2446     }
2447
2448     if (!DisablePort(omx_vid_rend, omx_rend_input_port, true))
2449     {
2450       logger->debug(TAG, "Disable Tunnel Port failed 1");
2451     }
2452
2453     if (!DisablePort(omx_vid_dec, omx_codec_output_port, true))
2454     {
2455       logger->debug(TAG, "Disable Tunnel Port failed 6");
2456     }
2457
2458     if (!DisablePort(omx_vid_dec, omx_codec_input_port, true))
2459     {
2460       logger->debug(TAG, "Disable Tunnel Port failed 7");
2461     }
2462
2463     if (dodeint)
2464     {
2465       if (!DisablePort(omx_vid_deint, omx_deint_output_port, true))
2466       {
2467         logger->debug(TAG, "Disable Tunnel Port failed 6a");
2468       }
2469
2470       if (!DisablePort(omx_vid_deint, omx_deint_input_port, true))
2471       {
2472         logger->debug(TAG, "Disable Tunnel Port failed 7a");
2473       }
2474     }
2475
2476     if (!DisablePort(omx_vid_sched, omx_shed_input_port, true))
2477     {
2478       logger->debug(TAG, "Disable Tunnel Port failed 3");
2479     }
2480
2481     if (!DisablePort(omx_vid_sched, omx_shed_clock_port, true))
2482     {
2483       logger->debug(TAG, "Disable Tunnel Port failed 4");
2484     }
2485
2486     if (!DisablePort(omx_clock, omx_clock_output_port, true))
2487     {
2488       logger->debug(TAG, "Disable Tunnel Port failed 5");
2489     }
2490
2491     error = OMX_SetupTunnel(omx_vid_dec, omx_codec_output_port, NULL, 0);
2492
2493     if (error != OMX_ErrorNone)
2494     {
2495       logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2496     }
2497
2498     if (dodeint)
2499     {
2500       error = OMX_SetupTunnel(omx_vid_deint, omx_deint_input_port, NULL, 0);
2501
2502       if (error != OMX_ErrorNone)
2503       {
2504         logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2505       }
2506
2507       error = OMX_SetupTunnel(omx_vid_deint, omx_deint_output_port, NULL, 0);
2508
2509       if (error != OMX_ErrorNone)
2510       {
2511         logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2512       }
2513     }
2514
2515     error = OMX_SetupTunnel(omx_vid_sched, omx_shed_input_port, NULL, 0);
2516
2517     if (error != OMX_ErrorNone)
2518     {
2519       logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2520     }
2521
2522     error = OMX_SetupTunnel(omx_vid_sched, omx_shed_output_port, NULL, 0);
2523
2524     if (error != OMX_ErrorNone)
2525     {
2526       logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2527     }
2528
2529     error = OMX_SetupTunnel(omx_vid_rend, omx_rend_input_port, NULL, 0);
2530
2531     if (error != OMX_ErrorNone)
2532     {
2533       logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2534     }
2535
2536     error = OMX_SetupTunnel(omx_clock, omx_clock_output_port, NULL, 0);
2537
2538     if (error != OMX_ErrorNone)
2539     {
2540       logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2541     }
2542
2543     error = OMX_SetupTunnel(omx_vid_sched, omx_shed_clock_port, NULL, 0);
2544
2545     if (error != OMX_ErrorNone)
2546     {
2547       logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2548     }
2549
2550     error = OMX_FreeHandle(omx_vid_dec);
2551     error = OMX_FreeHandle(omx_vid_sched);
2552     error = OMX_FreeHandle(omx_vid_rend);
2553
2554     if (dodeint) error = OMX_FreeHandle(omx_vid_deint);
2555
2556     omx_vid_dec = NULL;
2557     omx_vid_stalled = false;
2558     clock_mutex.unlock();
2559     destroyClock();
2560
2561     if (error != OMX_ErrorNone)
2562     {
2563       logger->debug(TAG, "FreeHandle failed {}", error);
2564     }
2565   }
2566   else
2567     clock_mutex.unlock();
2568
2569   logger->debug(TAG, "leave deallocate codecs OMX");
2570
2571   return 1;
2572 }
2573
2574 void VideoOMX::destroyClock()
2575 {
2576   clock_mutex.lock();
2577
2578   if (clock_references > 0)
2579   {
2580     clock_references--;
2581
2582     if (clock_references == 0)
2583     {
2584       OMX_ERRORTYPE error;
2585       logger->debug(TAG, "destroy omx clock");
2586       error = OMX_FreeHandle(omx_clock);
2587
2588       if (error != OMX_ErrorNone)
2589       {
2590         logger->debug(TAG, "FreeHandle failed {}", error);
2591       }
2592     }
2593   }
2594
2595   clock_mutex.unlock();
2596 }
2597
2598 int VideoOMX::stop()
2599 {
2600   if (!initted) return 0;
2601
2602   iframemode = false;
2603
2604   //Check if libav mode
2605   DeAllocateCodecsOMX();
2606
2607   //  if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2608   return 1;
2609 }
2610
2611 int VideoOMX::reset()
2612 {
2613   if (!initted) return 0;
2614
2615   iframemode = false;
2616   DeAllocateCodecsOMX();
2617   //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2618   return 1;
2619 }
2620
2621 int VideoOMX::pause()
2622 {
2623   if (!initted) return 0;
2624
2625   logger->debug(TAG, "enter pause");
2626   // clockPause();
2627   // ignore it audio handles this
2628   return 1;
2629 }
2630
2631 int VideoOMX::unPause() // FIXME get rid - same as play!! Not here!
2632 {
2633   if (!initted) return 0;
2634
2635   logger->debug(TAG, "enter unpause");
2636
2637   //clockUnpause();
2638   //ignore it audio handles this
2639
2640   return 1;
2641 }
2642
2643 int VideoOMX::fastForward()
2644 {
2645   if (!initted) return 0;
2646
2647   //  if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2648   return 1;
2649 }
2650
2651 int VideoOMX::unFastForward()
2652 {
2653   if (!initted) return 0;
2654
2655   //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2656
2657   //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2658   return 1;
2659 }
2660
2661 int VideoOMX::attachFrameBuffer()
2662 {
2663   if (!initted) return 0;
2664
2665   //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2666   return 1;
2667 }
2668
2669 int VideoOMX::blank(void)
2670 {
2671   //  if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2672   //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2673   return 1;
2674 }
2675
2676 u8 VideoOMX::getCurrentTimestamp()
2677 {
2678   if (iframemode)
2679     return 0;
2680
2681   long long ncur_clock_time = cur_clock_time;
2682
2683   if (omx_running)
2684   {
2685     int oldcancelstate;
2686     int oldcanceltype;
2687     pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2688     pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2689     clock_mutex.lock();
2690     OMX_ERRORTYPE error;
2691     OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
2692     memset(&clock_conf, 0, sizeof(clock_conf));
2693     clock_conf.nSize = sizeof(clock_conf);
2694     clock_conf.nVersion.nVersion = OMX_VERSION;
2695     error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeClockState, &clock_conf);
2696
2697     if (error != OMX_ErrorNone)
2698     {
2699       logger->debug(TAG, "getCurrentTimestamp IndexConfigTimeClockState failed {:#x}", error);
2700     }
2701
2702     if (clock_conf.eState == OMX_TIME_ClockStateRunning)
2703     {
2704       OMX_TIME_CONFIG_TIMESTAMPTYPE cur_time_stamp;
2705       memset(&cur_time_stamp, 0, sizeof(cur_time_stamp));
2706       cur_time_stamp.nSize = sizeof(cur_time_stamp);
2707       cur_time_stamp.nVersion.nVersion = OMX_VERSION;
2708       cur_time_stamp.nPortIndex = omx_clock_output_port;
2709       error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime, &cur_time_stamp);
2710
2711       if (error != OMX_ErrorNone)
2712       {
2713         logger->debug(TAG, "getCurrentTimestamp OMX_IndexConfigTimeCurrentMediaTime failed {:#x}", error);
2714       }
2715       else
2716       {
2717         long long temp = cur_time_stamp.nTimestamp.nLowPart
2718                          | ((long long) cur_time_stamp.nTimestamp.nHighPart << 32);
2719         ncur_clock_time = cur_clock_time = temp * 10LL;
2720       }
2721     }
2722
2723     clock_mutex.unlock();
2724     pthread_setcancelstate(oldcancelstate, NULL);
2725     pthread_setcanceltype(oldcanceltype, NULL);
2726   }
2727
2728   //ncur_clock_time -= startoffset;
2729   ncur_clock_time -= lastreftimeOMX;
2730   long long result = lastreftimePTS;
2731
2732   if (lastreftimePTS == 0) return 0; // invalid time
2733
2734   result += (long long) (ncur_clock_time / 10000LL * 90LL);
2735
2736   if (result < 0)
2737     result = (1LL << 33) - result;
2738
2739   //logger->debug(TAG,"getCurrentTimestamp {} {} {} {} {} {}",ncur_clock_time,cur_clock_time,lastreftimeOMX,lastreftimePTS,result,startoffset);
2740
2741   return result;
2742
2743 }
2744
2745 // to be removed
2746 /*
2747 u4 VideoOMX::timecodeToFrameNumber(u8 timecode)
2748 {
2749   if (format == PAL) return (u4)(((double)timecode / (double)90000) * (double)25);
2750   else               return (u4)(((double)timecode / (double)90000) * (double)30);
2751 }
2752
2753 */
2754 #ifdef DEV
2755 int VideoOMX::test()
2756 {
2757   return 0;
2758
2759   //  u8 stc = 0;
2760   //  return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2761   /*
2762    // reset();
2763     return 1;
2764   */
2765 }
2766
2767 int VideoOMX::test2()
2768 {
2769   return 0;
2770 }
2771 #endif
2772
2773 long long VideoOMX::SetStartOffset(long long curreftime, bool* rsync)
2774 {
2775   *rsync = false;
2776
2777   if (offsetnotset)
2778   {
2779     startoffset = curreftime; //offset is set for audio
2780     offsetnotset = false;
2781     offsetvideonotset = false;
2782   }
2783   else
2784   {
2785     if (offsetvideonotset)
2786     {
2787       offsetvideonotset = false;
2788       *rsync = true;
2789     }
2790     else
2791     {
2792       if ( (curreftime - lastrefvideotime) > 10000000LL
2793            || (curreftime - lastrefvideotime) < -10000000LL) //if pts jumps to big resync
2794       {
2795         startoffset += curreftime - lastrefvideotime;
2796         lastrefaudiotime += curreftime - lastrefvideotime;
2797         //*rsync=true;
2798         offsetaudionotset = true;
2799       }
2800     }
2801   }
2802
2803   lastrefvideotime = curreftime;
2804
2805   return startoffset;
2806 }
2807
2808 long long VideoOMX::SetStartAudioOffset(long long curreftime, bool* rsync)
2809 {
2810   *rsync = false;
2811
2812   if (offsetnotset)
2813   {
2814     startoffset = curreftime;
2815     offsetnotset = false;
2816     offsetaudionotset = false;
2817   }
2818   else
2819   {
2820     if (offsetaudionotset)
2821     {
2822       offsetaudionotset = false;
2823       *rsync = true;
2824     }
2825     else
2826     {
2827       if ( (curreftime - lastrefaudiotime) > 10000000LL
2828            || (curreftime - lastrefaudiotime) < -10000000LL) //if pts jumps to big resync
2829       {
2830         startoffset += curreftime - lastrefaudiotime;
2831         lastrefvideotime += curreftime - lastrefaudiotime;
2832         //*rsync=true;
2833         offsetvideonotset = true;
2834       }
2835     }
2836   }
2837
2838   lastrefaudiotime = curreftime;
2839   return startoffset;
2840 }
2841
2842 void VideoOMX::ResetTimeOffsets()
2843 {
2844   offsetnotset = true; //called from demuxer
2845   offsetvideonotset = true;
2846   offsetaudionotset = true;
2847   startoffset = 0;
2848   lastrefaudiotime = 0;
2849   lastrefvideotime = 0;
2850   lastreftimeOMX = 0;
2851   lastreftimePTS = 0;
2852 }
2853
2854 void VideoOMX::FirstFrameFix()
2855 {
2856   int oldcancelstate;
2857   int oldcanceltype;
2858   Demuxer* demux = Demuxer::getInstance();
2859   pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2860   pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2861   clock_mutex.lock();
2862
2863   if (WaitForEvent(omx_vid_dec, OMX_EventPortSettingsChanged, 0))
2864   {
2865     WaitForEvent(omx_vid_deint, OMX_EventPortSettingsChanged, 0); //clear old messages
2866     OMX_ERRORTYPE error;
2867     OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
2868     memset(&port_def_type, 0, sizeof(port_def_type));
2869     port_def_type.nSize = sizeof(port_def_type);
2870     port_def_type.nVersion.nVersion = OMX_VERSION;
2871     port_def_type.nPortIndex = omx_codec_output_port;
2872
2873     error = OMX_GetParameter(omx_vid_dec, OMX_IndexParamPortDefinition, &port_def_type);
2874
2875     if (error != OMX_ErrorNone)
2876     {
2877       logger->debug(TAG, "OMX_IndexParamPortDefinition fix failed {:#x}", error);
2878       clock_mutex.unlock();
2879       return;
2880     }
2881
2882     logger->debug(TAG,
2883                   "Deinit first frame fix {} {} {} {} {} {} {} {}", port_def_type.format.video.nFrameWidth, demux->getHorizontalSize(),
2884                   port_def_type.format.video.nFrameHeight, demux->getVerticalSize(), port_def_type.format.video.nStride,
2885                   port_def_type.format.video.nSliceHeight, port_def_type.format.video.xFramerate,
2886                   port_def_type.format.video.bFlagErrorConcealment );
2887     logger->debug(TAG,
2888                   "Deinit first frame fix2 {}  {}",
2889                   port_def_type.format.video.eCompressionFormat,
2890                   port_def_type.format.video.eColorFormat );
2891     first_frame = false;
2892
2893     // we cause the video_decode to determine the interlacing properties
2894     OMX_CONFIG_INTERLACETYPE il;
2895     memset(&il, 0, sizeof(il));
2896     il.nSize = sizeof(il);
2897     il.nVersion.nVersion = OMX_VERSION;
2898     il.nPortIndex = omx_codec_output_port;
2899     error = OMX_GetConfig(omx_vid_dec, OMX_IndexConfigCommonInterlace, &il);
2900
2901     if (error != OMX_ErrorNone)
2902     {
2903       logger->debug(TAG, "OMX_IndexConfigCommonInterlace fix failed {:#x}", error);
2904     }
2905
2906     DisablePort(omx_vid_dec, omx_codec_output_port, true);
2907     DisablePort(omx_vid_sched, omx_shed_input_port, true);
2908
2909     if (dodeint)
2910     {
2911       DisablePort(omx_vid_deint, omx_deint_input_port, true);
2912       // This is a dirty hack
2913       DisablePort(omx_vid_deint, omx_deint_output_port, true);
2914
2915       port_def_type.nPortIndex = omx_deint_output_port;
2916       error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, &port_def_type);
2917
2918       if (error != OMX_ErrorNone)
2919       {
2920         logger->debug(TAG, "Set OMX_IndexParamPortDefinition1 failed {:#x}", error);
2921         clock_mutex.unlock();
2922         pthread_setcancelstate(oldcancelstate, NULL);
2923         pthread_setcanceltype(oldcanceltype, NULL);
2924         return;
2925       }
2926
2927       // dirty hack end
2928
2929       port_def_type.nPortIndex = omx_deint_input_port;
2930       error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, &port_def_type);
2931
2932       if (error != OMX_ErrorNone)
2933       {
2934         logger->debug(TAG, "Set OMX_IndexParamPortDefinition1 failed {:#x}", error);
2935         clock_mutex.unlock();
2936         pthread_setcancelstate(oldcancelstate, NULL);
2937         pthread_setcanceltype(oldcanceltype, NULL);
2938         return;
2939       }
2940
2941       //  WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged);
2942
2943       logger->debug(TAG, "Marker");
2944       EnablePort(omx_vid_deint, omx_deint_input_port, true);
2945       WaitForEvent(omx_vid_deint, OMX_EventPortSettingsChanged);
2946       port_def_type.nPortIndex = omx_deint_output_port;
2947       error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamPortDefinition, &port_def_type);
2948
2949       if (error != OMX_ErrorNone)
2950       {
2951         logger->debug(TAG, "Get OMX_IndexParamPortDefinition2 failed {:#x}", error);
2952         clock_mutex.unlock();
2953         pthread_setcancelstate(oldcancelstate, NULL);
2954         pthread_setcanceltype(oldcanceltype, NULL);
2955         return;
2956       }
2957
2958       logger->debug(TAG,
2959                     "Deinit first frame fix3 {} {} {} {} {} {} {} ", port_def_type.format.image.nFrameWidth, demux->getHorizontalSize(),
2960                     port_def_type.format.image.nFrameHeight, demux->getVerticalSize(), port_def_type.format.image.nStride,
2961                     port_def_type.format.image.nSliceHeight, /*port_def_type.format.image.xFramerate,*/
2962                     port_def_type.format.image.bFlagErrorConcealment );
2963       logger->debug(TAG,
2964                     "Deinit first frame fix4 {}  {}",
2965                     port_def_type.format.image.eCompressionFormat,
2966                     port_def_type.format.image.eColorFormat );
2967
2968       DisablePort(omx_vid_deint, omx_deint_output_port, true);
2969     }
2970
2971     port_def_type.nPortIndex = omx_shed_input_port;
2972     error = OMX_SetParameter(omx_vid_sched, OMX_IndexParamPortDefinition, &port_def_type);
2973
2974     if (error != OMX_ErrorNone)
2975     {
2976       logger->debug(TAG, "Set OMX_IndexParamPortDefinition3 failed {:#x}", error);
2977       clock_mutex.unlock();
2978       pthread_setcancelstate(oldcancelstate, NULL);
2979       pthread_setcanceltype(oldcanceltype, NULL);
2980       return;
2981     }
2982
2983     WaitForEvent(omx_vid_sched, OMX_EventPortSettingsChanged);
2984
2985     if (dodeint)
2986       EnablePort(omx_vid_deint, omx_deint_output_port, true);
2987
2988     EnablePort(omx_vid_dec, omx_codec_output_port, true);
2989     EnablePort(omx_vid_sched, omx_shed_input_port, true);
2990   }
2991
2992   clock_mutex.unlock();
2993   pthread_setcancelstate(oldcancelstate, NULL);
2994   pthread_setcanceltype(oldcanceltype, NULL);
2995 }
2996
2997 void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer)
2998 {
2999   OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, buffer);
3000
3001   if (error != OMX_ErrorNone)
3002   {
3003     logger->debug(TAG, "OMX_EmptyThisBuffer failed {:#x}", error);
3004   }
3005
3006   if (first_frame) FirstFrameFix();
3007 }
3008
3009 OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer)
3010 {
3011   // protect the call to empty this buffer
3012   int oldcancelstate;
3013   int oldcanceltype;
3014   /*    long long temp =buffer->nTimeStamp.nLowPart
3015                                                         | ((long long) buffer->nTimeStamp.nHighPart << 32);*/
3016
3017   //pthread_testcancel();
3018   pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
3019   pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
3020   clock_mutex.lock();
3021   // Diagnosis code
3022   /*    OMX_ERRORTYPE error;
3023         OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp;
3024         memset(&timestamp, 0, sizeof(timestamp));
3025         timestamp.nSize = sizeof(timestamp);
3026         timestamp.nVersion.nVersion = OMX_VERSION;
3027         timestamp.nPortIndex =omx_clock_output_port;
3028
3029         error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
3030                         &timestamp);
3031
3032         if (error != OMX_ErrorNone) {
3033                 logger->debug(TAG,
3034                                 "Init OMX_IndexConfigAudioRenderingLatencyfailed {:#x} {}", error,
3035                                 omx_rend_input_port);
3036         }
3037         long long temp2 =timestamp.nTimestamp.nLowPart
3038                                                                 | ((long long) timestamp.nTimestamp.nHighPart << 32);
3039
3040         logger->info(TAG, "OMXETB {:#x} {} {} {:#x}",handle,temp,temp2,buffer->nFlags);*/
3041   OMX_ERRORTYPE ret_val;
3042   ret_val = OMX_EmptyThisBuffer(handle, buffer);
3043   clock_mutex.unlock();
3044   pthread_setcancelstate(oldcancelstate, NULL);
3045   pthread_setcanceltype(oldcanceltype, NULL);
3046   //pthread_testcancel();
3047   return ret_val;
3048 }
3049
3050 bool VideoOMX::detectIFrame(const u1* buffer, unsigned int length)
3051 {
3052   const u1* curbuf = buffer;
3053   const u1* curbufend = buffer + length;
3054   unsigned int detector = 0xFFFFFFFF;
3055   bool gotaud = false; // have seen access unit delimiter
3056
3057   while (curbuf != curbufend)
3058   {
3059     detector <<= 8;
3060     detector |= *curbuf;
3061
3062     if (h264)
3063     {
3064       if (detector == 0x00000109)
3065       {
3066         gotaud = true;
3067         detector = 0xFFFFFFFF;
3068       }
3069       else if (gotaud && detector == 0x00000001)
3070       {
3071         curbuf++;
3072
3073         if (curbuf != curbufend)
3074         {
3075           unsigned char picttype = (*curbuf) & 0x1F;
3076           return picttype == 0x07;
3077         }
3078       }
3079     }
3080     else
3081     {
3082       if (detector == 0x00000100)
3083       {
3084         curbuf++;
3085
3086         if (curbuf == curbufend) return false;
3087
3088         curbuf++;
3089
3090         if (curbuf == curbufend) return false;
3091
3092         unsigned char picttype = ((*curbuf) >> 3) & 0x07;
3093         return picttype == 1;
3094       }
3095     }
3096
3097     curbuf++;
3098   }
3099
3100   return false; // no frame found
3101 }
3102
3103 bool VideoOMX::DrainTargetBufferFull()
3104 {
3105   //Check, if we have OMX output buffers
3106   bool full;
3107   input_bufs_omx_mutex.lock();
3108   full = (input_bufs_omx_free.size() == 0);
3109   input_bufs_omx_mutex.unlock();
3110   checkForStalledBuffers(); // check if the decoder has a problem
3111
3112   if (full && omx_vid_stalled && !omx_first_frame)
3113   {
3114     omx_vid_stalled = false;
3115     logger->debug(TAG, "Decoder is stalled, do a reset!");
3116
3117     int oldcancelstate;
3118     int oldcanceltype;
3119     pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
3120     pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
3121
3122     clock_mutex.lock();
3123     FlushRenderingPipe();
3124     omx_first_frame = true;
3125     clock_mutex.unlock();
3126
3127     pthread_setcancelstate(oldcancelstate, NULL);
3128     pthread_setcanceltype(oldcanceltype, NULL);
3129   }
3130
3131   return full;
3132 }
3133
3134 void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist, u4 /* samplepos */)
3135 {
3136   mediapackets.clear();
3137   std::list<MediaPacket>::const_iterator begin = mplist.begin();
3138   std::list<MediaPacket>::const_iterator itty = mplist.begin();
3139   advance(itty, std::min(mplist.size(), 10U));
3140   mediapackets.insert(mediapackets.begin(), begin, itty); //front
3141 }
3142
3143 u4 VideoOMX::DeliverMediaSample(u1* buffer, u4* samplepos)
3144 {
3145   u4 consumed = 0;
3146
3147   while (consumed < mediapackets.size())
3148   {
3149     DeliverMediaPacket(mediapackets[consumed], buffer, samplepos);
3150
3151     if (*samplepos == mediapackets[consumed].length)
3152     {
3153       *samplepos = 0;
3154       consumed++;
3155       //return 1;
3156     }
3157     else return consumed;
3158   }
3159
3160   return consumed;
3161 }
3162
3163 u4 VideoOMX::DeliverMediaPacket(MediaPacket packet, const u1* buffer, u4* samplepos)
3164 {
3165   if (packet.type == MPTYPE_VIDEO_H264)
3166   {
3167     h264 = true;
3168   }
3169   else
3170   {
3171     h264 = false;
3172   }
3173
3174   //Later add fail back code for libav
3175   /*    if (!videoon) {
3176                 *samplepos+=packet.length;
3177                 return packet.length;
3178         }*/
3179
3180   if (!omx_running) return 0; // if we are not runnig do not do this
3181
3182   if (isClockPaused()) return 0; //Block if we pause
3183
3184   //    logger->debug(TAG, "DMP mark 1");
3185   //logger->debug(TAG, "DeliverMediaPacketOMX time {}", packet.presentation_time);
3186
3187   /*First Check, if we have an video sample*/
3188   if (iframemode)
3189   {
3190     //samplepos=0;
3191     MILLISLEEP(10);
3192     return 0; //Not in iframe mode!
3193   }
3194
3195   u4 headerstrip = 0;
3196
3197   if (packet.disconti)
3198   {
3199     firstsynched = false;
3200
3201     if (cur_input_buf_omx)
3202     {
3203       PutBufferToPres(cur_input_buf_omx);
3204       cur_input_buf_omx = NULL;
3205     }
3206   }
3207
3208   //logger->debug(TAG, "DMP mark 2");
3209   /*Inspect PES-Header */
3210
3211   //    OMX_STATETYPE temp_state;
3212   //    OMX_GetState(omx_vid_dec,&temp_state);
3213
3214   if (*samplepos == 0) //stripheader
3215   {
3216     headerstrip = buffer[packet.pos_buffer + 8] + 9/*is this right*/;
3217     //  if (h264) logger->debug(TAG, "PES info {:#x} {:#x} {:#x} {:#x}",
3218     //                  buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
3219     *samplepos += headerstrip;
3220
3221     if (headerstrip >= packet.length)
3222     {
3223       *samplepos = packet.length; // Packet is obviously damaged
3224       return packet.length;//skip it!
3225     }
3226
3227     if (packet.synched)
3228     {
3229       if (!firstsynched)
3230       {
3231         //logger->debug(TAG, "DMP mark 2a");
3232         // check if this is an I frame, the decoder does not like non I frames at startup!
3233         if (!detectIFrame(buffer, packet.length))
3234         {
3235           *samplepos = packet.length; //if we have not processed at least one
3236           //logger->debug(TAG, "DMP mark 3");
3237           return packet.length;//synched packet ignore it!
3238         }
3239       }
3240
3241       if (cur_input_buf_omx)
3242       {
3243         //logger->debug(TAG, "DMP mark 4a");
3244         cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
3245         PutBufferToPres(cur_input_buf_omx);
3246         cur_input_buf_omx = NULL; //write out old data
3247
3248         //logger->debug(TAG, "DMP mark 4b");
3249       }
3250
3251       firstsynched = true;
3252     }
3253     else
3254     {
3255       if (!firstsynched)  //
3256       {
3257         *samplepos = packet.length; //if we have not processed at least one
3258         //logger->debug(TAG, "DMP mark 5");
3259         return packet.length;//synched packet ignore it!
3260       }
3261     }
3262   }
3263
3264   //logger->debug(TAG, "DMP mark 6");
3265   if (!cur_input_buf_omx)
3266   {
3267     input_bufs_omx_mutex.lock();
3268
3269     if (input_bufs_omx_free.size() == 0)
3270     {
3271       input_bufs_omx_mutex.unlock();
3272       //logger->debug(TAG, "Deliver MediaPacket no free sample");
3273       //logger->debug(TAG, "DMP mark 7");
3274       return 0; // we do not have a free media sample
3275     }
3276
3277     cur_input_buf_omx = input_bufs_omx_free.front();
3278     cur_input_buf_omx->nFilledLen = 0;
3279     cur_input_buf_omx->nOffset = 0;
3280     cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3281     input_bufs_omx_free.pop_front();
3282     input_bufs_omx_mutex.unlock();
3283   }
3284
3285   if (cur_input_buf_omx->nFilledLen == 0) //will only be changed on first packet
3286   {
3287     if (packet.synched)
3288     {
3289       //        logger->debug(TAG, "packet synched marker");
3290
3291       //lastreftimePTS=packet.pts;
3292       if (omx_first_frame)   // TODO time
3293       {
3294         cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3295         logger->debug(TAG, "Starttime");
3296         omx_first_frame = false;
3297       }
3298       else
3299       {
3300         cur_input_buf_omx->nFlags = 0;
3301         //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
3302       }
3303
3304       lastreftimeOMX = packet.presentation_time;
3305       // logger->debug(TAG, "Time code {} pts {}", lastreftimeOMX,packet.pts);
3306       lastreftimePTS = packet.pts;
3307       cur_input_buf_omx->nTimeStamp = intToOMXTicks(lastreftimeOMX / 10LL); // the clock component is faulty;
3308     }
3309     else
3310     {
3311       cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
3312       cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3313       //logger->debug(TAG, "packet unsynched marker");
3314     }
3315
3316     if (packet.disconti) cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_DISCONTINUITY;
3317   }
3318
3319   unsigned int haveToCopy = packet.length - *samplepos;
3320   //logger->debug(TAG, "DMP mark 8");
3321
3322   while (haveToCopy > (cur_input_buf_omx->nAllocLen - cur_input_buf_omx->nFilledLen))
3323   {
3324     //logger->debug(TAG, "Big buffer {} {} {}",packet.length,cur_input_buf_omx->nAllocLen,cur_input_buf_omx->nFilledLen);
3325     unsigned int cancopy = cur_input_buf_omx->nAllocLen - cur_input_buf_omx->nFilledLen;
3326     memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen, buffer + packet.pos_buffer + *samplepos, cancopy);
3327     haveToCopy -= cancopy;
3328     cur_input_buf_omx->nFilledLen += cancopy;
3329     *samplepos += cancopy;
3330     // push old buffer out
3331     //logger->debug(TAG, "DMP mark 9");
3332
3333     PutBufferToPres(cur_input_buf_omx);
3334     cur_input_buf_omx = NULL;
3335     // get5 new buffer
3336     input_bufs_omx_mutex.lock();
3337
3338     if (input_bufs_omx_free.size() == 0)
3339     {
3340       input_bufs_omx_mutex.unlock();
3341       //        logger->debug(TAG, "Deliver MediaPacket no free sample2");
3342       return *samplepos; // we do not have a free media sample
3343     }
3344
3345     cur_input_buf_omx = input_bufs_omx_free.front();
3346     cur_input_buf_omx->nFilledLen = 0;
3347     cur_input_buf_omx->nOffset = 0;
3348     cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
3349     cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3350     input_bufs_omx_free.pop_front();
3351     input_bufs_omx_mutex.unlock();
3352     //logger->debug(TAG, "DMP mark 10");
3353   }
3354
3355   memcpy(cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
3356          buffer + packet.pos_buffer + *samplepos, haveToCopy);
3357   cur_input_buf_omx->nFilledLen += haveToCopy;
3358
3359   //    logger->debug(TAG, "DMP mark 11");
3360
3361   *samplepos += haveToCopy;
3362
3363   return *samplepos;
3364 }
3365
3366 bool VideoOMX::displayIFrame(const u1* buffer, u4 length)
3367 {
3368   if (!omx_running) return false;
3369
3370   if (!iframemode)
3371     EnterIframePlayback();
3372
3373   //int haveToCopy = length;
3374
3375   if (!cur_input_buf_omx)
3376   {
3377     input_bufs_omx_mutex.lock();
3378
3379     if (input_bufs_omx_free.size() == 0)
3380     {
3381       input_bufs_omx_mutex.unlock();
3382       //        logger->debug(TAG,
3383       //                "Deliver MediaPacket no free sample");
3384       return false; // we do not have a free media sample
3385     }
3386
3387     cur_input_buf_omx = input_bufs_omx_free.front();
3388     cur_input_buf_omx->nFilledLen = 0;
3389     cur_input_buf_omx->nOffset = 0;
3390     cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3391     input_bufs_omx_free.pop_front();
3392     input_bufs_omx_mutex.unlock();
3393   }
3394
3395   u4 read_pos = 0;
3396   unsigned int pattern, packet_length;
3397   unsigned int headerstrip = 0;
3398   bool first = true;
3399
3400   if (length < 4)
3401   {
3402     return false;
3403   }
3404
3405   //Now we strip the pes header
3406   pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
3407
3408   while ((read_pos + 7) <= length)
3409   {
3410     pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3];
3411
3412     if (pattern < 0x000001E0 || pattern > 0x000001EF)
3413     {
3414       read_pos++;
3415       continue;
3416     }
3417     else
3418     {
3419       headerstrip = buffer[read_pos + 8] + 9/*is this right*/;
3420       packet_length = ((buffer[read_pos + 4] << 8)
3421                        | (buffer[read_pos + 5])) + 6;
3422
3423       if (read_pos + packet_length > length)
3424         read_pos = length;
3425       else
3426       {
3427         if ((headerstrip < packet_length)
3428             && (cur_input_buf_omx->nFilledLen + packet_length
3429                 - headerstrip) > cur_input_buf_omx->nAllocLen)
3430         {
3431           if (first)
3432           {
3433             cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3434           }
3435           else
3436           {
3437             cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3438           }
3439
3440           cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3441           PutBufferToPres(cur_input_buf_omx);
3442           cur_input_buf_omx = NULL;
3443
3444           if (!cur_input_buf_omx)
3445           {
3446             int count = 0;
3447
3448             while (count < 100 && omx_running && iframemode)
3449             {
3450               count++;
3451
3452               input_bufs_omx_mutex.lock();
3453
3454               if (input_bufs_omx_free.size() == 0)
3455               {
3456                 input_bufs_omx_mutex.unlock();
3457                 //                      logger->debug(TAG,
3458                 //                              "Ifrane no free sample");
3459                 MILLISLEEP(5);
3460
3461                 if (!omx_running) return false;
3462
3463                 continue;
3464               }
3465
3466               cur_input_buf_omx = input_bufs_omx_free.front();
3467               cur_input_buf_omx->nFilledLen = 0;
3468               cur_input_buf_omx->nOffset = 0;
3469               cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3470               cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3471               input_bufs_omx_free.pop_front();
3472               input_bufs_omx_mutex.unlock();
3473               break;
3474             }
3475
3476             if (!cur_input_buf_omx) return false;
3477           }
3478         }
3479
3480         if (packet_length > headerstrip)
3481         {
3482           memcpy(
3483             cur_input_buf_omx->pBuffer + cur_input_buf_omx->nFilledLen,
3484             buffer + read_pos + headerstrip,
3485             packet_length - headerstrip);
3486
3487           cur_input_buf_omx->nFilledLen += packet_length - headerstrip;
3488         }
3489
3490         read_pos += packet_length;
3491
3492         pattern = (buffer[read_pos] << 16)
3493                   | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]);
3494       }
3495     }
3496   }
3497
3498   if (first)
3499   {
3500     cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3501   }
3502   else
3503   {
3504     cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3505   }
3506
3507   cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3508
3509   PutBufferToPres(cur_input_buf_omx);
3510   cur_input_buf_omx = NULL;
3511
3512   MILLISLEEP(40); //Block a bit
3513   return true;
3514 }
3515
3516 int VideoOMX::EnterIframePlayback()
3517 {
3518   logger->debug(TAG, "EnterIframePlayback");
3519
3520   if (cur_input_buf_omx)
3521   {
3522     PutBufferToPres(cur_input_buf_omx);
3523     cur_input_buf_omx = NULL;
3524   }
3525
3526   logger->debug(TAG, "EnterIframePlayback 2");
3527   dynamic_cast<AudioOMX*>(Audio::getInstance())->DeAllocateCodecsOMX();
3528   DeAllocateCodecsOMX();
3529   AllocateCodecsOMX();
3530   logger->debug(TAG, "leave IframePlayback");
3531
3532   iframemode = true;
3533
3534   return 1;
3535 }