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