]> git.vomp.tv Git - vompclient.git/blob - videoomx.cc
Remove legacy output code and enhance new Stream interface
[vompclient.git] / videoomx.cc
1 /*
2     Copyright 2004-2005 Chris Tallon, 2009 Marten Richter
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #include "videoomx.h"
22 #include "audioomx.h"
23 #include "mtdraspberry.h"
24 #include "demuxer.h"
25 #include "osdopengl.h"
26
27 // temp
28 #include "log.h"
29
30 //A lot of parts of this file are heavily inspired by xbmc omx implementations
31
32 VideoOMX::VideoOMX() {
33
34         omx_running = false;
35
36         omx_vid_dec = 0;
37         cur_input_buf_omx = NULL;
38         omx_h264 = omx_mpeg2 = true;
39         clock_references = 0;
40
41         offsetnotset = true;
42         offsetvideonotset = true;
43         offsetaudionotset = true;
44         startoffset = 0;
45         lastrefaudiotime = 0;
46         lastrefvideotime = 0;
47         lastreftimeOMX = 0;
48         lastreftimePTS = 0;
49         firstsynched = false;
50
51 }
52
53 VideoOMX::~VideoOMX()
54 {
55   instance = NULL;
56 }
57
58 int VideoOMX::init(UCHAR tformat)
59 {
60   if (initted) return 0;
61   initted = 1;
62
63   if (!setFormat(tformat))           { shutdown(); return 0; }
64   if (!setConnection(COMPOSITERGB))  { shutdown(); return 0; }
65   if (!setAspectRatio(ASPECT4X3))    { shutdown(); return 0; }
66   if (!setMode(NORMAL))              { shutdown(); return 0; }
67   if (!setSource())                  { shutdown(); return 0; }
68   if (!attachFrameBuffer())          { shutdown(); return 0; }
69
70   setTVsize(ASPECT4X3);
71
72
73
74
75
76   //stop();
77
78
79
80   return 1;
81 }
82
83 int VideoOMX::initUsingOSDObjects()
84 {
85
86 // we are called before the audio
87         OMX_ERRORTYPE error;
88         error=OMX_Init();
89         if (error!=OMX_ErrorNone) {
90                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error);
91                 return 0;
92         }
93
94         return 1;
95 }
96
97
98 OMX_ERRORTYPE VideoOMX::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
99            OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
100            OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
101
102         Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
103
104         struct VPE_OMX_EVENT  new_event;
105         new_event.handle=handle;
106         new_event.appdata=appdata;
107         new_event.event_type=event_type;
108         new_event.data1=data1;
109         new_event.data2=data2;
110         new_event.event_data=event_data;
111
112         VideoOMX *video=(VideoOMX *)getInstance();
113         video->AddOmxEvent(new_event);
114
115 /*      switch (event_type) {
116         case OMX_EventCmdComplete: {
117
118         } break;
119         }*/
120
121         return OMX_ErrorNone;
122
123 }
124
125 void VideoOMX::AddOmxEvent(VPE_OMX_EVENT  new_event)
126 {
127         omx_event_mutex.Lock();
128     omx_events.push_back(new_event);
129         omx_event_mutex.Unlock();
130 }
131
132
133 OMX_ERRORTYPE VideoOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
134
135         //Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
136         VideoOMX *video=(VideoOMX *)getInstance();
137         video->ReturnEmptyOMXBuffer(buffer);
138         return OMX_ErrorNone;
139
140 }
141
142 void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
143         input_bufs_omx_mutex.Lock();
144         //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
145         input_bufs_omx_free.push_back(buffer);
146         //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
147         input_bufs_omx_mutex.Unlock();
148 }
149
150  OMX_ERRORTYPE VideoOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
151          Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
152         return OMX_ErrorNone;
153 }
154
155
156
157 int VideoOMX::shutdown()
158 {
159   if (!initted) return 0;
160   initted = 0;
161
162   DeAllocateCodecsOMX();
163   OMX_Deinit();
164   return 1;
165 }
166
167
168 int VideoOMX::setTVsize(UCHAR ttvsize)
169 {
170 /*  tvsize = ttvsize;
171
172   // Override the aspect ratio usage, temporarily use to set the video chip mode
173   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
174   close(fdVideo);
175   if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
176   if (!setSource())                  { shutdown(); return 0; }
177   if (!attachFramebuffer())          { shutdown(); return 0; }
178
179   // Reopening the fd causes the scart aspect line to go back to 4:3
180   // Set this again to the same as the tv screen size
181   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
182
183   // mode == LETTERBOX is invalid if the TV is widescreen
184   if (tvsize == ASPECT16X9) setMode(NORMAL);
185 */
186   return 1;
187 }
188
189 int VideoOMX::setDefaultAspect()
190 {
191   return setAspectRatio(tvsize);
192 }
193
194
195
196 int VideoOMX::setFormat(UCHAR tformat)
197 {
198   if (!initted) return 0;
199   if ((tformat != PAL) && (tformat != NTSC)) return 0;
200   format = tformat;
201
202 //  if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
203
204   if (format == NTSC)
205   {
206     screenWidth = 720;
207     screenHeight = 480;
208   }
209   if (format == PAL)
210   {
211     screenWidth = 720;
212     screenHeight = 576;
213   }
214
215   return 1;
216 }
217
218 int VideoOMX::setConnection(UCHAR tconnection)
219 {
220   if (!initted) return 0;
221   if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
222   connection = tconnection;
223
224 //  if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
225   return 1;
226 }
227
228 int VideoOMX::setAspectRatio(UCHAR taspectRatio)
229 {
230   if (!initted) return 0;
231   if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
232   aspectRatio = taspectRatio;
233
234   Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
235
236 //  if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
237   return 1;
238 }
239
240 int VideoOMX::setMode(UCHAR tmode)
241 {
242   if (!initted) return 0;
243
244   if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
245
246   if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
247       && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
248   mode = tmode;
249
250 //  if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
251   return 1;
252 }
253
254 int VideoOMX::signalOff()
255 {
256 //  if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
257   return 1;
258 }
259
260 int VideoOMX::signalOn()
261 {
262 //  if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
263   return 1;
264 }
265
266 int VideoOMX::setSource()
267 {
268   if (!initted) return 0;
269
270   // What does this do...
271 //  if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
272   return 1;
273 }
274
275 int VideoOMX::setPosition(int x, int y)
276 {
277   if (!initted) return 0;
278
279 //  vid_pos_regs_t pos_d;
280 //  pos_d.x = x;
281 //  pos_d.y = y;
282
283 /*  vid_pos_regs_t pos_d;
284
285   memset(&pos_d, 0, sizeof(pos_d));
286
287   pos_d.dest.y = y;
288   pos_d.dest.x = x;
289 /*
290 typedef struct {
291   int w;
292   int h;
293   int scale;
294   int x1;
295   int y;
296   int x;
297   int y2;
298   int x3;
299   int y3;
300   int x4;
301   int y4;
302 } vid_pos_regs_t;
303 */
304
305 /*
306   pos_d.w = 100;
307   pos_d.h = 30;
308   pos_d.scale = 2;
309   pos_d.x1 = 0;
310   pos_d.y = 100;            // Top left X
311   pos_d.x = 50;            // Top left Y
312   pos_d.y2 = 30;
313   pos_d.x3 = 60;
314   pos_d.y3 = 90;
315   pos_d.x4 = 120;
316   pos_d.y4 = 150;
317 */
318
319 //  if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
320   return 1;
321 }
322
323 int VideoOMX::sync()
324 {
325   if (!initted) return 0;
326
327 //  if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
328   return 1;
329 }
330
331
332 int VideoOMX::play() {
333         if (!initted)
334                 return 0;
335         iframemode = false;
336         Log::getInstance()->log("Video", Log::DEBUG, "enter play");
337
338         if (AllocateCodecsOMX()) {
339                 return 1;
340                 // Otherwise fall back to libav
341         } else {
342                 if (h264) {
343                         omx_h264 = false;
344                         Log::getInstance()->log("Video", Log::NOTICE,
345                                         "Allocate Codecs OMX failed assume h264 unsupported");
346                 } else {
347                         omx_mpeg2 = false;
348                         Log::getInstance()->log("Video", Log::NOTICE,
349                                         "Allocate Codecs OMX failed assume mpeg2 unsupported");
350                 }
351         }
352
353         return 0;
354
355 }
356
357
358 int VideoOMX::initClock()
359 {
360         OMX_ERRORTYPE error;
361         clock_mutex.Lock();
362         if (clock_references==0)
363         {
364
365                 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
366                 omx_events.clear();
367
368                 error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
369
370                 if (error!=OMX_ErrorNone) {
371                         Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
372                         clock_mutex.Unlock();
373                         DeAllocateCodecsOMX();
374                         return 0;
375                 }
376
377                 /* TODO Clock config to separate method */
378                 OMX_PORT_PARAM_TYPE p_param;
379                 memset(&p_param,0,sizeof(p_param));
380                 p_param.nSize=sizeof(p_param);
381                 p_param.nVersion.nVersion=OMX_VERSION;
382                 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
383                 if (error!=OMX_ErrorNone) {
384                         Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
385                         clock_mutex.Unlock();
386                         DeAllocateCodecsOMX();
387                         return 0;
388                 }
389                 omx_clock_output_port=p_param.nStartPortNumber;
390
391                 for (unsigned int i=0;i<p_param.nPorts;i++) {
392                         if (!DisablePort(omx_clock,p_param.nStartPortNumber+i,true) ) {
393                                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
394                                 clock_mutex.Unlock();
395                                 DeAllocateCodecsOMX();
396                                 return 0;
397                         }
398                 }
399
400
401
402
403         }
404         Log::getInstance()->log("Video", Log::DEBUG, "init omx clock %x %x",this,omx_clock);
405         clock_references++;
406         clock_mutex.Unlock();
407         return 1;
408 }
409
410 int VideoOMX::getClockAudioandInit(OMX_HANDLETYPE *p_omx_clock,OMX_U32 *p_omx_clock_output_port)
411 {
412         OMX_ERRORTYPE error;
413         *p_omx_clock=NULL;
414         *p_omx_clock_output_port=0;
415
416         if (!initClock()) {
417                 return 0;
418         }
419         clock_mutex.Lock();
420
421         OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
422         memset(&refclock,0,sizeof(refclock));
423         refclock.nSize=sizeof(refclock);
424         refclock.nVersion.nVersion=OMX_VERSION;
425
426         refclock.eClock=OMX_TIME_RefClockAudio;
427
428         //refclock.eClock=OMX_TIME_RefClockVideo;
429         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
430         if (error!=OMX_ErrorNone){
431                 Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
432                 clock_mutex.Unlock();
433                 DeAllocateCodecsOMX();
434                 return 0;
435         }
436
437         OMX_PORT_PARAM_TYPE p_param;
438         memset(&p_param,0,sizeof(p_param));
439         p_param.nSize=sizeof(p_param);
440         p_param.nVersion.nVersion=OMX_VERSION;
441         error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
442         if (error!=OMX_ErrorNone){
443                 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
444                 clock_mutex.Unlock();
445                 DeAllocateCodecsOMX();
446                 return 0;
447         }
448
449         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
450         memset(&clock_conf,0,sizeof(clock_conf));
451         clock_conf.nSize=sizeof(clock_conf);
452         clock_conf.nVersion.nVersion=OMX_VERSION;
453         clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
454         clock_conf.nStartTime=0;
455         clock_conf.nOffset=0;
456         if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT1;
457         else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
458         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
459         if (error!=OMX_ErrorNone) {
460                 Log::getInstance()->log("Video", Log::DEBUG, "AuI Clock IndexConfigTimeClockState failed %x", error);
461         }
462
463
464         *p_omx_clock_output_port=p_param.nStartPortNumber+1;
465         *p_omx_clock=omx_clock;
466         clock_mutex.Unlock();
467         return 1;
468 }
469
470 int VideoOMX::getClockVideoandInit()
471 {
472         OMX_ERRORTYPE error;
473
474         if (!initClock()) {
475                 return 0;
476         }
477         clock_mutex.Lock();
478
479         if (clock_references==1) { // only if no audio is attached to this clock!
480                 OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refclock;
481                 memset(&refclock,0,sizeof(refclock));
482                 refclock.nSize=sizeof(refclock);
483                 refclock.nVersion.nVersion=OMX_VERSION;
484
485                 //refclock.eClock=OMX_TIME_RefClockAudio;
486
487                 refclock.eClock=OMX_TIME_RefClockVideo;
488                 error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeActiveRefClock,&refclock);
489                 if (error!=OMX_ErrorNone) {
490                         Log::getInstance()->log("Video", Log::DEBUG, "Clock OMX_IndexConfigTimeActiveRefClock failed %x", error);
491                         clock_mutex.Unlock();
492                         DeAllocateCodecsOMX();
493                         return 0;
494                 }
495         }
496
497         OMX_PORT_PARAM_TYPE p_param;
498         memset(&p_param,0,sizeof(p_param));
499         p_param.nSize=sizeof(p_param);
500         p_param.nVersion.nVersion=OMX_VERSION;
501         error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
502         if (error!=OMX_ErrorNone){
503                 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
504                 clock_mutex.Unlock();
505                 DeAllocateCodecsOMX();
506                 return 0;
507         }
508
509
510         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
511         memset(&clock_conf,0,sizeof(clock_conf));
512         clock_conf.nSize=sizeof(clock_conf);
513         clock_conf.nVersion.nVersion=OMX_VERSION;
514         clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
515         clock_conf.nStartTime=0;
516         clock_conf.nOffset=0;
517         if (clock_references==1) clock_conf.nWaitMask=OMX_CLOCKPORT0;
518         else clock_conf.nWaitMask=OMX_CLOCKPORT0|OMX_CLOCKPORT1;
519         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
520         if (error!=OMX_ErrorNone) {
521                 Log::getInstance()->log("Video", Log::DEBUG, "VuI Clock IndexConfigTimeClockState failed %x", error);
522         }
523
524         omx_clock_output_port=p_param.nStartPortNumber;
525         clock_mutex.Unlock();
526
527         return 1;
528 }
529
530 void VideoOMX::clockUnpause()
531 {
532         OMX_ERRORTYPE error;
533         clock_mutex.Lock();
534         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
535         memset(&clock_conf,0,sizeof(clock_conf));
536         clock_conf.nSize=sizeof(clock_conf);
537         clock_conf.nVersion.nVersion=OMX_VERSION;
538         clock_conf.eState=OMX_TIME_ClockStateRunning;
539         clock_conf.nStartTime=0;
540         clock_conf.nOffset=0;
541         clock_conf.nWaitMask=OMX_CLOCKPORT1;
542         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
543         if (error!=OMX_ErrorNone) {
544                 Log::getInstance()->log("Video", Log::DEBUG, "ClockUnpause IndexConfigTimeClockState failed %x", error);
545         }
546
547         clock_mutex.Unlock();
548 }
549
550
551 void VideoOMX::clockPause()
552 {
553         OMX_ERRORTYPE error;
554         clock_mutex.Lock();
555         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
556         memset(&clock_conf,0,sizeof(clock_conf));
557         clock_conf.nSize=sizeof(clock_conf);
558         clock_conf.nVersion.nVersion=OMX_VERSION;
559         clock_conf.eState=OMX_TIME_ClockStateStopped;
560         clock_conf.nStartTime=0;
561         clock_conf.nOffset=0;
562         clock_conf.nWaitMask=OMX_CLOCKPORT1;
563         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
564         if (error!=OMX_ErrorNone) {
565                 Log::getInstance()->log("Video", Log::DEBUG, "ClockUnpause IndexConfigTimeClockState failed %x", error);
566         }
567         clock_mutex.Unlock();
568 }
569
570
571
572 int VideoOMX::AllocateCodecsOMX()
573 {
574         OMX_ERRORTYPE error;
575         static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
576
577         Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
578         //Clock, move later to audio including events
579
580         Log::getInstance()->log("Video", Log::DEBUG, "Nmark1 ");
581         if (!getClockVideoandInit()){
582                 return 0;// get the clock and init it if necessary
583         }
584         Log::getInstance()->log("Video", Log::DEBUG, "Nmark2 ");
585
586         if (!idleClock()) {
587                 Log::getInstance()->log("Video", Log::DEBUG, "idleClock failed");
588                 return 0;
589         }
590         /* TODO end */
591
592
593         clock_mutex.Lock();
594         if (h264) {
595                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
596         } else {
597                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
598         }
599
600         if (error!=OMX_ErrorNone){
601                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
602                 clock_mutex.Unlock();
603                 DeAllocateCodecsOMX();
604                 return 0;
605         }
606
607
608         Log::getInstance()->log("Video", Log::DEBUG, "Nmark3 ");
609         OMX_PORT_PARAM_TYPE p_param;
610         memset(&p_param,0,sizeof(p_param));
611         p_param.nSize=sizeof(p_param);
612         p_param.nVersion.nVersion=OMX_VERSION;
613         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
614         if (error!=OMX_ErrorNone){
615                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
616                 clock_mutex.Unlock();
617                 DeAllocateCodecsOMX();
618             return 0;
619         }
620         omx_codec_input_port=p_param.nStartPortNumber;
621         omx_codec_output_port=p_param.nStartPortNumber+1;
622
623         if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
624                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
625                 clock_mutex.Unlock();
626                 DeAllocateCodecsOMX();
627                 return 0;
628         }
629
630         Log::getInstance()->log("Video", Log::DEBUG, "Nmark4 ");
631
632         OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
633         memset(&conceal,0,sizeof(conceal));
634         conceal.nSize=sizeof(conceal);
635         conceal.nVersion.nVersion=OMX_VERSION;
636         conceal.bStartWithValidFrame=OMX_FALSE;
637
638         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
639         if (error!=OMX_ErrorNone){
640                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
641                 clock_mutex.Unlock();
642                 DeAllocateCodecsOMX();
643                 return 0;
644         }
645
646
647         error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
648         if (error!=OMX_ErrorNone){
649                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
650                 clock_mutex.Unlock();
651                 DeAllocateCodecsOMX();
652                 return 0;
653         }
654
655
656
657         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
658         if (error!=OMX_ErrorNone){
659                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
660                 clock_mutex.Unlock();
661                 DeAllocateCodecsOMX();
662                 return 0;
663         }
664         omx_shed_input_port=p_param.nStartPortNumber;
665         omx_shed_output_port=p_param.nStartPortNumber+1;
666
667
668         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
669         if (error!=OMX_ErrorNone){
670                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
671                 clock_mutex.Unlock();
672                 DeAllocateCodecsOMX();
673                 return 0;
674         }
675         omx_shed_clock_port=p_param.nStartPortNumber;
676         Log::getInstance()->log("Video", Log::DEBUG, "scheduler ports %d %d %d ",omx_shed_input_port,omx_shed_output_port,omx_shed_clock_port);
677
678
679         if (!DisablePort(omx_vid_sched,omx_shed_input_port,true) || !DisablePort(omx_vid_sched,omx_shed_output_port,true)
680                         || !DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
681                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
682                 clock_mutex.Unlock();
683                 DeAllocateCodecsOMX();
684                 return 0;
685         }
686
687
688         error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
689         if (error!=OMX_ErrorNone){
690                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
691                 clock_mutex.Unlock();
692                 DeAllocateCodecsOMX();
693                 return 0;
694         }
695
696         error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
697         if (error!=OMX_ErrorNone){
698                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
699                 clock_mutex.Unlock();
700                 DeAllocateCodecsOMX();
701                 return 0;
702         }
703         omx_rend_input_port=p_param.nStartPortNumber;
704         //omx_rend_output_port=p_param.nStartPortNumber+1;
705
706
707         if (!DisablePort(omx_vid_rend,omx_rend_input_port,true) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
708                                 ) {
709                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
710                 clock_mutex.Unlock();
711                 DeAllocateCodecsOMX();
712                 return 0;
713         }
714
715         //Setuo chain
716
717
718
719         error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
720         if (error!=OMX_ErrorNone){
721                 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);
722                 clock_mutex.Unlock();
723                 DeAllocateCodecsOMX();
724                 return 0;
725         }
726
727         if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
728                                         ) {
729                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
730                 clock_mutex.Unlock();
731                 DeAllocateCodecsOMX();
732                 return 0;
733         }
734
735
736         Log::getInstance()->log("Video", Log::DEBUG, "mark2 ");
737         if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
738                 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
739                 clock_mutex.Unlock();
740                 DeAllocateCodecsOMX();
741                 return 0;
742         }
743
744
745
746         Log::getInstance()->log("Video", Log::DEBUG, "mark1 ");
747         if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
748                 clock_mutex.Unlock();
749                 DeAllocateCodecsOMX();
750                 return 0;
751         }
752
753
754
755
756         Log::getInstance()->log("Video", Log::DEBUG, "mark1 special ");
757         if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
758                 clock_mutex.Unlock();
759                 DeAllocateCodecsOMX();
760                 return 0;
761         }
762         clock_mutex.Unlock();
763
764
765         Log::getInstance()->log("Video", Log::DEBUG, "mark1b ");
766
767
768 /*      error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
769         if (error!=OMX_ErrorNone){
770                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
771                 return 0;
772         }*/
773
774         OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
775         memset(&ft_type,0,sizeof(ft_type));
776         ft_type.nSize=sizeof(ft_type);
777         ft_type.nVersion.nVersion=OMX_VERSION;
778
779         ft_type.nPortIndex=omx_codec_input_port;
780         if (h264) {
781                 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
782         } else {
783                 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
784         }
785
786         Demuxer* demux=Demuxer::getInstance();
787
788     ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
789     Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
790         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
791         if (error!=OMX_ErrorNone){
792                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
793                 clock_mutex.Unlock();
794                 DeAllocateCodecsOMX();
795                 return 0;
796         }
797
798
799         if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
800                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
801                 clock_mutex.Unlock();
802                 DeAllocateCodecsOMX();
803                 return 0;
804         }
805
806
807         if (!PrepareInputBufsOMX()) {
808                 clock_mutex.Unlock();
809                 DeAllocateCodecsOMX();
810                 return 0;
811         }
812
813
814         error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
815         if (error!=OMX_ErrorNone){
816                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
817                 clock_mutex.Unlock();
818                 DeAllocateCodecsOMX();
819                 return 0;
820         }
821
822
823
824         if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
825                                                 ) {
826                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
827                 clock_mutex.Unlock();
828                 DeAllocateCodecsOMX();
829                 return 0;
830         }
831
832         if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
833                 clock_mutex.Unlock();
834                 DeAllocateCodecsOMX();
835                 return 0;
836         }
837
838         if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
839                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
840                 clock_mutex.Unlock();
841                 DeAllocateCodecsOMX();
842                 return 0;
843         }
844
845         error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
846         if (error!=OMX_ErrorNone){
847                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel  sched to rend failed %x", error);
848                 clock_mutex.Unlock();
849                 DeAllocateCodecsOMX();
850                 return 0;
851         }
852
853         if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
854                                                         ) {
855                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX  shed rend failed");
856                 clock_mutex.Unlock();
857                 DeAllocateCodecsOMX();
858                 return 0;
859         }
860
861         if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
862                                         || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
863                 clock_mutex.Unlock();
864                 DeAllocateCodecsOMX();
865                 return 0;
866         }
867
868         if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
869                 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
870                 clock_mutex.Unlock();
871                 DeAllocateCodecsOMX();
872                 return 0;
873         }
874
875
876         if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
877                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
878                 clock_mutex.Unlock();
879                 DeAllocateCodecsOMX();
880                 return 0;
881         }
882
883         if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
884                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
885                 clock_mutex.Unlock();
886                 DeAllocateCodecsOMX();
887                 return 0;
888         }
889
890         //raspbi specifif
891         OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
892         memset(&dispconf,0,sizeof(dispconf));
893         dispconf.nSize=sizeof(dispconf);
894         dispconf.nVersion.nVersion=OMX_VERSION;
895
896         dispconf.nPortIndex=omx_rend_input_port;
897
898         dispconf.set=OMX_DISPLAY_SET_LAYER ;
899         dispconf.layer=1;
900         error=OMX_SetConfig(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
901         if (error!=OMX_ErrorNone){
902                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
903                 clock_mutex.Unlock();
904                 DeAllocateCodecsOMX();
905                 return 0;
906         }
907
908 /*      dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
909         dispconf.fullscreen=OMX_FALSE;
910         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
911         if (error!=OMX_ErrorNone){
912                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
913                 clock_mutex.Unlock();
914                 DeAllocateCodecsOMX();
915                 return 0;
916         }
917
918         dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
919         dispconf.dest_rect.x_offset=100;
920         dispconf.dest_rect.y_offset=100;
921         dispconf.dest_rect.width=640;
922         dispconf.dest_rect.height=480;
923         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
924         if (error!=OMX_ErrorNone){
925                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
926                 clock_mutex.Unlock();
927                 DeAllocateCodecsOMX();
928                 return 0;
929         }*/
930
931
932         playbacktimeoffset=-GetCurrentSystemTime();
933         paused=false;
934         iframemode=false;
935         omx_running=true;
936         clock_mutex.Unlock();
937
938         setClockExecutingandRunning();
939
940
941
942
943
944         return 1;
945 }
946
947 int VideoOMX::idleClock()
948 {
949         OMX_ERRORTYPE error;
950         OMX_STATETYPE temp_state;
951         clock_mutex.Lock();
952         OMX_GetState(omx_clock,&temp_state);
953
954         if (temp_state!=OMX_StateIdle) {
955                 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
956                         Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle failed");
957                         clock_mutex.Unlock();
958                         return 0;
959                 }
960         }
961         clock_mutex.Unlock();
962         return 1;
963 }
964
965 int VideoOMX::setClockExecutingandRunning()
966 {
967         OMX_ERRORTYPE error;
968         OMX_STATETYPE temp_state;
969         clock_mutex.Lock();
970         OMX_GetState(omx_clock,&temp_state);
971
972         if (temp_state!=OMX_StateExecuting) {
973                 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
974                         Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Execute failed");
975                         clock_mutex.Unlock();
976                         DeAllocateCodecsOMX();
977                         return 0;
978                 }
979         }
980
981         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
982         memset(&clock_conf,0,sizeof(clock_conf));
983         clock_conf.nSize=sizeof(clock_conf);
984         clock_conf.nVersion.nVersion=OMX_VERSION;
985         clock_conf.eState=OMX_TIME_ClockStateRunning;
986         error=OMX_SetConfig(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
987         if (error!=OMX_ErrorNone) {
988                 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
989                 clock_mutex.Unlock();
990                 DeAllocateCodecsOMX();
991                 return 0;
992         }
993         clock_mutex.Unlock();
994         return 1;
995
996 }
997
998
999 int VideoOMX::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type) //needs to be called with locked mutex
1000 {
1001         OMX_ERRORTYPE error;
1002         error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1003         if (error!=OMX_ErrorNone){
1004                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1005                 return 0;
1006         }
1007
1008         if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1009                 return 0;
1010         }
1011
1012         return 1;
1013 }
1014
1015
1016 int VideoOMX::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1017 {
1018         OMX_ERRORTYPE error;
1019         error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1020         if (error!=OMX_ErrorNone){
1021                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1022                 return 0;
1023         }
1024
1025         if (!wait) return 1;
1026         if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1027                 return 0;
1028         }
1029
1030         return 1;
1031 }
1032
1033
1034 int VideoOMX::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs to be called with locked mutex
1035 {
1036         OMX_ERRORTYPE error;
1037         error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1038         if (error!=OMX_ErrorNone){
1039                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1040                 return 0;
1041         }
1042
1043         if (!wait) return 1;
1044         if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1045                 return 0;
1046         }
1047
1048
1049         return 1;
1050 }
1051
1052
1053
1054
1055 int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex
1056 {
1057         int i=0;
1058         while (i<1000) {
1059                 omx_event_mutex.Lock();
1060                 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1061                 while (itty!=omx_events.end()) {
1062
1063                         VPE_OMX_EVENT current=*itty;
1064                         if (current.handle==handle) { //this is ours
1065                                 if (current.event_type==OMX_EventError) {
1066                                         omx_events.erase(itty);
1067                                         omx_event_mutex.Unlock();
1068                                         Log::getInstance()->log("Video", Log::DEBUG, "Command Finished on Error");
1069                                         return 0;
1070
1071                                 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1072                                         omx_events.erase(itty);
1073                                         omx_event_mutex.Unlock();
1074                                         //Log::getInstance()->log("Video", Log::DEBUG, "Command Finished Completed");
1075                                         return 1;
1076                                 }
1077                         }
1078                         itty++;
1079
1080                 }
1081                 omx_event_mutex.Unlock();
1082                 MILLISLEEP(2);
1083                 i++;
1084
1085         }
1086         Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1087         return 0;
1088
1089 }
1090
1091
1092
1093
1094
1095 int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex
1096 {
1097         OMX_ERRORTYPE error;
1098         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1099         memset(&port_def_type,0,sizeof(port_def_type));
1100         port_def_type.nSize=sizeof(port_def_type);
1101         port_def_type.nVersion.nVersion=OMX_VERSION;
1102         port_def_type.nPortIndex=omx_codec_input_port;
1103
1104         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1105
1106         if (error!=OMX_ErrorNone){
1107                         Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1108         }
1109 /*      Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1110                         port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1111                         port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1112
1113         port_def_type.nBufferCountActual=60;
1114         port_def_type.nBufferSize=max(port_def_type.nBufferSize,200000); // for transcoder important
1115
1116         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1117
1118         if (error!=OMX_ErrorNone){
1119                         Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1120         }
1121
1122
1123         error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1124         if (error!=OMX_ErrorNone){
1125                 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1126                 return 0;
1127         }
1128
1129         input_bufs_omx_mutex.Lock();
1130         for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1131
1132         //      unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1133                 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1134         /*      error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1135                 if (error!=OMX_ErrorNone){
1136                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1137                         input_bufs_omx_mutex.Unlock();
1138                         return 0;
1139                 }*/
1140                 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1141                 if (error!=OMX_ErrorNone){
1142                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1143                                 input_bufs_omx_mutex.Unlock();
1144                         return 0;
1145                 }
1146                 input_bufs_omx_all.push_back(buf_head);
1147                 input_bufs_omx_free.push_back(buf_head);
1148         }
1149         omx_first_frame=true;
1150
1151         firstsynched=false;
1152         cur_input_buf_omx=NULL;
1153         input_bufs_omx_mutex.Unlock();
1154
1155
1156         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1157         if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1158                 return 0;
1159         }
1160         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1161
1162         return 1;
1163 }
1164
1165 int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex
1166 {
1167         OMX_ERRORTYPE error;
1168
1169         cur_input_buf_omx=NULL;
1170         input_bufs_omx_mutex.Lock();
1171         for (int i=0; i< input_bufs_omx_all.size();i++) {
1172         //      free(input_bufs_omx_all[i]->pBuffer);
1173         //      input_bufs_omx_all[i]->pBuffer=NULL;
1174                 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1175                 if (error!=OMX_ErrorNone){
1176                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1177                         input_bufs_omx_mutex.Unlock();
1178                         return 0;
1179                 }
1180
1181         }
1182         input_bufs_omx_all.clear();
1183         input_bufs_omx_free.clear();
1184         input_bufs_omx_mutex.Unlock();
1185
1186 }
1187
1188
1189
1190
1191 int VideoOMX::DeAllocateCodecsOMX()
1192 {
1193         OMX_ERRORTYPE error;
1194         omx_running=false;
1195           Log::getInstance()->log("Video", Log::DEBUG, "enter deallocatecodecsomx");
1196
1197    clock_mutex.Lock();
1198    if (cur_input_buf_omx) {
1199                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
1200                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1201                 if (error!=OMX_ErrorNone) {
1202                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1203                 }
1204
1205                 cur_input_buf_omx=NULL;//write out old data
1206         }
1207
1208         if (omx_vid_dec) {
1209                 // first stop the omx elements
1210                 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1211                         Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1212
1213                 }
1214                 clock_mutex.Unlock();
1215
1216                 idleClock();
1217                 clock_mutex.Lock();
1218
1219
1220                 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1221                         Log::getInstance()->log("Video", Log::DEBUG, "vid_shed ChangeComponentState");
1222
1223                 }
1224
1225                 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1226                         Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1227
1228                 }
1229
1230
1231
1232         // TODO proper deinit sequence
1233                 // first flush all buffers
1234
1235                 error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1236                 if (error!=OMX_ErrorNone) {
1237                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1238
1239                 }
1240
1241                 if (!CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
1242                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
1243                 }
1244
1245                 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1246                 if (error!=OMX_ErrorNone){
1247                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1248
1249                 }
1250
1251
1252
1253                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_input_port, NULL);
1254                 if (error!=OMX_ErrorNone){
1255                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed in failed %x", error);
1256
1257                 }
1258
1259                 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_output_port) ||
1260                                 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_input_port)) {
1261                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec shed failed");
1262                 }
1263
1264
1265                 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1266                 if (error!=OMX_ErrorNone){
1267                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1268
1269                 }
1270
1271                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
1272                 if (error!=OMX_ErrorNone){
1273                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
1274
1275                 }
1276
1277                 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1278                         !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
1279                                 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
1280                 }
1281
1282                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_output_port, NULL);
1283                 if (error!=OMX_ErrorNone) {
1284                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed out failed %x", error);
1285
1286                 }
1287
1288
1289
1290                 if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ) {
1291                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
1292                 }
1293
1294
1295
1296
1297
1298
1299                 DestroyInputBufsOMX();
1300
1301                 //todo flushing
1302                 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
1303                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
1304                 }
1305                 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
1306                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
1307                 }
1308
1309
1310
1311
1312                 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
1313                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
1314                 }
1315
1316
1317
1318                 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
1319                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
1320                 }
1321
1322
1323
1324
1325                 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
1326                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
1327                 }
1328
1329                 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1330                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
1331                 }
1332
1333                 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
1334                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
1335                 }
1336
1337
1338
1339
1340                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
1341                 if (error!=OMX_ErrorNone) {
1342                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1343
1344                 }
1345
1346                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
1347                 if (error!=OMX_ErrorNone) {
1348                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1349
1350                 }
1351
1352
1353                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
1354                 if (error!=OMX_ErrorNone) {
1355                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1356
1357                 }
1358
1359                 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
1360                 if (error!=OMX_ErrorNone) {
1361                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1362
1363                 }
1364
1365
1366                 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1367                 if (error!=OMX_ErrorNone) {
1368                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1369
1370                 }
1371
1372                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
1373                 if (error!=OMX_ErrorNone) {
1374                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1375
1376                 }
1377
1378
1379
1380
1381                 error=OMX_FreeHandle(omx_vid_dec);
1382                 error=OMX_FreeHandle(omx_vid_sched);
1383                 error=OMX_FreeHandle(omx_vid_rend);
1384                 omx_vid_dec=NULL;
1385                 clock_mutex.Unlock();
1386                 destroyClock();
1387                 if (error!=OMX_ErrorNone) {
1388                         Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1389                 }
1390         } else  clock_mutex.Unlock();
1391           Log::getInstance()->log("Video", Log::DEBUG, "leave deallocate codecs OMX");
1392
1393         return 1;
1394 }
1395
1396
1397 void VideoOMX::destroyClock()
1398 {
1399         clock_mutex.Lock();
1400         if (clock_references>0) {
1401                 clock_references--;
1402                 if (clock_references==0) {
1403                         OMX_ERRORTYPE error;
1404                         Log::getInstance()->log("Video", Log::DEBUG, "destroy omx clock");
1405                         error=OMX_FreeHandle(omx_clock);
1406                         if (error!=OMX_ErrorNone) {
1407                                 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1408                         }
1409
1410                 }
1411         }
1412         clock_mutex.Unlock();
1413
1414 }
1415
1416 int VideoOMX::stop()
1417 {
1418   if (!initted) return 0;
1419   iframemode=false;
1420
1421   //Check if libav mode
1422   DeAllocateCodecsOMX();
1423
1424
1425
1426
1427 //  if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
1428   return 1;
1429 }
1430
1431 int VideoOMX::reset()
1432 {
1433   if (!initted) return 0;
1434
1435   iframemode=false;
1436   DeAllocateCodecsOMX();
1437 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
1438   return 1;
1439 }
1440
1441 int VideoOMX::pause()
1442 {
1443   if (!initted) return 0;
1444   Log::getInstance()->log("Video", Log::DEBUG, "enter pause");
1445   if (!paused) {
1446           paused=true;
1447           //maybe also change omx clock?
1448           pausetimecode=GetCurrentSystemTime();
1449
1450   }
1451   return 1;
1452 }
1453
1454 int VideoOMX::unPause() // FIXME get rid - same as play!! Not here!
1455 {
1456   if (!initted) return 0;
1457   Log::getInstance()->log("Video", Log::DEBUG, "enter unpause");
1458
1459   if (paused) {
1460           playbacktimeoffset+=GetCurrentSystemTime()-pausetimecode;
1461           paused=false; // may be also change omx clock
1462   }
1463
1464   return 1;
1465 }
1466
1467 int VideoOMX::fastForward()
1468 {
1469   if (!initted) return 0;
1470
1471 //  if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
1472   return 1;
1473 }
1474
1475 int VideoOMX::unFastForward()
1476 {
1477   if (!initted) return 0;
1478
1479 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
1480
1481  //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
1482   return 1;
1483 }
1484
1485 int VideoOMX::attachFrameBuffer()
1486 {
1487   if (!initted) return 0;
1488
1489 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
1490   return 1;
1491 }
1492
1493 int VideoOMX::blank(void)
1494 {
1495 //  if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
1496 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
1497   return 1;
1498 }
1499
1500 ULLONG VideoOMX::getCurrentTimestamp()
1501 {
1502   if (iframemode) return 0;
1503   return lastreftimePTS;
1504 }
1505
1506 // to be removed
1507 /*
1508 ULONG VideoOMX::timecodeToFrameNumber(ULLONG timecode)
1509 {
1510   if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
1511   else               return (ULONG)(((double)timecode / (double)90000) * (double)30);
1512 }
1513
1514 */
1515 #ifdef DEV
1516 int VideoOMX::test()
1517 {
1518   return 0;
1519
1520 //  ULLONG stc = 0;
1521 //  return ioctl(fdVideo, AV_SET_VID_STC, &stc);
1522 /*
1523  // reset();
1524   return 1;
1525 */
1526 }
1527
1528 int VideoOMX::test2()
1529 {
1530   return 0;
1531 }
1532 #endif
1533
1534
1535
1536 long long VideoOMX::SetStartOffset(long long curreftime, bool *rsync)
1537 {
1538   *rsync=false;
1539   if (offsetnotset) {
1540     startoffset=curreftime;//offset is set for audio
1541     offsetnotset=false;
1542     offsetvideonotset=false;
1543   } else {
1544     if (offsetvideonotset) {
1545       offsetvideonotset=false;
1546       *rsync=true;
1547     } else {
1548       if ( (curreftime-lastrefvideotime)>10000000LL
1549         || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
1550         startoffset+=curreftime-lastrefvideotime;
1551         lastrefaudiotime+=curreftime-lastrefvideotime;
1552         //*rsync=true;
1553         offsetaudionotset=true;
1554
1555       }
1556     }
1557
1558   }
1559
1560   lastrefvideotime=curreftime;
1561
1562   return startoffset;
1563
1564 }
1565
1566 long long VideoOMX::SetStartAudioOffset(long long curreftime, bool *rsync)
1567 {
1568   *rsync=false;
1569   if (offsetnotset) {
1570     startoffset=curreftime;
1571     offsetnotset=false;
1572     offsetaudionotset=false;
1573   }else {
1574     if (offsetaudionotset) {
1575       offsetaudionotset=false;
1576       *rsync=true;
1577     } else {
1578       if ( (curreftime-lastrefaudiotime)>10000000LL
1579         || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
1580         startoffset+=curreftime-lastrefaudiotime;
1581         lastrefvideotime+=curreftime-lastrefaudiotime;
1582         //*rsync=true;
1583         offsetvideonotset=true;
1584
1585       }
1586     }
1587
1588   }
1589   lastrefaudiotime=curreftime;
1590   return startoffset;
1591
1592 }
1593
1594 void VideoOMX::ResetTimeOffsets() {
1595   offsetnotset=true; //called from demuxer
1596   offsetvideonotset=true;
1597   offsetaudionotset=true;
1598   startoffset=0;
1599   lastrefaudiotime=0;
1600   lastrefvideotime=0;
1601   lastreftimeOMX=0;
1602   lastreftimePTS=0;
1603 }
1604
1605 long long VideoOMX::GetCurrentSystemTime()
1606 {
1607         struct timespec ts;
1608         clock_gettime(CLOCK_MONOTONIC, &ts);
1609         return ts.tv_sec*10000000LL+ts.tv_nsec/100LL;
1610 }
1611
1612 void VideoOMX::WaitUntil(long long time)
1613 {
1614         struct timespec interval;
1615         interval.tv_sec=time/10000000LL;
1616         interval.tv_nsec=(time %10000000LL)*100LL;
1617         while (clock_nanosleep(CLOCK_MONOTONIC,TIMER_ABSTIME,&interval,NULL)==EINTR) {};
1618 }
1619
1620 void VideoOMX::FrameWaitforDisplay(long long pts)
1621 {
1622         //ok first calculate the absolute time
1623         long long target_time=pts-playbacktimeoffset;
1624         // we have to wait untile the next frame
1625         long long offset=Demuxer::getInstance()->getFrameRate();
1626         long long current_time=GetCurrentSystemTime();
1627         if ((target_time-current_time)>5000000LL) target_time=current_time+5000000LL; // something is wrong do not wait too long
1628         if (offset==0) offset=25;
1629         offset=10000000LL/offset;
1630         target_time+=offset;
1631         Log::getInstance()->log("Video", Log::DEBUG, "Wait for display pts: %lld target: %lld sys: %lld off: %lld diff %lld",pts,target_time,current_time,offset,
1632                         target_time-current_time);
1633
1634         WaitUntil(target_time);
1635         Log::getInstance()->log("Video", Log::DEBUG, "Wait for display out %lld",GetCurrentSystemTime());
1636 }
1637
1638 void VideoOMX::AdjustAudioPTS(long long pts)
1639 {
1640         long long newplaybacktimeoffset=pts-GetCurrentSystemTime();
1641 /*      if ((newplaybacktimeoffset-1000000LL)>playbacktimeoffset
1642             || (newplaybacktimeoffset+1000000LL)<playbacktimeoffset) {
1643                 Log::getInstance()->log("Video", Log::DEBUG, "Adjust Playbackoffsettime o: %lld n: %lld",
1644                                 playbacktimeoffset,newplaybacktimeoffset);*/
1645                 playbacktimeoffset=newplaybacktimeoffset;
1646
1647         //}
1648 }
1649
1650
1651 void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1652 {
1653   mediapacket = mplist.front();
1654 }
1655
1656 UINT VideoOMX::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
1657 {
1658   DeliverMediaPacket(mediapacket, buffer, samplepos);
1659   if (*samplepos == mediapacket.length) {
1660     *samplepos = 0;
1661     return 1;
1662   }
1663   else return 0;
1664 }
1665
1666 UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
1667                 const UCHAR* buffer,
1668                 UINT *samplepos)
1669 {
1670         if (packet.type == MPTYPE_VIDEO_H264)
1671         {
1672                 h264=true;
1673         }
1674         else
1675         {
1676                 h264=false;
1677         }
1678
1679
1680         //Later add fail back code for libav
1681 /*      if (!videoon) {
1682                 *samplepos+=packet.length;
1683                 return packet.length;
1684         }*/
1685
1686
1687         if (!omx_running) return 0; // if we are not runnig do not do this
1688         if (paused) return 0; //Block if we pause
1689
1690         long long current_media_time=GetCurrentSystemTime()+playbacktimeoffset;
1691         if (packet.synched &&
1692                         (packet.presentation_time<0 /*|| // preroll skip frames
1693                         (packet.presentation_time+5000000LL)<(current_media_time)*/)) { // we are late skip
1694                 Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX Preroll or too late %lld %lld; %lld", packet.presentation_time,current_media_time,playbacktimeoffset);
1695                 *samplepos=packet.length;
1696                 return packet.length;
1697         }
1698
1699         OMX_ERRORTYPE error;
1700
1701         /*First Check, if we have an video sample*/
1702         if (iframemode) {
1703                 //samplepos=0;
1704                 MILLISLEEP(10);
1705                 return 0; //Not in iframe mode!
1706         }
1707
1708         UINT headerstrip=0;
1709         if (packet.disconti) {
1710                 firstsynched=false;
1711                 if (cur_input_buf_omx) {
1712                         OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1713                         if (error!=OMX_ErrorNone){
1714                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1715                         }
1716                         FrameWaitforDisplay(lastreftimeOMX);
1717                         cur_input_buf_omx=NULL;
1718                 }
1719         }
1720
1721         /*Inspect PES-Header */
1722
1723 //      OMX_STATETYPE temp_state;
1724 //      OMX_GetState(omx_vid_dec,&temp_state);
1725
1726         if (*samplepos==0) {//stripheader
1727                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
1728                 if (h264) Log::getInstance()->log("Video", Log::DEBUG, "PES info %x %x %x %x",
1729                                 buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
1730                 *samplepos+=headerstrip;
1731                 if ( packet.synched ) {
1732                         if (cur_input_buf_omx) {
1733                                 cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
1734                                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1735                                 if (error!=OMX_ErrorNone){
1736                                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1737                                 }
1738                                 cur_input_buf_omx=NULL;//write out old data
1739                                 FrameWaitforDisplay(lastreftimeOMX);
1740
1741
1742                         }
1743                         firstsynched=true;
1744                 } else {
1745                         if (!firstsynched) {//
1746                                 *samplepos=packet.length;//if we have not processed at least one
1747                                 return packet.length;//synched packet ignore it!
1748                         }
1749                 }
1750         }
1751
1752         if (!cur_input_buf_omx) {
1753                 input_bufs_omx_mutex.Lock();
1754                 if (input_bufs_omx_free.size()==0) {
1755                         input_bufs_omx_mutex.Unlock();
1756                         Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
1757                         return 0; // we do not have a free media sample
1758
1759                 }
1760                 cur_input_buf_omx=input_bufs_omx_free.front();
1761                 cur_input_buf_omx->nFilledLen=0;
1762                 cur_input_buf_omx->nOffset=0;
1763                 cur_input_buf_omx->nTimeStamp=0;
1764                 input_bufs_omx_free.pop_front();
1765                 input_bufs_omx_mutex.Unlock();
1766         }
1767
1768
1769
1770
1771         if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
1772                 if (packet.synched) {
1773                         Log::getInstance()->log("Video", Log::DEBUG, "packet synched marker");
1774
1775                         //lastreftimePTS=packet.pts;
1776                    if (omx_first_frame) { // TODO time
1777                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
1778                            Log::getInstance()->log("Video", Log::DEBUG, "Starttime");
1779                            omx_first_frame=false;
1780                    } else {
1781                            //cur_input_buf_omx->nFlags=0;
1782                            cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
1783                    }
1784                    lastreftimeOMX=packet.presentation_time;
1785                    Log::getInstance()->log("Video", Log::DEBUG, "Time code %lld pts %lld", lastreftimeOMX,packet.pts);
1786                    lastreftimePTS=packet.pts;
1787                    cur_input_buf_omx->nTimeStamp=0;//lastreftimeOMX; // the clock component is faulty;
1788                 }
1789                 else
1790                 {
1791                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1792                         cur_input_buf_omx->nTimeStamp=0;
1793
1794
1795                         //  ms->SetSyncPoint(TRUE);
1796                 }
1797                 if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
1798
1799
1800
1801         }
1802         unsigned int haveToCopy=packet.length-*samplepos;
1803
1804         while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
1805                 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
1806                 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
1807                 haveToCopy-=cancopy;
1808                 cur_input_buf_omx->nFilledLen+=cancopy;
1809                 *samplepos+=cancopy;
1810                 // push old buffer out
1811
1812                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1813                 if (error!=OMX_ErrorNone){
1814                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1815                 }
1816                 // get5 new buffer
1817                 input_bufs_omx_mutex.Lock();
1818                 if (input_bufs_omx_free.size()==0) {
1819                         input_bufs_omx_mutex.Unlock();
1820                         //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
1821                         return *samplepos; // we do not have a free media sample
1822                 }
1823                 cur_input_buf_omx=input_bufs_omx_free.front();
1824                 cur_input_buf_omx->nFilledLen=0;
1825                 cur_input_buf_omx->nOffset=0;
1826                 cur_input_buf_omx->nTimeStamp=0;
1827                 input_bufs_omx_free.pop_front();
1828                 input_bufs_omx_mutex.Unlock();
1829
1830                 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1831
1832         }
1833         memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
1834                         buffer+packet.pos_buffer+*samplepos,haveToCopy);
1835         cur_input_buf_omx->nFilledLen+=haveToCopy;
1836
1837
1838
1839         *samplepos+=haveToCopy;
1840
1841         return *samplepos;
1842
1843 }
1844
1845
1846
1847
1848 bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) {
1849         if (!omx_running) return false;
1850         if (!iframemode)
1851                 EnterIframePlayback();
1852
1853         int haveToCopy = length;
1854
1855         if (!cur_input_buf_omx) {
1856                 input_bufs_omx_mutex.Lock();
1857                 if (input_bufs_omx_free.size() == 0) {
1858                         input_bufs_omx_mutex.Unlock();
1859                         Log::getInstance()->log("Video", Log::DEBUG,
1860                                         "Deliver MediaPacket no free sample");
1861                         return false; // we do not have a free media sample
1862
1863                 }
1864                 cur_input_buf_omx = input_bufs_omx_free.front();
1865                 cur_input_buf_omx->nFilledLen = 0;
1866                 cur_input_buf_omx->nOffset = 0;
1867                 cur_input_buf_omx->nTimeStamp = 0;
1868                 input_bufs_omx_free.pop_front();
1869                 input_bufs_omx_mutex.Unlock();
1870         }
1871
1872         int read_pos = 0;
1873         unsigned int pattern, packet_length;
1874         unsigned int headerstrip = 0;
1875         bool first = true;
1876         if (length < 4){
1877                 return false;
1878         }
1879         //Now we strip the pes header
1880         pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);
1881         while (read_pos + 7 <= length) {
1882                 pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos + 3];
1883                 if (pattern < 0x000001E0 || pattern > 0x000001EF) {
1884                         read_pos++;
1885                         continue;
1886                 } else {
1887                         headerstrip = buffer[read_pos + 8] + 9/*is this right*/;
1888                         packet_length = ((buffer[read_pos + 4] << 8)
1889                                         | (buffer[read_pos + 5])) + 6;
1890                         if (read_pos + packet_length > length)
1891                                 read_pos = length;
1892                         else {
1893                                 if ((headerstrip < packet_length)
1894                                                 && (cur_input_buf_omx->nFilledLen + packet_length
1895                                                                 - headerstrip) > cur_input_buf_omx->nAllocLen) {
1896                                         if (first) {
1897                                                 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1898
1899                                         } else {
1900                                                 cur_input_buf_omx->nFlags
1901                                                                 |= OMX_BUFFERFLAG_TIME_UNKNOWN;
1902
1903                                         }
1904                                         cur_input_buf_omx->nTimeStamp = 0;
1905                                         OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_vid_dec,
1906                                                         cur_input_buf_omx);
1907                                         if (error != OMX_ErrorNone) {
1908                                                 Log::getInstance()->log("Video", Log::DEBUG,
1909                                                                 "OMX_EmptyThisBuffer failed %x", error);
1910                                         }
1911                                         cur_input_buf_omx = NULL;
1912
1913                                         if (!cur_input_buf_omx) {
1914                                                 int count = 0;
1915                                                 while (count < 100 && omx_running && iframemode) {
1916                                                         count++;
1917
1918                                                         input_bufs_omx_mutex.Lock();
1919                                                         if (input_bufs_omx_free.size() == 0) {
1920                                                                 input_bufs_omx_mutex.Unlock();
1921                                                                 Log::getInstance()->log("Video", Log::DEBUG,
1922                                                                                 "Ifrane no free sample");
1923                                                                 MILLISLEEP(5);
1924                                                                 if (!omx_running) return false;
1925                                                                 continue;
1926                                                         }
1927                                                         cur_input_buf_omx = input_bufs_omx_free.front();
1928                                                         cur_input_buf_omx->nFilledLen = 0;
1929                                                         cur_input_buf_omx->nOffset = 0;
1930                                                         cur_input_buf_omx->nTimeStamp = 0;
1931                                                         input_bufs_omx_free.pop_front();
1932                                                         input_bufs_omx_mutex.Unlock();
1933                                                         break;
1934                                                 }
1935                                                 if (!cur_input_buf_omx)
1936                                                         return false;
1937                                         }
1938
1939                                 }
1940                                 if (packet_length > headerstrip) {
1941                                         memcpy(
1942                                                         cur_input_buf_omx->pBuffer
1943                                                                         + cur_input_buf_omx->nFilledLen,
1944                                                         buffer + read_pos + headerstrip,
1945                                                         packet_length - headerstrip);
1946                                         cur_input_buf_omx->nFilledLen += packet_length
1947                                                         - headerstrip;
1948                                 }
1949                                 read_pos += packet_length;
1950
1951                                 pattern = (buffer[read_pos] << 16)
1952                                                 | (buffer[read_pos + 1] << 8) | (buffer[read_pos + 2]);
1953                         }
1954                 }
1955         }
1956
1957         if (first) {
1958                 cur_input_buf_omx->nFlags = OMX_BUFFERFLAG_STARTTIME;
1959
1960         } else {
1961                 cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
1962
1963         }
1964         cur_input_buf_omx->nTimeStamp = 0;
1965         OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_vid_dec, cur_input_buf_omx);
1966         if (error != OMX_ErrorNone) {
1967                 Log::getInstance()->log("Video", Log::DEBUG,
1968                                 "OMX_EmptyThisBuffer failed %x", error);
1969         }
1970         cur_input_buf_omx = NULL;
1971
1972
1973         MILLISLEEP(40); //Block a bit
1974         return true;
1975 }
1976
1977 int VideoOMX::EnterIframePlayback()
1978 {
1979         clock_mutex.Lock();
1980         if (cur_input_buf_omx) {
1981                 OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_vid_dec,
1982                                 cur_input_buf_omx);
1983                 if (error != OMX_ErrorNone) {
1984                         Log::getInstance()->log("Video", Log::DEBUG,
1985                                         "OMX_EmptyThisBuffer failed %x", error);
1986                 }
1987
1988                 cur_input_buf_omx = NULL;
1989         }
1990         clock_mutex.Unlock();
1991         iframemode=true;
1992
1993         return 1;
1994 }
1995