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