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