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