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