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