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