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