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