]> git.vomp.tv Git - vompclient.git/blob - videovpeogl.cc
Custom libav + transcode patches + first mpeg2 playback through transcoding
[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_LIBAV_SUPPORT
45   mpeg2codec_context_libav=NULL;
46   libav_running=false;
47   dec_frame_libav_uploading_framebuf=NULL;
48   dec_frame_libav_decoding=NULL;
49   ogl_frame_outside=false;
50   //decoding_mode=VPE_NO_XVMC;
51   decoding_mode=VPE_XVMC_MOCOMP;
52   //decoding_mode=VPE_XVMC_IDCT;
53   framebuf_framenum=0;
54   moco_shader=NULL;
55
56   ogl_forward_ref_frame_num=0;
57   ogl_backward_ref_frame_num=0;
58   ogl_forward_ref_frame=NULL;
59   ogl_backward_ref_frame=NULL;
60 #endif
61
62 #ifdef  VPE_LIBAV_MPEG2_TRANSCODING
63          transcodecodec_libav=NULL;
64          transcodecodec_context_libav=NULL;
65 #endif
66
67
68 #ifdef BENCHMARK_FPS
69         time_in_decoder=0;
70     num_frames=0;
71         time_in_decoder_gl=0;
72     num_frames_gl=0;
73 #endif
74
75 }
76
77 VideoVPEOGL::~VideoVPEOGL()
78 {
79   instance = NULL;
80 }
81
82 int VideoVPEOGL::init(UCHAR tformat)
83 {
84   if (initted) return 0;
85   initted = 1;
86
87 //  if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
88
89   if (!setFormat(tformat))           { shutdown(); return 0; }
90   if (!setConnection(COMPOSITERGB))  { shutdown(); return 0; }
91   if (!setAspectRatio(ASPECT4X3))    { shutdown(); return 0; }
92   if (!setMode(NORMAL))              { shutdown(); return 0; }
93   if (!setSource())                  { shutdown(); return 0; }
94   if (!attachFrameBuffer())          { shutdown(); return 0; }
95
96   setTVsize(ASPECT4X3);
97
98 /*  if (format == PAL) setLetterboxBorder("38");
99   else setLetterboxBorder("31");*/
100
101   /* new stulibav */
102
103
104
105
106   //stop();
107
108
109
110   return 1;
111 }
112
113 int VideoVPEOGL::initUsingOSDObjects()
114 {
115         EGLDisplay i_egl_display;
116         EGLSurface i_egl_surface;
117         EGLContext i_egl_context;
118         EGLConfig i_egl_config;
119         OsdOpenGL *osd=(OsdOpenGL*)osd->getInstance();
120         osd->getEGLObjs(&i_egl_display,&i_egl_surface,&i_egl_context, &i_egl_config);
121         const EGLint attr_context[]={
122                         EGL_CONTEXT_CLIENT_VERSION,2,
123                 EGL_NONE
124         };
125
126         egl_display=i_egl_display;
127         egl_context=eglCreateContext(egl_display,i_egl_config,i_egl_context,attr_context);
128         if (egl_context==EGL_NO_CONTEXT) {
129                  Log::getInstance()->log("Video", Log::WARN, "Creating egl context failed! %x",eglGetError());
130                  return 0;
131         }
132         // We create a dummy surface here, in order to allow two contexts
133         const EGLint attr_pbuffer[]={
134                         EGL_WIDTH, 1, EGL_HEIGHT,1,
135                     EGL_NONE
136         };
137         egl_surface=eglCreatePbufferSurface(egl_display,i_egl_config,attr_pbuffer);
138         if (egl_surface==EGL_NO_SURFACE) {
139                  Log::getInstance()->log("Video", Log::WARN, "Creating egl pbuffer failed! %x",eglGetError());
140                  return 0;
141         }
142
143
144
145
146         //egl_surface=i_egl_surface;
147         //egl_context=i_egl_context;
148
149
150 #ifdef VPE_OMX_SUPPORT
151 // we are called before the audio
152         OMX_ERRORTYPE error;
153         error=OMX_Init();
154         if (error!=OMX_ErrorNone) {
155                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error);
156                 return 0;
157         }
158
159         //our callbacks move to play?
160
161 #endif
162
163 #if defined(VPE_LIBAV_MPEG2_TRANSCODING) || defined(VPE_LIBAV_SUPPORT)
164         av_register_all();
165 #endif
166
167 #ifdef VPE_LIBAV_SUPPORT
168
169
170         if (decoding_mode==VPE_NO_XVMC) {
171                 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
172         } else {
173                 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_XVMC);
174         }
175         if (mpeg2codec_libav==NULL) {
176                 Log::getInstance()->log("Video", Log::DEBUG, "Find libav mpeg2 codec failed");
177                 return 0;
178         }
179 #endif
180 #ifdef  VPE_LIBAV_MPEG2_TRANSCODING
181         transcodecodec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_MPEG4);
182         if (transcodecodec_libav==NULL) {
183                 Log::getInstance()->log("Video", Log::DEBUG, "Find libav mpeg2 transcoder failed");
184                 return 0;
185         }
186 #endif
187
188
189         threadStart();
190         return 1;
191 }
192
193
194 #ifdef VPE_OMX_SUPPORT
195
196 OMX_ERRORTYPE VideoVPEOGL::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
197            OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
198            OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
199
200         Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
201
202         struct VPE_OMX_EVENT  new_event;
203         new_event.handle=handle;
204         new_event.appdata=appdata;
205         new_event.event_type=event_type;
206         new_event.data1=data1;
207         new_event.data2=data2;
208         new_event.event_data=event_data;
209
210         VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
211         video->AddOmxEvent(new_event);
212
213 /*      switch (event_type) {
214         case OMX_EventCmdComplete: {
215
216         } break;
217         }*/
218
219         return OMX_ErrorNone;
220
221 }
222
223 void VideoVPEOGL::AddOmxEvent(VPE_OMX_EVENT  new_event)
224 {
225         omx_event_mutex.Lock();
226     omx_events.push_back(new_event);
227         omx_event_mutex.Unlock();
228 }
229
230
231 OMX_ERRORTYPE VideoVPEOGL::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
232
233         //Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
234         VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
235         video->ReturnEmptyOMXBuffer(buffer);
236         return OMX_ErrorNone;
237
238 }
239
240 void VideoVPEOGL::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
241         input_bufs_omx_mutex.Lock();
242         //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
243         input_bufs_omx_free.push_back(buffer);
244         //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
245         input_bufs_omx_mutex.Unlock();
246 }
247
248  OMX_ERRORTYPE VideoVPEOGL::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
249          Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
250         return OMX_ErrorNone;
251 }
252
253 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
254
255  enum PixelFormat VideoVPEOGL::get_format_transcode(struct AVCodecContext *s, const enum PixelFormat *fmt)
256  {
257         enum PixelFormat ret_pix=PIX_FMT_NONE;
258
259         while (*fmt!=PIX_FMT_NONE) {
260                 if (*fmt== PIX_FMT_TRANSCODE ) {
261                         ret_pix=PIX_FMT_TRANSCODE;
262                 }
263                 fmt++;
264         }
265         return ret_pix;
266  }
267
268  int VideoVPEOGL::reget_buffer_transcode(struct AVCodecContext *c, AVFrame *pic)
269  {
270          Log::getInstance()->log("Video", Log::DEBUG,"Buffer reusing! Should not happen!Not Implemented! \n");
271
272         return -1;
273  }
274
275  int VideoVPEOGL::get_buffer_transcode(struct AVCodecContext *c, AVFrame *pic)
276  {
277
278         //reget logic from mplayer
279         if (pic->opaque && pic->data[0] && (!pic->buffer_hints ||pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE )){
280                 Log::getInstance()->log("Video", Log::DEBUG,"Buffer reusing! Should not happen!\n");
281                 return 0;
282         }
283
284
285         if (c->pix_fmt!=PIX_FMT_TRANSCODE ) {
286                 Log::getInstance()->log("Video", Log::DEBUG,"We only support transcode pixel fmt\n");
287                 return 0;
288         }
289         VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
290         transcode_pix_fmt *pix_trans=NULL;
291         OMX_BUFFERHEADERTYPE* our_buf=video->GetFreeOMXBufferforlibav(&pix_trans);
292         if (our_buf==NULL|| pix_trans==NULL) {
293                 Log::getInstance()->log("Video", Log::DEBUG,"Getting buffer failed\n");
294                 return -1;
295         } else {
296
297         }
298
299
300
301
302         //populate pict
303         pic->type=FF_BUFFER_TYPE_USER; // we are controlling the buffers
304
305         pic->base[0]=(uint8_t*)our_buf; // our buf
306         //pic->extended_data=pic->data;
307         if(c->pkt) pic->pkt_pts=c->pkt->pts;
308         else pic->pkt_pts=AV_NOPTS_VALUE;
309         pic->width=c->width;
310         pic->height=c->height;
311         pic->format=c->pix_fmt;
312         pic->sample_aspect_ratio=c->sample_aspect_ratio;
313         pic->reordered_opaque= c->reordered_opaque;
314         //pic->age=INT_MAX;
315         pic->data[0]=(uint8_t*)pix_trans;
316         pix_trans->transcode_id=AV_TRANSCODE_ID;
317         pix_trans->packet.data=(uint8_t*)our_buf->pBuffer;
318         pix_trans->packet.size=our_buf->nAllocLen;
319         //that is all folks
320
321         return 0;
322
323  }
324
325  OMX_BUFFERHEADERTYPE* VideoVPEOGL::GetFreeOMXBufferforlibav(transcode_pix_fmt **pix_trans)
326  {
327          OMX_BUFFERHEADERTYPE* returned_buf=NULL;
328          *pix_trans=NULL;
329          int time_out=0;
330
331          while (returned_buf==NULL && time_out<100){
332                  input_bufs_omx_mutex.Lock();
333                   if (input_bufs_omx_free.size()!=0) {
334                             returned_buf=input_bufs_omx_free.front();
335                             returned_buf->nFilledLen=0;
336                             returned_buf->nOffset=0;
337                             returned_buf->nTimeStamp=0;
338                                 input_bufs_omx_free.pop_front();
339                                 input_bufs_omx_in_libav.push_back(returned_buf);
340                                 input_bufs_omx_mutex.Unlock();
341                                 returned_buf->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
342                                 break;
343                   }
344                   input_bufs_omx_mutex.Unlock();
345                  Log::getInstance()->log("Video", Log::DEBUG, "GetFreeOMXBuffer_libav no free sample block");
346                  time_out++;
347                  MILLISLEEP(20);
348          }
349          if (returned_buf) {
350          *pix_trans=pix_fmt_omx_free.front();
351           pix_fmt_omx_free.pop_front(); // we assume that there is always a twin
352          }
353          return returned_buf;
354  }
355
356  void VideoVPEOGL::release_buffer_transcode(struct AVCodecContext *c, AVFrame *pic)
357  {
358          VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
359          video->ReturnEmptyOMXBuffer_libav((OMX_BUFFERHEADERTYPE*) pic->base[0],(transcode_pix_fmt *)pic->data[0]);
360          pic->data[0]=NULL; //without doing this avcodec is going to cry
361  }
362
363  void VideoVPEOGL::ReturnEmptyOMXBuffer_libav(OMX_BUFFERHEADERTYPE* buffer,transcode_pix_fmt *pix_fmt){
364         input_bufs_omx_mutex.Lock();
365         // We only return it, if it was not passed to OMX!
366         Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer_libav %d",input_bufs_omx_free.size());
367         pix_fmt_omx_free.push_back(pix_fmt);
368         list<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_in_libav.begin();
369         while (itty!=input_bufs_omx_in_libav.end()) {
370                 if (*itty==buffer) {
371                         input_bufs_omx_in_libav.remove(buffer);
372                         input_bufs_omx_free.push_back(buffer);
373                         Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer_libav %d",input_bufs_omx_free.size());
374                         break;
375                 }
376         }
377         input_bufs_omx_mutex.Unlock();
378  }
379
380
381 #endif
382
383 #endif
384
385 int VideoVPEOGL::shutdown()
386 {
387   if (!initted) return 0;
388   initted = 0;
389   threadCancel();
390
391   decoding_backend=0;
392 #ifdef VPE_OMX_SUPPORT
393   DeAllocateCodecsOMX();
394   OMX_Deinit();
395 #endif
396 #ifdef VPE_LIBAV_SUPPORT
397   DeAllocateCodecsLibav();
398 #endif
399   eglDestroyContext(egl_display,egl_context);
400 //  close(fdVideo);
401   return 1;
402 }
403 #ifdef VPE_LIBAV_SUPPORT
404 int VideoVPEOGL::AllocateYUV400OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
405 {
406         Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 400");
407         // Y
408         glGenTextures(1, &outframe->textures[0]);
409         glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
410         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride, height, 0, GL_LUMINANCE,
411                                 GL_UNSIGNED_BYTE, NULL);
412         // U
413         glGenTextures(1, &outframe->textures[1]);
414         glBindTexture(GL_TEXTURE_2D, outframe->textures[1]);
415         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
416                                 GL_UNSIGNED_BYTE, NULL);
417         // V
418         glGenTextures(1, &outframe->textures[2]);
419         glBindTexture(GL_TEXTURE_2D, outframe->textures[2]);
420         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
421                         GL_UNSIGNED_BYTE, NULL);
422         outframe->height=height;
423         outframe->width=width;
424         outframe->stride=stride;
425         outframe->type=1;
426         return 1;
427 }
428
429 int VideoVPEOGL::AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
430 {
431         Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 444");
432         // Y
433         glGenTextures(1, &outframe->textures[0]);
434         glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
435         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
436                                 GL_UNSIGNED_BYTE, NULL);
437         outframe->textures[1]=outframe->textures[2]=0; // no handles here
438
439
440
441
442         outframe->type=2;
443         outframe->height=height;
444         outframe->width=width;
445         outframe->stride=stride;// does not make any sense otherwise, just to prevent reallocating
446         return 1;
447 }
448
449
450 VPEOGLFrame *VideoVPEOGL::getReadyOGLFrame(){
451         VPEOGLFrame *return_obj=NULL;
452         ogl_frame_mutex.Lock();
453         if (ready_ogl_frames.size()>0) {
454                 return_obj=ready_ogl_frames.front();
455                 ready_ogl_frames.pop_front();
456                 //Log::getInstance()->log("Video", Log::WARN, "readyOGLRFrame markoutgoing  num: %d",return_obj->pict_num);
457                 ogl_frame_outside=true;
458         }
459         ogl_frame_mutex.Unlock();
460         return return_obj;
461 }
462
463 void VideoVPEOGL::returnOGLFrame(VPEOGLFrame *frame)
464 {
465         ogl_frame_mutex.Lock();
466         if (frame) {
467                 ogl_frame_outside=false;
468                 //Log::getInstance()->log("Video", Log::WARN, "returnOGLRFrame mark incoming num: %d",frame->pict_num);
469                 if (frame->pict_num==ogl_forward_ref_frame_num ||
470                                 frame->pict_num==ogl_backward_ref_frame_num ) {
471                         recycle_ref_ogl_frames.push_back(frame);
472                 } else {
473                         free_ogl_frames.push_back(frame);
474                 }
475         }
476         ogl_frame_mutex.Unlock();
477 }
478
479 void VideoVPEOGL::recycleOGLRefFrames()
480 {
481         // This function recycles frames formerly used as reference frame
482         ogl_frame_mutex.Lock();
483         list<VPEOGLFrame*> keep;
484         list<VPEOGLFrame*>::iterator itty=recycle_ref_ogl_frames.begin();
485         while (itty!=recycle_ref_ogl_frames.end()) {
486         //      Log::getInstance()->log("Video", Log::WARN, "recycleOGLRefFrame mark3");
487                 if ((*itty)->pict_num==ogl_forward_ref_frame_num
488                                 || (*itty)->pict_num==ogl_backward_ref_frame_num)
489                 {
490                         // ok we have to keep this
491                         keep.push_back(*itty);
492                 } else {
493                         free_ogl_frames.push_back(*itty);
494                 }
495                 itty++;
496         }
497         recycle_ref_ogl_frames.clear();
498         recycle_ref_ogl_frames=keep;
499
500         ogl_frame_mutex.Unlock();
501
502
503 }
504 #endif
505
506 void VideoVPEOGL::threadMethod()
507 {
508         if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
509                 Log::getInstance()->log("Video", Log::WARN, "Making egl Current failed in thread %d",eglGetError());
510                 return;
511         }
512         long long run=0;
513         while (1) {
514                 bool sleep=true;
515
516                 run++;
517 #ifdef VPE_LIBAV_SUPPORT
518                 bool upload=false;
519                 bool view=false;
520                 dec_frame_libav_mutex.Lock();
521                 AVFrame* dec_frame_libav_uploading_int=NULL;
522
523
524                 if (dec_frame_libav_upload_and_view_pending.size()>0  ) {
525
526                         dec_frame_libav_uploading_int=dec_frame_libav_upload_and_view_pending.front();
527                         dec_frame_libav_uploading_framebuf=(VPE_FrameBuf*)dec_frame_libav_uploading_int->base[0];
528                         //Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view %d %lld %x",(dec_frame_libav_uploading_framebuf)->pict_num,run,
529                 //                      dec_frame_libav_uploading_framebuf);
530                 //      if (dec_frame_libav_upload_only_pending.size()>0) Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view2 %d",
531                 //                      ((VPE_FrameBuf*)dec_frame_libav_upload_only_pending.front())->pict_num);
532
533                         view=true;
534                         if ((dec_frame_libav_uploading_framebuf)->ogl_uploaded || decoding_mode==VPE_NO_XVMC  ) {
535                                 dec_frame_libav_upload_and_view_pending.pop_front();
536                                 if (decoding_mode==VPE_NO_XVMC) upload=true;
537                         } else {
538                                 dec_frame_libav_uploading_framebuf=NULL;
539                                 dec_frame_libav_uploading_int=NULL; // if not uploaded do not do it yet
540                                 view=false; //do the upload
541                         //      Log::getInstance()->log("Video", Log::WARN, "threadMethod u and view view canceled");
542                         }
543                 }
544
545                 if (!view && dec_frame_libav_upload_only_pending.size()>0) { //this is for uploading reference frames ahead
546
547                         dec_frame_libav_uploading_framebuf=dec_frame_libav_upload_only_pending.front();
548                         //Log::getInstance()->log("Video", Log::WARN, "threadMethod u  %d %lld %x",((VPE_FrameBuf*)dec_frame_libav_uploading_framebuf)->pict_num,run,
549                                 //      dec_frame_libav_uploading_framebuf);
550                         dec_frame_libav_upload_only_pending.pop_front();
551                         view=false;
552                         upload=true;
553                 /*      if (((VPE_FrameBuf*)dec_frame_libav_uploading->base[0])->ogl_uploaded) {
554                                 upload=false;
555                                 dec_frame_libav_uploading=NULL; //do not upload again
556                         }*/
557                 }
558
559
560
561
562
563
564                 if (dec_frame_libav_upload_and_view_pending.size()>0
565                         ||dec_frame_libav_upload_only_pending.size()>0) sleep=false;
566
567                 dec_frame_libav_mutex.Unlock();
568
569
570                 if (dec_frame_libav_uploading_framebuf) {
571
572                         //Code Block for debugging if needed
573                 /*      Log::getInstance()->log("Video", Log::WARN, "Iterate all free ogl frames");
574                         ogl_frame_mutex.Lock();
575                         list<VPEOGLFrame*>::iterator itty=free_ogl_frames.begin();
576                         while (itty!=free_ogl_frames.end()) {
577                                 Log::getInstance()->log("Video", Log::WARN, "free ogl pict num %d",(*itty)->pict_num);
578
579                                 itty++;
580                         }
581
582                         itty=recycle_ref_ogl_frames.begin();
583                         while (itty!=recycle_ref_ogl_frames.end()) {
584                                 Log::getInstance()->log("Video", Log::WARN, "recycle ogl pict num %d",(*itty)->pict_num);
585
586                                 itty++;
587                         }
588                         itty=ready_ogl_frames.begin();
589                         while (itty!=ready_ogl_frames.end()) {
590                                 Log::getInstance()->log("Video", Log::WARN, "ready ogl pict num %d",(*itty)->pict_num);
591
592                                 itty++;
593                         }
594                         ogl_frame_mutex.Unlock();*/
595
596
597                         if (upload) {
598                                 int width,height,pixfmt;
599                                 //First get a free ogl image
600                                 VPEOGLFrame* out_frame=NULL;
601                                 //int msleep=0;
602                                 while (!out_frame) {
603                                         ogl_frame_mutex.Lock();
604                                 //      Log::getInstance()->log("Video", Log::WARN, "threadMethod mark upload 1a %d %d %d %d %d",all_ogl_frames.size(),free_ogl_frames.size(),
605                                         //                                                              recycle_ref_ogl_frames.size(),ready_ogl_frames.size(),ogl_frame_outside);
606                                         if (all_ogl_frames.size()==0) {
607                                                 ogl_frame_mutex.Unlock(); break;
608                                         }
609
610                                         if (free_ogl_frames.size()>0) {
611                                                 width=libavwidth;
612                                                 height=libavheight;
613                                                 pixfmt=libavpixfmt;
614                                                 out_frame=free_ogl_frames.front();
615                                                 free_ogl_frames.pop_front();
616                                         } else {
617                                                 ogl_frame_mutex.Unlock();
618                                                 MILLISLEEP(2);
619                                         //      msleep+=2;
620                                                 ogl_frame_mutex.Lock();
621                                         }
622                                 //      if (msleep)Log::getInstance()->log("Video", Log::WARN, "msleep FPS %d",msleep);
623                                         ogl_frame_mutex.Unlock();
624                                 }
625                                 bool failed=false;
626                                 if (out_frame) {
627                                 //      Log::getInstance()->log("Video", Log::WARN, "outframes old pict num: %d",out_frame->pict_num);
628                                         if (out_frame->textures[0]==0 || out_frame->width!=width ||
629                                                         out_frame->height!=height || out_frame->stride!=dec_frame_libav_uploading_framebuf->stride) {
630                                                 if (out_frame->textures[0]!=0) {
631                                                         glDeleteTextures(1,&out_frame->textures[0]);
632                                                         out_frame->textures[0]=0;
633                                                 }
634                                                 if (out_frame->textures[1]!=0) {
635                                                         glDeleteTextures(1,&out_frame->textures[1]);
636                                                         out_frame->textures[1]=0;
637                                                 }
638                                                 if (out_frame->textures[2]!=0) {
639                                                         glDeleteTextures(1,&out_frame->textures[2]);
640                                                         out_frame->textures[2]=0;
641                                                 }
642
643                                                 if (decoding_mode==VPE_NO_XVMC) {
644                                                         if (!AllocateYUV400OglTexture(out_frame,width,height,dec_frame_libav_uploading_framebuf->stride)) failed=true;
645                                                 } else {
646                                                         if (!AllocateYUV444OglTexture(out_frame,width,height,dec_frame_libav_uploading_framebuf->stride)) failed=true; //We use a YUV 444 texture in this case
647                                                         // the shaders are easier to implement
648                                                 }
649                                         }
650                                         dec_frame_libav_uploading_framebuf->ogl_ref=out_frame;
651                                         dec_frame_libav_uploading_framebuf->ogl_uploaded=true;
652
653
654                                         if (!failed) {
655                                                 //up to now only YUV data, this is for reference only, since the pi is too slow.
656                                                 if (decoding_mode==VPE_NO_XVMC) {
657                                                         glBindTexture(GL_TEXTURE_2D, out_frame->textures[0]);
658                                                         glPixelStorei(GL_UNPACK_ALIGNMENT,1);
659                                                         glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
660                                                                         out_frame->stride,out_frame->height,
661                                                                         GL_LUMINANCE,GL_UNSIGNED_BYTE,
662                                                                         dec_frame_libav_uploading_framebuf->data[0]);
663
664                                                         glBindTexture(GL_TEXTURE_2D, out_frame->textures[1]);
665                                                         glPixelStorei(GL_UNPACK_ALIGNMENT,1);
666                                                         glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
667                                                                         out_frame->stride>>1,out_frame->height>>1,
668                                                                         GL_LUMINANCE,GL_UNSIGNED_BYTE,
669                                                                         dec_frame_libav_uploading_framebuf->data[1]);
670
671                                                         glBindTexture(GL_TEXTURE_2D, out_frame->textures[2]);
672                                                         glPixelStorei(GL_UNPACK_ALIGNMENT,1);
673                                                         glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
674                                                                         out_frame->stride>>1,out_frame->height>>1,
675                                                                         GL_LUMINANCE,GL_UNSIGNED_BYTE,
676                                                                         dec_frame_libav_uploading_framebuf->data[2]);
677                                                 } else {
678                                                         //XVMC case
679                                                         xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading_framebuf->data[2];
680                                                         if (moco_shader && pix_fmt) {
681
682 #ifdef BENCHMARK_FPS
683                                                                 int cur_time=getTimeMS();
684 #endif
685                                                                 moco_shader->uploadDataBlocks(pix_fmt->data_blocks,pix_fmt->next_free_data_block_num,
686                                                                                 pix_fmt->mv_blocks , pix_fmt->filled_mv_blocks_num );
687                                                         //      Log::getInstance()->log("Video", Log::WARN, "Pictnum %d Forward %d Backward %d ",pix_fmt->p_surface,
688                                                                 //                                                      pix_fmt->p_past_surface,pix_fmt->p_future_surface);
689
690                                                                 if (((int)pix_fmt->p_future_surface)!=0 && ogl_backward_ref_frame_num!=((int)pix_fmt->p_future_surface))
691                                                                 {
692                                                                         //Now determine the frame, that fits
693                                                                         ogl_frame_mutex.Lock();
694                                                                         bool found=false;
695                                                                         for (int i=0;i<all_ogl_frames.size();i++) {
696                                                                                 if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_future_surface))
697                                                                                 {
698                                                                                         ogl_forward_ref_frame=ogl_backward_ref_frame; //mpeg life time axioms
699                                                                                         ogl_forward_ref_frame_num=ogl_backward_ref_frame_num;
700                                                                                         ogl_backward_ref_frame=all_ogl_frames[i];
701                                                                                         ogl_backward_ref_frame_num=(int)pix_fmt->p_future_surface;
702                                                                                         found=true;
703                                                                                         break;
704                                                                                 }
705                                                                         }
706                                                                 //      if (!found) {// for debugging
707                                                                 //              Log::getInstance()->log("Video", Log::WARN, "Emergency reference frame not found");
708                                                                 //              exit(0);
709                                                                 //      }
710
711                                                                         ogl_frame_mutex.Unlock();
712                                                                         recycleOGLRefFrames(); //needed for recycling of reference frames
713                                                                 }
714                                                         //      Log::getInstance()->log("Video", Log::WARN, "Pictnum mark1");
715
716 /*
717                                                                 if ( ((int)pix_fmt->p_past_surface)==ogl_backward_ref_frame_num)
718                                                                 {
719
720                                                                 }*/
721
722                                                                 if (((int)pix_fmt->p_past_surface)!=0 && ogl_forward_ref_frame_num!=((int)pix_fmt->p_past_surface))
723                                                                 {
724                                                                         //Now determine the frame, that fits
725                                                                         ogl_frame_mutex.Lock();
726                                                                         bool found=false;
727                                                                         for (int i=0;i<all_ogl_frames.size();i++) {
728                                                                                 if (all_ogl_frames[i]->pict_num==((int)pix_fmt->p_past_surface))
729                                                                                 {
730                                                                                         ogl_forward_ref_frame=all_ogl_frames[i];
731                                                                                         ogl_forward_ref_frame_num=(int)pix_fmt->p_past_surface; // This should not happen, or for DMV, who knows
732                                                                                         found=true;
733                                                                                         break;
734                                                                                 }
735                                                                         }
736                                                                 //      if (!found) {
737                                                                 //              Log::getInstance()->log("Video", Log::WARN, "Emergency reference frame not found %d %d",ogl_forward_ref_frame_num,
738                                                                 //                              ((int)pix_fmt->p_past_surface));
739                                                                 //              exit(0);
740                                                                 //      }
741
742                                                                         ogl_frame_mutex.Unlock();
743                                                                         recycleOGLRefFrames(); //needed for recycling of reference frames
744
745                                                                 }
746                                                                 //Log::getInstance()->log("Video", Log::WARN, "Pictnum mark2");
747
748                                                                 if (decoding_mode==VPE_XVMC_MOCOMP)
749                                                                 {
750                                                                         //DCT Blocks upload
751
752                                                                 } else {
753                                                                         //DCT Blocks upload
754                                                                 }
755                                                                 out_frame->pict_num=dec_frame_libav_uploading_framebuf->pict_num;
756
757                                                         //      Log::getInstance()->log("Video", Log::WARN, "Pictnum mark3");
758
759                                                                 moco_shader->doMoCo(out_frame,(((int)pix_fmt->p_past_surface)!=0)? ogl_forward_ref_frame:NULL,
760                                                                                 (((int)pix_fmt->p_future_surface)!=0)? ogl_backward_ref_frame:NULL);
761
762 #ifdef BENCHMARK_FPS
763                                                                 time_in_decoder_gl+=getTimeMS()-cur_time;
764                                                                 num_frames_gl++;
765                                                                 if ((num_frames_gl%100)==0) {
766                                                                         float fps=1000./(float)(time_in_decoder_gl);
767                                                                         fps*=((float)num_frames_gl);
768                                                                         Log::getInstance()->log("Video", Log::NOTICE, "Current GL Decoding FPS %g", fps);
769                                                                 }
770 #endif
771
772                                                                 //Log::getInstance()->log("Video", Log::WARN, "Pictnum mark4");
773                                                                 // Excute motion compensation
774                                                         } else {
775                                                                 //Log::getInstance()->log("Video", Log::WARN, "moco pixfmt error abort");
776                                                                 //                                      exit(0);
777                                                         }
778                                                 }
779
780
781
782                                         }
783                                 }
784
785                         }
786
787
788
789                         if (view) {
790
791                                 //Log::getInstance()->log("Video", Log::WARN, "threadMethod mark view");
792                                 VPEOGLFrame* out_frame=dec_frame_libav_uploading_framebuf->ogl_ref;
793                                 xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading_framebuf->data[2];
794                         /*      Log::getInstance()->log("Video", Log::WARN, "View Pictnum %d Forward %d Backward %d pict_num %d",pix_fmt->p_surface,
795                                                                                                                         pix_fmt->p_past_surface,pix_fmt->p_future_surface,out_frame->pict_num);
796                                 Log::getInstance()->log("Video", Log::WARN, "Real Pictnum %d ",out_frame->pict_num);*/
797
798                                 releaseFrameBufUpload(dec_frame_libav_uploading_framebuf);
799                                 ogl_frame_mutex.Lock();
800                                 ready_ogl_frames.push_back(out_frame);
801                                 ogl_frame_mutex.Unlock();
802                                 ((OsdOpenGL*)Osd::getInstance())->AdviseAboutNewFrame(); //Tell him, that we have a frame waiting
803
804                                 dec_frame_libav_mutex.Lock();
805                                 dec_frame_libav_free.push_back(dec_frame_libav_uploading_int);
806                                 dec_frame_libav_mutex.Unlock();
807                         }
808
809
810                         dec_frame_libav_mutex.Lock();
811                         dec_frame_libav_uploading_framebuf=NULL;
812
813                         if (dec_frame_libav_upload_and_view_pending.size()>0
814                                         ||dec_frame_libav_upload_only_pending.size()>0) sleep=false;
815
816                         dec_frame_libav_mutex.Unlock();
817
818
819
820                 }
821 #endif
822
823                 if (sleep) {
824                         struct timespec target_time;
825                         int ts=20; //20 ms
826                         clock_gettime(CLOCK_REALTIME,&target_time);
827                         target_time.tv_nsec+=1000000LL*ts;
828                         if (target_time.tv_nsec>999999999) {
829                                 target_time.tv_nsec-=1000000000L;
830                                 target_time.tv_sec+=1;
831                         }
832                         threadWaitForSignalTimed(&target_time);
833                         //Log::getInstance()->log("Video", Log::WARN, "threadMethod signalled FPS");
834                 }
835                 threadCheckExit();
836         }
837
838 }
839
840
841 void VideoVPEOGL::threadPostStopCleanup()
842 {
843         eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
844 #ifdef VPE_LIBAV_SUPPORT
845         dec_frame_libav_uploading_framebuf=NULL;
846 #endif
847 }
848
849
850
851
852 int VideoVPEOGL::setTVsize(UCHAR ttvsize)
853 {
854 /*  tvsize = ttvsize;
855
856   // Override the aspect ratio usage, temporarily use to set the video chip mode
857   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
858   close(fdVideo);
859   if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
860   if (!setSource())                  { shutdown(); return 0; }
861   if (!attachFramebuffer())          { shutdown(); return 0; }
862
863   // Reopening the fd causes the scart aspect line to go back to 4:3
864   // Set this again to the same as the tv screen size
865   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
866
867   // mode == LETTERBOX is invalid if the TV is widescreen
868   if (tvsize == ASPECT16X9) setMode(NORMAL);
869 */
870   return 1;
871 }
872
873 int VideoVPEOGL::setDefaultAspect()
874 {
875   return setAspectRatio(tvsize);
876 }
877
878
879
880 int VideoVPEOGL::setFormat(UCHAR tformat)
881 {
882   if (!initted) return 0;
883   if ((tformat != PAL) && (tformat != NTSC)) return 0;
884   format = tformat;
885
886 //  if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
887
888   if (format == NTSC)
889   {
890     screenWidth = 720;
891     screenHeight = 480;
892   }
893   if (format == PAL)
894   {
895     screenWidth = 720;
896     screenHeight = 576;
897   }
898
899   return 1;
900 }
901
902 int VideoVPEOGL::setConnection(UCHAR tconnection)
903 {
904   if (!initted) return 0;
905   if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
906   connection = tconnection;
907
908 //  if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
909   return 1;
910 }
911
912 int VideoVPEOGL::setAspectRatio(UCHAR taspectRatio)
913 {
914   if (!initted) return 0;
915   if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
916   aspectRatio = taspectRatio;
917
918   Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
919
920 //  if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
921   return 1;
922 }
923
924 int VideoVPEOGL::setMode(UCHAR tmode)
925 {
926   if (!initted) return 0;
927
928   if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
929
930   if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
931       && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
932   mode = tmode;
933
934 //  if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
935   return 1;
936 }
937
938 int VideoVPEOGL::signalOff()
939 {
940 //  if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
941   return 1;
942 }
943
944 int VideoVPEOGL::signalOn()
945 {
946 //  if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
947   return 1;
948 }
949
950 int VideoVPEOGL::setSource()
951 {
952   if (!initted) return 0;
953
954   // What does this do...
955 //  if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
956   return 1;
957 }
958
959 int VideoVPEOGL::setPosition(int x, int y)
960 {
961   if (!initted) return 0;
962
963 //  vid_pos_regs_t pos_d;
964 //  pos_d.x = x;
965 //  pos_d.y = y;
966
967 /*  vid_pos_regs_t pos_d;
968
969   memset(&pos_d, 0, sizeof(pos_d));
970
971   pos_d.dest.y = y;
972   pos_d.dest.x = x;
973 /*
974 typedef struct {
975   int w;
976   int h;
977   int scale;
978   int x1;
979   int y;
980   int x;
981   int y2;
982   int x3;
983   int y3;
984   int x4;
985   int y4;
986 } vid_pos_regs_t;
987 */
988
989 /*
990   pos_d.w = 100;
991   pos_d.h = 30;
992   pos_d.scale = 2;
993   pos_d.x1 = 0;
994   pos_d.y = 100;            // Top left X
995   pos_d.x = 50;            // Top left Y
996   pos_d.y2 = 30;
997   pos_d.x3 = 60;
998   pos_d.y3 = 90;
999   pos_d.x4 = 120;
1000   pos_d.y4 = 150;
1001 */
1002
1003 //  if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
1004   return 1;
1005 }
1006
1007 int VideoVPEOGL::sync()
1008 {
1009   if (!initted) return 0;
1010
1011 //  if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
1012   return 1;
1013 }
1014
1015
1016
1017
1018 int VideoVPEOGL::play()
1019 {
1020   if (!initted) return 0;
1021   decoding_backend=0;
1022 #ifdef VPE_OMX_SUPPORT
1023   bool doomx=true;
1024   if (h264) {
1025           if (!omx_h264) doomx=false;
1026   } else {
1027           if (!omx_mpeg2) doomx=false;
1028   }
1029   if (doomx) {
1030           if (AllocateCodecsOMX()) {
1031                   //decoding_backend=VPE_DECODER_OMX;
1032                   return 1;
1033                   // Otherwise fall back to libav
1034           } else {
1035                   if (h264) {
1036                           omx_h264=false;
1037                           Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume h264 unsupported");
1038                   } else {
1039                           omx_mpeg2=false;
1040                           Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume mpeg2 unsupported");
1041                   }
1042           }
1043   }
1044 #endif
1045 #ifdef VPE_LIBAV_SUPPORT
1046   if (AllocateCodecsLibav()) {
1047           decoding_backend=VPE_DECODER_libav;
1048           return 1;
1049                   // Otherwise fall back to libav
1050   }
1051 #endif
1052   return 0;
1053
1054
1055
1056 }
1057
1058 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1059
1060 int VideoVPEOGL::InitTranscoderLibAV() {
1061         transcodecodec_context_libav = avcodec_alloc_context3(transcodecodec_libav);
1062         if (!transcodecodec_context_libav) {
1063                 Log::getInstance()->log("Video", Log::DEBUG, "Alloc avcodec context failed!");
1064                 return 0;
1065         }
1066
1067         transcodecodec_context_libav->slice_flags = SLICE_FLAG_CODED_ORDER;
1068
1069         transcodecodec_context_libav->pix_fmt = PIX_FMT_TRANSCODE;
1070         transcodecodec_context_libav->get_format = get_format_transcode;
1071         transcodecodec_context_libav->get_buffer = get_buffer_transcode;
1072         transcodecodec_context_libav->reget_buffer = reget_buffer_transcode;
1073         transcodecodec_context_libav->release_buffer = release_buffer_transcode;
1074         //transcodecodec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
1075         //transcodecodec_context_libav->time_base.den=9000; //pts values 90 KHz Clock /10;
1076
1077         int avc_ret = avcodec_open2(transcodecodec_context_libav, transcodecodec_libav, NULL);
1078         if (avc_ret < 0) {
1079                 Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec  failed \n");
1080                 return 0;
1081         }
1082
1083         memset(&incom_packet_libav, 0, sizeof(incom_packet_libav));
1084         incom_packet_libav_size = 200000;
1085         incom_packet_libav.data = (uint8_t*) av_malloc(incom_packet_libav_size + FF_INPUT_BUFFER_PADDING_SIZE);
1086
1087         return 1;
1088 }
1089
1090
1091
1092 int VideoVPEOGL::DeInitTranscoderLibAV() {
1093
1094         av_free(incom_packet_libav.data);
1095         incom_packet_libav.data=NULL;
1096         incom_packet_libav_size=0;
1097
1098         if (transcodecodec_context_libav) {
1099                 avcodec_close(transcodecodec_context_libav);
1100                 av_free(transcodecodec_context_libav);
1101                 transcodecodec_context_libav=NULL;
1102
1103         }
1104
1105         return 1;
1106 }
1107
1108 #endif
1109
1110 #ifdef VPE_OMX_SUPPORT
1111 int VideoVPEOGL::AllocateCodecsOMX()
1112 {
1113         OMX_ERRORTYPE error;
1114         static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
1115
1116         Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
1117         //Clock, move later to audio
1118
1119         omx_events.clear();
1120
1121         error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
1122
1123
1124         if (error!=OMX_ErrorNone){
1125                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
1126                 DeAllocateCodecsOMX();
1127                 return 0;
1128         }
1129
1130
1131
1132         OMX_PORT_PARAM_TYPE p_param;
1133         memset(&p_param,0,sizeof(p_param));
1134         p_param.nSize=sizeof(p_param);
1135         p_param.nVersion.nVersion=OMX_VERSION;
1136         error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
1137         if (error!=OMX_ErrorNone){
1138                 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
1139                 DeAllocateCodecsOMX();
1140                 return 0;
1141         }
1142         omx_clock_output_port=p_param.nStartPortNumber;
1143
1144         for (unsigned int i=0;i<p_param.nPorts;i++) {
1145                 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i) ) {
1146                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
1147                         DeAllocateCodecsOMX();
1148                         return 0;
1149                 }
1150         }
1151
1152
1153         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
1154         memset(&clock_conf,0,sizeof(clock_conf));
1155         clock_conf.nSize=sizeof(clock_conf);
1156         clock_conf.nVersion.nVersion=OMX_VERSION;
1157         clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
1158         clock_conf.nStartTime=0;
1159         clock_conf.nOffset=0;
1160         clock_conf.nWaitMask=OMX_CLOCKPORT0;
1161         error=OMX_SetParameter(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
1162         if (error!=OMX_ErrorNone){
1163                 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
1164                 DeAllocateCodecsOMX();
1165                 return 0;
1166         }
1167
1168
1169
1170         if (h264) {
1171                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
1172         } else {
1173                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
1174         }
1175
1176         if (error!=OMX_ErrorNone){
1177                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
1178                 DeAllocateCodecsOMX();
1179                 return 0;
1180         }
1181
1182
1183
1184         memset(&p_param,0,sizeof(p_param));
1185         p_param.nSize=sizeof(p_param);
1186         p_param.nVersion.nVersion=OMX_VERSION;
1187         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
1188         if (error!=OMX_ErrorNone){
1189                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
1190                 DeAllocateCodecsOMX();
1191             return 0;
1192         }
1193         omx_codec_input_port=p_param.nStartPortNumber;
1194         omx_codec_output_port=p_param.nStartPortNumber+1;
1195
1196         if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
1197                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
1198                 DeAllocateCodecsOMX();
1199                 return 0;
1200         }
1201
1202
1203         OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
1204         memset(&conceal,0,sizeof(conceal));
1205         conceal.nSize=sizeof(conceal);
1206         conceal.nVersion.nVersion=OMX_VERSION;
1207         conceal.bStartWithValidFrame=OMX_FALSE;
1208
1209         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
1210         if (error!=OMX_ErrorNone){
1211                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
1212                 DeAllocateCodecsOMX();
1213                 return 0;
1214         }
1215
1216
1217         error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
1218         if (error!=OMX_ErrorNone){
1219                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
1220                 DeAllocateCodecsOMX();
1221                 return 0;
1222         }
1223
1224
1225
1226         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
1227         if (error!=OMX_ErrorNone){
1228                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1229                 DeAllocateCodecsOMX();
1230                 return 0;
1231         }
1232         omx_shed_input_port=p_param.nStartPortNumber;
1233         omx_shed_output_port=p_param.nStartPortNumber+1;
1234
1235
1236         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
1237         if (error!=OMX_ErrorNone){
1238                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
1239                 DeAllocateCodecsOMX();
1240                 return 0;
1241         }
1242         omx_shed_clock_port=p_param.nStartPortNumber;
1243
1244
1245         if (!DisablePort(omx_vid_sched,omx_shed_input_port) || !DisablePort(omx_vid_sched,omx_shed_output_port)
1246                         || !DisablePort(omx_vid_sched,omx_shed_clock_port)) {
1247                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
1248                 DeAllocateCodecsOMX();
1249                 return 0;
1250         }
1251
1252
1253         error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
1254         if (error!=OMX_ErrorNone){
1255                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
1256                 DeAllocateCodecsOMX();
1257                 return 0;
1258         }
1259
1260         error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
1261         if (error!=OMX_ErrorNone){
1262                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
1263                 DeAllocateCodecsOMX();
1264                 return 0;
1265         }
1266         omx_rend_input_port=p_param.nStartPortNumber;
1267         //omx_rend_output_port=p_param.nStartPortNumber+1;
1268
1269
1270         if (!DisablePort(omx_vid_rend,omx_rend_input_port) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
1271                                 ) {
1272                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
1273                 DeAllocateCodecsOMX();
1274                 return 0;
1275         }
1276
1277         //Setuo chain
1278
1279
1280
1281
1282
1283
1284
1285
1286 /*      error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
1287         if (error!=OMX_ErrorNone){
1288                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
1289                 return 0;
1290         }*/
1291
1292
1293
1294
1295         OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
1296         memset(&ft_type,0,sizeof(ft_type));
1297         ft_type.nSize=sizeof(ft_type);
1298         ft_type.nVersion.nVersion=OMX_VERSION;
1299
1300         ft_type.nPortIndex=omx_codec_input_port;
1301         if (h264) {
1302                 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
1303         } else {
1304                 //ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
1305                 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG4;
1306                 decoding_backend=VPE_DECODER_OMX_libav_TRANSCODE;
1307                 InitTranscoderLibAV();
1308         }
1309
1310         Demuxer* demux=Demuxer::getInstance();
1311
1312     ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
1313     Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
1314         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
1315         if (error!=OMX_ErrorNone){
1316                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
1317                 DeAllocateCodecsOMX();
1318                 return 0;
1319         }
1320
1321
1322         if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
1323                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
1324                 DeAllocateCodecsOMX();
1325                 return 0;
1326         }
1327
1328
1329         if (!PrepareInputBufsOMX()) {
1330                 DeAllocateCodecsOMX();
1331                 return 0;
1332         }
1333
1334
1335         if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
1336                 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle");
1337                 DeAllocateCodecsOMX();
1338                 return 0;
1339         }
1340
1341         error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
1342         if (error!=OMX_ErrorNone){
1343                 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);
1344                 DeAllocateCodecsOMX();
1345                 return 0;
1346         }
1347
1348         if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
1349                                         ) {
1350                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
1351                 DeAllocateCodecsOMX();
1352                 return 0;
1353         }
1354
1355         if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
1356                 DeAllocateCodecsOMX();
1357                 return 0;
1358         }
1359
1360         error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
1361         if (error!=OMX_ErrorNone){
1362                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
1363                 DeAllocateCodecsOMX();
1364                 return 0;
1365         }
1366
1367
1368
1369         if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
1370                                                 ) {
1371                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
1372                 DeAllocateCodecsOMX();
1373                 return 0;
1374         }
1375
1376         if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
1377                 return 0;
1378         }
1379         if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
1380                 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
1381                 DeAllocateCodecsOMX();
1382                 return 0;
1383         }
1384         if (!CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)
1385                         ||!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port)){
1386                 DeAllocateCodecsOMX();
1387                 return 0;
1388         }
1389
1390         if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
1391                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
1392                 DeAllocateCodecsOMX();
1393                 return 0;
1394         }
1395
1396         error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
1397         if (error!=OMX_ErrorNone){
1398                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel  sched to rend failed %x", error);
1399                 DeAllocateCodecsOMX();
1400                 return 0;
1401         }
1402
1403         if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
1404                                                         ) {
1405                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX  shed rend failed");
1406                 DeAllocateCodecsOMX();
1407                 return 0;
1408         }
1409
1410         if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
1411                                         || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
1412                 DeAllocateCodecsOMX();
1413                 return 0;
1414         }
1415
1416         if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
1417                 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
1418                 DeAllocateCodecsOMX();
1419                 return 0;
1420         }
1421
1422
1423         if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
1424                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
1425                 DeAllocateCodecsOMX();
1426                 return 0;
1427         }
1428
1429         if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
1430                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
1431                 DeAllocateCodecsOMX();
1432                 return 0;
1433         }
1434
1435         //raspbi specifif
1436         OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
1437         memset(&dispconf,0,sizeof(dispconf));
1438         dispconf.nSize=sizeof(dispconf);
1439         dispconf.nVersion.nVersion=OMX_VERSION;
1440
1441         dispconf.nPortIndex=omx_rend_input_port;
1442
1443         dispconf.set=OMX_DISPLAY_SET_LAYER ;
1444         dispconf.layer=1;
1445         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1446         if (error!=OMX_ErrorNone){
1447                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1448                 DeAllocateCodecsOMX();
1449                 return 0;
1450         }
1451
1452 /*      dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1453         dispconf.fullscreen=OMX_FALSE;
1454         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1455         if (error!=OMX_ErrorNone){
1456                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1457                 DeAllocateCodecsOMX();
1458                 return 0;
1459         }
1460
1461         dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1462         dispconf.dest_rect.x_offset=100;
1463         dispconf.dest_rect.y_offset=100;
1464         dispconf.dest_rect.width=640;
1465         dispconf.dest_rect.height=480;
1466         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1467         if (error!=OMX_ErrorNone){
1468                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1469                 DeAllocateCodecsOMX();
1470                 return 0;
1471         }*/
1472
1473
1474
1475
1476         if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1477                         Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Exccute");
1478                         DeAllocateCodecsOMX();
1479                         return 0;
1480         }
1481
1482         if (decoding_backend!=VPE_DECODER_OMX_libav_TRANSCODE) decoding_backend=VPE_DECODER_OMX;
1483         omx_running=true;
1484
1485         return 1;
1486 }
1487
1488
1489 int VideoVPEOGL::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type)
1490 {
1491         OMX_ERRORTYPE error;
1492         error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1493         if (error!=OMX_ErrorNone){
1494                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1495                 return 0;
1496         }
1497
1498         if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1499                 return 0;
1500         }
1501
1502         return 1;
1503 }
1504
1505
1506 int VideoVPEOGL::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1507 {
1508         OMX_ERRORTYPE error;
1509         error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1510         if (error!=OMX_ErrorNone){
1511                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1512                 return 0;
1513         }
1514
1515         if (!wait) return 1;
1516         if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1517                 return 0;
1518         }
1519
1520         return 1;
1521 }
1522
1523
1524 int VideoVPEOGL::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1525 {
1526         OMX_ERRORTYPE error;
1527         error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1528         if (error!=OMX_ErrorNone){
1529                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1530                 return 0;
1531         }
1532
1533         if (!wait) return 1;
1534         if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1535                 return 0;
1536         }
1537
1538
1539         return 1;
1540 }
1541
1542
1543
1544
1545 int VideoVPEOGL::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2)
1546 {
1547         int i=0;
1548         while (i<1000) {
1549                 omx_event_mutex.Lock();
1550                 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1551                 while (itty!=omx_events.end()) {
1552
1553                         VPE_OMX_EVENT current=*itty;
1554                         if (current.handle==handle) { //this is ours
1555                                 if (current.event_type==OMX_EventError) {
1556                                         omx_events.erase(itty);
1557                                         omx_event_mutex.Unlock();
1558                                         return 0;
1559
1560                                 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1561                                         omx_events.erase(itty);
1562                                         omx_event_mutex.Unlock();
1563                                         return 1;
1564                                 }
1565                         }
1566                         itty++;
1567
1568                 }
1569                 omx_event_mutex.Unlock();
1570                 MILLISLEEP(2);
1571                 i++;
1572
1573         }
1574         Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1575         return 0;
1576
1577 }
1578
1579
1580
1581
1582
1583 int VideoVPEOGL::PrepareInputBufsOMX()
1584 {
1585         OMX_ERRORTYPE error;
1586         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1587         memset(&port_def_type,0,sizeof(port_def_type));
1588         port_def_type.nSize=sizeof(port_def_type);
1589         port_def_type.nVersion.nVersion=OMX_VERSION;
1590         port_def_type.nPortIndex=omx_codec_input_port;
1591
1592         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1593
1594         if (error!=OMX_ErrorNone){
1595                         Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1596         }
1597 /*      Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1598                         port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1599                         port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1600
1601         port_def_type.nBufferCountActual=60;
1602         port_def_type.nBufferSize=max(port_def_type.nBufferSize,200000); // for transcoder important
1603
1604         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1605
1606         if (error!=OMX_ErrorNone){
1607                         Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1608         }
1609
1610
1611         error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1612         if (error!=OMX_ErrorNone){
1613                 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1614                 return 0;
1615         }
1616
1617         input_bufs_omx_mutex.Lock();
1618         for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1619
1620         //      unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1621                 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1622         /*      error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1623                 if (error!=OMX_ErrorNone){
1624                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1625                         input_bufs_omx_mutex.Unlock();
1626                         return 0;
1627                 }*/
1628                 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1629                 if (error!=OMX_ErrorNone){
1630                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1631                                 input_bufs_omx_mutex.Unlock();
1632                         return 0;
1633                 }
1634                 input_bufs_omx_all.push_back(buf_head);
1635                 input_bufs_omx_free.push_back(buf_head);
1636 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1637                 transcode_pix_fmt* new_pix=NULL;
1638                 new_pix=(transcode_pix_fmt*)malloc(sizeof(transcode_pix_fmt));
1639                 pix_fmt_omx_all.push_back(new_pix);
1640                 pix_fmt_omx_free.push_back(new_pix);
1641 #endif
1642         }
1643         omx_first_frame=true;
1644
1645         firstsynched=false;
1646         cur_input_buf_omx=NULL;
1647         input_bufs_omx_mutex.Unlock();
1648
1649
1650         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1651         if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1652                 return 0;
1653         }
1654         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1655
1656         return 1;
1657 }
1658
1659 int VideoVPEOGL::DestroyInputBufsOMX()
1660 {
1661         OMX_ERRORTYPE error;
1662
1663         cur_input_buf_omx=NULL;
1664         input_bufs_omx_mutex.Lock();
1665         for (int i=0; i< input_bufs_omx_all.size();i++) {
1666         //      free(input_bufs_omx_all[i]->pBuffer);
1667         //      input_bufs_omx_all[i]->pBuffer=NULL;
1668                 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1669                 if (error!=OMX_ErrorNone){
1670                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1671                         input_bufs_omx_mutex.Unlock();
1672                         return 0;
1673                 }
1674
1675 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1676                 free(pix_fmt_omx_all[i]);
1677 #endif
1678         }
1679         input_bufs_omx_all.clear();
1680         input_bufs_omx_free.clear();
1681 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1682         input_bufs_omx_in_libav.clear();
1683         pix_fmt_omx_all.clear();
1684         pix_fmt_omx_free.clear();
1685 #endif
1686         input_bufs_omx_mutex.Unlock();
1687
1688 }
1689
1690
1691
1692
1693 int VideoVPEOGL::DeAllocateCodecsOMX()
1694 {
1695         OMX_ERRORTYPE error;
1696         omx_running=false;
1697 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
1698    if (decoding_backend==VPE_DECODER_OMX_libav_TRANSCODE)
1699             DeInitTranscoderLibAV();
1700 #endif
1701
1702         if (omx_vid_dec) {
1703                 // first flush all buffers
1704
1705                 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_output_port, NULL);
1706                 if (error!=OMX_ErrorNone){
1707                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1708
1709                 }
1710
1711                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_input_port, NULL);
1712                 if (error!=OMX_ErrorNone){
1713                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed in failed %x", error);
1714
1715                 }
1716
1717                 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_output_port) ||
1718                                 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_input_port)) {
1719                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec shed failed");
1720                 }
1721
1722                 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1723                 if (error!=OMX_ErrorNone){
1724                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1725
1726                 }
1727
1728                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
1729                 if (error!=OMX_ErrorNone){
1730                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
1731
1732                 }
1733
1734                 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1735                         !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
1736                                 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
1737                 }
1738
1739                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_output_port, NULL);
1740                 if (error!=OMX_ErrorNone) {
1741                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed out failed %x", error);
1742
1743                 }
1744
1745                 error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1746                 if (error!=OMX_ErrorNone) {
1747                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1748
1749                 }
1750
1751                 if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ||
1752                                 !CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
1753                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
1754                 }
1755
1756
1757
1758
1759                 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1760                 if (error!=OMX_ErrorNone){
1761                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1762
1763                 }
1764
1765
1766                 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_input_port)) {
1767                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec input failed");
1768                 }
1769
1770                 DestroyInputBufsOMX();
1771
1772                 //todo flushing
1773                 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
1774                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
1775                 }
1776                 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
1777                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
1778                 }
1779
1780                 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
1781                 if (error!=OMX_ErrorNone){
1782                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1783
1784                 }
1785
1786                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
1787                 if (error!=OMX_ErrorNone){
1788                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1789
1790                 }
1791
1792                 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
1793                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
1794                 }
1795
1796                 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1797                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
1798                 }
1799
1800                 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
1801                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
1802                 }
1803                 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
1804                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
1805                 }
1806
1807
1808
1809                 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
1810                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
1811                 }
1812
1813
1814                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
1815                 if (error!=OMX_ErrorNone){
1816                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1817
1818                 }
1819                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
1820                 if (error!=OMX_ErrorNone){
1821                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1822
1823                 }
1824
1825                 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1826                 if (error!=OMX_ErrorNone){
1827                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1828
1829                 }
1830
1831                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
1832                 if (error!=OMX_ErrorNone){
1833                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1834
1835                 }
1836
1837
1838
1839
1840
1841                 error=OMX_FreeHandle(omx_vid_dec);
1842                 error=OMX_FreeHandle(omx_vid_sched);
1843                 error=OMX_FreeHandle(omx_vid_rend);
1844                 error=OMX_FreeHandle(omx_clock);
1845                 omx_vid_dec=NULL;
1846                 if (error!=OMX_ErrorNone) {
1847                         Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1848                 }
1849         }
1850
1851         return 1;
1852 }
1853
1854 #endif
1855
1856
1857 #ifdef VPE_LIBAV_SUPPORT
1858
1859 enum PixelFormat VideoVPEOGL::get_format_libav(struct AVCodecContext *s, const enum PixelFormat *fmt)
1860 {
1861         int dec_mode=((VideoVPEOGL*)getInstance())->getlibavDecodingMode();
1862         enum PixelFormat ret_pix=PIX_FMT_NONE;
1863         if (dec_mode==VPE_NO_XVMC) return PIX_FMT_NONE;
1864         while (*fmt!=PIX_FMT_NONE) {
1865                 if (*fmt== PIX_FMT_XVMC_MPEG2_IDCT && dec_mode==VPE_XVMC_IDCT) {
1866                         ret_pix=PIX_FMT_XVMC_MPEG2_IDCT;
1867                 } else if (*fmt== PIX_FMT_XVMC_MPEG2_MC && dec_mode==VPE_XVMC_MOCOMP) {
1868                         ret_pix=PIX_FMT_XVMC_MPEG2_MC;
1869                 }
1870                 fmt++;
1871         }
1872         return ret_pix;
1873 }
1874
1875 // we use this function to push the data to ogl out before hand, this is only useful for xvmc
1876 void VideoVPEOGL::draw_horiz_band_libav(struct AVCodecContext *s, const AVFrame *src, int offset[4], int y, int type, int height)
1877 {
1878         if ((y+height)==src->height) {
1879         /*      Log::getInstance()->log("Video", Log::NOTICE, "draw_horiz_band %d %d %d %d %d!",y,type,height,((xvmc_pix_fmt *)src->data[2])->p_surface,
1880                                 ((xvmc_pix_fmt *)src->data[2])->picture_structure);*/
1881                 if (((xvmc_pix_fmt *)src->data[2])->picture_structure!=3) {
1882                         Log::getInstance()->log("Video", Log::ERR, "Non frame pict not supported! Yet! Please send sample to authors!"); exit(0);
1883                 }
1884                 ((VideoVPEOGL*)Video::getInstance())->add_dec_frame_upload_only(s,src);
1885         }
1886
1887 }
1888
1889 int VideoVPEOGL::reget_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1890 {
1891         Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!Not Implemented!");
1892         return -1;
1893 }
1894
1895 int VideoVPEOGL::get_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1896 {
1897         unsigned int want_sizes[4]={0,0,0,0};
1898         AVPicture pict;
1899         bool normal_pixs=false;
1900         int num_blocks=0;
1901         int num_dct_blocks=0;
1902
1903         int s_a[4];
1904         //reget logic from mplayer
1905         if (pic->opaque && pic->data[0] && (!pic->buffer_hints ||pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE )){
1906                 Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!");
1907                 return 0;
1908         }
1909
1910
1911         if (c->pix_fmt!=PIX_FMT_XVMC_MPEG2_IDCT &&c->pix_fmt!=PIX_FMT_XVMC_MPEG2_MC) {
1912                 normal_pixs=true;
1913                 // standard pixel format
1914                 // this is written using much inspiration from libav util.c, so portions from there
1915                 int width,height;
1916
1917                 width=c->width;
1918                 height=c->height;
1919
1920                 avcodec_align_dimensions2(c, &width, &height, s_a);
1921                 if ((c->flags & CODEC_FLAG_EMU_EDGE)==0) {
1922                         width+=2*16;
1923                         height+=2*16;
1924                 }
1925                 // Now we have to determine alignment size
1926                 bool unaligned=true;
1927                 while (unaligned) {
1928                         av_image_fill_linesizes(pict.linesize, c->pix_fmt, width); //linesizes are derived
1929                         width+=width & ~(width-1); //trick from libav, now determine, if the alignment is ok
1930                         unaligned=false;
1931                         for (int i=0;i<4;i++) {
1932                                 if ((pict.linesize[i]%s_a[i])!=0) {
1933                                         unaligned=true;
1934                                         break;
1935                                 }
1936                         }
1937                 }
1938                 int tot_size=av_image_fill_pointers(pict.data, c->pix_fmt, height, NULL, pict.linesize); //get sizes
1939                 for (int i=0;i<4 ;i++) {
1940                         if (i<3 && pict.data[i+1]) {
1941                                 want_sizes[i]=pict.data[i+1]-pict.data[i];
1942                                 want_sizes[i]+=16;
1943                         } else {
1944                                 want_sizes[i]=(tot_size-(pict.data[i]-pict.data[0]));
1945                                 want_sizes[i]+=16;
1946                                 break;
1947                         }
1948                 }
1949
1950         } else {
1951                 //TODO set linesizes!
1952
1953                 num_blocks=((c->width+15)/16)*((c->height+15)/16);
1954                 num_dct_blocks=num_blocks*6; //6 blocks per macroblock
1955
1956                 want_sizes[2]=sizeof(xvmc_pix_fmt);
1957                 want_sizes[1]=sizeof(short)*num_dct_blocks*8*8;
1958                 want_sizes[0]=sizeof(XvMCMacroBlock)*num_blocks;
1959                 pict.linesize[0]=pict.linesize[1]=pict.linesize[2]=pict.linesize[3]=0;
1960
1961         }
1962
1963         VPE_FrameBuf *frame_buf=((VideoVPEOGL*)Video::getInstance())->getFrameBuf(want_sizes);
1964         frame_buf->ogl_ref=NULL; //do not use old references, crash instead!
1965         frame_buf->ogl_uploaded=false; //not uploaded yet
1966         frame_buf->width=pic->width;
1967         frame_buf->height=pic->height;
1968         frame_buf->stride=pic->linesize[0];
1969
1970         //Log::getInstance()->log("Video", Log::NOTICE, "get buffer %x",frame_buf);
1971         if (!frame_buf) {
1972                 Log::getInstance()->log("Video", Log::ERR, "Getting buffer libav failed");
1973                 return -1;
1974         }
1975
1976
1977         //populate pict
1978         pic->type=FF_BUFFER_TYPE_USER; // we are controlling the buffers
1979         int hchr_shift,vchr_shift;
1980         avcodec_get_chroma_sub_sample(c->pix_fmt,&hchr_shift,&vchr_shift);
1981         const int pixel_size = av_pix_fmt_descriptors[c->pix_fmt].comp[0].step_minus1+1;
1982         for (int i=0;i<4;i++) {
1983                 pic->data[i]=(uint8_t*)frame_buf->data[i];
1984                 pic->linesize[i]=pict.linesize[i];
1985                 if (normal_pixs) {
1986
1987                         int edge_width=16;
1988                         int edge_height=16;
1989                         if (i!=0) {
1990                                 edge_width>>=hchr_shift;
1991                                 edge_height>>=vchr_shift;
1992                         }
1993                         pic->data[i]+=FFALIGN((pic->linesize[i]*16) + (pixel_size*edge_width), s_a[i]);
1994                 }
1995         }
1996
1997         pic->base[0]=(uint8_t*)frame_buf; // our structure
1998         //pic->extended_data=pic->data;
1999         if(c->pkt) pic->pkt_pts=c->pkt->pts;
2000         else pic->pkt_pts=AV_NOPTS_VALUE;
2001         pic->width=c->width;
2002         pic->height=c->height;
2003         pic->format=c->pix_fmt;
2004         pic->sample_aspect_ratio=c->sample_aspect_ratio;
2005         pic->reordered_opaque= c->reordered_opaque;
2006         pic->age=INT_MAX;
2007         if (!normal_pixs) {
2008                 xvmc_pix_fmt *pix_xvmc=(xvmc_pix_fmt *)pic->data[2];
2009                 pix_xvmc->xvmc_id=AV_XVMC_ID;
2010                 pix_xvmc->data_blocks=(short*)pic->data[1];
2011                 pix_xvmc->mv_blocks=(XvMCMacroBlock*)pic->data[0];
2012                 pix_xvmc->allocated_mv_blocks=num_blocks;
2013                 pix_xvmc->allocated_data_blocks=num_dct_blocks;
2014                 if (c->pix_fmt==PIX_FMT_XVMC_MPEG2_IDCT) pix_xvmc->idct=1;
2015                 else pix_xvmc->idct=0;
2016                 pix_xvmc->unsigned_intra=1; // let see what happens
2017                 pix_xvmc->p_surface=(XvMCSurface*)frame_buf->pict_num;
2018                 pix_xvmc->start_mv_blocks_num=0;
2019                 pix_xvmc->filled_mv_blocks_num=0;
2020                 pix_xvmc->next_free_data_block_num=0;
2021                 //that is all folks
2022
2023
2024         }
2025
2026         return 0;
2027
2028 }
2029
2030 void VideoVPEOGL::release_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
2031 {
2032 //      Log::getInstance()->log("Video", Log::NOTICE, "release buffer %x",pic->base[0]);
2033         ((VideoVPEOGL*)Video::getInstance())->releaseFrameBufLibav((VPE_FrameBuf*) pic->base[0]);
2034         pic->base[0]=NULL;
2035         pic->data[0]=pic->data[1]=pic->data[2]=pic->data[3]=NULL;
2036
2037
2038 }
2039
2040 int VideoVPEOGL::AllocateCodecsLibav()
2041 {
2042         if (libav_running) DeAllocateCodecsLibav();
2043         libav_hastime=false;
2044         Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecslibav");
2045         mpeg2codec_context_libav=avcodec_alloc_context();
2046         if (mpeg2codec_context_libav==NULL) {
2047                 Log::getInstance()->log("Video", Log::DEBUG, "Creating libav codec context failed");
2048                 return 0;
2049         }
2050         if (decoding_mode!=VPE_NO_XVMC) {
2051                 mpeg2codec_context_libav->slice_flags=SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD;
2052                 if (decoding_mode==VPE_XVMC_MOCOMP) mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_MC;
2053                 else mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_IDCT;
2054                 mpeg2codec_context_libav->get_format=get_format_libav;
2055                 mpeg2codec_context_libav->draw_horiz_band=draw_horiz_band_libav;
2056
2057         }
2058         mpeg2codec_context_libav->get_buffer=get_buffer_libav;
2059         mpeg2codec_context_libav->reget_buffer=reget_buffer_libav;
2060         mpeg2codec_context_libav->release_buffer=release_buffer_libav;
2061
2062
2063
2064         int avc_ret=avcodec_open(mpeg2codec_context_libav, mpeg2codec_libav);
2065         if (avc_ret<0) {
2066                 Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec  failed ");
2067                 return 0;
2068         }
2069         memset(&incom_packet_libav,0,sizeof(incom_packet_libav));
2070         incom_packet_libav_size=200000;
2071         incom_packet_libav.data=(uint8_t*)av_malloc(incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
2072
2073         dec_frame_libav_mutex.Lock();
2074         for (int i=0;i<3;i++) {
2075                         AVFrame *dec_frame_libav=avcodec_alloc_frame(); // may be we need multiple frames, if we want to use async texture upload
2076                         if (!dec_frame_libav) {
2077                                 Log::getInstance()->log("Video", Log::DEBUG, "Allocating dec_frame  failed");
2078                                 return 0;
2079                         }
2080                         dec_frame_libav_all.push_back(dec_frame_libav);
2081                         dec_frame_libav_free.push_back(dec_frame_libav);
2082         }
2083         dec_frame_libav_decoding=NULL;
2084         dec_frame_libav_mutex.Unlock();
2085
2086         ogl_frame_mutex.Lock();
2087         //Allocate texture structs, since we do not know the sizes, we do not allocate the textures yet
2088         for (int i=0;i<5;i++) {
2089                 VPEOGLFrame *new_frame=(VPEOGLFrame *)malloc(sizeof(VPEOGLFrame));
2090                 new_frame->type=1; //1 = YUV, 2 RGB
2091                 new_frame->textures[0]=0;
2092                 new_frame->textures[1]=0;
2093                 new_frame->textures[2]=0;
2094                 new_frame->width=new_frame->height=0;
2095                 all_ogl_frames.push_back(new_frame);
2096                 free_ogl_frames.push_back(new_frame);
2097
2098         }
2099         ogl_frame_outside=false;
2100
2101         ogl_frame_mutex.Unlock();
2102
2103         if (decoding_mode==VPE_XVMC_MOCOMP) {
2104                 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
2105                 osd->BeginPainting(); // get OpenGl context
2106                 moco_shader=new GLMocoShader();
2107                 moco_shader->init();
2108                 osd->EndPainting();
2109         }
2110
2111         libav_running=true;
2112
2113         return 1;
2114
2115 }
2116
2117 int VideoVPEOGL::DeAllocateCodecsLibav()
2118 {
2119         libav_running=false;
2120         Log::getInstance()->log("Video", Log::NOTICE, "DeAllocateCodecslibav");
2121         dec_frame_libav_mutex.Lock();
2122         dec_frame_libav_upload_and_view_pending.clear();
2123         dec_frame_libav_upload_only_pending.clear();
2124         dec_frame_libav_free.clear();
2125         dec_frame_libav_mutex.Unlock();
2126         while (dec_frame_libav_uploading_framebuf) {
2127                 Log::getInstance()->log("Video", Log::NOTICE, "Wait for uploading to finish");
2128                 MILLISLEEP(20);
2129         }
2130         dec_frame_libav_mutex.Lock();
2131         for (int i=0; i< dec_frame_libav_all.size();i++) {
2132                 av_free(dec_frame_libav_all[i]);
2133         }
2134
2135         dec_frame_libav_all.clear();
2136
2137         av_free(incom_packet_libav.data);
2138         incom_packet_libav.data=NULL;
2139         incom_packet_libav_size=0;
2140
2141         dec_frame_libav_mutex.Unlock();
2142         dec_frame_libav_decoding=NULL;
2143         while (ogl_frame_outside) {
2144                 Log::getInstance()->log("Video", Log::NOTICE, "Wait for ogl frame from outside");
2145                 MILLISLEEP(20);
2146         }
2147
2148         ((OsdOpenGL*)Osd::getInstance())->BeginPainting(); // get osd's context
2149         ogl_frame_mutex.Lock();
2150         for (int i=0; i< dec_frame_libav_all.size();i++) {
2151                 VPEOGLFrame * del_frame=all_ogl_frames[i];
2152                 if (del_frame->textures[0]==0) {
2153                         glDeleteTextures(1,&del_frame->textures[0]);
2154                         del_frame->textures[0]=0;
2155                 }
2156                 if (del_frame->textures[1]==0) {
2157                         glDeleteTextures(1,&del_frame->textures[1]);
2158                         del_frame->textures[1]=0;
2159                 }
2160                 if (del_frame->textures[2]==0) {
2161                         glDeleteTextures(1,&del_frame->textures[2]);
2162                         del_frame->textures[2]=0;
2163                 }
2164
2165                 free(all_ogl_frames[i]);
2166         }
2167         all_ogl_frames.clear();
2168         free_ogl_frames.clear();
2169         ready_ogl_frames.clear();
2170         recycle_ref_ogl_frames.clear();
2171         ogl_forward_ref_frame_num=0;
2172         ogl_backward_ref_frame_num=0;
2173         ogl_forward_ref_frame=NULL;
2174         ogl_backward_ref_frame=NULL;
2175
2176         ogl_frame_mutex.Unlock();
2177         ((OsdOpenGL*)Osd::getInstance())->EndPainting();
2178
2179
2180         if (mpeg2codec_context_libav) {
2181                 avcodec_close(mpeg2codec_context_libav);
2182                 av_free(mpeg2codec_context_libav);
2183                 mpeg2codec_context_libav=NULL;
2184
2185         }
2186
2187
2188
2189         vpe_framebuf_mutex.Lock();
2190
2191         for (int i=0;i<all_frame_bufs.size();i++) {
2192                 VPE_FrameBuf* current=all_frame_bufs[i];
2193                 for (int x=0;x<4;x++) {
2194                         if (current->data[x]) {
2195                                 av_free(current->data[x]);
2196                         }
2197                 }
2198                 free(current);
2199         }
2200         all_frame_bufs.clear();
2201         free_frame_bufs.clear();
2202         locked_libav_frame_buf.clear();
2203         locked_uploading_frame_buf.clear();
2204
2205         vpe_framebuf_mutex.Unlock();
2206
2207
2208
2209         if (moco_shader) {
2210                 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
2211                 osd->BeginPainting(); // get OpenGl context
2212                 moco_shader->deinit();
2213                 delete moco_shader;
2214                 moco_shader=NULL;
2215                 osd->EndPainting();
2216         }
2217
2218
2219
2220
2221
2222         return 1;
2223 }
2224
2225
2226 VPE_FrameBuf *VideoVPEOGL::getFrameBuf(unsigned int *size)
2227 { //for libav
2228         VPE_FrameBuf* current=NULL;
2229         vpe_framebuf_mutex.Lock();
2230         if (free_frame_bufs.size()>0) {
2231                 current=free_frame_bufs.front();
2232                 free_frame_bufs.pop_front();
2233         } else if (all_frame_bufs.size()<6) {
2234                 current=(VPE_FrameBuf*)malloc(sizeof(VPE_FrameBuf));
2235                 memset(current,0,sizeof(VPE_FrameBuf));
2236         } else {
2237                 Log::getInstance()->log("Video", Log::NOTICE, "Framebuffer underrun!");
2238                 vpe_framebuf_mutex.Unlock();
2239                 return NULL; // We do not have a frame buffer
2240         }
2241         locked_libav_frame_buf.push_back(current);
2242         vpe_framebuf_mutex.Unlock();
2243         //check if we need reallocation
2244         for (int x=0;x<4;x++) {
2245                 if (current->size[x]!=size[x]) {
2246                         current->data[x]=av_realloc(current->data[x],size[x]);
2247                         current->size[x]=size[x];
2248                 }
2249         }
2250         framebuf_framenum++;
2251         current->pict_num=framebuf_framenum; //This is used for tracking reference frames through the conversion pipeline
2252         return current;
2253
2254 }
2255
2256 void VideoVPEOGL::lockFrameBufUpload(VPE_FrameBuf* buf)
2257 {
2258         // first find frame_buf memory
2259
2260         //Log::getInstance()->log("Video", Log::NOTICE, "lock buffer upload %x",buf);
2261         VPE_FrameBuf* current=buf;
2262         vpe_framebuf_mutex.Lock();
2263         if (current) locked_uploading_frame_buf.push_back(current); //locked
2264         vpe_framebuf_mutex.Unlock();
2265
2266 }
2267
2268
2269 void VideoVPEOGL::releaseFrameBufLibav(VPE_FrameBuf* buf)
2270 {
2271         // first find frame_buf memory
2272         //Log::getInstance()->log("Video", Log::NOTICE, "release buffer libav %x",buf);
2273         VPE_FrameBuf* current=buf;
2274         vpe_framebuf_mutex.Lock();
2275         if (current) {
2276                 locked_libav_frame_buf.remove(current); //unlocked
2277                 list<VPE_FrameBuf*>::iterator itty=locked_uploading_frame_buf.begin();
2278                 bool inlist=false;
2279                 while (itty!=locked_uploading_frame_buf.end()) {
2280                         if (*itty==current) {
2281                                 inlist=true;
2282                                 break;
2283                         }
2284                         itty++;
2285                 }
2286                 if (!inlist) {
2287                         free_frame_bufs.push_back(current);
2288                 }
2289         }
2290         vpe_framebuf_mutex.Unlock();
2291 }
2292
2293 void VideoVPEOGL::releaseFrameBufUpload(VPE_FrameBuf* buf)
2294 {
2295         // first find frame_buf memory
2296         VPE_FrameBuf* current=buf;
2297         //Log::getInstance()->log("Video", Log::NOTICE, "release buffer upload %x",buf);
2298         vpe_framebuf_mutex.Lock();
2299         if (current) {
2300                 locked_uploading_frame_buf.remove(current); //unlocked
2301                 list<VPE_FrameBuf*>::iterator itty=locked_libav_frame_buf.begin();
2302                 bool inlist=false;
2303                 while (itty!=locked_libav_frame_buf.end()) {
2304                         if (*itty==current) {
2305                                 inlist=true;
2306                                 break;
2307                         }
2308                         itty++;
2309                 }
2310                 if (!inlist) {
2311                         free_frame_bufs.push_back(current);
2312                 }
2313         }
2314         vpe_framebuf_mutex.Unlock();
2315 }
2316
2317 void VideoVPEOGL::add_dec_frame_upload_only(struct AVCodecContext *s,const AVFrame* data)
2318 {
2319         dec_frame_libav_mutex.Lock();
2320         libavwidth=s->width;
2321         libavheight=s->height;
2322         libavpixfmt=s->pix_fmt;
2323         //Log::getInstance()->log("Video", Log::DEBUG, "add_dec Frame info %d %d %d %d %x",libavwidth,libavheight,libavpixfmt,((VPE_FrameBuf*)data->base[0])->pict_num,data->base[0]);
2324
2325         dec_frame_libav_upload_only_pending.push_back((VPE_FrameBuf*)data->base[0]); // we are only uploading
2326         dec_frame_libav_mutex.Unlock();
2327         threadSignal();
2328 }
2329
2330
2331
2332
2333
2334 #endif
2335
2336 int VideoVPEOGL::stop()
2337 {
2338   if (!initted) return 0;
2339
2340 #ifdef VPE_OMX_SUPPORT
2341   //Check if libav mode
2342   if (decoding_backend==VPE_DECODER_OMX) DeAllocateCodecsOMX();
2343   decoding_backend=0;
2344
2345 #endif
2346
2347
2348
2349 //  if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
2350   return 1;
2351 }
2352
2353 int VideoVPEOGL::reset()
2354 {
2355   if (!initted) return 0;
2356
2357 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
2358   return 1;
2359 }
2360
2361 int VideoVPEOGL::pause()
2362 {
2363   if (!initted) return 0;
2364
2365 //  if (ioctl(fdVideo, AV_SET_VID_PAUSE, 0) != 0) return 0;
2366   return 1;
2367 }
2368
2369 int VideoVPEOGL::unPause() // FIXME get rid - same as play!!
2370 {
2371   if (!initted) return 0;
2372 //  if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2373   return 1;
2374 }
2375
2376 int VideoVPEOGL::fastForward()
2377 {
2378   if (!initted) return 0;
2379
2380 //  if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
2381   return 1;
2382 }
2383
2384 int VideoVPEOGL::unFastForward()
2385 {
2386   if (!initted) return 0;
2387
2388 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
2389
2390  //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
2391   return 1;
2392 }
2393
2394 int VideoVPEOGL::attachFrameBuffer()
2395 {
2396   if (!initted) return 0;
2397
2398 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2399   return 1;
2400 }
2401
2402 int VideoVPEOGL::blank(void)
2403 {
2404 //  if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
2405 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
2406   return 1;
2407 }
2408
2409 ULLONG VideoVPEOGL::getCurrentTimestamp()
2410 {
2411 /*  sync_data_t timestamps;
2412   if (ioctl(fdVideo, AV_GET_VID_TIMESTAMPS, &timestamps) == 0)
2413   {
2414     // FIXME are these the right way around?
2415
2416     timestamps.stc = (timestamps.stc >> 31 ) | (timestamps.stc & 1);
2417     timestamps.pts = (timestamps.pts >> 31 ) | (timestamps.pts & 1);
2418
2419     return timestamps.stc;
2420   }
2421   else
2422   {
2423     return 0;
2424   }*/
2425   return 0;
2426 }
2427
2428 ULONG VideoVPEOGL::timecodeToFrameNumber(ULLONG timecode)
2429 {
2430   if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
2431   else               return (ULONG)(((double)timecode / (double)90000) * (double)30);
2432 }
2433
2434 #ifdef DEV
2435 int VideoVPEOGL::test()
2436 {
2437   return 0;
2438
2439 //  ULLONG stc = 0;
2440 //  return ioctl(fdVideo, AV_SET_VID_STC, &stc);
2441 /*
2442  // reset();
2443   return 1;
2444 */
2445 }
2446
2447 int VideoVPEOGL::test2()
2448 {
2449   return 0;
2450 }
2451 #endif
2452
2453 void VideoVPEOGL::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
2454 {
2455   mediapacket = mplist.front();
2456 }
2457
2458 UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
2459 {
2460   DeliverMediaPacket(mediapacket, buffer, samplepos);
2461   if (*samplepos == mediapacket.length) {
2462     *samplepos = 0;
2463     return 1;
2464   }
2465   else return 0;
2466 }
2467
2468 UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
2469                 const UCHAR* buffer,
2470                 UINT *samplepos)
2471 {
2472         if (packet.type == MPTYPE_VIDEO_H264)
2473         {
2474                 h264=true;
2475         }
2476         else
2477         {
2478                 h264=false;
2479         }
2480         switch (decoding_backend) {
2481         default: case 0: return 0; // no backend runnigng
2482 #ifdef VPE_OMX_SUPPORT
2483         case VPE_DECODER_OMX: return DeliverMediaPacketOMX(packet,buffer,samplepos);
2484 #ifdef  VPE_LIBAV_MPEG2_TRANSCODING
2485         case VPE_DECODER_OMX_libav_TRANSCODE: return DeliverMediaPacketOMXTranscode(packet,buffer,samplepos);
2486 #endif
2487 #endif
2488 #ifdef VPE_LIBAV_SUPPORT
2489         case VPE_DECODER_libav: return DeliverMediaPacketlibav(packet,buffer,samplepos);
2490 #endif
2491         }
2492 }
2493
2494 #ifdef VPE_OMX_SUPPORT
2495 UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
2496                 const UCHAR* buffer,
2497                 UINT *samplepos)
2498 {
2499
2500
2501         //Later add fail back code for libav
2502         /*if (!videoon) {
2503                 *samplepos+=packet.length;
2504                 return packet.length;
2505         }*/
2506
2507
2508         if (!omx_running) return 0; // if we are not runnig do not do this
2509
2510
2511         OMX_ERRORTYPE error;
2512
2513 /*      OMX_PARAM_PORTDEFINITIONTYPE port_image;
2514         memset(&port_image,0,sizeof(port_image));
2515         port_image.nSize=sizeof(port_image);
2516         port_image.nVersion.nVersion=OMX_VERSION;
2517         port_image.nPortIndex =omx_codec_output_port;
2518         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_image);
2519         if (error!= OMX_ErrorNone){
2520                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_GetParameter failed %x", error);
2521         }
2522         Log::getInstance()->log("Video", Log::DEBUG, "Image port %d %d", port_image.format.video.nFrameWidth , port_image.format.video.nFrameHeight);*/
2523
2524         /*First Check, if we have an audio sample*/
2525         if (iframemode) {
2526                 //samplepos=0;
2527                 MILLISLEEP(10);
2528                 return 0; //Not in iframe mode!
2529         }
2530
2531         UINT headerstrip=0;
2532         if (packet.disconti) {
2533                 firstsynched=false;
2534                 if (cur_input_buf_omx) {
2535                         OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2536                         if (error!=OMX_ErrorNone){
2537                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2538                         }
2539                         cur_input_buf_omx=NULL;
2540                 }
2541         }
2542
2543         /*Inspect PES-Header */
2544
2545 //      OMX_STATETYPE temp_state;
2546 //      OMX_GetState(omx_vid_dec,&temp_state);
2547
2548         if (*samplepos==0) {//stripheader
2549                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2550                 *samplepos+=headerstrip;
2551                 if ( packet.synched ) {
2552
2553                         if (cur_input_buf_omx) {
2554                                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2555                                 if (error!=OMX_ErrorNone){
2556                                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2557                                 }
2558
2559                                 cur_input_buf_omx=NULL;//write out old data
2560                         }
2561                 //      reftime1=packet.presentation_time;
2562                 //      reftime2=reftime1+1;
2563                         firstsynched=true;
2564                 } else {
2565                         if (!firstsynched) {//
2566                                 *samplepos=packet.length;//if we have not processed at least one
2567                                 return packet.length;//synched packet ignore it!
2568                         }
2569                 }
2570         }
2571
2572         if (!cur_input_buf_omx) {
2573                 input_bufs_omx_mutex.Lock();
2574                 if (input_bufs_omx_free.size()==0) {
2575                         input_bufs_omx_mutex.Unlock();
2576                         Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2577                         return 0; // we do not have a free media sample
2578
2579                 }
2580                 cur_input_buf_omx=input_bufs_omx_free.front();
2581                 cur_input_buf_omx->nFilledLen=0;
2582                 cur_input_buf_omx->nOffset=0;
2583                 cur_input_buf_omx->nTimeStamp=0;
2584                 input_bufs_omx_free.pop_front();
2585                 input_bufs_omx_mutex.Unlock();
2586         }
2587
2588
2589
2590
2591         if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2592                 /*if (packet.disconti) {
2593                         ms->SetDiscontinuity(TRUE);
2594                 } else {
2595                         ms->SetDiscontinuity(FALSE);
2596                 }*/
2597                 //if (packet.synched) {
2598
2599                         //lastreftimePTS=packet.pts;
2600                    if (omx_first_frame) { // TODO time
2601                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2602                            omx_first_frame=false;
2603                    } else
2604
2605                 //}
2606                 //else
2607                 //{
2608                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2609
2610
2611                         //  ms->SetSyncPoint(TRUE);
2612                 //}
2613
2614         }
2615         unsigned int haveToCopy=packet.length-*samplepos;
2616
2617         while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
2618                 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
2619                 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
2620                 haveToCopy-=cancopy;
2621                 cur_input_buf_omx->nFilledLen+=cancopy;
2622                 *samplepos+=cancopy;
2623                 // push old buffer out
2624
2625                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2626                 if (error!=OMX_ErrorNone){
2627                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2628                 }
2629                 // get5 new buffer
2630                 input_bufs_omx_mutex.Lock();
2631                 if (input_bufs_omx_free.size()==0) {
2632                         input_bufs_omx_mutex.Unlock();
2633                         //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2634                         return *samplepos; // we do not have a free media sample
2635                 }
2636                 cur_input_buf_omx=input_bufs_omx_free.front();
2637                 cur_input_buf_omx->nFilledLen=0;
2638                 cur_input_buf_omx->nOffset=0;
2639                 cur_input_buf_omx->nTimeStamp=0;
2640                 input_bufs_omx_free.pop_front();
2641                 input_bufs_omx_mutex.Unlock();
2642
2643                 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2644
2645         }
2646         memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
2647                         buffer+packet.pos_buffer+*samplepos,haveToCopy);
2648         cur_input_buf_omx->nFilledLen+=haveToCopy;
2649
2650
2651
2652         *samplepos+=haveToCopy;
2653
2654         return *samplepos;
2655
2656 }
2657
2658 #endif
2659
2660 #ifdef VPE_LIBAV_MPEG2_TRANSCODING
2661
2662
2663
2664 int VideoVPEOGL::DecodePacketOMXTranscode()
2665 {
2666         unsigned int haveToCopy=incom_packet_libav.size;
2667         if (incom_packet_libav.size==0) return 1; // we are already empty
2668
2669
2670         while (haveToCopy>0) {
2671                 int dec_bytes=0;
2672                 int frame_ready=0;
2673
2674         //      Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
2675
2676 #ifdef BENCHMARK_FPS
2677             int cur_time=getTimeMS();
2678 #endif
2679                 dec_bytes=avcodec_decode_video2(transcodecodec_context_libav, &transcode_frame_libav,
2680                                 &frame_ready, &incom_packet_libav);
2681 #ifdef BENCHMARK_FPS
2682                 time_in_decoder+=getTimeMS()-cur_time;
2683                 if (frame_ready) num_frames++;
2684                 if ((num_frames%100)==0) {
2685                         float fps=1000./(float)(time_in_decoder);
2686                         fps*=((float)num_frames);
2687                         Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
2688                 }
2689 #endif
2690                 if (dec_bytes<0) {
2691                         Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
2692                         return 0;
2693                 }
2694                 haveToCopy-=dec_bytes;
2695                 if (frame_ready) {
2696                         struct transcode_pix_fmt *transcode=(struct transcode_pix_fmt *)transcode_frame_libav.data[0];
2697                         //if (!benchmark) fwrite(transcode->packet.data,transcode->packet.size,1,output_file);
2698
2699
2700                     //add omx magic, this should be an omx packet
2701                         OMX_BUFFERHEADERTYPE* omx_packet=(OMX_BUFFERHEADERTYPE*)transcode_frame_libav.base[0];
2702                         omx_packet->nFilledLen=transcode->packet.size;
2703
2704                         input_bufs_omx_mutex.Lock();
2705                         input_bufs_omx_in_libav.remove(omx_packet); // say that it  is passed down to the decoder
2706                         input_bufs_omx_mutex.Unlock();
2707
2708                         OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,omx_packet);
2709                         if (error!=OMX_ErrorNone){
2710                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2711                         }
2712
2713
2714
2715                 }
2716
2717         }
2718         incom_packet_libav.size=0;
2719         return 1;
2720
2721 }
2722
2723
2724 UINT VideoVPEOGL::DeliverMediaPacketOMXTranscode(MediaPacket packet,
2725                 const UCHAR* buffer,
2726                 UINT *samplepos)
2727 {
2728         //Later add fail back code for libav
2729         /*if (!videoon) {
2730                 *samplepos+=packet.length;
2731                 return packet.length;
2732         }*/
2733
2734         if (!omx_running) return 0; // if we are not runnig do not do this
2735
2736
2737         if (iframemode) {
2738                 //samplepos=0;
2739                 MILLISLEEP(10);
2740                 return 0; //Not in iframe mode!
2741         }
2742
2743         UINT headerstrip=0;
2744         if (packet.disconti) {
2745                 firstsynched=false;
2746                 if (!DecodePacketOMXTranscode()) return 0;
2747         }
2748
2749         /*Inspect PES-Header */
2750         if (*samplepos==0) {//stripheader
2751                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2752                 *samplepos+=headerstrip;
2753                 if ( packet.synched ) {
2754
2755                         if (!DecodePacketOMXTranscode()) return 0; // WriteOut old Data
2756
2757
2758                         incom_packet_libav.pts=packet.pts/3600;
2759                         incom_packet_libav.dts=packet.dts/3600;
2760                 //      reftime1=packet.presentation_time;
2761                 //      reftime2=reftime1+1;
2762                         firstsynched=true;
2763                 } else {
2764                         incom_packet_libav.pts=0;
2765                         incom_packet_libav.dts=0;
2766                         if (!firstsynched) {//
2767                                 *samplepos=packet.length;//if we have not processed at least one
2768                                 return packet.length;//synched packet ignore it!
2769                         }
2770                 }
2771         }
2772
2773
2774
2775
2776
2777
2778         /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2779                 /*if (packet.disconti) {
2780                         ms->SetDiscontinuity(TRUE);
2781                 } else {
2782                         ms->SetDiscontinuity(FALSE);
2783                 }*
2784                 //if (packet.synched) {
2785
2786                         //lastreftimePTS=packet.pts;
2787                    if (omx_first_frame) { // TODO time
2788                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2789                            omx_first_frame=false;
2790                    } else
2791
2792                 //}
2793                 //else
2794                 //{
2795                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2796
2797
2798                         //  ms->SetSyncPoint(TRUE);
2799                 //}
2800
2801         }*/
2802         unsigned int haveToCopy=packet.length-*samplepos;
2803
2804         if  ((incom_packet_libav_size-incom_packet_libav.size)< haveToCopy) {
2805                 // if the buffer is to small reallocate
2806                 incom_packet_libav_size+=haveToCopy;
2807                 incom_packet_libav.data=(uint8_t*)av_realloc(incom_packet_libav.data,incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
2808                 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_libav_size);
2809         }
2810         memcpy(incom_packet_libav.data+incom_packet_libav.size,buffer+packet.pos_buffer+*samplepos,haveToCopy);
2811         incom_packet_libav.size+=haveToCopy;
2812
2813         *samplepos+=haveToCopy;
2814
2815
2816         return *samplepos;
2817
2818
2819 }
2820
2821 #endif
2822
2823
2824 #ifdef VPE_LIBAV_SUPPORT
2825 int VideoVPEOGL::DecodePacketlibav()
2826 {
2827         unsigned int haveToCopy=incom_packet_libav.size;
2828         if (incom_packet_libav.size==0) return 1; // we are already empty
2829         while (haveToCopy>0) {
2830                 int dec_bytes=0;
2831                 int frame_ready=0;
2832
2833         //      Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
2834
2835 #ifdef BENCHMARK_FPS
2836             int cur_time=getTimeMS();
2837 #endif
2838                 dec_bytes=avcodec_decode_video2(mpeg2codec_context_libav, dec_frame_libav_decoding,
2839                                 &frame_ready, &incom_packet_libav);
2840 #ifdef BENCHMARK_FPS
2841                 time_in_decoder+=getTimeMS()-cur_time;
2842                 if (frame_ready) num_frames++;
2843                 if ((num_frames%100)==0) {
2844                         float fps=1000./(float)(time_in_decoder);
2845                         fps*=((float)num_frames);
2846                         Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
2847                 }
2848 #endif
2849                 if (dec_bytes<0) {
2850                         Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
2851                         return 0;
2852                 }
2853                 haveToCopy-=dec_bytes;
2854                 if (frame_ready) {
2855                 //      Log::getInstance()->log("Video", Log::DEBUG, "We have a frame push it to osd");
2856
2857                         lockFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_decoding->base[0]); //lock for upload, so that ffmpeg does not reuse
2858                         dec_frame_libav_mutex.Lock();
2859                         libavwidth=mpeg2codec_context_libav->width;
2860                         libavheight=mpeg2codec_context_libav->height;
2861                         libavpixfmt=mpeg2codec_context_libav->pix_fmt;
2862                 //      Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",libavwidth,libavheight,libavpixfmt);
2863                 //      Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d %d %x",libavwidth,libavheight,libavpixfmt,
2864                         //              ((VPE_FrameBuf*)dec_frame_libav_decoding->base[0])->pict_num,dec_frame_libav_decoding->base[0]);
2865
2866
2867                         dec_frame_libav_upload_and_view_pending.push_back(dec_frame_libav_decoding);
2868                         dec_frame_libav_decoding=NULL;
2869                         if (dec_frame_libav_free.size()>0) {
2870                                 dec_frame_libav_decoding=dec_frame_libav_free.front();
2871                                 dec_frame_libav_free.pop_front();
2872                                 dec_frame_libav_mutex.Unlock();
2873                                 threadSignal();
2874                                 libav_hastime=false;
2875                         } else {
2876                                 libav_hastime=false;
2877                                 dec_frame_libav_mutex.Unlock();
2878                                 Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers 2 FPS");
2879                                 threadSignal();
2880                                 // No free buffers
2881                                 return 0;
2882                         }
2883
2884
2885                 }
2886
2887         }
2888         incom_packet_libav.size=0;
2889         return 1;
2890
2891 }
2892
2893
2894 UINT VideoVPEOGL::DeliverMediaPacketlibav(MediaPacket packet,
2895                 const UCHAR* buffer,
2896                 UINT *samplepos)
2897 {
2898         //Later add fail back code for libav
2899         /*if (!videoon) {
2900                 *samplepos+=packet.length;
2901                 return packet.length;
2902         }*/
2903
2904         if (!libav_running) return 0; // if we are not runnig do not do this
2905
2906
2907         if (iframemode) {
2908                 //samplepos=0;
2909                 MILLISLEEP(10);
2910                 return 0; //Not in iframe mode!
2911         }
2912
2913         UINT headerstrip=0;
2914         if (packet.disconti) {
2915                 firstsynched=false;
2916                 if (!DecodePacketlibav()) return 0;
2917         }
2918
2919         /*Inspect PES-Header */
2920         if (!dec_frame_libav_decoding) {
2921                 dec_frame_libav_mutex.Lock();
2922                 if (dec_frame_libav_free.size()>0) {
2923                         dec_frame_libav_decoding=dec_frame_libav_free.front();
2924                         dec_frame_libav_free.pop_front();
2925                         dec_frame_libav_mutex.Unlock();
2926                 } else {
2927                         Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers FPS");
2928                         dec_frame_libav_mutex.Unlock();
2929                         // No free buffers
2930                         return 0;
2931                 }
2932         }
2933
2934
2935
2936         if (*samplepos==0) {//stripheader
2937                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2938                 *samplepos+=headerstrip;
2939                 if ( packet.synched ) {
2940
2941                         if (!DecodePacketlibav()) return 0; // WriteOut old Data
2942
2943                         libav_time=packet.presentation_time;
2944                         libav_hastime=true;
2945                 //      reftime1=packet.presentation_time;
2946                 //      reftime2=reftime1+1;
2947                         firstsynched=true;
2948                 } else {
2949                         if (!firstsynched) {//
2950                                 *samplepos=packet.length;//if we have not processed at least one
2951                                 return packet.length;//synched packet ignore it!
2952                         }
2953                 }
2954         }
2955
2956
2957
2958
2959
2960
2961         /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2962                 /*if (packet.disconti) {
2963                         ms->SetDiscontinuity(TRUE);
2964                 } else {
2965                         ms->SetDiscontinuity(FALSE);
2966                 }*
2967                 //if (packet.synched) {
2968
2969                         //lastreftimePTS=packet.pts;
2970                    if (omx_first_frame) { // TODO time
2971                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2972                            omx_first_frame=false;
2973                    } else
2974
2975                 //}
2976                 //else
2977                 //{
2978                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2979
2980
2981                         //  ms->SetSyncPoint(TRUE);
2982                 //}
2983
2984         }*/
2985         unsigned int haveToCopy=packet.length-*samplepos;
2986
2987         if  ((incom_packet_libav_size-incom_packet_libav.size)< haveToCopy) {
2988                 // if the buffer is to small reallocate
2989                 incom_packet_libav_size+=haveToCopy;
2990                 incom_packet_libav.data=(uint8_t*)av_realloc(incom_packet_libav.data,incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
2991                 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_libav_size);
2992         }
2993         memcpy(incom_packet_libav.data+incom_packet_libav.size,buffer+packet.pos_buffer+*samplepos,haveToCopy);
2994         incom_packet_libav.size+=haveToCopy;
2995
2996         *samplepos+=haveToCopy;
2997
2998
2999         return *samplepos;
3000
3001
3002 }
3003
3004 #endif
3005
3006
3007
3008
3009
3010
3011 void VideoVPEOGL::ResetTimeOffsets()
3012 {
3013 }
3014
3015 bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length)
3016 {
3017   //write(fdVideo, buffer, length);
3018         if (!iframemode) EnterIframePlayback();
3019 //      WriteOutTS(buffer,length, h264?MPTYPE_VIDEO_H264 :MPTYPE_VIDEO_MPEG2 );
3020
3021   lastpacketnum=-1;
3022   return true;
3023 }
3024
3025 int VideoVPEOGL::EnterIframePlayback()
3026 {
3027
3028         return 0;
3029 }
3030