]> git.vomp.tv Git - vompclient-marten.git/blob - videovpeogl.cc
Bugfix + Initial fallback to ffmpeg, no decoding yet
[vompclient-marten.git] / videovpeogl.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 "videovpeogl.h"
22 #include "audiovpe.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 VideoVPEOGL::VideoVPEOGL()
33 {
34   lastpacketnum=-1;
35
36 #ifdef VPE_OMX_SUPPORT
37   omx_running=false;
38
39   omx_vid_dec=0;
40   cur_input_buf_omx=NULL;
41   omx_h264=omx_mpeg2=true;
42 #endif
43
44 #ifdef VPE_FFMPEG_SUPPORT
45   mpeg2codec_context_ff=NULL;
46   dec_frame_ff=NULL;
47 #endif
48   
49 }
50
51 VideoVPEOGL::~VideoVPEOGL()
52 {
53   instance = NULL;
54 }
55
56 int VideoVPEOGL::init(UCHAR tformat)
57 {
58   if (initted) return 0;
59   initted = 1;
60
61 //  if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
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 /*  if (format == PAL) setLetterboxBorder("38");
73   else setLetterboxBorder("31");*/
74
75   /* new stuff */
76
77
78   stop();
79
80
81   return 1;
82 }
83
84 int VideoVPEOGL::initUsingOSDObjects()
85 {
86         EGLDisplay i_egl_display;
87         EGLSurface i_egl_surface;
88         EGLContext i_egl_context;
89         OsdOpenGL *osd=(OsdOpenGL*)osd->getInstance();
90         osd->getEGLObjs(&i_egl_display,&i_egl_surface,&i_egl_context);
91
92         egl_display=i_egl_display;
93         egl_surface=i_egl_surface;
94         egl_context=i_egl_context;
95
96
97 #ifdef VPE_OMX_SUPPORT
98 // we are called before the audio
99         OMX_ERRORTYPE error;
100         error=OMX_Init();
101         if (error!=OMX_ErrorNone) {
102                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error);
103                 return 0;
104         }
105
106         //our callbacks move to play?
107
108 #endif
109
110 #ifdef VPE_FFMPEG_SUPPORT
111
112         av_register_all();
113         mpeg2codec_ff=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
114         //mpeg2codec_ff=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_XVMC);
115         if (mpeg2codec_ff==NULL) {
116                 Log::getInstance()->log("Video", Log::DEBUG, "Find ffmpeg mpeg2 codec failed");
117                 return 0;
118         }
119
120 #endif
121         return 1;
122 }
123
124
125 #ifdef VPE_OMX_SUPPORT
126
127 OMX_ERRORTYPE VideoVPEOGL::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
128            OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
129            OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
130
131         Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
132
133         struct VPE_OMX_EVENT  new_event;
134         new_event.handle=handle;
135         new_event.appdata=appdata;
136         new_event.event_type=event_type;
137         new_event.data1=data1;
138         new_event.data2=data2;
139         new_event.event_data=event_data;
140
141         VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
142         video->AddOmxEvent(new_event);
143
144 /*      switch (event_type) {
145         case OMX_EventCmdComplete: {
146
147         } break;
148         }*/
149
150         return OMX_ErrorNone;
151
152 }
153
154 void VideoVPEOGL::AddOmxEvent(VPE_OMX_EVENT  new_event)
155 {
156         omx_event_mutex.Lock();
157     omx_events.push_back(new_event);
158         omx_event_mutex.Unlock();
159 }
160
161
162 OMX_ERRORTYPE VideoVPEOGL::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
163
164         Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
165         VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
166         video->ReturnEmptyOMXBuffer(buffer);
167         return OMX_ErrorNone;
168
169 }
170
171 void VideoVPEOGL::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
172         input_bufs_omx_mutex.Lock();
173         Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
174         input_bufs_omx_free.push_back(buffer);
175         Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
176         input_bufs_omx_mutex.Unlock();
177 }
178
179  OMX_ERRORTYPE VideoVPEOGL::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
180          Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
181         return OMX_ErrorNone;
182 }
183
184 #endif
185
186 int VideoVPEOGL::shutdown()
187 {
188   if (!initted) return 0;
189   initted = 0;
190
191   decoding_backend=0;
192 #ifdef VPE_OMX_SUPPORT
193   DeAllocateCodecsOMX();
194   OMX_Deinit();
195 #endif
196 #ifdef VPE_FFMPEG_SUPPORT
197   DeAllocateCodecsFFMPEG();
198 #endif
199   eglDestroyContext(egl_display,egl_context);
200 //  close(fdVideo);
201   return 1;
202 }
203
204
205
206
207 int VideoVPEOGL::setTVsize(UCHAR ttvsize)
208 {
209 /*  tvsize = ttvsize;
210
211   // Override the aspect ratio usage, temporarily use to set the video chip mode
212   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
213   close(fdVideo);
214   if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
215   if (!setSource())                  { shutdown(); return 0; }
216   if (!attachFrameBuffer())          { shutdown(); return 0; }
217
218   // Reopening the fd causes the scart aspect line to go back to 4:3
219   // Set this again to the same as the tv screen size
220   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
221
222   // mode == LETTERBOX is invalid if the TV is widescreen
223   if (tvsize == ASPECT16X9) setMode(NORMAL);
224 */
225   return 1;
226 }
227
228 int VideoVPEOGL::setDefaultAspect()
229 {
230   return setAspectRatio(tvsize);
231 }
232
233
234
235 int VideoVPEOGL::setFormat(UCHAR tformat)
236 {
237   if (!initted) return 0;
238   if ((tformat != PAL) && (tformat != NTSC)) return 0;
239   format = tformat;
240
241 //  if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
242
243   if (format == NTSC)
244   {
245     screenWidth = 720;
246     screenHeight = 480;
247   }
248   if (format == PAL)
249   {
250     screenWidth = 720;
251     screenHeight = 576;
252   }
253
254   return 1;
255 }
256
257 int VideoVPEOGL::setConnection(UCHAR tconnection)
258 {
259   if (!initted) return 0;
260   if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
261   connection = tconnection;
262
263 //  if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
264   return 1;
265 }
266
267 int VideoVPEOGL::setAspectRatio(UCHAR taspectRatio)
268 {
269   if (!initted) return 0;
270   if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
271   aspectRatio = taspectRatio;
272
273   Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
274
275 //  if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
276   return 1;
277 }
278
279 int VideoVPEOGL::setMode(UCHAR tmode)
280 {
281   if (!initted) return 0;
282
283   if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
284
285   if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
286       && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
287   mode = tmode;
288
289 //  if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
290   return 1;
291 }
292
293 int VideoVPEOGL::signalOff()
294 {
295 //  if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
296   return 1;
297 }
298
299 int VideoVPEOGL::signalOn()
300 {
301 //  if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
302   return 1;
303 }
304
305 int VideoVPEOGL::setSource()
306 {
307   if (!initted) return 0;
308
309   // What does this do...
310 //  if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
311   return 1;
312 }
313
314 int VideoVPEOGL::setPosition(int x, int y)
315 {
316   if (!initted) return 0;
317
318 //  vid_pos_regs_t pos_d;
319 //  pos_d.x = x;
320 //  pos_d.y = y;
321
322 /*  vid_pos_regs_t pos_d;
323
324   memset(&pos_d, 0, sizeof(pos_d));
325
326   pos_d.dest.y = y;
327   pos_d.dest.x = x;
328 /*
329 typedef struct {
330   int w;
331   int h;
332   int scale;
333   int x1;
334   int y;
335   int x;
336   int y2;
337   int x3;
338   int y3;
339   int x4;
340   int y4;
341 } vid_pos_regs_t;
342 */
343
344 /*
345   pos_d.w = 100;
346   pos_d.h = 30;
347   pos_d.scale = 2;
348   pos_d.x1 = 0;
349   pos_d.y = 100;            // Top left X
350   pos_d.x = 50;            // Top left Y
351   pos_d.y2 = 30;
352   pos_d.x3 = 60;
353   pos_d.y3 = 90;
354   pos_d.x4 = 120;
355   pos_d.y4 = 150;
356 */
357
358 //  if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
359   return 1;
360 }
361
362 int VideoVPEOGL::sync()
363 {
364   if (!initted) return 0;
365
366 //  if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
367   return 1;
368 }
369
370
371
372
373 int VideoVPEOGL::play()
374 {
375   if (!initted) return 0;
376   decoding_backend=0;
377 #ifdef VPE_OMX_SUPPORT
378   bool doomx=true;
379   if (h264) {
380           if (!omx_h264) doomx=false;
381   } else {
382           if (!omx_mpeg2) doomx=false;
383   }
384   if (doomx) {
385           if (AllocateCodecsOMX()) {
386                   decoding_backend=VPE_DECODER_OMX;
387                   return 1;
388                   // Otherwise fall back to ffmpeg
389           } else {
390                   if (h264) {
391                           omx_h264=false;
392                           Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume h264 unsupported");
393                   } else {
394                           omx_mpeg2=false;
395                           Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume mpeg2 unsupported");
396                   }
397           }
398   }
399 #endif
400 #ifdef VPE_FFMPEG_SUPPORT
401   if (AllocateCodecsFFMPEG()) {
402           decoding_backend=VPE_DECODER_FFMPEG;
403           return 1;
404                   // Otherwise fall back to ffmpeg
405   }
406 #endif
407   return 0;
408
409
410
411 }
412
413 #ifdef VPE_OMX_SUPPORT
414 int VideoVPEOGL::AllocateCodecsOMX()
415 {
416         OMX_ERRORTYPE error;
417         static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
418
419         Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
420         //Clock, move later to audio
421
422         omx_events.clear();
423
424         error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
425
426
427         if (error!=OMX_ErrorNone){
428                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
429                 DeAllocateCodecsOMX();
430                 return 0;
431         }
432
433
434
435         OMX_PORT_PARAM_TYPE p_param;
436         memset(&p_param,0,sizeof(p_param));
437         p_param.nSize=sizeof(p_param);
438         p_param.nVersion.nVersion=OMX_VERSION;
439         error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
440         if (error!=OMX_ErrorNone){
441                 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
442                 DeAllocateCodecsOMX();
443                 return 0;
444         }
445         omx_clock_output_port=p_param.nStartPortNumber;
446
447         for (unsigned int i=0;i<p_param.nPorts;i++) {
448                 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i) ) {
449                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
450                         DeAllocateCodecsOMX();
451                         return 0;
452                 }
453         }
454
455
456         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
457         memset(&clock_conf,0,sizeof(clock_conf));
458         clock_conf.nSize=sizeof(clock_conf);
459         clock_conf.nVersion.nVersion=OMX_VERSION;
460         clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
461         clock_conf.nStartTime=0;
462         clock_conf.nOffset=0;
463         clock_conf.nWaitMask=OMX_CLOCKPORT0;
464         error=OMX_SetParameter(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
465         if (error!=OMX_ErrorNone){
466                 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
467                 DeAllocateCodecsOMX();
468                 return 0;
469         }
470
471
472
473         if (h264) {
474                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
475         } else {
476                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
477         }
478
479         if (error!=OMX_ErrorNone){
480                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
481                 DeAllocateCodecsOMX();
482                 return 0;
483         }
484
485
486
487         memset(&p_param,0,sizeof(p_param));
488         p_param.nSize=sizeof(p_param);
489         p_param.nVersion.nVersion=OMX_VERSION;
490         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
491         if (error!=OMX_ErrorNone){
492                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
493                 DeAllocateCodecsOMX();
494             return 0;
495         }
496         omx_codec_input_port=p_param.nStartPortNumber;
497         omx_codec_output_port=p_param.nStartPortNumber+1;
498
499         if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
500                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
501                 DeAllocateCodecsOMX();
502                 return 0;
503         }
504
505
506         OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
507         memset(&conceal,0,sizeof(conceal));
508         conceal.nSize=sizeof(conceal);
509         conceal.nVersion.nVersion=OMX_VERSION;
510         conceal.bStartWithValidFrame=OMX_FALSE;
511
512         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
513         if (error!=OMX_ErrorNone){
514                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
515                 DeAllocateCodecsOMX();
516                 return 0;
517         }
518
519
520         error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
521         if (error!=OMX_ErrorNone){
522                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
523                 DeAllocateCodecsOMX();
524                 return 0;
525         }
526
527
528
529         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
530         if (error!=OMX_ErrorNone){
531                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
532                 DeAllocateCodecsOMX();
533                 return 0;
534         }
535         omx_shed_input_port=p_param.nStartPortNumber;
536         omx_shed_output_port=p_param.nStartPortNumber+1;
537
538
539         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
540         if (error!=OMX_ErrorNone){
541                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
542                 DeAllocateCodecsOMX();
543                 return 0;
544         }
545         omx_shed_clock_port=p_param.nStartPortNumber;
546
547
548         if (!DisablePort(omx_vid_sched,omx_shed_input_port) || !DisablePort(omx_vid_sched,omx_shed_output_port)
549                         || !DisablePort(omx_vid_sched,omx_shed_clock_port)) {
550                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
551                 DeAllocateCodecsOMX();
552                 return 0;
553         }
554
555
556         error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
557         if (error!=OMX_ErrorNone){
558                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
559                 DeAllocateCodecsOMX();
560                 return 0;
561         }
562
563         error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
564         if (error!=OMX_ErrorNone){
565                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
566                 DeAllocateCodecsOMX();
567                 return 0;
568         }
569         omx_rend_input_port=p_param.nStartPortNumber;
570         //omx_rend_output_port=p_param.nStartPortNumber+1;
571
572
573         if (!DisablePort(omx_vid_rend,omx_rend_input_port) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
574                                 ) {
575                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
576                 DeAllocateCodecsOMX();
577                 return 0;
578         }
579
580         //Setuo chain
581
582
583
584
585
586
587
588
589 /*      error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
590         if (error!=OMX_ErrorNone){
591                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
592                 return 0;
593         }*/
594
595
596
597
598         OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
599         memset(&ft_type,0,sizeof(ft_type));
600         ft_type.nSize=sizeof(ft_type);
601         ft_type.nVersion.nVersion=OMX_VERSION;
602
603         ft_type.nPortIndex=omx_codec_input_port;
604         if (h264) {
605                 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
606         } else {
607                 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
608         }
609
610         Demuxer* demux=Demuxer::getInstance();
611
612     ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
613     Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
614         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
615         if (error!=OMX_ErrorNone){
616                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
617                 DeAllocateCodecsOMX();
618                 return 0;
619         }
620
621
622         if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
623                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
624                 DeAllocateCodecsOMX();
625                 return 0;
626         }
627
628
629         if (!PrepareInputBufsOMX()) {
630                 DeAllocateCodecsOMX();
631                 return 0;
632         }
633
634
635         if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
636                 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle");
637                 DeAllocateCodecsOMX();
638                 return 0;
639         }
640
641         error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
642         if (error!=OMX_ErrorNone){
643                 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);
644                 DeAllocateCodecsOMX();
645                 return 0;
646         }
647
648         if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
649                                         ) {
650                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
651                 DeAllocateCodecsOMX();
652                 return 0;
653         }
654
655         if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
656                 DeAllocateCodecsOMX();
657                 return 0;
658         }
659
660         error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
661         if (error!=OMX_ErrorNone){
662                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
663                 DeAllocateCodecsOMX();
664                 return 0;
665         }
666
667
668
669         if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
670                                                 ) {
671                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
672                 DeAllocateCodecsOMX();
673                 return 0;
674         }
675
676         if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
677                 return 0;
678         }
679         if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
680                 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
681                 DeAllocateCodecsOMX();
682                 return 0;
683         }
684         if (!CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)
685                         ||!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port)){
686                 DeAllocateCodecsOMX();
687                 return 0;
688         }
689
690         if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
691                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
692                 DeAllocateCodecsOMX();
693                 return 0;
694         }
695
696         error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
697         if (error!=OMX_ErrorNone){
698                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel  sched to rend failed %x", error);
699                 DeAllocateCodecsOMX();
700                 return 0;
701         }
702
703         if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
704                                                         ) {
705                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX  shed rend failed");
706                 DeAllocateCodecsOMX();
707                 return 0;
708         }
709
710         if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
711                                         || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
712                 DeAllocateCodecsOMX();
713                 return 0;
714         }
715
716         if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
717                 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
718                 DeAllocateCodecsOMX();
719                 return 0;
720         }
721
722
723         if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
724                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
725                 DeAllocateCodecsOMX();
726                 return 0;
727         }
728
729         if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
730                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
731                 DeAllocateCodecsOMX();
732                 return 0;
733         }
734
735         //raspbi specifif
736         OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
737         memset(&dispconf,0,sizeof(dispconf));
738         dispconf.nSize=sizeof(dispconf);
739         dispconf.nVersion.nVersion=OMX_VERSION;
740
741         dispconf.nPortIndex=omx_rend_input_port;
742
743         dispconf.set=OMX_DISPLAY_SET_LAYER ;
744         dispconf.layer=1;
745         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
746         if (error!=OMX_ErrorNone){
747                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
748                 DeAllocateCodecsOMX();
749                 return 0;
750         }
751
752 /*      dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
753         dispconf.fullscreen=OMX_FALSE;
754         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
755         if (error!=OMX_ErrorNone){
756                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
757                 DeAllocateCodecsOMX();
758                 return 0;
759         }
760
761         dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
762         dispconf.dest_rect.x_offset=100;
763         dispconf.dest_rect.y_offset=100;
764         dispconf.dest_rect.width=640;
765         dispconf.dest_rect.height=480;
766         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
767         if (error!=OMX_ErrorNone){
768                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
769                 DeAllocateCodecsOMX();
770                 return 0;
771         }*/
772
773
774
775
776         if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
777                         Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Exccute");
778                         DeAllocateCodecsOMX();
779                         return 0;
780         }
781
782         omx_running=true;
783
784         return 1;
785 }
786
787
788 int VideoVPEOGL::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type)
789 {
790         OMX_ERRORTYPE error;
791         error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
792         if (error!=OMX_ErrorNone){
793                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
794                 return 0;
795         }
796
797         if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
798                 return 0;
799         }
800
801         return 1;
802 }
803
804
805 int VideoVPEOGL::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
806 {
807         OMX_ERRORTYPE error;
808         error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
809         if (error!=OMX_ErrorNone){
810                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
811                 return 0;
812         }
813
814         if (!wait) return 1;
815         if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
816                 return 0;
817         }
818
819         return 1;
820 }
821
822
823 int VideoVPEOGL::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
824 {
825         OMX_ERRORTYPE error;
826         error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
827         if (error!=OMX_ErrorNone){
828                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
829                 return 0;
830         }
831
832         if (!wait) return 1;
833         if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
834                 return 0;
835         }
836
837
838         return 1;
839 }
840
841
842
843
844 int VideoVPEOGL::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2)
845 {
846         int i=0;
847         while (i<1000) {
848                 omx_event_mutex.Lock();
849                 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
850                 while (itty!=omx_events.end()) {
851
852                         VPE_OMX_EVENT current=*itty;
853                         if (current.handle==handle) { //this is ours
854                                 if (current.event_type==OMX_EventError) {
855                                         omx_events.erase(itty);
856                                         omx_event_mutex.Unlock();
857                                         return 0;
858
859                                 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
860                                         omx_events.erase(itty);
861                                         omx_event_mutex.Unlock();
862                                         return 1;
863                                 }
864                         }
865                         itty++;
866
867                 }
868                 omx_event_mutex.Unlock();
869                 MILLISLEEP(2);
870                 i++;
871
872         }
873         Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
874         return 0;
875
876 }
877
878
879
880
881
882 int VideoVPEOGL::PrepareInputBufsOMX()
883 {
884         OMX_ERRORTYPE error;
885         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
886         memset(&port_def_type,0,sizeof(port_def_type));
887         port_def_type.nSize=sizeof(port_def_type);
888         port_def_type.nVersion.nVersion=OMX_VERSION;
889         port_def_type.nPortIndex=omx_codec_input_port;
890
891         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
892
893         if (error!=OMX_ErrorNone){
894                         Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
895         }
896 /*      Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
897                         port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
898                         port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
899
900         port_def_type.nBufferCountActual=60;
901
902         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
903
904         if (error!=OMX_ErrorNone){
905                         Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
906         }
907
908
909         error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
910         if (error!=OMX_ErrorNone){
911                 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
912                 return 0;
913         }
914
915         input_bufs_omx_mutex.Lock();
916         for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
917
918         //      unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nBufferSize);
919                 OMX_BUFFERHEADERTYPE *buf_head=NULL;
920         /*      error=OMX_UseBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize,new_buffer_data);
921                 if (error!=OMX_ErrorNone){
922                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_UseBuffer failed %x", error);
923                         input_bufs_omx_mutex.Unlock();
924                         return 0;
925                 }*/
926                 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
927                 if (error!=OMX_ErrorNone){
928                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
929                                 input_bufs_omx_mutex.Unlock();
930                         return 0;
931                 }
932                 input_bufs_omx_all.push_back(buf_head);
933                 input_bufs_omx_free.push_back(buf_head);
934         }
935         omx_first_frame=true;
936
937         firstsynched=false;
938         cur_input_buf_omx=NULL;
939         input_bufs_omx_mutex.Unlock();
940
941
942         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
943         if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
944                 return 0;
945         }
946         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
947
948         return 1;
949 }
950
951 int VideoVPEOGL::DestroyInputBufsOMX()
952 {
953         OMX_ERRORTYPE error;
954
955         cur_input_buf_omx=NULL;
956         input_bufs_omx_mutex.Lock();
957         for (int i=0; i< input_bufs_omx_all.size();i++) {
958         //      free(input_bufs_omx_all[i]->pBuffer);
959         //      input_bufs_omx_all[i]->pBuffer=NULL;
960                 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
961                 if (error!=OMX_ErrorNone){
962                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
963                         input_bufs_omx_mutex.Unlock();
964                         return 0;
965                 }
966         }
967         input_bufs_omx_all.clear();
968         input_bufs_omx_free.clear();
969         input_bufs_omx_mutex.Unlock();
970
971 }
972
973
974
975
976 int VideoVPEOGL::DeAllocateCodecsOMX()
977 {
978         OMX_ERRORTYPE error;
979         omx_running=false;
980         if (omx_vid_dec) {
981                 // first flush all buffers
982
983                 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_output_port, NULL);
984                 if (error!=OMX_ErrorNone){
985                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
986
987                 }
988
989                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_input_port, NULL);
990                 if (error!=OMX_ErrorNone){
991                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed in failed %x", error);
992
993                 }
994
995                 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_output_port) ||
996                                 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_input_port)) {
997                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec shed failed");
998                 }
999
1000                 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1001                 if (error!=OMX_ErrorNone){
1002                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1003
1004                 }
1005
1006                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
1007                 if (error!=OMX_ErrorNone){
1008                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
1009
1010                 }
1011
1012                 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1013                         !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
1014                                 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
1015                 }
1016
1017                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_output_port, NULL);
1018                 if (error!=OMX_ErrorNone) {
1019                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed out failed %x", error);
1020
1021                 }
1022
1023                 error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1024                 if (error!=OMX_ErrorNone) {
1025                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1026
1027                 }
1028
1029                 if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ||
1030                                 !CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
1031                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
1032                 }
1033
1034
1035
1036
1037                 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1038                 if (error!=OMX_ErrorNone){
1039                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1040
1041                 }
1042
1043
1044                 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_input_port)) {
1045                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec input failed");
1046                 }
1047
1048                 DestroyInputBufsOMX();
1049
1050                 //todo flushing
1051                 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
1052                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
1053                 }
1054                 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
1055                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
1056                 }
1057
1058                 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
1059                 if (error!=OMX_ErrorNone){
1060                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1061
1062                 }
1063
1064                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
1065                 if (error!=OMX_ErrorNone){
1066                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1067
1068                 }
1069
1070                 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
1071                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
1072                 }
1073
1074                 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1075                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
1076                 }
1077
1078                 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
1079                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
1080                 }
1081                 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
1082                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
1083                 }
1084
1085
1086
1087                 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
1088                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
1089                 }
1090
1091
1092                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
1093                 if (error!=OMX_ErrorNone){
1094                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1095
1096                 }
1097                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
1098                 if (error!=OMX_ErrorNone){
1099                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1100
1101                 }
1102
1103                 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1104                 if (error!=OMX_ErrorNone){
1105                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1106
1107                 }
1108
1109                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
1110                 if (error!=OMX_ErrorNone){
1111                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1112
1113                 }
1114
1115
1116
1117
1118
1119                 error=OMX_FreeHandle(omx_vid_dec);
1120                 error=OMX_FreeHandle(omx_vid_sched);
1121                 error=OMX_FreeHandle(omx_vid_rend);
1122                 error=OMX_FreeHandle(omx_clock);
1123                 omx_vid_dec=NULL;
1124                 if (error!=OMX_ErrorNone) {
1125                         Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1126                 }
1127         }
1128
1129         return 1;
1130 }
1131
1132 #endif
1133
1134
1135 #ifdef VPE_FFMPEG_SUPPORT
1136
1137 int VideoVPEOGL::AllocateCodecsFFMPEG()
1138 {
1139         Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecsFFmpeg");
1140         mpeg2codec_context_ff=avcodec_alloc_context();
1141         if (mpeg2codec_context_ff==NULL) {
1142                 Log::getInstance()->log("Video", Log::DEBUG, "Creating ffmpeg codec context failed");
1143                 return 0;
1144         }
1145         if(avcodec_open(mpeg2codec_context_ff, mpeg2codec_ff)<0) {
1146                 Log::getInstance()->log("Video", Log::DEBUG, "Opening ffmpeg codec  failed");
1147                 return 0;
1148         }
1149         dec_frame_ff=avcodec_alloc_frame(); // may be we need multiple frames, if we want to use async texture upload
1150         if (!dec_frame_ff) {
1151                 Log::getInstance()->log("Video", Log::DEBUG, "Allocating dec_frame  failed");
1152                 return 0;
1153         }
1154
1155         return 1;
1156
1157 }
1158
1159 int VideoVPEOGL::DeAllocateCodecsFFMPEG()
1160 {
1161         Log::getInstance()->log("Video", Log::NOTICE, "DeAllocateCodecsFFmpeg");
1162         if (dec_frame_ff) {
1163                 av_free(dec_frame_ff);
1164                 dec_frame_ff=NULL;
1165         }
1166         if (mpeg2codec_context_ff) {
1167                 avcodec_close(mpeg2codec_context_ff);
1168                 av_free(mpeg2codec_context_ff);
1169                 mpeg2codec_context_ff=NULL;
1170
1171         }
1172
1173
1174
1175         return 1;
1176 }
1177
1178
1179
1180
1181
1182 #endif
1183
1184 int VideoVPEOGL::stop()
1185 {
1186   if (!initted) return 0;
1187
1188 #ifdef VPE_OMX_SUPPORT
1189   //Check if ffmpeg mode
1190   if (decoding_backend==VPE_DECODER_OMX) DeAllocateCodecsOMX();
1191   decoding_backend=0;
1192
1193 #endif
1194
1195   
1196
1197 //  if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
1198   return 1;
1199 }
1200
1201 int VideoVPEOGL::reset()
1202 {
1203   if (!initted) return 0;
1204  
1205 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
1206   return 1;
1207 }
1208
1209 int VideoVPEOGL::pause()
1210 {
1211   if (!initted) return 0;
1212
1213 //  if (ioctl(fdVideo, AV_SET_VID_PAUSE, 0) != 0) return 0;
1214   return 1;
1215 }
1216
1217 int VideoVPEOGL::unPause() // FIXME get rid - same as play!!
1218 {
1219   if (!initted) return 0;
1220 //  if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
1221   return 1;
1222 }
1223
1224 int VideoVPEOGL::fastForward()
1225 {
1226   if (!initted) return 0;
1227
1228 //  if (ioctl(fdVideo, AV_SET_VID_FFWD, 1) != 0) return 0;
1229   return 1;
1230 }
1231
1232 int VideoVPEOGL::unFastForward()
1233 {
1234   if (!initted) return 0;
1235
1236 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
1237
1238  //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
1239   return 1;
1240 }
1241
1242 int VideoVPEOGL::attachFrameBuffer()
1243 {
1244   if (!initted) return 0;
1245
1246 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
1247   return 1;
1248 }
1249
1250 int VideoVPEOGL::blank(void)
1251 {
1252 //  if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
1253 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
1254   return 1;
1255 }
1256
1257 ULLONG VideoVPEOGL::getCurrentTimestamp()
1258 {
1259 /*  sync_data_t timestamps;
1260   if (ioctl(fdVideo, AV_GET_VID_TIMESTAMPS, &timestamps) == 0)
1261   {
1262     // FIXME are these the right way around?
1263
1264     timestamps.stc = (timestamps.stc >> 31 ) | (timestamps.stc & 1);
1265     timestamps.pts = (timestamps.pts >> 31 ) | (timestamps.pts & 1);
1266
1267     return timestamps.stc;
1268   }
1269   else
1270   {
1271     return 0;
1272   }*/
1273   return 0;
1274 }
1275
1276 ULONG VideoVPEOGL::timecodeToFrameNumber(ULLONG timecode)
1277 {
1278   if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
1279   else               return (ULONG)(((double)timecode / (double)90000) * (double)30);
1280 }
1281
1282 #ifdef DEV
1283 int VideoVPEOGL::test()
1284 {
1285   return 0;
1286
1287 //  ULLONG stc = 0;
1288 //  return ioctl(fdVideo, AV_SET_VID_STC, &stc);
1289 /*
1290  // reset();
1291   return 1;
1292 */
1293 }
1294
1295 int VideoVPEOGL::test2()
1296 {
1297   return 0;
1298 }
1299 #endif
1300
1301 void VideoVPEOGL::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1302 {
1303   mediapacket = mplist.front();
1304 }
1305
1306 UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
1307 {
1308   DeliverMediaPacket(mediapacket, buffer, samplepos);
1309   if (*samplepos == mediapacket.length) {
1310     *samplepos = 0;
1311     return 1;
1312   }
1313   else return 0;
1314 }
1315
1316 UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
1317                 const UCHAR* buffer,
1318                 UINT *samplepos)
1319 {
1320         if (packet.type == MPTYPE_VIDEO_H264)
1321         {
1322                 h264=true;
1323         }
1324         else
1325         {
1326                 h264=false;
1327         }
1328         switch (decoding_backend) {
1329         default: case 0: return 0; // no backend runnigng
1330 #ifdef VPE_OMX_SUPPORT
1331         case VPE_DECODER_OMX: return DeliverMediaPacketOMX(packet,buffer,samplepos);
1332 #endif
1333 #ifdef VPE_FFMPEG_SUPPORT
1334         case VPE_DECODER_FFMPEG: return DeliverMediaPacketFFMPEG(packet,buffer,samplepos);
1335 #endif
1336         }
1337 }
1338
1339 #ifdef VPE_OMX_SUPPORT
1340 UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
1341                 const UCHAR* buffer,
1342                 UINT *samplepos)
1343 {
1344
1345
1346         //Later add fail back code for ffmpeg
1347         /*if (!videoon) {
1348                 *samplepos+=packet.length;
1349                 return packet.length;
1350         }*/
1351
1352
1353         if (!omx_running) return 0; // if we are not runnig do not do this
1354
1355
1356         OMX_ERRORTYPE error;
1357
1358         OMX_PARAM_PORTDEFINITIONTYPE port_image;
1359         memset(&port_image,0,sizeof(port_image));
1360         port_image.nSize=sizeof(port_image);
1361         port_image.nVersion.nVersion=OMX_VERSION;
1362         port_image.nPortIndex =omx_codec_output_port;
1363         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_image);
1364         if (error!= OMX_ErrorNone){
1365                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_GetParameter failed %x", error);
1366         }
1367         Log::getInstance()->log("Video", Log::DEBUG, "Image port %d %d", port_image.format.video.nFrameWidth , port_image.format.video.nFrameHeight);
1368
1369         /*First Check, if we have an audio sample*/
1370         if (iframemode) {
1371                 //samplepos=0;
1372                 MILLISLEEP(10);
1373                 return 0; //Not in iframe mode!
1374         }
1375
1376         UINT headerstrip=0;
1377         if (packet.disconti) {
1378                 firstsynched=false;
1379                 if (cur_input_buf_omx) {
1380                         OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1381                         if (error!=OMX_ErrorNone){
1382                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1383                         }
1384                         cur_input_buf_omx=NULL;
1385                 }
1386         }
1387
1388         /*Inspect PES-Header */
1389
1390         OMX_STATETYPE temp_state;
1391         OMX_GetState(omx_vid_dec,&temp_state);
1392
1393         if (*samplepos==0) {//stripheader
1394                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
1395                 //headerstrip+=6; //h264
1396                 *samplepos+=headerstrip;
1397                 if ( packet.synched ) {
1398
1399                         if (cur_input_buf_omx) {
1400                                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1401                                 if (error!=OMX_ErrorNone){
1402                                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1403                                 }
1404
1405                                 cur_input_buf_omx=NULL;//write out old data
1406                         }
1407                 //      reftime1=packet.presentation_time;
1408                 //      reftime2=reftime1+1;
1409                         firstsynched=true;
1410                 } else {
1411                         if (!firstsynched) {//
1412                                 *samplepos=packet.length;//if we have not processed at least one
1413                                 return packet.length;//synched packet ignore it!
1414                         }
1415                 }
1416         }
1417
1418         if (!cur_input_buf_omx) {
1419                 input_bufs_omx_mutex.Lock();
1420                 if (input_bufs_omx_free.size()==0) {
1421                         input_bufs_omx_mutex.Unlock();
1422                         Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
1423                         return 0; // we do not have a free media sample
1424
1425                 }
1426                 cur_input_buf_omx=input_bufs_omx_free.front();
1427                 cur_input_buf_omx->nFilledLen=0;
1428                 cur_input_buf_omx->nOffset=0;
1429                 cur_input_buf_omx->nTimeStamp=0;
1430                 input_bufs_omx_free.pop_front();
1431                 input_bufs_omx_mutex.Unlock();
1432         }
1433
1434
1435
1436
1437         if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
1438                 /*if (packet.disconti) {
1439                         ms->SetDiscontinuity(TRUE);
1440                 } else {
1441                         ms->SetDiscontinuity(FALSE);
1442                 }*/
1443                 //if (packet.synched) {
1444
1445                         //lastreftimePTS=packet.pts;
1446                    if (omx_first_frame) { // TODO time
1447                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
1448                            omx_first_frame=false;
1449                    } else
1450
1451                 //}
1452                 //else
1453                 //{
1454                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1455
1456
1457                         //  ms->SetSyncPoint(TRUE);
1458                 //}
1459
1460         }
1461         unsigned int haveToCopy=packet.length-*samplepos;
1462
1463         while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
1464                 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
1465                 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
1466                 haveToCopy-=cancopy;
1467                 cur_input_buf_omx->nFilledLen+=cancopy;
1468                 *samplepos+=cancopy;
1469                 // push old buffer out
1470
1471                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1472                 if (error!=OMX_ErrorNone){
1473                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1474                 }
1475                 // get5 new buffer
1476                 input_bufs_omx_mutex.Lock();
1477                 if (input_bufs_omx_free.size()==0) {
1478                         input_bufs_omx_mutex.Unlock();
1479                         //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
1480                         return *samplepos; // we do not have a free media sample
1481                 }
1482                 cur_input_buf_omx=input_bufs_omx_free.front();
1483                 cur_input_buf_omx->nFilledLen=0;
1484                 cur_input_buf_omx->nOffset=0;
1485                 cur_input_buf_omx->nTimeStamp=0;
1486                 input_bufs_omx_free.pop_front();
1487                 input_bufs_omx_mutex.Unlock();
1488
1489                 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1490
1491         }
1492         memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
1493                         buffer+packet.pos_buffer+*samplepos,haveToCopy);
1494         cur_input_buf_omx->nFilledLen+=haveToCopy;
1495
1496
1497
1498         *samplepos+=haveToCopy;
1499
1500         return *samplepos;
1501
1502 }
1503
1504 #endif
1505
1506
1507 #ifdef VPE_FFMPEG_SUPPORT
1508 UINT VideoVPEOGL::DeliverMediaPacketFFMPEG(MediaPacket packet,
1509                 const UCHAR* buffer,
1510                 UINT *samplepos)
1511 {
1512
1513 #if 0
1514         //Later add fail back code for ffmpeg
1515         /*if (!videoon) {
1516                 *samplepos+=packet.length;
1517                 return packet.length;
1518         }*/
1519
1520
1521         if (!omx_running) return 0; // if we are not runnig do not do this
1522
1523
1524         OMX_ERRORTYPE error;
1525
1526         OMX_PARAM_PORTDEFINITIONTYPE port_image;
1527         memset(&port_image,0,sizeof(port_image));
1528         port_image.nSize=sizeof(port_image);
1529         port_image.nVersion.nVersion=OMX_VERSION;
1530         port_image.nPortIndex =omx_codec_output_port;
1531         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_image);
1532         if (error!= OMX_ErrorNone){
1533                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_GetParameter failed %x", error);
1534         }
1535         Log::getInstance()->log("Video", Log::DEBUG, "Image port %d %d", port_image.format.video.nFrameWidth , port_image.format.video.nFrameHeight);
1536
1537         /*First Check, if we have an audio sample*/
1538         if (iframemode) {
1539                 //samplepos=0;
1540                 MILLISLEEP(10);
1541                 return 0; //Not in iframe mode!
1542         }
1543
1544         UINT headerstrip=0;
1545         if (packet.disconti) {
1546                 firstsynched=false;
1547                 if (cur_input_buf_omx) {
1548                         OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1549                         if (error!=OMX_ErrorNone){
1550                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1551                         }
1552                         cur_input_buf_omx=NULL;
1553                 }
1554         }
1555
1556         /*Inspect PES-Header */
1557
1558         OMX_STATETYPE temp_state;
1559         OMX_GetState(omx_vid_dec,&temp_state);
1560
1561         if (*samplepos==0) {//stripheader
1562                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
1563                 //headerstrip+=6; //h264
1564                 *samplepos+=headerstrip;
1565                 if ( packet.synched ) {
1566
1567                         if (cur_input_buf_omx) {
1568                                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1569                                 if (error!=OMX_ErrorNone){
1570                                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1571                                 }
1572
1573                                 cur_input_buf_omx=NULL;//write out old data
1574                         }
1575                 //      reftime1=packet.presentation_time;
1576                 //      reftime2=reftime1+1;
1577                         firstsynched=true;
1578                 } else {
1579                         if (!firstsynched) {//
1580                                 *samplepos=packet.length;//if we have not processed at least one
1581                                 return packet.length;//synched packet ignore it!
1582                         }
1583                 }
1584         }
1585
1586         if (!cur_input_buf_omx) {
1587                 input_bufs_omx_mutex.Lock();
1588                 if (input_bufs_omx_free.size()==0) {
1589                         input_bufs_omx_mutex.Unlock();
1590                         Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
1591                         return 0; // we do not have a free media sample
1592
1593                 }
1594                 cur_input_buf_omx=input_bufs_omx_free.front();
1595                 cur_input_buf_omx->nFilledLen=0;
1596                 cur_input_buf_omx->nOffset=0;
1597                 cur_input_buf_omx->nTimeStamp=0;
1598                 input_bufs_omx_free.pop_front();
1599                 input_bufs_omx_mutex.Unlock();
1600         }
1601
1602
1603
1604
1605         if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
1606                 /*if (packet.disconti) {
1607                         ms->SetDiscontinuity(TRUE);
1608                 } else {
1609                         ms->SetDiscontinuity(FALSE);
1610                 }*/
1611                 //if (packet.synched) {
1612
1613                         //lastreftimePTS=packet.pts;
1614                    if (omx_first_frame) { // TODO time
1615                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
1616                            omx_first_frame=false;
1617                    } else
1618
1619                 //}
1620                 //else
1621                 //{
1622                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1623
1624
1625                         //  ms->SetSyncPoint(TRUE);
1626                 //}
1627
1628         }
1629         unsigned int haveToCopy=packet.length-*samplepos;
1630
1631         while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
1632                 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
1633                 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
1634                 haveToCopy-=cancopy;
1635                 cur_input_buf_omx->nFilledLen+=cancopy;
1636                 *samplepos+=cancopy;
1637                 // push old buffer out
1638
1639                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1640                 if (error!=OMX_ErrorNone){
1641                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1642                 }
1643                 // get5 new buffer
1644                 input_bufs_omx_mutex.Lock();
1645                 if (input_bufs_omx_free.size()==0) {
1646                         input_bufs_omx_mutex.Unlock();
1647                         //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
1648                         return *samplepos; // we do not have a free media sample
1649                 }
1650                 cur_input_buf_omx=input_bufs_omx_free.front();
1651                 cur_input_buf_omx->nFilledLen=0;
1652                 cur_input_buf_omx->nOffset=0;
1653                 cur_input_buf_omx->nTimeStamp=0;
1654                 input_bufs_omx_free.pop_front();
1655                 input_bufs_omx_mutex.Unlock();
1656
1657                 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1658
1659         }
1660         memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
1661                         buffer+packet.pos_buffer+*samplepos,haveToCopy);
1662         cur_input_buf_omx->nFilledLen+=haveToCopy;
1663
1664
1665
1666         *samplepos+=haveToCopy;
1667
1668         return *samplepos;
1669 #endif
1670         return 0;
1671
1672 }
1673
1674 #endif
1675
1676
1677
1678
1679
1680
1681 void VideoVPEOGL::ResetTimeOffsets()
1682 {
1683 }
1684
1685 bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length)
1686 {
1687   //write(fdVideo, buffer, length);
1688         if (!iframemode) EnterIframePlayback();
1689 //      WriteOutTS(buffer,length, h264?MPTYPE_VIDEO_H264 :MPTYPE_VIDEO_MPEG2 );
1690  
1691   lastpacketnum=-1;
1692   return true;
1693 }
1694
1695 int VideoVPEOGL::EnterIframePlayback()
1696 {
1697
1698         return 0;
1699 }
1700