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