]> git.vomp.tv Git - vompclient.git/blob - src/videoomx.cc
Type change: UCHAR -> u1
[vompclient.git] / src / videoomx.cc
1 /*
2     Copyright 2004-2005 Chris Tallon, 2009-12 Marten Richter
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include <algorithm>
21 #include <chrono>
22
23 #include <bcm_host.h>
24 #include <linux/fb.h>
25
26
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(u1 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(u4 id, const char* displayText, const char* configSection, const char* configKey, u4 optionType,
357            u4 numChoices, u4 defaultChoice, u4 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(u1 ttvsize)
380 {
381   if (tvsize!=ttvsize) pendingmodechange=true;
382   tvsize=ttvsize;
383   return 1;
384 }
385
386 u1 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(u1 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(u1 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(u1 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(u1 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     // FIXME FIXME FIXME why do this? Probably to do with reinitting CEC, but should refine this
765         InputMan::getInstance()->shutdown();
766         vc_tv_power_off();
767         InputMan::getInstance()->init();
768         signalon=false;
769     return 1;
770 }
771
772 int VideoOMX::signalOn()
773 {
774   if (!signalon)  {
775           Osd::getInstance()->shutdown();
776           LogNT::getInstance()->info(TAG, "signalOn");
777           selectVideoMode(0);
778           Osd::getInstance()->restore();
779           Osd::getInstance()->init();
780           BoxStack::getInstance()->redrawAllBoxes();
781           initted=1;
782
783   }
784   return 1;
785 }
786
787 int VideoOMX::setSource()
788 {
789   if (!initted) return 0;
790
791   // What does this do...
792 //  if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
793   return 1;
794 }
795
796 int VideoOMX::setPosition(int x, int y) {
797         if (!initted)
798                 return 0;
799         xpos = ((float) x*2.f) / ((float) screenWidth);
800         ypos = ((float) y*2.f) / ((float) screenHeight);
801
802         updateMode();
803         return 1;
804 }
805
806 int VideoOMX::sync()
807 {
808   if (!initted) return 0;
809
810 //  if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
811   return 1;
812 }
813
814 void VideoOMX::interlaceSwitch4Demux() {
815         return;
816         Demuxer *demux=Demuxer::getInstance();
817
818         if (hdmi) { // only switch if hdmi and HD or interlaced SD material
819
820
821                 //OMX_Deinit();
822                 int set_interlaced=0;
823                 if (demux->getHorizontalSize()>720  && demux->getInterlaced()) {
824                         set_interlaced=1;
825                 }
826                 LogNT::getInstance()->info(TAG, "switch interlacing {} {} {}",demux->getInterlaced(),outputinterlaced,set_interlaced);
827                 if (outputinterlaced!=set_interlaced) {
828                         selectVideoMode(set_interlaced);
829                         Osd::getInstance()->shutdown();
830                         Osd::getInstance()->restore();
831                         Osd::getInstance()->init();
832                         BoxStack::getInstance()->redrawAllBoxes();
833                         initted=1;
834                 }
835                 //OMX_Init();
836
837
838         }
839
840
841 }
842
843
844 int VideoOMX::play() {
845         if (!initted)
846                 return 0;
847         iframemode = false;
848         logger->debug(TAG, "enter play");
849
850         interlaceSwitch4Demux();
851
852         if (AllocateCodecsOMX()) {
853                 return 1;
854                 // Otherwise fall back to libav
855         } else {
856                 if (h264) {
857                         omx_h264 = false;
858                         LogNT::getInstance()->info(TAG,
859                                         "Allocate Codecs OMX failed assume h264 unsupported");
860                 } else {
861                         omx_mpeg2 = false;
862                         LogNT::getInstance()->info(TAG,
863                                         "Allocate Codecs OMX failed assume mpeg2 unsupported");
864                 }
865         }
866
867         return 0;
868
869 }
870
871
872 int VideoOMX::initClock()
873 {
874         OMX_ERRORTYPE error;
875         clock_mutex.lock();
876         if (clock_references==0)
877         {
878
879                 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
880                 omx_event_mutex.lock();
881                 omx_events.clear();
882                 omx_event_mutex.unlock();
883
884                 error=OMX_GetHandle(&omx_clock,L_VPE_OMX_CLOCK,NULL,&callbacks);
885
886                 if (error!=OMX_ErrorNone) {
887                         logger->debug(TAG, "Init OMX clock failed {:#x}", error);
888                         clock_mutex.unlock();
889                         DeAllocateCodecsOMX();
890                         return 0;
891                 }
892
893                 /* TODO Clock config to separate method */
894                 OMX_PORT_PARAM_TYPE p_param;
895                 memset(&p_param,0,sizeof(p_param));
896                 p_param.nSize=sizeof(p_param);
897                 p_param.nVersion.nVersion=OMX_VERSION;
898                 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
899                 if (error!=OMX_ErrorNone) {
900                         logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
901                         clock_mutex.unlock();
902                         DeAllocateCodecsOMX();
903                         return 0;
904                 }
905                 omx_clock_output_port=p_param.nStartPortNumber;
906
907                 for (unsigned int i=0;i<p_param.nPorts;i++) {
908                         if (!DisablePort(omx_clock,p_param.nStartPortNumber+i,true) ) {
909                                 logger->debug(TAG, "Disable Ports OMX clock failed {}",i);
910                                 clock_mutex.unlock();
911                                 DeAllocateCodecsOMX();
912                                 return 0;
913                         }
914                 }
915
916
917
918
919         }
920         logger->debug(TAG, "init omx clock {:p} {}", (void*)this, omx_clock);
921         clock_references++;
922         clock_mutex.unlock();
923         return 1;
924 }
925
926 int VideoOMX::getClockAudioandInit(OMX_HANDLETYPE *p_omx_clock,OMX_U32 *p_omx_clock_output_port)
927 {
928         OMX_ERRORTYPE error;
929         *p_omx_clock=NULL;
930         *p_omx_clock_output_port=0;
931
932         if (!initClock()) {
933                 return 0;
934         }
935         clock_mutex.lock();
936
937         OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
938         memset(&refclock,0,sizeof(refclock));
939         refclock.nSize=sizeof(refclock);
940         refclock.nVersion.nVersion=OMX_VERSION;
941
942         refclock.eClock=OMX_TIME_RefClockAudio;
943
944         //refclock.eClock=OMX_TIME_RefClockVideo;
945         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
946         if (error!=OMX_ErrorNone){
947                 logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error);
948                 clock_mutex.unlock();
949                 DeAllocateCodecsOMX();
950                 return 0;
951         }
952
953         OMX_PORT_PARAM_TYPE p_param;
954         memset(&p_param,0,sizeof(p_param));
955         p_param.nSize=sizeof(p_param);
956         p_param.nVersion.nVersion=OMX_VERSION;
957         error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
958         if (error!=OMX_ErrorNone){
959                 logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
960                 clock_mutex.unlock();
961                 DeAllocateCodecsOMX();
962                 return 0;
963         }
964
965         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
966         memset(&clock_conf,0,sizeof(clock_conf));
967         clock_conf.nSize=sizeof(clock_conf);
968         clock_conf.nVersion.nVersion=OMX_VERSION;
969         clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
970         clock_conf.nStartTime=intToOMXTicks(0);
971         clock_conf.nOffset=intToOMXTicks(0);
972         if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT1;
973         else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
974         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
975         if (error!=OMX_ErrorNone) {
976                 logger->debug(TAG, "AuI Clock IndexConfigTimeClockState failed {:#x}", error);
977         }
978
979
980         *p_omx_clock_output_port=p_param.nStartPortNumber+1;
981         *p_omx_clock=omx_clock;
982         clock_mutex.unlock();
983         return 1;
984 }
985
986 int VideoOMX::getClockVideoandInit()
987 {
988         OMX_ERRORTYPE error;
989
990         if (!initClock()) {
991                 return 0;
992         }
993         clock_mutex.lock();
994
995         if (clock_references==1) { // only if no audio is attached to this clock!
996                 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
997                 memset(&refclock,0,sizeof(refclock));
998                 refclock.nSize=sizeof(refclock);
999                 refclock.nVersion.nVersion=OMX_VERSION;
1000
1001                 //refclock.eClock=OMX_TIME_RefClockAudio;
1002
1003                 refclock.eClock=OMX_TIME_RefClockVideo;
1004                 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
1005                 if (error!=OMX_ErrorNone) {
1006                         logger->debug(TAG, "Clock OMX_IndexConfigTimeActiveRefClock failed {:#x}", error);
1007                         clock_mutex.unlock();
1008                         DeAllocateCodecsOMX();
1009                         return 0;
1010                 }
1011         }
1012
1013         OMX_PORT_PARAM_TYPE p_param;
1014         memset(&p_param,0,sizeof(p_param));
1015         p_param.nSize=sizeof(p_param);
1016         p_param.nVersion.nVersion=OMX_VERSION;
1017         error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
1018         if (error!=OMX_ErrorNone){
1019                 logger->debug(TAG, "Init clock OMX_GetParameter failed {:#x}", error);
1020                 clock_mutex.unlock();
1021                 DeAllocateCodecsOMX();
1022                 return 0;
1023         }
1024
1025
1026         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1027         memset(&clock_conf,0,sizeof(clock_conf));
1028         clock_conf.nSize=sizeof(clock_conf);
1029         clock_conf.nVersion.nVersion=OMX_VERSION;
1030         clock_conf.eState=OMX_TIME_ClockStateStopped;
1031         clock_conf.nStartTime=intToOMXTicks(0);
1032         clock_conf.nOffset=intToOMXTicks(0);
1033         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1034         if (error!=OMX_ErrorNone) {
1035                 logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error);
1036         }
1037
1038
1039         memset(&clock_conf,0,sizeof(clock_conf));
1040         clock_conf.nSize=sizeof(clock_conf);
1041         clock_conf.nVersion.nVersion=OMX_VERSION;
1042         clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
1043         clock_conf.nStartTime=intToOMXTicks(0);
1044         clock_conf.nOffset=intToOMXTicks(0);
1045         if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT0;
1046         else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
1047         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1048         if (error!=OMX_ErrorNone) {
1049                 logger->debug(TAG, "VuI Clock IndexConfigTimeClockState failed {:#x}", error);
1050         }
1051
1052         omx_clock_output_port=p_param.nStartPortNumber;
1053         clock_mutex.unlock();
1054
1055         return 1;
1056 }
1057
1058 void VideoOMX::clockUnpause()
1059 {
1060         OMX_ERRORTYPE error;
1061         LogNT::getInstance()->info(TAG, "enter Clockunpause");
1062         clock_mutex.lock();
1063         if (clock_references>0 && clockpaused) {
1064                 OMX_TIME_CONFIG_SCALETYPE scale_type;
1065                 memset(&scale_type,0,sizeof(scale_type));
1066                 scale_type.nSize=sizeof(scale_type);
1067                 scale_type.nVersion.nVersion=OMX_VERSION;
1068                 scale_type.xScale=1<<16;
1069                 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeScale,&scale_type);
1070                 if (error!=OMX_ErrorNone) {
1071                         logger->debug(TAG, "ClockUnpause OMX_IndexConfigTimeScale failed {:#x}", error);
1072                 }
1073                 LogNT::getInstance()->info(TAG, "set playback speed ClockUnpause");
1074                 clockpaused=false;
1075         }
1076         clock_mutex.unlock();
1077 }
1078
1079
1080 void VideoOMX::clockPause()
1081 {
1082         OMX_ERRORTYPE error;
1083         LogNT::getInstance()->info(TAG, "enter ClockPause");
1084         clock_mutex.lock();
1085         if (clock_references>0 && !clockpaused) {
1086                 OMX_TIME_CONFIG_SCALETYPE scale_type;
1087                 memset(&scale_type,0,sizeof(scale_type));
1088                 scale_type.nSize=sizeof(scale_type);
1089                 scale_type.nVersion.nVersion=OMX_VERSION;
1090                 scale_type.xScale=0;
1091                 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeScale,&scale_type);
1092                 if (error!=OMX_ErrorNone) {
1093                         logger->debug(TAG, "ClockPause OMX_IndexConfigTimeScale failed {:#x}", error);
1094                 }
1095                 LogNT::getInstance()->info(TAG, "set playback speed ClockPause");
1096                 clockpaused=true;
1097         }
1098         clock_mutex.unlock();
1099 }
1100
1101
1102
1103 int VideoOMX::AllocateCodecsOMX()
1104 {
1105         OMX_ERRORTYPE error;
1106         static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
1107
1108         Demuxer* demux=Demuxer::getInstance();
1109
1110         dodeint=false;
1111         first_frame=true;
1112
1113         LogNT::getInstance()->info(TAG, "Allocate Codecs OMX");
1114         //Clock, move later to audio including events
1115
1116         LogNT::getInstance()->info(TAG, "Deinter VideoType {} x {} i: {}", demux->getHorizontalSize(),demux->getVerticalSize(),demux->getInterlaced());
1117         if (deinterlace!=0 && /*(demux->getHorizontalSize()<=720 ) &&*/ demux->getInterlaced()) { 
1118                 dodeint=true;
1119
1120
1121                 LogNT::getInstance()->info(TAG, "Deinterlacing activated {}",deinterlace);
1122
1123         }
1124
1125
1126         if (!getClockVideoandInit()){
1127                 return 0;// get the clock and init it if necessary
1128         }
1129
1130
1131         if (!idleClock()) {
1132                 logger->debug(TAG, "idleClock failed");
1133                 return 0;
1134         }
1135         /* TODO end */
1136
1137         clock_mutex.lock();
1138         if (h264) {
1139                 error=OMX_GetHandle(&omx_vid_dec,L_VPE_OMX_H264_DECODER,NULL,&callbacks);
1140         } else {
1141                 error=OMX_GetHandle(&omx_vid_dec,L_VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
1142         }
1143
1144         if (error!=OMX_ErrorNone){
1145                 logger->debug(TAG, "Init OMX video decoder failed {:#x}", error);
1146                 clock_mutex.unlock();
1147                 DeAllocateCodecsOMX();
1148                 return 0;
1149         }
1150
1151
1152         logger->debug(TAG, "Nmark3 ");
1153         OMX_PORT_PARAM_TYPE p_param;
1154         memset(&p_param,0,sizeof(p_param));
1155         p_param.nSize=sizeof(p_param);
1156         p_param.nVersion.nVersion=OMX_VERSION;
1157         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
1158         if (error!=OMX_ErrorNone){
1159                 logger->debug(TAG, "Init OMX h264 decoder OMX_GetParameter failed {:#x}", error);
1160                 clock_mutex.unlock();
1161                 DeAllocateCodecsOMX();
1162             return 0;
1163         }
1164         omx_codec_input_port=p_param.nStartPortNumber;
1165         omx_codec_output_port=p_param.nStartPortNumber+1;
1166
1167         if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
1168                 logger->debug(TAG, "Disable Ports OMX video decoder failed");
1169                 clock_mutex.unlock();
1170                 DeAllocateCodecsOMX();
1171                 return 0;
1172         }
1173
1174         logger->debug(TAG, "Nmark4 ");
1175
1176         OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
1177         memset(&conceal,0,sizeof(conceal));
1178         conceal.nSize=sizeof(conceal);
1179         conceal.nVersion.nVersion=OMX_VERSION;
1180         conceal.bStartWithValidFrame=OMX_FALSE;
1181
1182         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
1183         if (error!=OMX_ErrorNone){
1184                 logger->debug(TAG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed {:#x}", error);
1185                 clock_mutex.unlock();
1186                 DeAllocateCodecsOMX();
1187                 return 0;
1188         }
1189
1190         if (dodeint) {
1191                 error = OMX_GetHandle(&omx_vid_deint, L_VPE_OMX_VIDEO_DEINTERLACE, NULL,
1192                                 &callbacks);
1193                 if (error != OMX_ErrorNone) {
1194                         LogNT::getInstance()->debug(TAG,
1195                                         "Init OMX video deinterlacer failed {:#x}", error);
1196                         clock_mutex.unlock();
1197                         DeAllocateCodecsOMX();
1198                         return 0;
1199                 }
1200
1201                 error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamImageInit,
1202                                 &p_param);
1203                 if (error != OMX_ErrorNone) {
1204                         LogNT::getInstance()->debug(TAG,
1205                                         "Init OMX video deinterlacer OMX_GetParameter failed {:#x}",
1206                                         error);
1207                         clock_mutex.unlock();
1208                         DeAllocateCodecsOMX();
1209                         return 0;
1210                 }
1211                 omx_deint_input_port = p_param.nStartPortNumber;
1212                 omx_deint_output_port = p_param.nStartPortNumber + 1;
1213
1214                 if (!DisablePort(omx_vid_deint, omx_deint_input_port, true)
1215                                 || !DisablePort(omx_vid_deint, omx_deint_output_port, true)) {
1216                         LogNT::getInstance()->debug(TAG,
1217                                         "Disable Ports OMX video deint failed");
1218                         clock_mutex.unlock();
1219                         DeAllocateCodecsOMX();
1220                         return 0;
1221                 }
1222
1223         }
1224
1225
1226         error=OMX_GetHandle(&omx_vid_sched,L_VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
1227         if (error!=OMX_ErrorNone){
1228                 logger->debug(TAG, "Init OMX video scheduler failed {:#x}", error);
1229                 clock_mutex.unlock();
1230                 DeAllocateCodecsOMX();
1231                 return 0;
1232         }
1233
1234
1235
1236         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
1237         if (error!=OMX_ErrorNone){
1238                 logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error);
1239                 clock_mutex.unlock();
1240                 DeAllocateCodecsOMX();
1241                 return 0;
1242         }
1243         omx_shed_input_port=p_param.nStartPortNumber;
1244         omx_shed_output_port=p_param.nStartPortNumber+1;
1245
1246
1247         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
1248         if (error!=OMX_ErrorNone){
1249                 logger->debug(TAG, "Init OMX video scheduler OMX_GetParameter failed {:#x}", error);
1250                 clock_mutex.unlock();
1251                 DeAllocateCodecsOMX();
1252                 return 0;
1253         }
1254         omx_shed_clock_port=p_param.nStartPortNumber;
1255         logger->debug(TAG, "scheduler ports {} {} {}",omx_shed_input_port,omx_shed_output_port,omx_shed_clock_port);
1256
1257
1258         if (!DisablePort(omx_vid_sched,omx_shed_input_port,true) || !DisablePort(omx_vid_sched,omx_shed_output_port,true)
1259                         || !DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1260                 logger->debug(TAG, "Disable Ports OMX video shed failed");
1261                 clock_mutex.unlock();
1262                 DeAllocateCodecsOMX();
1263                 return 0;
1264         }
1265
1266
1267         error=OMX_GetHandle(&omx_vid_rend,L_VPE_OMX_VIDEO_REND,NULL,&callbacks);
1268         if (error!=OMX_ErrorNone){
1269                 logger->debug(TAG, "Init OMX video rend failed {:#x}", error);
1270                 clock_mutex.unlock();
1271                 DeAllocateCodecsOMX();
1272                 return 0;
1273         }
1274
1275         error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
1276         if (error!=OMX_ErrorNone){
1277                 logger->debug(TAG, "Init OMX video rend OMX_GetParameter failed {:#x}", error);
1278                 clock_mutex.unlock();
1279                 DeAllocateCodecsOMX();
1280                 return 0;
1281         }
1282         omx_rend_input_port=p_param.nStartPortNumber;
1283         //omx_rend_output_port=p_param.nStartPortNumber+1;
1284
1285
1286         if (!DisablePort(omx_vid_rend,omx_rend_input_port,true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
1287                                 ) {
1288                 logger->debug(TAG, "Disable Ports OMX video rend failed");
1289                 clock_mutex.unlock();
1290                 DeAllocateCodecsOMX();
1291                 return 0;
1292         }
1293
1294         //Setuo chain
1295
1296
1297
1298         error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
1299         if (error!=OMX_ErrorNone){
1300                 logger->debug(TAG, "OMX_Setup tunnel clock to sched failed {:#x} {} {}", error,omx_clock_output_port,omx_shed_clock_port);
1301                 clock_mutex.unlock();
1302                 DeAllocateCodecsOMX();
1303                 return 0;
1304         }
1305
1306         if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
1307                                         ) {
1308                 logger->debug(TAG, "Enable Ports OMX clock shed failed");
1309                 clock_mutex.unlock();
1310                 DeAllocateCodecsOMX();
1311                 return 0;
1312         }
1313
1314
1315
1316         if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1317                 logger->debug(TAG, "vid_sched idle ChangeComponentState");
1318                 clock_mutex.unlock();
1319                 DeAllocateCodecsOMX();
1320                 return 0;
1321         }
1322
1323
1324
1325
1326         if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
1327                 clock_mutex.unlock();
1328                 DeAllocateCodecsOMX();
1329                 return 0;
1330         }
1331
1332
1333
1334
1335
1336         if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
1337                 clock_mutex.unlock();
1338                 DeAllocateCodecsOMX();
1339                 return 0;
1340         }
1341
1342
1343
1344 /*      error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1345         if (error!=OMX_ErrorNone){
1346                 logger->debug(TAG, "vid_dec Send Command to OMX State Idle {:#x}", error);
1347                 return 0;
1348         }*/
1349
1350         OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1351         memset(&ft_type,0,sizeof(ft_type));
1352         ft_type.nSize=sizeof(ft_type);
1353         ft_type.nVersion.nVersion=OMX_VERSION;
1354
1355         ft_type.nPortIndex=omx_codec_input_port;
1356         if (h264) {
1357                 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
1358         } else {
1359                 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
1360         }
1361
1362
1363
1364     ft_type.xFramerate=0*(1<<16);//25*(1<<16);//demux->getFrameRate()*(1<<16);
1365     logger->debug(TAG, "Framerate: {}",demux->getFrameRate());
1366         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
1367         if (error!=OMX_ErrorNone){
1368                 logger->debug(TAG, "Init OMX_IndexParamVideoPortFormat failed {:#x}", error);
1369                 clock_mutex.unlock();
1370                 DeAllocateCodecsOMX();
1371                 return 0;
1372         }
1373
1374
1375         if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1376                 logger->debug(TAG, "vid_dec ChangeComponentState");
1377                 clock_mutex.unlock();
1378                 DeAllocateCodecsOMX();
1379                 return 0;
1380         }
1381
1382         OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
1383         memset(&stall_conf,0,sizeof(stall_conf));
1384         stall_conf.nSize=sizeof(stall_conf);
1385         stall_conf.nVersion.nVersion=OMX_VERSION;
1386         stall_conf.nPortIndex=omx_codec_output_port;
1387         stall_conf.nDelay=1500*1000;
1388         error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf);
1389         if (error!=OMX_ErrorNone){
1390                 logger->debug(TAG, "Init OMX_IndexConfigBufferStall failed {:#x}", error);
1391                 clock_mutex.unlock();
1392                 DeAllocateCodecsOMX();
1393                 return 0;
1394         }
1395         omx_vid_stalled = false;
1396
1397         OMX_CONFIG_REQUESTCALLBACKTYPE req_callback;
1398         memset(&req_callback,0,sizeof(req_callback));
1399         req_callback.nSize=sizeof(req_callback);
1400         req_callback.nVersion.nVersion=OMX_VERSION;
1401         req_callback.nPortIndex=omx_codec_output_port;
1402         req_callback.nIndex=OMX_IndexConfigBufferStall;
1403         req_callback.bEnable=OMX_TRUE;
1404         error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigRequestCallback,&req_callback);
1405         if (error!=OMX_ErrorNone){
1406                 logger->debug(TAG, "Init OMX_IndexConfigRequestCallback  failed {:#x}", error);
1407                 clock_mutex.unlock();
1408                 DeAllocateCodecsOMX();
1409                 return 0;
1410         }
1411
1412
1413
1414         if (!PrepareInputBufsOMX()) {
1415                 clock_mutex.unlock();
1416                 DeAllocateCodecsOMX();
1417                 return 0;
1418         }
1419
1420         if (!dodeint) {
1421                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
1422                 if (error!=OMX_ErrorNone){
1423                         logger->debug(TAG, "OMX_Setup tunnel dec to sched failed {:#x}", error);
1424                         clock_mutex.unlock();
1425                         DeAllocateCodecsOMX();
1426                         return 0;
1427                 }
1428
1429
1430
1431                 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1432                 ) {
1433                         logger->debug(TAG, "Enable Ports OMX codec shed failed");
1434                         clock_mutex.unlock();
1435                         DeAllocateCodecsOMX();
1436                         return 0;
1437                 }
1438
1439                 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1440                         clock_mutex.unlock();
1441                         DeAllocateCodecsOMX();
1442                         return 0;
1443                 }
1444
1445         } else {
1446
1447                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_deint,omx_deint_input_port);
1448                 if (error!=OMX_ErrorNone){
1449                         logger->debug(TAG, "OMX_Setup tunnel dec to deint failed {:#x}", error);
1450                         clock_mutex.unlock();
1451                         DeAllocateCodecsOMX();
1452                         return 0;
1453                 }
1454
1455
1456
1457                 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_deint,omx_deint_input_port,false)
1458                 ) {
1459                         logger->debug(TAG, "Enable Ports OMX codec deint failed");
1460                         clock_mutex.unlock();
1461                         DeAllocateCodecsOMX();
1462                         return 0;
1463                 }
1464
1465                 if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_input_port)) {
1466                         clock_mutex.unlock();
1467                         DeAllocateCodecsOMX();
1468                         return 0;
1469                 }
1470
1471                 if (!ChangeComponentState(omx_vid_deint,OMX_StateIdle)) {
1472                         logger->debug(TAG, "vid_deint ChangeComponentState");
1473                         clock_mutex.unlock();
1474                         DeAllocateCodecsOMX();
1475                         return 0;
1476                 }
1477
1478                 OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter;
1479                 memset(&imagefilter,0,sizeof(imagefilter));
1480                 imagefilter.nSize=sizeof(imagefilter);
1481                 imagefilter.nVersion.nVersion=OMX_VERSION;
1482
1483                 imagefilter.nPortIndex=omx_deint_output_port;
1484                 imagefilter.nNumParams=4;
1485                 imagefilter.nParams[0]=3;//???
1486                 imagefilter.nParams[1]=0;//default frame interval
1487                 imagefilter.nParams[2]=0;// frame rate
1488                 if (demux->getHorizontalSize() <= 720){
1489                         imagefilter.nParams[3] = 1;//use qpus
1490                 }
1491                 else 
1492                 {
1493                         imagefilter.nParams[3] = 0;//use qpus
1494                 }
1495
1496                 switch (deinterlace) {
1497                 case 1:
1498                         imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceLineDouble; break;
1499                 case 2:
1500                         imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceAdvanced; break;
1501                 case 3:
1502                         imagefilter.eImageFilter=OMX_ImageFilterFilm; break;
1503                 case 4:
1504                         imagefilter.eImageFilter = OMX_ImageFilterDeInterlaceFast; break;
1505                 }
1506
1507
1508                 error=OMX_SetConfig(omx_vid_deint,OMX_IndexConfigCommonImageFilterParameters,&imagefilter);
1509                 if (error!=OMX_ErrorNone){
1510                         logger->debug(TAG, "Init OMX_IndexConfigCommonImageFilterParameters failed {:#x}", error);
1511                         clock_mutex.unlock();
1512                         DeAllocateCodecsOMX();
1513                         return 0;
1514                 }
1515
1516
1517                 error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,omx_vid_sched,omx_shed_input_port);
1518                 if (error!=OMX_ErrorNone){
1519                         logger->debug(TAG, "OMX_Setup tunnel deint to sched failed {:#x}", error);
1520                         clock_mutex.unlock();
1521                         DeAllocateCodecsOMX();
1522                         return 0;
1523                 }
1524
1525                 if (!EnablePort(omx_vid_deint,omx_deint_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1526                 ) {
1527                         logger->debug(TAG, "Enable Ports OMX deint shed failed");
1528                         clock_mutex.unlock();
1529                         DeAllocateCodecsOMX();
1530                         return 0;
1531                 }
1532
1533                 if ( !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1534                         clock_mutex.unlock();
1535                         DeAllocateCodecsOMX();
1536                         return 0;
1537                 }
1538
1539         }
1540
1541         if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
1542                 logger->debug(TAG, "omx_vid_dec ChangeComponentState Execute");
1543                 clock_mutex.unlock();
1544                 DeAllocateCodecsOMX();
1545                 return 0;
1546         }
1547
1548         error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
1549         if (error!=OMX_ErrorNone){
1550                 logger->debug(TAG, "OMX_Setup tunnel  sched to rend failed {:#x}", error);
1551                 clock_mutex.unlock();
1552                 DeAllocateCodecsOMX();
1553                 return 0;
1554         }
1555
1556         if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
1557                                                         ) {
1558                 logger->debug(TAG, "Enable Ports OMX  shed rend failed");
1559                 clock_mutex.unlock();
1560                 DeAllocateCodecsOMX();
1561                 return 0;
1562         }
1563
1564         if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
1565                                         || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1566                 clock_mutex.unlock();
1567                 DeAllocateCodecsOMX();
1568                 return 0;
1569         }
1570
1571         if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1572                 logger->debug(TAG, "vid_rend ChangeComponentState");
1573                 clock_mutex.unlock();
1574                 DeAllocateCodecsOMX();
1575                 return 0;
1576         }
1577
1578         if (dodeint) {
1579                 if (!ChangeComponentState(omx_vid_deint,OMX_StateExecuting)) {
1580                         logger->debug(TAG, "vid_vid_deint ChangeComponentState");
1581                         clock_mutex.unlock();
1582                         DeAllocateCodecsOMX();
1583                         return 0;
1584                 }
1585                 DisablePort(omx_vid_deint,omx_deint_output_port,false);
1586                 DisablePort(omx_vid_deint,omx_deint_input_port,false);
1587         }
1588
1589         if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
1590                 logger->debug(TAG, "omx_vid_sched ChangeComponentState Execute");
1591                 clock_mutex.unlock();
1592                 DeAllocateCodecsOMX();
1593                 return 0;
1594         }
1595
1596         if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
1597                 logger->debug(TAG, "omx_vid_rend ChangeComponentState Execute");
1598                 clock_mutex.unlock();
1599                 DeAllocateCodecsOMX();
1600                 return 0;
1601         }
1602
1603         //raspbi specifif
1604         /*OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1605         memset(&dispconf,0,sizeof(dispconf));
1606         dispconf.nSize=sizeof(dispconf);
1607         dispconf.nVersion.nVersion=OMX_VERSION;
1608
1609         dispconf.nPortIndex=omx_rend_input_port;
1610
1611         dispconf.set=OMX_DISPLAY_SET_LAYER ;
1612         dispconf.layer=1;
1613         error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1614         if (error!=OMX_ErrorNone){
1615                 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1616                 clock_mutex.unlock();
1617                 DeAllocateCodecsOMX();
1618                 return 0;
1619         }*/
1620
1621 /*      dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1622         dispconf.fullscreen=OMX_FALSE;
1623         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1624         if (error!=OMX_ErrorNone){
1625                 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1626                 clock_mutex.unlock();
1627                 DeAllocateCodecsOMX();
1628                 return 0;
1629         }
1630
1631         dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1632         dispconf.dest_rect.x_offset=100;
1633         dispconf.dest_rect.y_offset=100;
1634         dispconf.dest_rect.width=640;
1635         dispconf.dest_rect.height=480;
1636         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1637         if (error!=OMX_ErrorNone){
1638                 logger->debug(TAG, "Init OMX_IndexConfigDisplayRegion failed {:#x}", error);
1639                 clock_mutex.unlock();
1640                 DeAllocateCodecsOMX();
1641                 return 0;
1642         }*/
1643
1644
1645         //playbacktimeoffset=-GetCurrentSystemTime();
1646
1647         iframemode=false;
1648         omx_running=true;
1649         clock_mutex.unlock();
1650         clockUnpause();
1651         updateMode();
1652
1653         setClockExecutingandRunning();
1654
1655
1656
1657
1658
1659         return 1;
1660 }
1661
1662 int VideoOMX::idleClock()
1663 {
1664         //OMX_ERRORTYPE error;
1665         OMX_STATETYPE temp_state;
1666         clock_mutex.lock();
1667         OMX_GetState(omx_clock,&temp_state);
1668
1669         if (temp_state!=OMX_StateIdle) {
1670                 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1671                         logger->debug(TAG, "omx_clock ChangeComponentState Idle failed");
1672                         clock_mutex.unlock();
1673                         return 0;
1674                 }
1675         }
1676         clock_mutex.unlock();
1677         return 1;
1678 }
1679
1680 int VideoOMX::setClockExecutingandRunning()
1681 {
1682         OMX_ERRORTYPE error;
1683         OMX_STATETYPE temp_state;
1684         clock_mutex.lock();
1685         OMX_GetState(omx_clock,&temp_state);
1686
1687         if (temp_state!=OMX_StateExecuting) {
1688                 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1689                         logger->debug(TAG, "omx_clock ChangeComponentState Execute failed");
1690                         clock_mutex.unlock();
1691                         DeAllocateCodecsOMX();
1692                         return 0;
1693                 }
1694         }
1695
1696         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1697         memset(&clock_conf,0,sizeof(clock_conf));
1698         clock_conf.nSize=sizeof(clock_conf);
1699         clock_conf.nVersion.nVersion=OMX_VERSION;
1700         clock_conf.eState=OMX_TIME_ClockStateRunning;
1701         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1702         if (error!=OMX_ErrorNone) {
1703                 logger->debug(TAG, "Clock IndexConfigTimeClockState failed {:#x}", error);
1704                 clock_mutex.unlock();
1705                 DeAllocateCodecsOMX();
1706                 return 0;
1707         }
1708         clock_mutex.unlock();
1709         return 1;
1710
1711 }
1712
1713
1714 int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type,bool wait) //needs to be called with locked mutex
1715 {
1716         OMX_ERRORTYPE error;
1717         error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1718         if (error!=OMX_ErrorNone){
1719                 logger->debug(TAG, "handle {:#x} Send Command to OMX State {:#x} {:#x}",handle,type, error);
1720                 return 0;
1721         }
1722
1723         if (wait) {
1724                 if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1725                         return 0;
1726                 }
1727         }
1728
1729         return 1;
1730 }
1731
1732
1733 int VideoOMX::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1734 {
1735         OMX_ERRORTYPE error;
1736         bool skip=false;
1737
1738         OMX_PARAM_PORTDEFINITIONTYPE pdt;
1739         memset(&pdt,0,sizeof(pdt));
1740         pdt.nSize=sizeof(pdt);
1741         pdt.nVersion.nVersion=OMX_VERSION;
1742         pdt.nPortIndex=port;
1743         error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt);
1744         if (error==OMX_ErrorNone) {
1745                 if(pdt.bEnabled==OMX_TRUE) {
1746                         skip=true; //already disabled;
1747                 }
1748
1749         }
1750
1751         if (!skip) {
1752                 error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1753                 if (error!=OMX_ErrorNone){
1754                         logger->debug(TAG, "handle {:#x} Send Command to enable port {:#x} {:#x}",handle,port, error);
1755                         return 0;
1756                 }
1757
1758                 if (!wait) return 1;
1759                 if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1760                         return 0;
1761                 }
1762
1763         }
1764         return 1;
1765 }
1766
1767
1768 int VideoOMX::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1769 {
1770         OMX_ERRORTYPE error;
1771         bool skip=false;
1772
1773         OMX_PARAM_PORTDEFINITIONTYPE pdt;
1774         memset(&pdt,0,sizeof(pdt));
1775         pdt.nSize=sizeof(pdt);
1776         pdt.nVersion.nVersion=OMX_VERSION;
1777         pdt.nPortIndex=port;
1778         error=OMX_GetParameter(handle,OMX_IndexParamPortDefinition, &pdt);
1779         if (error==OMX_ErrorNone) {
1780                 if(pdt.bEnabled==OMX_FALSE) {
1781                         skip=true; //already disabled;
1782                 }
1783
1784         }
1785
1786
1787         if (!skip) {
1788                 error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1789                 if (error!=OMX_ErrorNone){
1790                         logger->debug(TAG, "handle {:#x} Send Command to disable port {:#x} {:#x}",handle,port, error);
1791                         return 0;
1792                 }
1793
1794                 if (!wait) return 1;
1795                 if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1796                         return 0;
1797                 }
1798         }
1799
1800         return 1;
1801 }
1802
1803 int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event, int wait) //needs to be called with locked mutex
1804 {
1805         int i=0;
1806         int iend=(wait/5+1);
1807         while (i<iend) {
1808                 omx_event_mutex.lock();
1809                 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1810                 while (itty!=omx_events.end()) {
1811
1812                         VPE_OMX_EVENT current=*itty;
1813                         if (current.handle==handle) { //this is ours
1814                                 if (current.event_type==OMX_EventError) {
1815                                         omx_events.erase(itty);
1816                                         omx_event_mutex.unlock();
1817                                         logger->debug(TAG, "WaitForEvent Finished on Error");
1818                                         return 0;
1819
1820                                 } else if (current.event_type==event) {
1821                                         omx_events.erase(itty);
1822                                         omx_event_mutex.unlock();
1823                                         logger->debug(TAG, "WaitForEvent Finished Completed");
1824                                         return 1;
1825                                 }
1826                         }
1827                         itty++;
1828
1829                 }
1830                 omx_event_mutex.unlock();
1831
1832         //logger->debug(TAG, "WaitForEvent");
1833         std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
1834         omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
1835         ul.unlock();
1836
1837         i++;
1838
1839         }
1840         logger->debug(TAG, "WaitForEvent waited too long {:p} {:#x}",(void*)handle,event);
1841         return 0;
1842
1843 }
1844
1845 int VideoOMX::clearEvents()
1846 {
1847         omx_event_mutex.lock();
1848         omx_events.clear();
1849         omx_event_mutex.unlock();
1850
1851         return 1;
1852 }
1853
1854 int VideoOMX::clearEventsForComponent(OMX_HANDLETYPE handle)
1855 {
1856         omx_event_mutex.lock();
1857         std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1858         while (itty!=omx_events.end()) {
1859                 VPE_OMX_EVENT current=*itty;
1860                 if (current.handle==handle) { //this is ours
1861                         itty=omx_events.erase(itty);
1862                         continue;
1863                 }
1864                 itty++;
1865
1866         }
1867         omx_event_mutex.unlock();
1868         return 1;
1869 }
1870
1871 void VideoOMX::checkForStalledBuffers()
1872 {
1873         //logger->debug(TAG, "Check stalled");
1874         clock_mutex.lock();
1875         omx_event_mutex.lock();
1876         std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1877         while (itty!=omx_events.end()) {
1878                 VPE_OMX_EVENT current=*itty;
1879                 if (current.event_type==OMX_EventParamOrConfigChanged && current.data1==omx_codec_output_port
1880                                 && current.handle==omx_vid_dec && current.data2==OMX_IndexConfigBufferStall) {
1881                         OMX_ERRORTYPE error;
1882                         OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
1883                         memset(&stall_conf,0,sizeof(stall_conf));
1884                         stall_conf.nSize=sizeof(stall_conf);
1885                         stall_conf.nVersion.nVersion=OMX_VERSION;
1886                         stall_conf.nPortIndex=omx_codec_output_port;
1887                         stall_conf.nDelay=200000;
1888
1889                         error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf);
1890                         if (error!=OMX_ErrorNone){
1891                                         logger->debug(TAG, "Get OMX_IndexConfigBufferStall failed {:#x}", error);
1892                                         clock_mutex.unlock();
1893                                         omx_event_mutex.unlock();
1894                                         return ;
1895                                 }
1896                         if (stall_conf.bStalled==OMX_TRUE) {
1897                                 omx_vid_stalled=true;
1898                                 logger->debug(TAG, "Video decoder stalled! {}", stall_conf.nDelay);
1899                         } else {
1900                                 omx_vid_stalled=false;
1901                                 logger->debug(TAG, "Video decoder unstalled! {}",stall_conf.nDelay);
1902                         }
1903                         omx_events.erase(itty);
1904                         break;
1905                 }
1906                 itty++;
1907         }
1908         omx_event_mutex.unlock();
1909         clock_mutex.unlock();
1910 }
1911
1912
1913
1914
1915 int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex
1916 {
1917         int i=0;
1918         while (i<200/*1000*/) {
1919                 omx_event_mutex.lock();
1920                 std::list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1921                 while (itty!=omx_events.end()) {
1922
1923                         VPE_OMX_EVENT current=*itty;
1924                         if (current.handle==handle) { //this is ours
1925                                 if (current.event_type==OMX_EventError) {
1926                                         omx_events.erase(itty);
1927                                         omx_event_mutex.unlock();
1928                                         logger->debug(TAG, "Command Finished on Error {:#x}",current.data1);
1929                                         return 0;
1930
1931                                 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1932                                         omx_events.erase(itty);
1933                                         omx_event_mutex.unlock();
1934                                         //logger->debug(TAG, "Command Finished Completed");
1935                                         return 1;
1936                                 }
1937                         }
1938                         itty++;
1939
1940                 }
1941                 omx_event_mutex.unlock();
1942
1943         std::unique_lock<std::mutex> ul(omx_event_ready_signal_mutex);
1944         omx_event_ready_signal.wait_for(ul, std::chrono::milliseconds(10));
1945         ul.unlock();
1946
1947                 i++;
1948
1949         }
1950         logger->debug(TAG, "CommandFinished waited too long {:#x} {:#x} {:#x}",handle,command, data2);
1951         return 0;
1952
1953 }
1954
1955
1956
1957 int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex
1958 {
1959         OMX_ERRORTYPE error;
1960         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1961         memset(&port_def_type,0,sizeof(port_def_type));
1962         port_def_type.nSize=sizeof(port_def_type);
1963         port_def_type.nVersion.nVersion=OMX_VERSION;
1964         port_def_type.nPortIndex=omx_codec_input_port;
1965
1966         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1967
1968         if (error!=OMX_ErrorNone){
1969                         logger->debug(TAG, "Get OMX OMX_IndexParamPortDefinition failed {:#x}", error);
1970         }
1971 /*      logger->debug(TAG, "Port para {} {} {} {} {} {} {}", port_def_type.nBufferCountActual,
1972                         port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1973                         port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1974
1975         port_def_type.nBufferCountActual=100;
1976         port_def_type.nBufferSize=std::max(toi4(port_def_type.nBufferSize),150000); // for transcoder important
1977
1978         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1979
1980         if (error!=OMX_ErrorNone){
1981                         logger->debug(TAG, "Set OMX OMX_IndexParamPortDefinition failed {:#x}", error);
1982         }
1983
1984
1985         error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1986         if (error!=OMX_ErrorNone){
1987                 logger->debug(TAG, "Prepare Input bufs Send Command to enable port {:#x}", error);
1988                 return 0;
1989         }
1990
1991         input_bufs_omx_mutex.lock();
1992         for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1993
1994         //      unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1995                 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1996         /*      error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1997                 if (error!=OMX_ErrorNone){
1998                         logger->debug(TAG, "Use OMX_Usebuffer failed {:#x}", error);
1999                         input_bufs_omx_mutex.unlock();
2000                         return 0;
2001                 }*/
2002                 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
2003                 if (error!=OMX_ErrorNone){
2004                         logger->debug(TAG, "Use OMX_AllocateBuffer failed {:#x}", error);
2005                                 input_bufs_omx_mutex.unlock();
2006                         return 0;
2007                 }
2008                 input_bufs_omx_all.push_back(buf_head);
2009                 input_bufs_omx_free.push_back(buf_head);
2010         }
2011         omx_first_frame=true;
2012
2013         firstsynched=false;
2014         cur_input_buf_omx=NULL;
2015         input_bufs_omx_mutex.unlock();
2016
2017
2018         logger->debug(TAG, "PrepareInputBufsOMX mark3");
2019         if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
2020                 return 0;
2021         }
2022         logger->debug(TAG, "PrepareInputBufsOMX mark4");
2023
2024         return 1;
2025 }
2026
2027 int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex
2028 {
2029         OMX_ERRORTYPE error;
2030
2031         cur_input_buf_omx=NULL;
2032         input_bufs_omx_mutex.lock();
2033         for (u4 i=0; i< input_bufs_omx_all.size();i++) {
2034         //      free(input_bufs_omx_all[i]->pBuffer);
2035         //      input_bufs_omx_all[i]->pBuffer=NULL;
2036                 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
2037                 if (error!=OMX_ErrorNone){
2038                         logger->debug(TAG, "Use OMX_FreeBuffer failed {:#x}", error);
2039                         input_bufs_omx_mutex.unlock();
2040                         return 0;
2041                 }
2042
2043         }
2044         input_bufs_omx_all.clear();
2045         input_bufs_omx_free.clear();
2046         input_bufs_omx_mutex.unlock();
2047
2048         return 1;
2049 }
2050
2051
2052
2053 int VideoOMX::FlushRenderingPipe()
2054 {
2055         OMX_ERRORTYPE error;
2056
2057         if (!dodeint) {
2058
2059                 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2060                                 omx_codec_output_port, NULL);
2061                 if (error != OMX_ErrorNone) {
2062                         LogNT::getInstance()->debug(TAG,
2063                                         "OMX_Flush codec out 1 failed {:#x}", error);
2064
2065                 }
2066
2067                 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2068                                 omx_shed_input_port, NULL);
2069                 if (error != OMX_ErrorNone) {
2070                         LogNT::getInstance()->debug(TAG,
2071                                         "OMX_Flush shed in 2 failed {:#x}", error);
2072
2073                 }
2074
2075                 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
2076                                 omx_codec_output_port)) {
2077                         LogNT::getInstance()->debug(TAG,
2078                                         "flush cmd codec  3 failed");
2079                 }
2080
2081                 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2082                                 omx_shed_input_port)) {
2083                         LogNT::getInstance()->debug(TAG,
2084                                         "flush cmd  shed 4 failed");
2085                 }
2086         } else {
2087                 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2088                                 omx_codec_output_port, NULL);
2089                 if (error != OMX_ErrorNone) {
2090                         LogNT::getInstance()->debug(TAG,
2091                                         "OMX_Flush codec out 5 failed {:#x}", error);
2092
2093                 }
2094
2095                 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
2096                                 omx_deint_input_port, NULL);
2097                 if (error != OMX_ErrorNone) {
2098                         LogNT::getInstance()->debug(TAG,
2099                                         "OMX_Flush deint in 6 failed {:#x}", error);
2100
2101                 }
2102
2103                 if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
2104                                 omx_codec_output_port)) {
2105                         LogNT::getInstance()->debug(TAG,
2106                                         "flush cmd codec  7 failed");
2107                 }
2108
2109                 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
2110                                 omx_deint_input_port)) {
2111                         LogNT::getInstance()->debug(TAG,
2112                                         "flush cmd  deint 8 failed");
2113                 }
2114
2115                 //m
2116                 error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
2117                                 omx_deint_output_port, NULL);
2118                 if (error != OMX_ErrorNone) {
2119                         LogNT::getInstance()->debug(TAG,
2120                                         "OMX_Flush deint out 9 failed {:#x}", error);
2121
2122                 }
2123
2124                 error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2125                                 omx_shed_input_port, NULL);
2126                 if (error != OMX_ErrorNone) {
2127                         LogNT::getInstance()->debug(TAG,
2128                                         "OMX_Flush shed in 10 failed {:#x}", error);
2129
2130                 }
2131
2132                 if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
2133                                 omx_deint_output_port)) {
2134                         LogNT::getInstance()->debug(TAG,
2135                                         "flush cmd deint 11 failed");
2136                 }
2137
2138                 if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2139                                 omx_shed_input_port)) {
2140                         LogNT::getInstance()->debug(TAG,
2141                                         "flush cmd  shed 12 failed");
2142                 }
2143
2144         }
2145
2146
2147
2148
2149         error = OMX_SendCommand(omx_vid_rend, OMX_CommandFlush,
2150                         omx_rend_input_port, NULL);
2151         if (error != OMX_ErrorNone) {
2152                 LogNT::getInstance()->debug(TAG,
2153                                 "OMX_Flush rend in failed {:#x}", error);
2154
2155         }
2156
2157         error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
2158                         omx_shed_output_port, NULL);
2159         if (error != OMX_ErrorNone) {
2160                 LogNT::getInstance()->debug(TAG,
2161                                 "OMX_Flush shed out failed {:#x}", error);
2162
2163         }
2164
2165
2166
2167         if (!CommandFinished(omx_vid_rend, OMX_CommandFlush,
2168                         omx_rend_input_port)) {
2169                 LogNT::getInstance()->debug(TAG,
2170                                 "flush cmd shed rend failed");
2171         }
2172
2173         if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
2174                         omx_shed_output_port)) {
2175                 LogNT::getInstance()->debug(TAG,
2176                                 "flush cmd shed rend failed");
2177         }
2178
2179         return 1;
2180 }
2181
2182
2183 int VideoOMX::DeAllocateCodecsOMX()
2184 {
2185         OMX_ERRORTYPE error;
2186         omx_running=false;
2187           logger->debug(TAG, "enter deallocatecodecsomx");
2188
2189    if (cur_input_buf_omx) {
2190                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
2191                 error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2192                 if (error!=OMX_ErrorNone) {
2193                         logger->debug(TAG, "OMX_EmptyThisBuffer failed {:#x}", error);
2194                 }
2195
2196                 cur_input_buf_omx=NULL;//write out old data
2197         }
2198    clock_mutex.lock();
2199    clearEvents();
2200         if (omx_vid_dec) {
2201                 // first stop the omx elements
2202                 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
2203                         logger->debug(TAG, "vid_dec ChangeComponentState");
2204
2205                 }
2206                 clock_mutex.unlock();
2207
2208                 idleClock();
2209                 clock_mutex.lock();
2210
2211                 if (dodeint) {
2212                         if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) {
2213                                 LogNT::getInstance()->debug(TAG,
2214                                                 "vid_deint ChangeComponentState");
2215
2216                         }
2217                 }
2218
2219
2220                 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
2221                         logger->debug(TAG, "vid_shed ChangeComponentState");
2222
2223                 }
2224
2225                 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
2226                         logger->debug(TAG, "vid_rend ChangeComponentState");
2227
2228                 }
2229
2230
2231
2232         // TODO proper deinit sequence
2233                 // first flush all buffers
2234                 FlushRenderingPipe();
2235
2236
2237
2238
2239
2240                 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
2241                 if (error!=OMX_ErrorNone){
2242                         logger->debug(TAG, "OMX_Flush clock out failed {:#x}", error);
2243
2244                 }
2245
2246                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
2247                 if (error!=OMX_ErrorNone){
2248                         logger->debug(TAG, "OMX_Flush shed clock failed {:#x}", error);
2249
2250                 }
2251
2252                 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
2253                         !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
2254                                 logger->debug(TAG, "flush cmd clock shed failed");
2255                 }
2256
2257
2258
2259
2260                 error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
2261                                 omx_codec_input_port, NULL);
2262                 if (error != OMX_ErrorNone) {
2263                         LogNT::getInstance()->debug(TAG,
2264                                         "OMX_Flush codec out failed {:#x}", error);
2265
2266                 }
2267
2268
2269
2270
2271                 DestroyInputBufsOMX();
2272
2273                 //todo flushing
2274                 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
2275                         logger->debug(TAG, "Disable Tunnel Port failed 2");
2276                 }
2277                 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
2278                         logger->debug(TAG, "Disable Tunnel Port failed 1");
2279                 }
2280
2281
2282
2283
2284                 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
2285                         logger->debug(TAG, "Disable Tunnel Port failed 6");
2286                 }
2287
2288
2289
2290                 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
2291                         logger->debug(TAG, "Disable Tunnel Port failed 7");
2292                 }
2293
2294                 if (dodeint) {
2295                         if (!DisablePort(omx_vid_deint,omx_deint_output_port,true)) {
2296                                 logger->debug(TAG, "Disable Tunnel Port failed 6a");
2297                         }
2298
2299
2300
2301                         if (!DisablePort(omx_vid_deint,omx_deint_input_port,true)) {
2302                                 logger->debug(TAG, "Disable Tunnel Port failed 7a");
2303                         }
2304                 }
2305
2306
2307
2308                 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
2309                         logger->debug(TAG, "Disable Tunnel Port failed 3");
2310                 }
2311
2312                 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
2313                         logger->debug(TAG, "Disable Tunnel Port failed 4");
2314                 }
2315
2316                 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
2317                         logger->debug(TAG, "Disable Tunnel Port failed 5");
2318                 }
2319
2320
2321
2322
2323                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,0);
2324                 if (error!=OMX_ErrorNone) {
2325                         logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2326
2327                 }
2328
2329                 if (dodeint) {
2330                         error=OMX_SetupTunnel(omx_vid_deint,omx_deint_input_port,NULL,0);
2331                         if (error!=OMX_ErrorNone) {
2332                                 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2333                         }
2334
2335
2336                         error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,NULL,0);
2337                         if (error!=OMX_ErrorNone) {
2338                                 logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2339                         }
2340                 }
2341
2342                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,0);
2343                 if (error!=OMX_ErrorNone) {
2344                         logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2345
2346                 }
2347
2348
2349                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,0);
2350                 if (error!=OMX_ErrorNone) {
2351                         logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2352
2353                 }
2354
2355                 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,0);
2356                 if (error!=OMX_ErrorNone) {
2357                         logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2358
2359                 }
2360
2361
2362                 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,0);
2363                 if (error!=OMX_ErrorNone) {
2364                         logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2365
2366                 }
2367
2368                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,0);
2369                 if (error!=OMX_ErrorNone) {
2370                         logger->debug(TAG, "OMX_Setup tunnel teardown failed {:#x}", error);
2371
2372                 }
2373
2374
2375
2376
2377                 error=OMX_FreeHandle(omx_vid_dec);
2378                 error=OMX_FreeHandle(omx_vid_sched);
2379                 error=OMX_FreeHandle(omx_vid_rend);
2380                 if (dodeint) error=OMX_FreeHandle(omx_vid_deint);
2381                 omx_vid_dec=NULL;
2382                 omx_vid_stalled = false;
2383                 clock_mutex.unlock();
2384                 destroyClock();
2385                 if (error!=OMX_ErrorNone) {
2386                         logger->debug(TAG, "FreeHandle failed {}", error);
2387                 }
2388         } else  clock_mutex.unlock();
2389           logger->debug(TAG, "leave deallocate codecs OMX");
2390
2391         return 1;
2392 }
2393
2394
2395 void VideoOMX::destroyClock()
2396 {
2397         clock_mutex.lock();
2398         if (clock_references>0) {
2399                 clock_references--;
2400                 if (clock_references==0) {
2401                         OMX_ERRORTYPE error;
2402                         logger->debug(TAG, "destroy omx clock");
2403                         error=OMX_FreeHandle(omx_clock);
2404                         if (error!=OMX_ErrorNone) {
2405                                 logger->debug(TAG, "FreeHandle failed {}", error);
2406                         }
2407
2408                 }
2409         }
2410         clock_mutex.unlock();
2411
2412 }
2413
2414 int VideoOMX::stop()
2415 {
2416   if (!initted) return 0;
2417   iframemode=false;
2418
2419   //Check if libav mode
2420   DeAllocateCodecsOMX();
2421
2422
2423
2424
2425 //  if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2426   return 1;
2427 }
2428
2429 int VideoOMX::reset()
2430 {
2431   if (!initted) return 0;
2432
2433   iframemode=false;
2434   DeAllocateCodecsOMX();
2435 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2436   return 1;
2437 }
2438
2439 int VideoOMX::pause()
2440 {
2441   if (!initted) return 0;
2442   logger->debug(TAG, "enter pause");
2443  // clockPause();
2444   // ignore it audio handles this
2445   return 1;
2446 }
2447
2448 int VideoOMX::unPause() // FIXME get rid - same as play!! Not here!
2449 {
2450   if (!initted) return 0;
2451   logger->debug(TAG, "enter unpause");
2452
2453   //clockUnpause();
2454   //ignore it audio handles this
2455
2456   return 1;
2457 }
2458
2459 int VideoOMX::fastForward()
2460 {
2461   if (!initted) return 0;
2462
2463 //  if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2464   return 1;
2465 }
2466
2467 int VideoOMX::unFastForward()
2468 {
2469   if (!initted) return 0;
2470
2471 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2472
2473  //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2474   return 1;
2475 }
2476
2477 int VideoOMX::attachFrameBuffer()
2478 {
2479   if (!initted) return 0;
2480
2481 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2482   return 1;
2483 }
2484
2485 int VideoOMX::blank(void)
2486 {
2487 //  if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2488 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2489   return 1;
2490 }
2491
2492 u8 VideoOMX::getCurrentTimestamp() {
2493         if (iframemode)
2494                 return 0;
2495         long long ncur_clock_time = cur_clock_time;
2496         if (omx_running) {
2497                 int oldcancelstate;
2498                 int oldcanceltype;
2499                 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2500                 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2501                 clock_mutex.lock();
2502                 OMX_ERRORTYPE error;
2503                 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
2504                 memset(&clock_conf, 0, sizeof(clock_conf));
2505                 clock_conf.nSize = sizeof(clock_conf);
2506                 clock_conf.nVersion.nVersion = OMX_VERSION;
2507                 error= OMX_GetConfig(omx_clock, OMX_IndexConfigTimeClockState,
2508                                 &clock_conf);
2509                 if (error != OMX_ErrorNone) {
2510                         LogNT::getInstance()->debug(TAG,"getCurrentTimestamp IndexConfigTimeClockState failed {:#x}",error);
2511                 }
2512
2513                 if (clock_conf.eState == OMX_TIME_ClockStateRunning) {
2514
2515                         OMX_TIME_CONFIG_TIMESTAMPTYPE cur_time_stamp;
2516                         memset(&cur_time_stamp, 0, sizeof(cur_time_stamp));
2517                         cur_time_stamp.nSize = sizeof(cur_time_stamp);
2518                         cur_time_stamp.nVersion.nVersion = OMX_VERSION;
2519                         cur_time_stamp.nPortIndex = omx_clock_output_port;
2520                         error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
2521                                         &cur_time_stamp);
2522                         if (error != OMX_ErrorNone) {
2523                                 LogNT::getInstance()->debug(TAG, "getCurrentTimestamp OMX_IndexConfigTimeCurrentMediaTime failed {:#x}",error);
2524                         } else {
2525                                 long long temp = cur_time_stamp.nTimestamp.nLowPart
2526                                                 | ((long long) cur_time_stamp.nTimestamp.nHighPart << 32);
2527                                 ncur_clock_time = cur_clock_time = temp * 10LL;
2528                         }
2529                 }
2530                 clock_mutex.unlock();
2531                 pthread_setcancelstate(oldcancelstate, NULL);
2532                 pthread_setcanceltype(oldcanceltype, NULL);
2533         }
2534
2535         //ncur_clock_time -= startoffset;
2536         ncur_clock_time -= lastreftimeOMX;
2537         long long result = lastreftimePTS;
2538         if (lastreftimePTS==0) return 0; // invalid time
2539         result += (long long) (ncur_clock_time / 10000LL * 90LL);
2540         if (result < 0)
2541                 result = (1LL << 33) - result;
2542         //LogNT::getInstance()->debug(TAG,"getCurrentTimestamp {} {} {} {} {} {}",ncur_clock_time,cur_clock_time,lastreftimeOMX,lastreftimePTS,result,startoffset);
2543
2544         return result;
2545
2546 }
2547
2548 // to be removed
2549 /*
2550 u4 VideoOMX::timecodeToFrameNumber(u8 timecode)
2551 {
2552   if (format == PAL) return (u4)(((double)timecode / (double)90000) * (double)25);
2553   else               return (u4)(((double)timecode / (double)90000) * (double)30);
2554 }
2555
2556 */
2557 #ifdef DEV
2558 int VideoOMX::test()
2559 {
2560   return 0;
2561
2562 //  u8 stc = 0;
2563 //  return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2564 /*
2565  // reset();
2566   return 1;
2567 */
2568 }
2569
2570 int VideoOMX::test2()
2571 {
2572   return 0;
2573 }
2574 #endif
2575
2576
2577
2578 long long VideoOMX::SetStartOffset(long long curreftime, bool *rsync)
2579 {
2580   *rsync=false;
2581   if (offsetnotset) {
2582     startoffset=curreftime;//offset is set for audio
2583     offsetnotset=false;
2584     offsetvideonotset=false;
2585   } else {
2586     if (offsetvideonotset) {
2587       offsetvideonotset=false;
2588       *rsync=true;
2589     } else {
2590       if ( (curreftime-lastrefvideotime)>10000000LL
2591         || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
2592         startoffset+=curreftime-lastrefvideotime;
2593         lastrefaudiotime+=curreftime-lastrefvideotime;
2594         //*rsync=true;
2595         offsetaudionotset=true;
2596
2597       }
2598     }
2599
2600   }
2601
2602   lastrefvideotime=curreftime;
2603
2604   return startoffset;
2605
2606 }
2607
2608 long long VideoOMX::SetStartAudioOffset(long long curreftime, bool *rsync)
2609 {
2610   *rsync=false;
2611   if (offsetnotset) {
2612     startoffset=curreftime;
2613     offsetnotset=false;
2614     offsetaudionotset=false;
2615   }else {
2616     if (offsetaudionotset) {
2617       offsetaudionotset=false;
2618       *rsync=true;
2619     } else {
2620       if ( (curreftime-lastrefaudiotime)>10000000LL
2621         || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
2622         startoffset+=curreftime-lastrefaudiotime;
2623         lastrefvideotime+=curreftime-lastrefaudiotime;
2624         //*rsync=true;
2625         offsetvideonotset=true;
2626
2627       }
2628     }
2629
2630   }
2631   lastrefaudiotime=curreftime;
2632   return startoffset;
2633
2634 }
2635
2636 void VideoOMX::ResetTimeOffsets() {
2637   offsetnotset=true; //called from demuxer
2638   offsetvideonotset=true;
2639   offsetaudionotset=true;
2640   startoffset=0;
2641   lastrefaudiotime=0;
2642   lastrefvideotime=0;
2643   lastreftimeOMX=0;
2644   lastreftimePTS=0;
2645 }
2646
2647
2648 void VideoOMX::FirstFrameFix()
2649 {
2650         int oldcancelstate;
2651         int oldcanceltype;
2652         Demuxer* demux=Demuxer::getInstance();
2653         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2654         pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2655         clock_mutex.lock();
2656         if (WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged,0)){
2657                 WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged,0); //clear old messages
2658                 OMX_ERRORTYPE error;
2659                 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
2660                 memset(&port_def_type,0,sizeof(port_def_type));
2661                 port_def_type.nSize=sizeof(port_def_type);
2662                 port_def_type.nVersion.nVersion=OMX_VERSION;
2663                 port_def_type.nPortIndex=omx_codec_output_port;
2664
2665                 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
2666                 if (error != OMX_ErrorNone) {
2667                         LogNT::getInstance()->debug(TAG,
2668                                         "OMX_IndexParamPortDefinition fix failed {:#x}", error);
2669                         clock_mutex.unlock();
2670                         return;
2671                 }
2672
2673
2674                 LogNT::getInstance()->debug(TAG,
2675                                                         "Deinit first frame fix {} {} {} {} {} {} {} {}",port_def_type.format.video.nFrameWidth , demux->getHorizontalSize(),
2676                                                         port_def_type.format.video.nFrameHeight , demux->getVerticalSize(),port_def_type.format.video.nStride,
2677                                                         port_def_type.format.video.nSliceHeight, port_def_type.format.video.xFramerate,
2678                                                          port_def_type.format.video.bFlagErrorConcealment );
2679                 LogNT::getInstance()->debug(TAG,
2680                                                                         "Deinit first frame fix2 {}  {}",
2681                                                                         port_def_type.format.video.eCompressionFormat ,
2682                                                                         port_def_type.format.video.eColorFormat );
2683                 first_frame=false;
2684
2685                 // we cause the video_decode to determine the interlacing properties
2686                 OMX_CONFIG_INTERLACETYPE il;
2687                 memset(&il,0,sizeof(il));
2688                 il.nSize=sizeof(il);
2689                 il.nVersion.nVersion=OMX_VERSION;
2690                 il.nPortIndex=omx_codec_output_port;
2691                 error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigCommonInterlace, &il);
2692                 if (error != OMX_ErrorNone) {
2693                         LogNT::getInstance()->debug(TAG,
2694                                         "OMX_IndexConfigCommonInterlace fix failed {:#x}", error);
2695                 }
2696
2697
2698                 DisablePort(omx_vid_dec,omx_codec_output_port,true);
2699                 DisablePort(omx_vid_sched,omx_shed_input_port,true);
2700                 if (dodeint) {
2701
2702                         DisablePort(omx_vid_deint,omx_deint_input_port,true);
2703                         // This is a dirty hack
2704                         DisablePort(omx_vid_deint,omx_deint_output_port,true);
2705
2706
2707                         port_def_type.nPortIndex=omx_deint_output_port;
2708                         error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2709                                         &port_def_type);
2710                         if (error != OMX_ErrorNone) {
2711                                 LogNT::getInstance()->debug(TAG,
2712                                                 "Set OMX_IndexParamPortDefinition1 failed {:#x}", error);
2713                                 clock_mutex.unlock();
2714                                 pthread_setcancelstate(oldcancelstate, NULL);
2715                                 pthread_setcanceltype(oldcanceltype, NULL);
2716                                 return;
2717                         }
2718                         // dirty hack end
2719
2720
2721                         port_def_type.nPortIndex=omx_deint_input_port;
2722                         error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2723                                         &port_def_type);
2724                         if (error != OMX_ErrorNone) {
2725                                 LogNT::getInstance()->debug(TAG,
2726                                                 "Set OMX_IndexParamPortDefinition1 failed {:#x}", error);
2727                                 clock_mutex.unlock();
2728                                 pthread_setcancelstate(oldcancelstate, NULL);
2729                                 pthread_setcanceltype(oldcanceltype, NULL);
2730                                 return;
2731                         }
2732                 //      WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged);
2733
2734                         LogNT::getInstance()->debug(TAG,
2735                                                                         "Marker");
2736                         EnablePort(omx_vid_deint,omx_deint_input_port,true);
2737                         WaitForEvent(omx_vid_deint,OMX_EventPortSettingsChanged);
2738                         port_def_type.nPortIndex=omx_deint_output_port;
2739                         error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
2740                                         &port_def_type);
2741                         if (error != OMX_ErrorNone) {
2742                                 LogNT::getInstance()->debug(TAG,
2743                                                 "Get OMX_IndexParamPortDefinition2 failed {:#x}", error);
2744                                 clock_mutex.unlock();
2745                                 pthread_setcancelstate(oldcancelstate, NULL);
2746                                 pthread_setcanceltype(oldcanceltype, NULL);
2747                                 return;
2748                         }
2749                         LogNT::getInstance()->debug(TAG,
2750                                         "Deinit first frame fix3 {} {} {} {} {} {} {} ",port_def_type.format.image.nFrameWidth , demux->getHorizontalSize(),
2751                                         port_def_type.format.image.nFrameHeight , demux->getVerticalSize(),port_def_type.format.image.nStride,
2752                                         port_def_type.format.image.nSliceHeight, /*port_def_type.format.image.xFramerate,*/
2753                                         port_def_type.format.image.bFlagErrorConcealment );
2754                         LogNT::getInstance()->debug(TAG,
2755                                         "Deinit first frame fix4 {}  {}",
2756                                         port_def_type.format.image.eCompressionFormat ,
2757                                         port_def_type.format.image.eColorFormat );
2758                         DisablePort(omx_vid_deint,omx_deint_output_port,true);
2759
2760                 }
2761                 port_def_type.nPortIndex=omx_shed_input_port;
2762                 error = OMX_SetParameter(omx_vid_sched, OMX_IndexParamPortDefinition,
2763                                         &port_def_type);
2764                 if (error != OMX_ErrorNone) {
2765                         LogNT::getInstance()->debug(TAG,
2766                                         "Set OMX_IndexParamPortDefinition3 failed {:#x}", error);
2767                         clock_mutex.unlock();
2768                         pthread_setcancelstate(oldcancelstate, NULL);
2769                         pthread_setcanceltype(oldcanceltype, NULL);
2770                         return;
2771                 }
2772                 WaitForEvent(omx_vid_sched,OMX_EventPortSettingsChanged);
2773
2774
2775                 if (dodeint) {
2776                         EnablePort(omx_vid_deint,omx_deint_output_port,true);
2777                 }
2778                 EnablePort(omx_vid_dec,omx_codec_output_port,true);
2779                 EnablePort(omx_vid_sched,omx_shed_input_port,true);
2780         }
2781         clock_mutex.unlock();
2782         pthread_setcancelstate(oldcancelstate, NULL);
2783         pthread_setcanceltype(oldcanceltype, NULL);
2784
2785
2786
2787 }
2788
2789
2790 void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer)
2791 {
2792
2793         OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, buffer);
2794         if (error != OMX_ErrorNone) {
2795                 LogNT::getInstance()->debug(TAG,
2796                                 "OMX_EmptyThisBuffer failed {:#x}", error);
2797         }
2798         if (first_frame) FirstFrameFix();
2799
2800 }
2801
2802 OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer)
2803 {
2804         // protect the call to empty this buffer
2805         int oldcancelstate;
2806         int oldcanceltype;
2807 /*      long long temp =buffer->nTimeStamp.nLowPart
2808                                                         | ((long long) buffer->nTimeStamp.nHighPart << 32);*/
2809
2810         //pthread_testcancel();
2811         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2812         pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2813         clock_mutex.lock();
2814 // Diagnosis code
2815 /*      OMX_ERRORTYPE error;
2816         OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp;
2817         memset(&timestamp, 0, sizeof(timestamp));
2818         timestamp.nSize = sizeof(timestamp);
2819         timestamp.nVersion.nVersion = OMX_VERSION;
2820         timestamp.nPortIndex =omx_clock_output_port;
2821
2822         error = OMX_GetConfig(omx_clock, OMX_IndexConfigTimeCurrentMediaTime,
2823                         &timestamp);
2824
2825         if (error != OMX_ErrorNone) {
2826                 LogNT::getInstance()->debug(TAG,
2827                                 "Init OMX_IndexConfigAudioRenderingLatencyfailed {:#x} {}", error,
2828                                 omx_rend_input_port);
2829         }
2830         long long temp2 =timestamp.nTimestamp.nLowPart
2831                                                                 | ((long long) timestamp.nTimestamp.nHighPart << 32);
2832
2833
2834         LogNT::getInstance()->info(TAG, "OMXETB {:#x} {} {} {:#x}",handle,temp,temp2,buffer->nFlags);*/
2835         OMX_ERRORTYPE ret_val;
2836         ret_val=OMX_EmptyThisBuffer(handle,buffer);
2837         clock_mutex.unlock();
2838         pthread_setcancelstate(oldcancelstate, NULL);
2839         pthread_setcanceltype(oldcanceltype, NULL);
2840         //pthread_testcancel();
2841         return ret_val;
2842 }
2843
2844 bool VideoOMX::detectIFrame(const u1 *buffer,unsigned int length)
2845 {
2846         const u1* curbuf=buffer;
2847         const u1* curbufend=buffer+length;
2848         unsigned int detector=0xFFFFFFFF;
2849         bool gotaud=false; // have seen access unit delimiter
2850
2851         while (curbuf!=curbufend) {
2852                 detector<<=8;
2853                 detector|=*curbuf;
2854                 if (h264) {
2855                         if (detector==0x00000109) {
2856                                 gotaud=true;
2857                                 detector=0xFFFFFFFF;
2858                         } else if (gotaud &&detector==0x00000001) {
2859                                 curbuf++;
2860                                 if (curbuf!=curbufend) {
2861                                         unsigned char picttype=(*curbuf)& 0x1F;
2862                                         return picttype==0x07;
2863                                 }
2864                         }
2865                 } else {
2866                         if (detector==0x00000100) {
2867                                 curbuf++;
2868                                 if (curbuf==curbufend) return false;
2869                                 curbuf++;
2870                                 if (curbuf==curbufend) return false;
2871                                 unsigned char picttype=((*curbuf) >> 3) & 0x07;
2872                                 return picttype==1;
2873                         }
2874                 }
2875                 curbuf++;
2876         }
2877
2878         return false; // no frame found
2879 }
2880
2881
2882
2883 bool VideoOMX::DrainTargetBufferFull()
2884 {
2885         //Check, if we have OMX output buffers
2886         bool full;
2887         input_bufs_omx_mutex.lock();
2888         full=(input_bufs_omx_free.size()==0);
2889         input_bufs_omx_mutex.unlock();
2890         checkForStalledBuffers(); // check if the decoder has a problem
2891         if (full && omx_vid_stalled && !omx_first_frame) {
2892                 omx_vid_stalled=false;
2893                 logger->debug(TAG, "Decoder is stalled, do a reset!");
2894
2895                 int oldcancelstate;
2896                 int oldcanceltype;
2897                 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
2898                 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
2899
2900                 clock_mutex.lock();
2901                 FlushRenderingPipe();
2902                 omx_first_frame=true;
2903                 clock_mutex.unlock();
2904
2905                 pthread_setcancelstate(oldcancelstate, NULL);
2906                 pthread_setcanceltype(oldcanceltype, NULL);
2907         }
2908         return full;
2909
2910 }
2911
2912 void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist, u4 /* samplepos */)
2913 {
2914
2915         mediapackets.clear();
2916         std::list<MediaPacket>::const_iterator begin=mplist.begin();
2917         std::list<MediaPacket>::const_iterator itty=mplist.begin();
2918         advance(itty,std::min(mplist.size(),10U));
2919         mediapackets.insert(mediapackets.begin(),begin,itty);//front
2920
2921 }
2922
2923 u4 VideoOMX::DeliverMediaSample(u1* buffer, u4 *samplepos)
2924 {
2925         u4 consumed=0;
2926         while (consumed < mediapackets.size()) {
2927             DeliverMediaPacket(mediapackets[consumed], buffer, samplepos);
2928             if (*samplepos == mediapackets[consumed].length) {
2929                 *samplepos = 0;
2930                 consumed++;
2931                 //return 1;
2932             } else return consumed;
2933         }
2934         return consumed;
2935 }
2936
2937 u4 VideoOMX::DeliverMediaPacket(MediaPacket packet,
2938                 const u1* buffer,
2939                 u4 *samplepos)
2940 {
2941         if (packet.type == MPTYPE_VIDEO_H264)
2942         {
2943                 h264=true;
2944         }
2945         else
2946         {
2947                 h264=false;
2948         }
2949
2950
2951         //Later add fail back code for libav
2952 /*      if (!videoon) {
2953                 *samplepos+=packet.length;
2954                 return packet.length;
2955         }*/
2956
2957
2958         if (!omx_running) return 0; // if we are not runnig do not do this
2959
2960         if (isClockPaused()) return 0; //Block if we pause
2961
2962 //      logger->debug(TAG, "DMP mark 1");
2963         //logger->debug(TAG, "DeliverMediaPacketOMX time {}", packet.presentation_time);
2964
2965
2966         /*First Check, if we have an video sample*/
2967         if (iframemode) {
2968                 //samplepos=0;
2969                 MILLISLEEP(10);
2970                 return 0; //Not in iframe mode!
2971         }
2972
2973         u4 headerstrip=0;
2974         if (packet.disconti) {
2975                 firstsynched=false;
2976                 if (cur_input_buf_omx) {
2977                         PutBufferToPres(cur_input_buf_omx);
2978                         cur_input_buf_omx=NULL;
2979                 }
2980         }
2981         //logger->debug(TAG, "DMP mark 2");
2982         /*Inspect PES-Header */
2983
2984 //      OMX_STATETYPE temp_state;
2985 //      OMX_GetState(omx_vid_dec,&temp_state);
2986
2987         if (*samplepos==0) {//stripheader
2988                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2989         //      if (h264) logger->debug(TAG, "PES info {:#x} {:#x} {:#x} {:#x}",
2990         //                      buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
2991                 *samplepos+=headerstrip;
2992                 if (headerstrip>=packet.length) {
2993                      *samplepos=packet.length;// Packet is obviously damaged
2994                      return packet.length;//skip it!
2995                 }
2996                 if ( packet.synched ) {
2997                         if (!firstsynched) {
2998                                 //logger->debug(TAG, "DMP mark 2a");
2999                           // check if this is an I frame, the decoder does not like non I frames at startup!
3000                           if (!detectIFrame(buffer,packet.length)) {
3001                                   *samplepos=packet.length;//if we have not processed at least one
3002                                   //logger->debug(TAG, "DMP mark 3");
3003                                   return packet.length;//synched packet ignore it!
3004                           }
3005                         }
3006                         if (cur_input_buf_omx) {
3007                                 //logger->debug(TAG, "DMP mark 4a");
3008                                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
3009                                 PutBufferToPres(cur_input_buf_omx);
3010                                 cur_input_buf_omx=NULL;//write out old data
3011
3012                                 //logger->debug(TAG, "DMP mark 4b");
3013
3014                         }
3015                         firstsynched=true;
3016                 } else {
3017                         if (!firstsynched) {//
3018                                 *samplepos=packet.length;//if we have not processed at least one
3019                                 //logger->debug(TAG, "DMP mark 5");
3020                                 return packet.length;//synched packet ignore it!
3021                         }
3022                 }
3023         }
3024         //logger->debug(TAG, "DMP mark 6");
3025         if (!cur_input_buf_omx) {
3026                 input_bufs_omx_mutex.lock();
3027                 if (input_bufs_omx_free.size()==0) {
3028                         input_bufs_omx_mutex.unlock();
3029                         //logger->debug(TAG, "Deliver MediaPacket no free sample");
3030                         //logger->debug(TAG, "DMP mark 7");
3031                         return 0; // we do not have a free media sample
3032
3033                 }
3034                 cur_input_buf_omx=input_bufs_omx_free.front();
3035                 cur_input_buf_omx->nFilledLen=0;
3036                 cur_input_buf_omx->nOffset=0;
3037                 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3038                 input_bufs_omx_free.pop_front();
3039                 input_bufs_omx_mutex.unlock();
3040         }
3041
3042
3043
3044
3045         if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
3046                 if (packet.synched) {
3047                 //      logger->debug(TAG, "packet synched marker");
3048
3049                         //lastreftimePTS=packet.pts;
3050                    if (omx_first_frame) { // TODO time
3051                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
3052                            logger->debug(TAG, "Starttime");
3053                            omx_first_frame=false;
3054                    } else {
3055                            cur_input_buf_omx->nFlags=0;
3056                            //cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
3057                    }
3058                    lastreftimeOMX=packet.presentation_time;
3059                   // logger->debug(TAG, "Time code {} pts {}", lastreftimeOMX,packet.pts);
3060                    lastreftimePTS=packet.pts;
3061                    cur_input_buf_omx->nTimeStamp=intToOMXTicks(lastreftimeOMX/10LL); // the clock component is faulty;
3062                 }
3063                 else
3064                 {
3065                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3066                         cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3067                         //logger->debug(TAG, "packet unsynched marker");
3068                 }
3069                 if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
3070
3071
3072
3073         }
3074         unsigned int haveToCopy=packet.length-*samplepos;
3075         //logger->debug(TAG, "DMP mark 8");
3076
3077         while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
3078                 //logger->debug(TAG, "Big buffer {} {} {}",packet.length,cur_input_buf_omx->nAllocLen,cur_input_buf_omx->nFilledLen);
3079                 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
3080                 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
3081                 haveToCopy-=cancopy;
3082                 cur_input_buf_omx->nFilledLen+=cancopy;
3083                 *samplepos+=cancopy;
3084                 // push old buffer out
3085                 //logger->debug(TAG, "DMP mark 9");
3086
3087                 PutBufferToPres(cur_input_buf_omx);
3088                 cur_input_buf_omx=NULL;
3089                 // get5 new buffer
3090                 input_bufs_omx_mutex.lock();
3091                 if (input_bufs_omx_free.size()==0) {
3092                         input_bufs_omx_mutex.unlock();
3093                 //      logger->debug(TAG, "Deliver MediaPacket no free sample2");
3094                         return *samplepos; // we do not have a free media sample
3095                 }
3096                 cur_input_buf_omx=input_bufs_omx_free.front();
3097                 cur_input_buf_omx->nFilledLen=0;
3098                 cur_input_buf_omx->nOffset=0;
3099                 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
3100                 cur_input_buf_omx->nTimeStamp=intToOMXTicks(0);
3101                 input_bufs_omx_free.pop_front();
3102                 input_bufs_omx_mutex.unlock();
3103                 //logger->debug(TAG, "DMP mark 10");
3104
3105         }
3106         memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
3107                         buffer+packet.pos_buffer+*samplepos,haveToCopy);
3108         cur_input_buf_omx->nFilledLen+=haveToCopy;
3109
3110 //      logger->debug(TAG, "DMP mark 11");
3111
3112         *samplepos+=haveToCopy;
3113
3114         return *samplepos;
3115
3116 }
3117
3118
3119
3120
3121 bool VideoOMX::displayIFrame(const u1* buffer, u4 length) {
3122         if (!omx_running) return false;
3123         if (!iframemode)
3124                 EnterIframePlayback();
3125
3126         //int haveToCopy = length;
3127
3128         if (!cur_input_buf_omx) {
3129                 input_bufs_omx_mutex.lock();
3130                 if (input_bufs_omx_free.size() == 0) {
3131                         input_bufs_omx_mutex.unlock();
3132                 //      LogNT::getInstance()->debug(TAG,
3133                         //              "Deliver MediaPacket no free sample");
3134                         return false; // we do not have a free media sample
3135
3136                 }
3137                 cur_input_buf_omx = input_bufs_omx_free.front();
3138                 cur_input_buf_omx->nFilledLen = 0;
3139                 cur_input_buf_omx->nOffset = 0;
3140                 cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3141                 input_bufs_omx_free.pop_front();
3142                 input_bufs_omx_mutex.unlock();
3143         }
3144
3145         u4 read_pos = 0;
3146         unsigned int pattern, packet_length;
3147         unsigned int headerstrip = 0;
3148         bool first = true;
3149         if (length < 4){
3150                 return false;
3151         }
3152         //Now we strip the pes header
3153         pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
3154         while ((read_pos + 7) <= length) {
3155                 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3];
3156                 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
3157                         read_pos++;
3158                         continue;
3159                 } else {
3160                         headerstrip = buffer[read_pos + 8] + 9/*is this right*/;
3161                         packet_length = ((buffer[read_pos + 4] << 8)
3162                                         | (buffer[read_pos + 5])) + 6;
3163                         if (read_pos + packet_length > length)
3164                                 read_pos = length;
3165                         else {
3166                                 if ((headerstrip < packet_length)
3167                                                 && (cur_input_buf_omx->nFilledLen + packet_length
3168                                                                 - headerstrip) > cur_input_buf_omx->nAllocLen) {
3169                                         if (first) {
3170                                                 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3171
3172                                         } else {
3173                                                 cur_input_buf_omx->nFlags
3174                                                                 |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3175
3176                                         }
3177                                         cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3178                                         PutBufferToPres(cur_input_buf_omx);
3179                                         cur_input_buf_omx = NULL;
3180
3181                                         if (!cur_input_buf_omx) {
3182                                                 int count = 0;
3183                                                 while (count < 100 && omx_running && iframemode) {
3184                                                         count++;
3185
3186                                                         input_bufs_omx_mutex.lock();
3187                                                         if (input_bufs_omx_free.size() == 0) {
3188                                                                 input_bufs_omx_mutex.unlock();
3189                                         //                      LogNT::getInstance()->debug(TAG,
3190                                                 //                              "Ifrane no free sample");
3191                                                                 MILLISLEEP(5);
3192                                                                 if (!omx_running) return false;
3193                                                                 continue;
3194                                                         }
3195                                                         cur_input_buf_omx = input_bufs_omx_free.front();
3196                                                         cur_input_buf_omx->nFilledLen = 0;
3197                                                         cur_input_buf_omx->nOffset = 0;
3198                                                         cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3199                                                         cur_input_buf_omx->nFlags|= OMX_BUFFERFLAG_TIME_UNKNOWN;
3200                                                         input_bufs_omx_free.pop_front();
3201                                                         input_bufs_omx_mutex.unlock();
3202                                                         break;
3203                                                 }
3204                                                 if (!cur_input_buf_omx)
3205                                                         return false;
3206                                         }
3207
3208                                 }
3209                                 if (packet_length > headerstrip) {
3210                                         memcpy(
3211                                                         cur_input_buf_omx->pBuffer
3212                                                                         + cur_input_buf_omx->nFilledLen,
3213                                                         buffer + read_pos + headerstrip,
3214                                                         packet_length - headerstrip);
3215                                         cur_input_buf_omx->nFilledLen += packet_length
3216                                                         - headerstrip;
3217                                 }
3218                                 read_pos += packet_length;
3219
3220                                 pattern = (buffer[read_pos] << 16)
3221                                                 | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]);
3222                         }
3223                 }
3224         }
3225
3226         if (first) {
3227                 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
3228
3229         } else {
3230                 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
3231
3232         }
3233         cur_input_buf_omx->nTimeStamp = intToOMXTicks(0);
3234
3235         PutBufferToPres(cur_input_buf_omx);
3236         cur_input_buf_omx = NULL;
3237
3238
3239         MILLISLEEP(40); //Block a bit
3240         return true;
3241 }
3242
3243 int VideoOMX::EnterIframePlayback()
3244 {
3245         LogNT::getInstance()->debug(TAG,
3246                                                 "EnterIframePlayback");
3247         if (cur_input_buf_omx) {
3248                 PutBufferToPres(cur_input_buf_omx);
3249                 cur_input_buf_omx = NULL;
3250         }
3251         LogNT::getInstance()->debug(TAG,
3252                                                         "EnterIframePlayback 2");
3253         dynamic_cast<AudioOMX*>(Audio::getInstance())->DeAllocateCodecsOMX();
3254         DeAllocateCodecsOMX();
3255         AllocateCodecsOMX();
3256         LogNT::getInstance()->debug(TAG,
3257                                                         "leave IframePlayback");
3258
3259         iframemode=true;
3260
3261         return 1;
3262 }
3263