]> git.vomp.tv Git - vompclient-marten.git/blob - videovpeogl.cc
moco on I frames working
[vompclient-marten.git] / videovpeogl.cc
1 /*
2     Copyright 2004-2005 Chris Tallon, 2009 Marten Richter
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #include "videovpeogl.h"
22 #include "audiovpe.h"
23 #include "mtdraspberry.h"
24 #include "demuxer.h"
25 #include "osdopengl.h"
26
27 // temp
28 #include "log.h"
29
30 //A lot of parts of this file are heavily inspired by xbmc omx implementations
31
32 VideoVPEOGL::VideoVPEOGL()
33 {
34   lastpacketnum=-1;
35
36 #ifdef VPE_OMX_SUPPORT
37   omx_running=false;
38
39   omx_vid_dec=0;
40   cur_input_buf_omx=NULL;
41   omx_h264=omx_mpeg2=true;
42 #endif
43
44 #ifdef VPE_LIBAV_SUPPORT
45   mpeg2codec_context_libav=NULL;
46   libav_running=false;
47   dec_frame_libav_uploading=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 #endif
56
57 #ifdef BENCHMARK_FPS
58         time_in_decoder=0;
59     num_frames=0;
60 #endif
61
62 }
63
64 VideoVPEOGL::~VideoVPEOGL()
65 {
66   instance = NULL;
67 }
68
69 int VideoVPEOGL::init(UCHAR tformat)
70 {
71   if (initted) return 0;
72   initted = 1;
73
74 //  if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
75
76   if (!setFormat(tformat))           { shutdown(); return 0; }
77   if (!setConnection(COMPOSITERGB))  { shutdown(); return 0; }
78   if (!setAspectRatio(ASPECT4X3))    { shutdown(); return 0; }
79   if (!setMode(NORMAL))              { shutdown(); return 0; }
80   if (!setSource())                  { shutdown(); return 0; }
81   if (!attachFrameBuffer())          { shutdown(); return 0; }
82
83   setTVsize(ASPECT4X3);
84
85 /*  if (format == PAL) setLetterboxBorder("38");
86   else setLetterboxBorder("31");*/
87
88   /* new stulibav */
89
90
91
92
93   //stop();
94
95
96
97   return 1;
98 }
99
100 int VideoVPEOGL::initUsingOSDObjects()
101 {
102         EGLDisplay i_egl_display;
103         EGLSurface i_egl_surface;
104         EGLContext i_egl_context;
105         EGLConfig i_egl_config;
106         OsdOpenGL *osd=(OsdOpenGL*)osd->getInstance();
107         osd->getEGLObjs(&i_egl_display,&i_egl_surface,&i_egl_context, &i_egl_config);
108         const EGLint attr_context[]={
109                         EGL_CONTEXT_CLIENT_VERSION,2,
110                 EGL_NONE
111         };
112
113         egl_display=i_egl_display;
114         egl_context=eglCreateContext(egl_display,i_egl_config,i_egl_context,attr_context);
115         if (egl_context==EGL_NO_CONTEXT) {
116                  Log::getInstance()->log("Video", Log::WARN, "Creating egl context failed! %x",eglGetError());
117                  return 0;
118         }
119         // We create a dummy surface here, in order to allow two contexts
120         const EGLint attr_pbuffer[]={
121                         EGL_WIDTH, 1, EGL_HEIGHT,1,
122                     EGL_NONE
123         };
124         egl_surface=eglCreatePbufferSurface(egl_display,i_egl_config,attr_pbuffer);
125         if (egl_surface==EGL_NO_SURFACE) {
126                  Log::getInstance()->log("Video", Log::WARN, "Creating egl pbuffer failed! %x",eglGetError());
127                  return 0;
128         }
129
130
131
132
133         //egl_surface=i_egl_surface;
134         //egl_context=i_egl_context;
135
136
137 #ifdef VPE_OMX_SUPPORT
138 // we are called before the audio
139         OMX_ERRORTYPE error;
140         error=OMX_Init();
141         if (error!=OMX_ErrorNone) {
142                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error);
143                 return 0;
144         }
145
146         //our callbacks move to play?
147
148 #endif
149
150 #ifdef VPE_LIBAV_SUPPORT
151
152         av_register_all();
153         if (decoding_mode==VPE_NO_XVMC) {
154                 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
155         } else {
156                 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_XVMC);
157         }
158         if (mpeg2codec_libav==NULL) {
159                 Log::getInstance()->log("Video", Log::DEBUG, "Find libav mpeg2 codec failed");
160                 return 0;
161         }
162
163 #endif
164         threadStart();
165         return 1;
166 }
167
168
169 #ifdef VPE_OMX_SUPPORT
170
171 OMX_ERRORTYPE VideoVPEOGL::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
172            OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
173            OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
174
175         Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
176
177         struct VPE_OMX_EVENT  new_event;
178         new_event.handle=handle;
179         new_event.appdata=appdata;
180         new_event.event_type=event_type;
181         new_event.data1=data1;
182         new_event.data2=data2;
183         new_event.event_data=event_data;
184
185         VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
186         video->AddOmxEvent(new_event);
187
188 /*      switch (event_type) {
189         case OMX_EventCmdComplete: {
190
191         } break;
192         }*/
193
194         return OMX_ErrorNone;
195
196 }
197
198 void VideoVPEOGL::AddOmxEvent(VPE_OMX_EVENT  new_event)
199 {
200         omx_event_mutex.Lock();
201     omx_events.push_back(new_event);
202         omx_event_mutex.Unlock();
203 }
204
205
206 OMX_ERRORTYPE VideoVPEOGL::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
207
208         Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
209         VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
210         video->ReturnEmptyOMXBuffer(buffer);
211         return OMX_ErrorNone;
212
213 }
214
215 void VideoVPEOGL::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
216         input_bufs_omx_mutex.Lock();
217         Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
218         input_bufs_omx_free.push_back(buffer);
219         Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
220         input_bufs_omx_mutex.Unlock();
221 }
222
223  OMX_ERRORTYPE VideoVPEOGL::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
224          Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
225         return OMX_ErrorNone;
226 }
227
228 #endif
229
230 int VideoVPEOGL::shutdown()
231 {
232   if (!initted) return 0;
233   initted = 0;
234   threadCancel();
235
236   decoding_backend=0;
237 #ifdef VPE_OMX_SUPPORT
238   DeAllocateCodecsOMX();
239   OMX_Deinit();
240 #endif
241 #ifdef VPE_LIBAV_SUPPORT
242   DeAllocateCodecsLibav();
243 #endif
244   eglDestroyContext(egl_display,egl_context);
245 //  close(fdVideo);
246   return 1;
247 }
248
249 int VideoVPEOGL::AllocateYUV400OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
250 {
251         Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 400");
252         // Y
253         glGenTextures(1, &outframe->textures[0]);
254         glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
255         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride, height, 0, GL_LUMINANCE,
256                                 GL_UNSIGNED_BYTE, NULL);
257         // U
258         glGenTextures(1, &outframe->textures[1]);
259         glBindTexture(GL_TEXTURE_2D, outframe->textures[1]);
260         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
261                                 GL_UNSIGNED_BYTE, NULL);
262         // V
263         glGenTextures(1, &outframe->textures[2]);
264         glBindTexture(GL_TEXTURE_2D, outframe->textures[2]);
265         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
266                         GL_UNSIGNED_BYTE, NULL);
267         outframe->height=height;
268         outframe->width=width;
269         outframe->stride=stride;
270         outframe->type=1;
271         return 1;
272 }
273
274 int VideoVPEOGL::AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height)
275 {
276         Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 444");
277         // Y
278         glGenTextures(1, &outframe->textures[0]);
279         glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
280         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
281                                 GL_UNSIGNED_BYTE, NULL);
282         outframe->textures[1]=outframe->textures[2]=0; // no handles here
283
284
285
286
287         outframe->type=2;
288         outframe->height=height;
289         outframe->width=width;
290         outframe->stride=width; // does not make any sense otherwiese
291         return 1;
292 }
293
294
295 VPEOGLFrame *VideoVPEOGL::getReadyOGLFrame(){
296         VPEOGLFrame *return_obj=NULL;
297         ogl_frame_mutex.Lock();
298         if (ready_ogl_frames.size()>0) {
299                 return_obj=ready_ogl_frames.front();
300                 ready_ogl_frames.pop_front();
301                 ogl_frame_outside=true;
302         }
303         ogl_frame_mutex.Unlock();
304         return return_obj;
305 }
306
307 void VideoVPEOGL::returnOGLFrame(VPEOGLFrame *frame)
308 {
309         ogl_frame_mutex.Lock();
310         if (frame) {
311                 ogl_frame_outside=false;
312                 free_ogl_frames.push_back(frame);
313         }
314         ogl_frame_mutex.Unlock();
315 }
316
317 void VideoVPEOGL::threadMethod()
318 {
319         if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
320                 Log::getInstance()->log("Video", Log::WARN, "Making egl Current failed in thread %d",eglGetError());
321                 return;
322         }
323         while (1) {
324                 bool sleep=true;
325 #ifdef VPE_LIBAV_SUPPORT
326                 dec_frame_libav_mutex.Lock();
327                 if (dec_frame_libav_upload_pending.size()>0) {
328                         dec_frame_libav_uploading=dec_frame_libav_upload_pending.front();
329                         dec_frame_libav_upload_pending.pop_front();
330                         if (dec_frame_libav_upload_pending.size()>0) sleep=false;
331                 }
332                 dec_frame_libav_mutex.Unlock();
333                 if (dec_frame_libav_uploading) {
334                         int width,height,pixfmt;
335                          //First get a free ogl image
336                         VPEOGLFrame* out_frame=NULL;
337                         while (!out_frame) {
338                                 ogl_frame_mutex.Lock();
339                                 if (all_ogl_frames.size()==0) {
340                                         ogl_frame_mutex.Unlock(); break;
341                                 }
342
343                                 if (free_ogl_frames.size()>0) {
344                                         width=libavwidth;
345                                         height=libavheight;
346                                         pixfmt=libavpixfmt;
347                                         out_frame=free_ogl_frames.front();
348                                         free_ogl_frames.pop_front();
349                                 } else MILLISLEEP(2);
350                                 ogl_frame_mutex.Unlock();
351                         }
352                         bool failed=false;
353                         if (out_frame) {
354                                 if (out_frame->textures[0]==0 || out_frame->width!=width ||
355                                                 out_frame->height!=height || out_frame->stride!=dec_frame_libav_uploading->linesize[0]) {
356                                         if (out_frame->textures[0]!=0) {
357                                                 glDeleteTextures(1,&out_frame->textures[0]);
358                                                 out_frame->textures[0]=0;
359                                         }
360                                         if (out_frame->textures[1]!=0) {
361                                                 glDeleteTextures(1,&out_frame->textures[1]);
362                                                 out_frame->textures[1]=0;
363                                         }
364                                         if (out_frame->textures[2]!=0) {
365                                                 glDeleteTextures(1,&out_frame->textures[2]);
366                                                 out_frame->textures[2]=0;
367                                         }
368
369                                         if (decoding_mode==VPE_NO_XVMC) {
370                                                 if (!AllocateYUV400OglTexture(out_frame,width,height,dec_frame_libav_uploading->linesize[0])) failed=true;
371                                         }else {
372                                                 if (!AllocateYUV444OglTexture(out_frame,width,height)) failed=true; //We use a YUV 444 texture in this case
373                                                 // the shaders are easier to implement
374                                         }
375                                 }
376                                 if (!failed) {
377                                         //up to now only YUV data, this is for reference only, since the pi is too slow.
378                                         if (decoding_mode==VPE_NO_XVMC) {
379                                                 glBindTexture(GL_TEXTURE_2D, out_frame->textures[0]);
380                                                 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
381                                                 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
382                                                                 out_frame->stride,out_frame->height,
383                                                                 GL_LUMINANCE,GL_UNSIGNED_BYTE,
384                                                                 dec_frame_libav_uploading->data[0]);
385
386                                                 glBindTexture(GL_TEXTURE_2D, out_frame->textures[1]);
387                                                 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
388                                                 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
389                                                                 out_frame->stride>>1,out_frame->height>>1,
390                                                                 GL_LUMINANCE,GL_UNSIGNED_BYTE,
391                                                                 dec_frame_libav_uploading->data[1]);
392
393                                                 glBindTexture(GL_TEXTURE_2D, out_frame->textures[2]);
394                                                 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
395                                                 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
396                                                                 out_frame->stride>>1,out_frame->height>>1,
397                                                                 GL_LUMINANCE,GL_UNSIGNED_BYTE,
398                                                                 dec_frame_libav_uploading->data[2]);
399                                         } else {
400                                                 //XVMC case
401                                                 xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading->data[2];
402                                                 if (moco_shader && pix_fmt) {
403
404
405                                                         moco_shader->uploadDataBlocks(pix_fmt->data_blocks,pix_fmt->next_free_data_block_num,
406                                                                         pix_fmt->mv_blocks , pix_fmt->filled_mv_blocks_num );
407                                                         if (decoding_mode==VPE_XVMC_MOCOMP)
408                                                         {
409                                                                 //DCT Blocks upload
410
411                                                         } else {
412                                                                 //DCT Blocks upload
413                                                         }
414                                                         moco_shader->doMoCo(out_frame);
415
416                                                 // Excute motion compensation
417                                                 }
418                                         }
419
420
421                                         releaseFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_uploading->base[0]);
422
423
424                                         ogl_frame_mutex.Lock();
425                                         ready_ogl_frames.push_back(out_frame);
426                                         ogl_frame_mutex.Unlock();
427                                         ((OsdOpenGL*)Osd::getInstance())->AdviseAboutNewFrame(); //Tell him, that we have a frame waiting
428
429                                 }
430
431                                 dec_frame_libav_mutex.Lock();
432                                 dec_frame_libav_free.push_back(dec_frame_libav_uploading);
433                                 dec_frame_libav_uploading=NULL;
434                                 dec_frame_libav_mutex.Unlock();
435
436
437
438
439                         }
440
441
442
443
444                 }
445 #endif
446
447                 if (sleep) threadWaitForSignal();
448                 threadCheckExit();
449         }
450
451 }
452
453 void VideoVPEOGL::threadPostStopCleanup()
454 {
455         eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
456 #ifdef VPE_LIBAV_SUPPORT
457         dec_frame_libav_uploading=NULL;
458 #endif
459 }
460
461
462
463
464 int VideoVPEOGL::setTVsize(UCHAR ttvsize)
465 {
466 /*  tvsize = ttvsize;
467
468   // Override the aspect ratio usage, temporarily use to set the video chip mode
469   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
470   close(fdVideo);
471   if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
472   if (!setSource())                  { shutdown(); return 0; }
473   if (!attachFramebuffer())          { shutdown(); return 0; }
474
475   // Reopening the fd causes the scart aspect line to go back to 4:3
476   // Set this again to the same as the tv screen size
477   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
478
479   // mode == LETTERBOX is invalid if the TV is widescreen
480   if (tvsize == ASPECT16X9) setMode(NORMAL);
481 */
482   return 1;
483 }
484
485 int VideoVPEOGL::setDefaultAspect()
486 {
487   return setAspectRatio(tvsize);
488 }
489
490
491
492 int VideoVPEOGL::setFormat(UCHAR tformat)
493 {
494   if (!initted) return 0;
495   if ((tformat != PAL) && (tformat != NTSC)) return 0;
496   format = tformat;
497
498 //  if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
499
500   if (format == NTSC)
501   {
502     screenWidth = 720;
503     screenHeight = 480;
504   }
505   if (format == PAL)
506   {
507     screenWidth = 720;
508     screenHeight = 576;
509   }
510
511   return 1;
512 }
513
514 int VideoVPEOGL::setConnection(UCHAR tconnection)
515 {
516   if (!initted) return 0;
517   if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
518   connection = tconnection;
519
520 //  if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
521   return 1;
522 }
523
524 int VideoVPEOGL::setAspectRatio(UCHAR taspectRatio)
525 {
526   if (!initted) return 0;
527   if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
528   aspectRatio = taspectRatio;
529
530   Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
531
532 //  if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
533   return 1;
534 }
535
536 int VideoVPEOGL::setMode(UCHAR tmode)
537 {
538   if (!initted) return 0;
539
540   if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
541
542   if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
543       && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
544   mode = tmode;
545
546 //  if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
547   return 1;
548 }
549
550 int VideoVPEOGL::signalOff()
551 {
552 //  if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
553   return 1;
554 }
555
556 int VideoVPEOGL::signalOn()
557 {
558 //  if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
559   return 1;
560 }
561
562 int VideoVPEOGL::setSource()
563 {
564   if (!initted) return 0;
565
566   // What does this do...
567 //  if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
568   return 1;
569 }
570
571 int VideoVPEOGL::setPosition(int x, int y)
572 {
573   if (!initted) return 0;
574
575 //  vid_pos_regs_t pos_d;
576 //  pos_d.x = x;
577 //  pos_d.y = y;
578
579 /*  vid_pos_regs_t pos_d;
580
581   memset(&pos_d, 0, sizeof(pos_d));
582
583   pos_d.dest.y = y;
584   pos_d.dest.x = x;
585 /*
586 typedef struct {
587   int w;
588   int h;
589   int scale;
590   int x1;
591   int y;
592   int x;
593   int y2;
594   int x3;
595   int y3;
596   int x4;
597   int y4;
598 } vid_pos_regs_t;
599 */
600
601 /*
602   pos_d.w = 100;
603   pos_d.h = 30;
604   pos_d.scale = 2;
605   pos_d.x1 = 0;
606   pos_d.y = 100;            // Top left X
607   pos_d.x = 50;            // Top left Y
608   pos_d.y2 = 30;
609   pos_d.x3 = 60;
610   pos_d.y3 = 90;
611   pos_d.x4 = 120;
612   pos_d.y4 = 150;
613 */
614
615 //  if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
616   return 1;
617 }
618
619 int VideoVPEOGL::sync()
620 {
621   if (!initted) return 0;
622
623 //  if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
624   return 1;
625 }
626
627
628
629
630 int VideoVPEOGL::play()
631 {
632   if (!initted) return 0;
633   decoding_backend=0;
634 #ifdef VPE_OMX_SUPPORT
635   bool doomx=true;
636   if (h264) {
637           if (!omx_h264) doomx=false;
638   } else {
639           if (!omx_mpeg2) doomx=false;
640   }
641   if (doomx) {
642           if (AllocateCodecsOMX()) {
643                   decoding_backend=VPE_DECODER_OMX;
644                   return 1;
645                   // Otherwise fall back to libav
646           } else {
647                   if (h264) {
648                           omx_h264=false;
649                           Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume h264 unsupported");
650                   } else {
651                           omx_mpeg2=false;
652                           Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume mpeg2 unsupported");
653                   }
654           }
655   }
656 #endif
657 #ifdef VPE_LIBAV_SUPPORT
658   if (AllocateCodecsLibav()) {
659           decoding_backend=VPE_DECODER_libav;
660           return 1;
661                   // Otherwise fall back to libav
662   }
663 #endif
664   return 0;
665
666
667
668 }
669
670 #ifdef VPE_OMX_SUPPORT
671 int VideoVPEOGL::AllocateCodecsOMX()
672 {
673         OMX_ERRORTYPE error;
674         static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
675
676         Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
677         //Clock, move later to audio
678
679         omx_events.clear();
680
681         error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
682
683
684         if (error!=OMX_ErrorNone){
685                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
686                 DeAllocateCodecsOMX();
687                 return 0;
688         }
689
690
691
692         OMX_PORT_PARAM_TYPE p_param;
693         memset(&p_param,0,sizeof(p_param));
694         p_param.nSize=sizeof(p_param);
695         p_param.nVersion.nVersion=OMX_VERSION;
696         error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
697         if (error!=OMX_ErrorNone){
698                 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
699                 DeAllocateCodecsOMX();
700                 return 0;
701         }
702         omx_clock_output_port=p_param.nStartPortNumber;
703
704         for (unsigned int i=0;i<p_param.nPorts;i++) {
705                 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i) ) {
706                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
707                         DeAllocateCodecsOMX();
708                         return 0;
709                 }
710         }
711
712
713         OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
714         memset(&clock_conf,0,sizeof(clock_conf));
715         clock_conf.nSize=sizeof(clock_conf);
716         clock_conf.nVersion.nVersion=OMX_VERSION;
717         clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
718         clock_conf.nStartTime=0;
719         clock_conf.nOffset=0;
720         clock_conf.nWaitMask=OMX_CLOCKPORT0;
721         error=OMX_SetParameter(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
722         if (error!=OMX_ErrorNone){
723                 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
724                 DeAllocateCodecsOMX();
725                 return 0;
726         }
727
728
729
730         if (h264) {
731                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
732         } else {
733                 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
734         }
735
736         if (error!=OMX_ErrorNone){
737                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
738                 DeAllocateCodecsOMX();
739                 return 0;
740         }
741
742
743
744         memset(&p_param,0,sizeof(p_param));
745         p_param.nSize=sizeof(p_param);
746         p_param.nVersion.nVersion=OMX_VERSION;
747         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
748         if (error!=OMX_ErrorNone){
749                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
750                 DeAllocateCodecsOMX();
751             return 0;
752         }
753         omx_codec_input_port=p_param.nStartPortNumber;
754         omx_codec_output_port=p_param.nStartPortNumber+1;
755
756         if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
757                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
758                 DeAllocateCodecsOMX();
759                 return 0;
760         }
761
762
763         OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
764         memset(&conceal,0,sizeof(conceal));
765         conceal.nSize=sizeof(conceal);
766         conceal.nVersion.nVersion=OMX_VERSION;
767         conceal.bStartWithValidFrame=OMX_FALSE;
768
769         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
770         if (error!=OMX_ErrorNone){
771                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
772                 DeAllocateCodecsOMX();
773                 return 0;
774         }
775
776
777         error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
778         if (error!=OMX_ErrorNone){
779                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
780                 DeAllocateCodecsOMX();
781                 return 0;
782         }
783
784
785
786         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
787         if (error!=OMX_ErrorNone){
788                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
789                 DeAllocateCodecsOMX();
790                 return 0;
791         }
792         omx_shed_input_port=p_param.nStartPortNumber;
793         omx_shed_output_port=p_param.nStartPortNumber+1;
794
795
796         error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
797         if (error!=OMX_ErrorNone){
798                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
799                 DeAllocateCodecsOMX();
800                 return 0;
801         }
802         omx_shed_clock_port=p_param.nStartPortNumber;
803
804
805         if (!DisablePort(omx_vid_sched,omx_shed_input_port) || !DisablePort(omx_vid_sched,omx_shed_output_port)
806                         || !DisablePort(omx_vid_sched,omx_shed_clock_port)) {
807                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
808                 DeAllocateCodecsOMX();
809                 return 0;
810         }
811
812
813         error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
814         if (error!=OMX_ErrorNone){
815                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
816                 DeAllocateCodecsOMX();
817                 return 0;
818         }
819
820         error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
821         if (error!=OMX_ErrorNone){
822                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
823                 DeAllocateCodecsOMX();
824                 return 0;
825         }
826         omx_rend_input_port=p_param.nStartPortNumber;
827         //omx_rend_output_port=p_param.nStartPortNumber+1;
828
829
830         if (!DisablePort(omx_vid_rend,omx_rend_input_port) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
831                                 ) {
832                 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
833                 DeAllocateCodecsOMX();
834                 return 0;
835         }
836
837         //Setuo chain
838
839
840
841
842
843
844
845
846 /*      error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
847         if (error!=OMX_ErrorNone){
848                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
849                 return 0;
850         }*/
851
852
853
854
855         OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
856         memset(&ft_type,0,sizeof(ft_type));
857         ft_type.nSize=sizeof(ft_type);
858         ft_type.nVersion.nVersion=OMX_VERSION;
859
860         ft_type.nPortIndex=omx_codec_input_port;
861         if (h264) {
862                 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
863         } else {
864                 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
865         }
866
867         Demuxer* demux=Demuxer::getInstance();
868
869     ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
870     Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
871         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
872         if (error!=OMX_ErrorNone){
873                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
874                 DeAllocateCodecsOMX();
875                 return 0;
876         }
877
878
879         if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
880                 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
881                 DeAllocateCodecsOMX();
882                 return 0;
883         }
884
885
886         if (!PrepareInputBufsOMX()) {
887                 DeAllocateCodecsOMX();
888                 return 0;
889         }
890
891
892         if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
893                 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle");
894                 DeAllocateCodecsOMX();
895                 return 0;
896         }
897
898         error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
899         if (error!=OMX_ErrorNone){
900                 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);
901                 DeAllocateCodecsOMX();
902                 return 0;
903         }
904
905         if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
906                                         ) {
907                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
908                 DeAllocateCodecsOMX();
909                 return 0;
910         }
911
912         if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
913                 DeAllocateCodecsOMX();
914                 return 0;
915         }
916
917         error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
918         if (error!=OMX_ErrorNone){
919                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
920                 DeAllocateCodecsOMX();
921                 return 0;
922         }
923
924
925
926         if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
927                                                 ) {
928                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
929                 DeAllocateCodecsOMX();
930                 return 0;
931         }
932
933         if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
934                 return 0;
935         }
936         if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
937                 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
938                 DeAllocateCodecsOMX();
939                 return 0;
940         }
941         if (!CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)
942                         ||!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port)){
943                 DeAllocateCodecsOMX();
944                 return 0;
945         }
946
947         if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
948                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
949                 DeAllocateCodecsOMX();
950                 return 0;
951         }
952
953         error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
954         if (error!=OMX_ErrorNone){
955                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel  sched to rend failed %x", error);
956                 DeAllocateCodecsOMX();
957                 return 0;
958         }
959
960         if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
961                                                         ) {
962                 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX  shed rend failed");
963                 DeAllocateCodecsOMX();
964                 return 0;
965         }
966
967         if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
968                                         || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
969                 DeAllocateCodecsOMX();
970                 return 0;
971         }
972
973         if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
974                 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
975                 DeAllocateCodecsOMX();
976                 return 0;
977         }
978
979
980         if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
981                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
982                 DeAllocateCodecsOMX();
983                 return 0;
984         }
985
986         if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
987                 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
988                 DeAllocateCodecsOMX();
989                 return 0;
990         }
991
992         //raspbi specifif
993         OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
994         memset(&dispconf,0,sizeof(dispconf));
995         dispconf.nSize=sizeof(dispconf);
996         dispconf.nVersion.nVersion=OMX_VERSION;
997
998         dispconf.nPortIndex=omx_rend_input_port;
999
1000         dispconf.set=OMX_DISPLAY_SET_LAYER ;
1001         dispconf.layer=1;
1002         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1003         if (error!=OMX_ErrorNone){
1004                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1005                 DeAllocateCodecsOMX();
1006                 return 0;
1007         }
1008
1009 /*      dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1010         dispconf.fullscreen=OMX_FALSE;
1011         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1012         if (error!=OMX_ErrorNone){
1013                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1014                 DeAllocateCodecsOMX();
1015                 return 0;
1016         }
1017
1018         dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1019         dispconf.dest_rect.x_offset=100;
1020         dispconf.dest_rect.y_offset=100;
1021         dispconf.dest_rect.width=640;
1022         dispconf.dest_rect.height=480;
1023         error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1024         if (error!=OMX_ErrorNone){
1025                 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1026                 DeAllocateCodecsOMX();
1027                 return 0;
1028         }*/
1029
1030
1031
1032
1033         if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1034                         Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Exccute");
1035                         DeAllocateCodecsOMX();
1036                         return 0;
1037         }
1038
1039         omx_running=true;
1040
1041         return 1;
1042 }
1043
1044
1045 int VideoVPEOGL::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type)
1046 {
1047         OMX_ERRORTYPE error;
1048         error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1049         if (error!=OMX_ErrorNone){
1050                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1051                 return 0;
1052         }
1053
1054         if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1055                 return 0;
1056         }
1057
1058         return 1;
1059 }
1060
1061
1062 int VideoVPEOGL::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1063 {
1064         OMX_ERRORTYPE error;
1065         error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1066         if (error!=OMX_ErrorNone){
1067                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1068                 return 0;
1069         }
1070
1071         if (!wait) return 1;
1072         if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1073                 return 0;
1074         }
1075
1076         return 1;
1077 }
1078
1079
1080 int VideoVPEOGL::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1081 {
1082         OMX_ERRORTYPE error;
1083         error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1084         if (error!=OMX_ErrorNone){
1085                 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1086                 return 0;
1087         }
1088
1089         if (!wait) return 1;
1090         if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1091                 return 0;
1092         }
1093
1094
1095         return 1;
1096 }
1097
1098
1099
1100
1101 int VideoVPEOGL::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2)
1102 {
1103         int i=0;
1104         while (i<1000) {
1105                 omx_event_mutex.Lock();
1106                 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1107                 while (itty!=omx_events.end()) {
1108
1109                         VPE_OMX_EVENT current=*itty;
1110                         if (current.handle==handle) { //this is ours
1111                                 if (current.event_type==OMX_EventError) {
1112                                         omx_events.erase(itty);
1113                                         omx_event_mutex.Unlock();
1114                                         return 0;
1115
1116                                 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1117                                         omx_events.erase(itty);
1118                                         omx_event_mutex.Unlock();
1119                                         return 1;
1120                                 }
1121                         }
1122                         itty++;
1123
1124                 }
1125                 omx_event_mutex.Unlock();
1126                 MILLISLEEP(2);
1127                 i++;
1128
1129         }
1130         Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1131         return 0;
1132
1133 }
1134
1135
1136
1137
1138
1139 int VideoVPEOGL::PrepareInputBufsOMX()
1140 {
1141         OMX_ERRORTYPE error;
1142         OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1143         memset(&port_def_type,0,sizeof(port_def_type));
1144         port_def_type.nSize=sizeof(port_def_type);
1145         port_def_type.nVersion.nVersion=OMX_VERSION;
1146         port_def_type.nPortIndex=omx_codec_input_port;
1147
1148         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1149
1150         if (error!=OMX_ErrorNone){
1151                         Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1152         }
1153 /*      Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1154                         port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1155                         port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1156
1157         port_def_type.nBufferCountActual=60;
1158
1159         error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1160
1161         if (error!=OMX_ErrorNone){
1162                         Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1163         }
1164
1165
1166         error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1167         if (error!=OMX_ErrorNone){
1168                 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1169                 return 0;
1170         }
1171
1172         input_bufs_omx_mutex.Lock();
1173         for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1174
1175         //      unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1176                 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1177         /*      error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1178                 if (error!=OMX_ErrorNone){
1179                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1180                         input_bufs_omx_mutex.Unlock();
1181                         return 0;
1182                 }*/
1183                 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1184                 if (error!=OMX_ErrorNone){
1185                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1186                                 input_bufs_omx_mutex.Unlock();
1187                         return 0;
1188                 }
1189                 input_bufs_omx_all.push_back(buf_head);
1190                 input_bufs_omx_free.push_back(buf_head);
1191         }
1192         omx_first_frame=true;
1193
1194         firstsynched=false;
1195         cur_input_buf_omx=NULL;
1196         input_bufs_omx_mutex.Unlock();
1197
1198
1199         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1200         if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1201                 return 0;
1202         }
1203         Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1204
1205         return 1;
1206 }
1207
1208 int VideoVPEOGL::DestroyInputBufsOMX()
1209 {
1210         OMX_ERRORTYPE error;
1211
1212         cur_input_buf_omx=NULL;
1213         input_bufs_omx_mutex.Lock();
1214         for (int i=0; i< input_bufs_omx_all.size();i++) {
1215         //      free(input_bufs_omx_all[i]->pBuffer);
1216         //      input_bufs_omx_all[i]->pBuffer=NULL;
1217                 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1218                 if (error!=OMX_ErrorNone){
1219                         Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1220                         input_bufs_omx_mutex.Unlock();
1221                         return 0;
1222                 }
1223         }
1224         input_bufs_omx_all.clear();
1225         input_bufs_omx_free.clear();
1226         input_bufs_omx_mutex.Unlock();
1227
1228 }
1229
1230
1231
1232
1233 int VideoVPEOGL::DeAllocateCodecsOMX()
1234 {
1235         OMX_ERRORTYPE error;
1236         omx_running=false;
1237         if (omx_vid_dec) {
1238                 // first flush all buffers
1239
1240                 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_output_port, NULL);
1241                 if (error!=OMX_ErrorNone){
1242                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1243
1244                 }
1245
1246                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_input_port, NULL);
1247                 if (error!=OMX_ErrorNone){
1248                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed in failed %x", error);
1249
1250                 }
1251
1252                 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_output_port) ||
1253                                 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_input_port)) {
1254                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec shed failed");
1255                 }
1256
1257                 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1258                 if (error!=OMX_ErrorNone){
1259                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1260
1261                 }
1262
1263                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
1264                 if (error!=OMX_ErrorNone){
1265                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
1266
1267                 }
1268
1269                 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1270                         !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
1271                                 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
1272                 }
1273
1274                 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_output_port, NULL);
1275                 if (error!=OMX_ErrorNone) {
1276                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed out failed %x", error);
1277
1278                 }
1279
1280                 error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1281                 if (error!=OMX_ErrorNone) {
1282                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1283
1284                 }
1285
1286                 if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ||
1287                                 !CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
1288                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
1289                 }
1290
1291
1292
1293
1294                 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1295                 if (error!=OMX_ErrorNone){
1296                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1297
1298                 }
1299
1300
1301                 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_input_port)) {
1302                         Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec input failed");
1303                 }
1304
1305                 DestroyInputBufsOMX();
1306
1307                 //todo flushing
1308                 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
1309                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
1310                 }
1311                 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
1312                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
1313                 }
1314
1315                 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
1316                 if (error!=OMX_ErrorNone){
1317                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1318
1319                 }
1320
1321                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
1322                 if (error!=OMX_ErrorNone){
1323                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1324
1325                 }
1326
1327                 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
1328                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
1329                 }
1330
1331                 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1332                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
1333                 }
1334
1335                 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
1336                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
1337                 }
1338                 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
1339                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
1340                 }
1341
1342
1343
1344                 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
1345                         Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
1346                 }
1347
1348
1349                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
1350                 if (error!=OMX_ErrorNone){
1351                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1352
1353                 }
1354                 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
1355                 if (error!=OMX_ErrorNone){
1356                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1357
1358                 }
1359
1360                 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1361                 if (error!=OMX_ErrorNone){
1362                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1363
1364                 }
1365
1366                 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
1367                 if (error!=OMX_ErrorNone){
1368                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1369
1370                 }
1371
1372
1373
1374
1375
1376                 error=OMX_FreeHandle(omx_vid_dec);
1377                 error=OMX_FreeHandle(omx_vid_sched);
1378                 error=OMX_FreeHandle(omx_vid_rend);
1379                 error=OMX_FreeHandle(omx_clock);
1380                 omx_vid_dec=NULL;
1381                 if (error!=OMX_ErrorNone) {
1382                         Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1383                 }
1384         }
1385
1386         return 1;
1387 }
1388
1389 #endif
1390
1391
1392 #ifdef VPE_LIBAV_SUPPORT
1393
1394 enum PixelFormat VideoVPEOGL::get_format_libav(struct AVCodecContext *s, const enum PixelFormat *fmt)
1395 {
1396         int dec_mode=((VideoVPEOGL*)getInstance())->getlibavDecodingMode();
1397         enum PixelFormat ret_pix=PIX_FMT_NONE;
1398         if (dec_mode==VPE_NO_XVMC) return PIX_FMT_NONE;
1399         while (*fmt!=PIX_FMT_NONE) {
1400                 if (*fmt== PIX_FMT_XVMC_MPEG2_IDCT && dec_mode==VPE_XVMC_IDCT) {
1401                         ret_pix=PIX_FMT_XVMC_MPEG2_IDCT;
1402                 } else if (*fmt== PIX_FMT_XVMC_MPEG2_MC && dec_mode==VPE_XVMC_MOCOMP) {
1403                         ret_pix=PIX_FMT_XVMC_MPEG2_MC;
1404                 }
1405                 fmt++;
1406         }
1407         return ret_pix;
1408 }
1409
1410 int VideoVPEOGL::reget_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1411 {
1412         Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!Not Implemented!");
1413         return -1;
1414 }
1415
1416 int VideoVPEOGL::get_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1417 {
1418         unsigned int want_sizes[4]={0,0,0,0};
1419         AVPicture pict;
1420         bool normal_pixs=false;
1421         int num_blocks=0;
1422         int num_dct_blocks=0;
1423
1424         int s_a[4];
1425         //reget logic from mplayer
1426         if (pic->opaque && pic->data[0] && (!pic->buffer_hints ||pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE )){
1427                 Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!");
1428                 return 0;
1429         }
1430
1431
1432         if (c->pix_fmt!=PIX_FMT_XVMC_MPEG2_IDCT &&c->pix_fmt!=PIX_FMT_XVMC_MPEG2_MC) {
1433                 normal_pixs=true;
1434                 // standard pixel format
1435                 // this is written using much inspiration from libav util.c, so portions from there
1436                 int width,height;
1437
1438                 width=c->width;
1439                 height=c->height;
1440
1441                 avcodec_align_dimensions2(c, &width, &height, s_a);
1442                 if ((c->flags & CODEC_FLAG_EMU_EDGE)==0) {
1443                         width+=2*16;
1444                         height+=2*16;
1445                 }
1446                 // Now we have to determine alignment size
1447                 bool unaligned=true;
1448                 while (unaligned) {
1449                         av_image_fill_linesizes(pict.linesize, c->pix_fmt, width); //linesizes are derived
1450                         width+=width & ~(width-1); //trick from libav, now determine, if the alignment is ok
1451                         unaligned=false;
1452                         for (int i=0;i<4;i++) {
1453                                 if ((pict.linesize[i]%s_a[i])!=0) {
1454                                         unaligned=true;
1455                                         break;
1456                                 }
1457                         }
1458                 }
1459                 int tot_size=av_image_fill_pointers(pict.data, c->pix_fmt, height, NULL, pict.linesize); //get sizes
1460                 for (int i=0;i<4 ;i++) {
1461                         if (i<3 && pict.data[i+1]) {
1462                                 want_sizes[i]=pict.data[i+1]-pict.data[i];
1463                                 want_sizes[i]+=16;
1464                         } else {
1465                                 want_sizes[i]=(tot_size-(pict.data[i]-pict.data[0]));
1466                                 want_sizes[i]+=16;
1467                                 break;
1468                         }
1469                 }
1470
1471         } else {
1472                 //TODO set linesizes!
1473
1474                 num_blocks=((c->width+15)/16)*((c->height+15)/16);
1475                 num_dct_blocks=num_blocks*6; //6 blocks per macroblock
1476
1477                 want_sizes[2]=sizeof(xvmc_pix_fmt);
1478                 want_sizes[1]=sizeof(short)*num_dct_blocks*8*8;
1479                 want_sizes[0]=sizeof(XvMCMacroBlock)*num_blocks;
1480                 pict.linesize[0]=pict.linesize[1]=pict.linesize[2]=pict.linesize[3]=0;
1481
1482         }
1483
1484         VPE_FrameBuf *frame_buf=((VideoVPEOGL*)Video::getInstance())->getFrameBuf(want_sizes);
1485
1486         //Log::getInstance()->log("Video", Log::NOTICE, "get buffer %x",frame_buf);
1487         if (!frame_buf) {
1488                 Log::getInstance()->log("Video", Log::ERR, "Getting buffer libav failed");
1489                 return -1;
1490         }
1491
1492
1493         //populate pict
1494         pic->type=FF_BUFFER_TYPE_USER; // we are controlling the buffers
1495         int hchr_shift,vchr_shift;
1496         avcodec_get_chroma_sub_sample(c->pix_fmt,&hchr_shift,&vchr_shift);
1497         const int pixel_size = av_pix_fmt_descriptors[c->pix_fmt].comp[0].step_minus1+1;
1498         for (int i=0;i<4;i++) {
1499                 pic->data[i]=(uint8_t*)frame_buf->data[i];
1500                 pic->linesize[i]=pict.linesize[i];
1501                 if (normal_pixs) {
1502
1503                         int edge_width=16;
1504                         int edge_height=16;
1505                         if (i!=0) {
1506                                 edge_width>>=hchr_shift;
1507                                 edge_height>>=vchr_shift;
1508                         }
1509                         pic->data[i]+=FFALIGN((pic->linesize[i]*16) + (pixel_size*edge_width), s_a[i]);
1510                 }
1511         }
1512
1513         pic->base[0]=(uint8_t*)frame_buf; // our structure
1514         //pic->extended_data=pic->data;
1515         if(c->pkt) pic->pkt_pts=c->pkt->pts;
1516         else pic->pkt_pts=AV_NOPTS_VALUE;
1517         pic->width=c->width;
1518         pic->height=c->height;
1519         pic->format=c->pix_fmt;
1520         pic->sample_aspect_ratio=c->sample_aspect_ratio;
1521         pic->reordered_opaque= c->reordered_opaque;
1522         pic->age=INT_MAX;
1523         if (!normal_pixs) {
1524                 xvmc_pix_fmt *pix_xvmc=(xvmc_pix_fmt *)pic->data[2];
1525                 pix_xvmc->xvmc_id=AV_XVMC_ID;
1526                 pix_xvmc->data_blocks=(short*)pic->data[1];
1527                 pix_xvmc->mv_blocks=(XvMCMacroBlock*)pic->data[0];
1528                 pix_xvmc->allocated_mv_blocks=num_blocks;
1529                 pix_xvmc->allocated_data_blocks=num_dct_blocks;
1530                 if (c->pix_fmt==PIX_FMT_XVMC_MPEG2_IDCT) pix_xvmc->idct=1;
1531                 else pix_xvmc->idct=0;
1532                 pix_xvmc->unsigned_intra=1; // let see what happens
1533                 pix_xvmc->p_surface=(XvMCSurface*)frame_buf->pict_num;
1534                 pix_xvmc->start_mv_blocks_num=0;
1535                 pix_xvmc->filled_mv_blocks_num=0;
1536                 pix_xvmc->next_free_data_block_num=0;
1537                 //that is all folks
1538
1539
1540         }
1541
1542         return 0;
1543
1544 }
1545
1546 void VideoVPEOGL::release_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1547 {
1548 //      Log::getInstance()->log("Video", Log::NOTICE, "release buffer %x",pic->base[0]);
1549         ((VideoVPEOGL*)Video::getInstance())->releaseFrameBufLibav((VPE_FrameBuf*) pic->base[0]);
1550         pic->base[0]=NULL;
1551         pic->data[0]=pic->data[1]=pic->data[2]=pic->data[3]=NULL;
1552
1553
1554 }
1555
1556 int VideoVPEOGL::AllocateCodecsLibav()
1557 {
1558         libav_hastime=false;
1559         Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecslibav");
1560         mpeg2codec_context_libav=avcodec_alloc_context();
1561         if (mpeg2codec_context_libav==NULL) {
1562                 Log::getInstance()->log("Video", Log::DEBUG, "Creating libav codec context failed");
1563                 return 0;
1564         }
1565         if (decoding_mode!=VPE_NO_XVMC) {
1566                 mpeg2codec_context_libav->slice_flags=SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD;
1567                 if (decoding_mode==VPE_XVMC_MOCOMP) mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_MC;
1568                 else mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_IDCT;
1569                 mpeg2codec_context_libav->get_format=get_format_libav;
1570
1571         }
1572         mpeg2codec_context_libav->get_buffer=get_buffer_libav;
1573         mpeg2codec_context_libav->reget_buffer=reget_buffer_libav;
1574         mpeg2codec_context_libav->release_buffer=release_buffer_libav;
1575
1576
1577         int avc_ret=avcodec_open(mpeg2codec_context_libav, mpeg2codec_libav);
1578         if (avc_ret<0) {
1579                 Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec  failed ");
1580                 return 0;
1581         }
1582         memset(&incom_packet_libav,0,sizeof(incom_packet_libav));
1583         incom_packet_libav_size=200000;
1584         incom_packet_libav.data=(uint8_t*)av_malloc(incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
1585
1586         dec_frame_libav_mutex.Lock();
1587         for (int i=0;i<3;i++) {
1588                         AVFrame *dec_frame_libav=avcodec_alloc_frame(); // may be we need multiple frames, if we want to use async texture upload
1589                         if (!dec_frame_libav) {
1590                                 Log::getInstance()->log("Video", Log::DEBUG, "Allocating dec_frame  failed");
1591                                 return 0;
1592                         }
1593                         dec_frame_libav_all.push_back(dec_frame_libav);
1594                         dec_frame_libav_free.push_back(dec_frame_libav);
1595         }
1596         dec_frame_libav_decoding=NULL;
1597         dec_frame_libav_mutex.Unlock();
1598
1599         ogl_frame_mutex.Lock();
1600         //Allocate texture structs, since we do not know the sizes, we do not allocate the textures yet
1601         for (int i=0;i<3;i++) {
1602                 VPEOGLFrame *new_frame=(VPEOGLFrame *)malloc(sizeof(VPEOGLFrame));
1603                 new_frame->type=1; //1 = YUV, 2 RGB
1604                 new_frame->textures[0]=0;
1605                 new_frame->textures[1]=0;
1606                 new_frame->textures[2]=0;
1607                 new_frame->width=new_frame->height=0;
1608                 all_ogl_frames.push_back(new_frame);
1609                 free_ogl_frames.push_back(new_frame);
1610
1611         }
1612         ogl_frame_outside=false;
1613
1614         ogl_frame_mutex.Unlock();
1615
1616         if (decoding_mode==VPE_XVMC_MOCOMP) {
1617                 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
1618                 osd->BeginPainting(); // get OpenGl context
1619                 moco_shader=new GLMocoShader();
1620                 moco_shader->init();
1621                 osd->EndPainting();
1622         }
1623
1624         libav_running=true;
1625
1626         return 1;
1627
1628 }
1629
1630 int VideoVPEOGL::DeAllocateCodecsLibav()
1631 {
1632         libav_running=false;
1633         Log::getInstance()->log("Video", Log::NOTICE, "DeAllocateCodecslibav");
1634         dec_frame_libav_mutex.Lock();
1635         dec_frame_libav_upload_pending.clear();
1636         dec_frame_libav_free.clear();
1637         dec_frame_libav_mutex.Unlock();
1638         while (dec_frame_libav_uploading) {
1639                 Log::getInstance()->log("Video", Log::NOTICE, "Wait for uploading to finish");
1640                 MILLISLEEP(20);
1641         }
1642         dec_frame_libav_mutex.Lock();
1643         for (int i=0; i< dec_frame_libav_all.size();i++) {
1644                 av_free(dec_frame_libav_all[i]);
1645         }
1646
1647         dec_frame_libav_all.clear();
1648
1649         av_free(incom_packet_libav.data);
1650         incom_packet_libav.data=NULL;
1651         incom_packet_libav_size=0;
1652
1653         dec_frame_libav_mutex.Unlock();
1654         dec_frame_libav_decoding=NULL;
1655         while (ogl_frame_outside) {
1656                 Log::getInstance()->log("Video", Log::NOTICE, "Wait for ogl frame from outside");
1657                 MILLISLEEP(20);
1658         }
1659
1660         ((OsdOpenGL*)Osd::getInstance())->BeginPainting(); // get osd's context
1661         ogl_frame_mutex.Lock();
1662         for (int i=0; i< dec_frame_libav_all.size();i++) {
1663                 VPEOGLFrame * del_frame=all_ogl_frames[i];
1664                 if (del_frame->textures[0]==0) {
1665                         glDeleteTextures(1,&del_frame->textures[0]);
1666                         del_frame->textures[0]=0;
1667                 }
1668                 if (del_frame->textures[1]==0) {
1669                         glDeleteTextures(1,&del_frame->textures[1]);
1670                         del_frame->textures[1]=0;
1671                 }
1672                 if (del_frame->textures[2]==0) {
1673                         glDeleteTextures(1,&del_frame->textures[2]);
1674                         del_frame->textures[2]=0;
1675                 }
1676
1677                 free(all_ogl_frames[i]);
1678         }
1679         all_ogl_frames.clear();
1680         free_ogl_frames.clear();
1681         ready_ogl_frames.clear();
1682         ogl_frame_mutex.Unlock();
1683         ((OsdOpenGL*)Osd::getInstance())->EndPainting();
1684
1685
1686         if (mpeg2codec_context_libav) {
1687                 avcodec_close(mpeg2codec_context_libav);
1688                 av_free(mpeg2codec_context_libav);
1689                 mpeg2codec_context_libav=NULL;
1690
1691         }
1692
1693
1694
1695         vpe_framebuf_mutex.Lock();
1696
1697         for (int i=0;i<all_frame_bufs.size();i++) {
1698                 VPE_FrameBuf* current=all_frame_bufs[i];
1699                 for (int x=0;x<4;x++) {
1700                         if (current->data[x]) {
1701                                 av_free(current->data[x]);
1702                         }
1703                 }
1704                 free(current);
1705         }
1706         all_frame_bufs.clear();
1707         free_frame_bufs.clear();
1708         locked_libav_frame_buf.clear();
1709         locked_uploading_frame_buf.clear();
1710
1711         vpe_framebuf_mutex.Unlock();
1712
1713
1714
1715         if (moco_shader) {
1716                 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
1717                 osd->BeginPainting(); // get OpenGl context
1718                 moco_shader->deinit();
1719                 delete moco_shader;
1720                 moco_shader=NULL;
1721                 osd->EndPainting();
1722         }
1723
1724
1725
1726
1727
1728         return 1;
1729 }
1730
1731
1732 VPE_FrameBuf *VideoVPEOGL::getFrameBuf(unsigned int *size)
1733 { //for libav
1734         VPE_FrameBuf* current=NULL;
1735         vpe_framebuf_mutex.Lock();
1736         if (free_frame_bufs.size()>0) {
1737                 current=free_frame_bufs.front();
1738                 free_frame_bufs.pop_front();
1739         } else if (all_frame_bufs.size()<6) {
1740                 current=(VPE_FrameBuf*)malloc(sizeof(VPE_FrameBuf));
1741                 memset(current,0,sizeof(VPE_FrameBuf));
1742         } else {
1743                 Log::getInstance()->log("Video", Log::NOTICE, "Framebuffer underrun!");
1744                 vpe_framebuf_mutex.Unlock();
1745                 return NULL; // We do not have a frame buffer
1746         }
1747         locked_libav_frame_buf.push_back(current);
1748         vpe_framebuf_mutex.Unlock();
1749         //check if we need reallocation
1750         for (int x=0;x<4;x++) {
1751                 if (current->size[x]!=size[x]) {
1752                         current->data[x]=av_realloc(current->data[x],size[x]);
1753                         current->size[x]=size[x];
1754                 }
1755         }
1756         framebuf_framenum++;
1757         current->pict_num=framebuf_framenum; //This is used for tracking reference frames through the conversion pipeline
1758         return current;
1759
1760 }
1761
1762 void VideoVPEOGL::lockFrameBufUpload(VPE_FrameBuf* buf)
1763 {
1764         // first find frame_buf memory
1765
1766         //Log::getInstance()->log("Video", Log::NOTICE, "lock buffer upload %x",buf);
1767         VPE_FrameBuf* current=buf;
1768         vpe_framebuf_mutex.Lock();
1769         if (current) locked_uploading_frame_buf.push_back(current); //locked
1770         vpe_framebuf_mutex.Unlock();
1771
1772 }
1773
1774
1775 void VideoVPEOGL::releaseFrameBufLibav(VPE_FrameBuf* buf)
1776 {
1777         // first find frame_buf memory
1778         //Log::getInstance()->log("Video", Log::NOTICE, "release buffer libav %x",buf);
1779         VPE_FrameBuf* current=buf;
1780         vpe_framebuf_mutex.Lock();
1781         if (current) {
1782                 locked_libav_frame_buf.remove(current); //unlocked
1783                 list<VPE_FrameBuf*>::iterator itty=locked_uploading_frame_buf.begin();
1784                 bool inlist=false;
1785                 while (itty!=locked_uploading_frame_buf.end()) {
1786                         if (*itty==current) {
1787                                 inlist=true;
1788                                 break;
1789                         }
1790                         itty++;
1791                 }
1792                 if (!inlist) {
1793                         free_frame_bufs.push_back(current);
1794                 }
1795         }
1796         vpe_framebuf_mutex.Unlock();
1797 }
1798
1799 void VideoVPEOGL::releaseFrameBufUpload(VPE_FrameBuf* buf)
1800 {
1801         // first find frame_buf memory
1802         VPE_FrameBuf* current=buf;
1803         //Log::getInstance()->log("Video", Log::NOTICE, "release buffer upload %x",buf);
1804         vpe_framebuf_mutex.Lock();
1805         if (current) {
1806                 locked_uploading_frame_buf.remove(current); //unlocked
1807                 list<VPE_FrameBuf*>::iterator itty=locked_libav_frame_buf.begin();
1808                 bool inlist=false;
1809                 while (itty!=locked_libav_frame_buf.end()) {
1810                         if (*itty==current) {
1811                                 inlist=true;
1812                                 break;
1813                         }
1814                         itty++;
1815                 }
1816                 if (!inlist) {
1817                         free_frame_bufs.push_back(current);
1818                 }
1819         }
1820         vpe_framebuf_mutex.Unlock();
1821 }
1822
1823
1824
1825
1826
1827
1828 #endif
1829
1830 int VideoVPEOGL::stop()
1831 {
1832   if (!initted) return 0;
1833
1834 #ifdef VPE_OMX_SUPPORT
1835   //Check if libav mode
1836   if (decoding_backend==VPE_DECODER_OMX) DeAllocateCodecsOMX();
1837   decoding_backend=0;
1838
1839 #endif
1840
1841
1842
1843 //  if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
1844   return 1;
1845 }
1846
1847 int VideoVPEOGL::reset()
1848 {
1849   if (!initted) return 0;
1850
1851 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
1852   return 1;
1853 }
1854
1855 int VideoVPEOGL::pause()
1856 {
1857   if (!initted) return 0;
1858
1859 //  if (ioctl(fdVideo, AV_SET_VID_PAUSE, 0) != 0) return 0;
1860   return 1;
1861 }
1862
1863 int VideoVPEOGL::unPause() // FIXME get rid - same as play!!
1864 {
1865   if (!initted) return 0;
1866 //  if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
1867   return 1;
1868 }
1869
1870 int VideoVPEOGL::fastForward()
1871 {
1872   if (!initted) return 0;
1873
1874 //  if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
1875   return 1;
1876 }
1877
1878 int VideoVPEOGL::unFastForward()
1879 {
1880   if (!initted) return 0;
1881
1882 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
1883
1884  //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
1885   return 1;
1886 }
1887
1888 int VideoVPEOGL::attachFrameBuffer()
1889 {
1890   if (!initted) return 0;
1891
1892 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
1893   return 1;
1894 }
1895
1896 int VideoVPEOGL::blank(void)
1897 {
1898 //  if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
1899 //  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
1900   return 1;
1901 }
1902
1903 ULLONG VideoVPEOGL::getCurrentTimestamp()
1904 {
1905 /*  sync_data_t timestamps;
1906   if (ioctl(fdVideo, AV_GET_VID_TIMESTAMPS, &timestamps) == 0)
1907   {
1908     // FIXME are these the right way around?
1909
1910     timestamps.stc = (timestamps.stc >> 31 ) | (timestamps.stc & 1);
1911     timestamps.pts = (timestamps.pts >> 31 ) | (timestamps.pts & 1);
1912
1913     return timestamps.stc;
1914   }
1915   else
1916   {
1917     return 0;
1918   }*/
1919   return 0;
1920 }
1921
1922 ULONG VideoVPEOGL::timecodeToFrameNumber(ULLONG timecode)
1923 {
1924   if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
1925   else               return (ULONG)(((double)timecode / (double)90000) * (double)30);
1926 }
1927
1928 #ifdef DEV
1929 int VideoVPEOGL::test()
1930 {
1931   return 0;
1932
1933 //  ULLONG stc = 0;
1934 //  return ioctl(fdVideo, AV_SET_VID_STC, &stc);
1935 /*
1936  // reset();
1937   return 1;
1938 */
1939 }
1940
1941 int VideoVPEOGL::test2()
1942 {
1943   return 0;
1944 }
1945 #endif
1946
1947 void VideoVPEOGL::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1948 {
1949   mediapacket = mplist.front();
1950 }
1951
1952 UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
1953 {
1954   DeliverMediaPacket(mediapacket, buffer, samplepos);
1955   if (*samplepos == mediapacket.length) {
1956     *samplepos = 0;
1957     return 1;
1958   }
1959   else return 0;
1960 }
1961
1962 UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
1963                 const UCHAR* buffer,
1964                 UINT *samplepos)
1965 {
1966         if (packet.type == MPTYPE_VIDEO_H264)
1967         {
1968                 h264=true;
1969         }
1970         else
1971         {
1972                 h264=false;
1973         }
1974         switch (decoding_backend) {
1975         default: case 0: return 0; // no backend runnigng
1976 #ifdef VPE_OMX_SUPPORT
1977         case VPE_DECODER_OMX: return DeliverMediaPacketOMX(packet,buffer,samplepos);
1978 #endif
1979 #ifdef VPE_LIBAV_SUPPORT
1980         case VPE_DECODER_libav: return DeliverMediaPacketlibav(packet,buffer,samplepos);
1981 #endif
1982         }
1983 }
1984
1985 #ifdef VPE_OMX_SUPPORT
1986 UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
1987                 const UCHAR* buffer,
1988                 UINT *samplepos)
1989 {
1990
1991
1992         //Later add fail back code for libav
1993         /*if (!videoon) {
1994                 *samplepos+=packet.length;
1995                 return packet.length;
1996         }*/
1997
1998
1999         if (!omx_running) return 0; // if we are not runnig do not do this
2000
2001
2002         OMX_ERRORTYPE error;
2003
2004 /*      OMX_PARAM_PORTDEFINITIONTYPE port_image;
2005         memset(&port_image,0,sizeof(port_image));
2006         port_image.nSize=sizeof(port_image);
2007         port_image.nVersion.nVersion=OMX_VERSION;
2008         port_image.nPortIndex =omx_codec_output_port;
2009         error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_image);
2010         if (error!= OMX_ErrorNone){
2011                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_GetParameter failed %x", error);
2012         }
2013         Log::getInstance()->log("Video", Log::DEBUG, "Image port %d %d", port_image.format.video.nFrameWidth , port_image.format.video.nFrameHeight);*/
2014
2015         /*First Check, if we have an audio sample*/
2016         if (iframemode) {
2017                 //samplepos=0;
2018                 MILLISLEEP(10);
2019                 return 0; //Not in iframe mode!
2020         }
2021
2022         UINT headerstrip=0;
2023         if (packet.disconti) {
2024                 firstsynched=false;
2025                 if (cur_input_buf_omx) {
2026                         OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2027                         if (error!=OMX_ErrorNone){
2028                                 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2029                         }
2030                         cur_input_buf_omx=NULL;
2031                 }
2032         }
2033
2034         /*Inspect PES-Header */
2035
2036 //      OMX_STATETYPE temp_state;
2037 //      OMX_GetState(omx_vid_dec,&temp_state);
2038
2039         if (*samplepos==0) {//stripheader
2040                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2041                 *samplepos+=headerstrip;
2042                 if ( packet.synched ) {
2043
2044                         if (cur_input_buf_omx) {
2045                                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2046                                 if (error!=OMX_ErrorNone){
2047                                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2048                                 }
2049
2050                                 cur_input_buf_omx=NULL;//write out old data
2051                         }
2052                 //      reftime1=packet.presentation_time;
2053                 //      reftime2=reftime1+1;
2054                         firstsynched=true;
2055                 } else {
2056                         if (!firstsynched) {//
2057                                 *samplepos=packet.length;//if we have not processed at least one
2058                                 return packet.length;//synched packet ignore it!
2059                         }
2060                 }
2061         }
2062
2063         if (!cur_input_buf_omx) {
2064                 input_bufs_omx_mutex.Lock();
2065                 if (input_bufs_omx_free.size()==0) {
2066                         input_bufs_omx_mutex.Unlock();
2067                         Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2068                         return 0; // we do not have a free media sample
2069
2070                 }
2071                 cur_input_buf_omx=input_bufs_omx_free.front();
2072                 cur_input_buf_omx->nFilledLen=0;
2073                 cur_input_buf_omx->nOffset=0;
2074                 cur_input_buf_omx->nTimeStamp=0;
2075                 input_bufs_omx_free.pop_front();
2076                 input_bufs_omx_mutex.Unlock();
2077         }
2078
2079
2080
2081
2082         if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2083                 /*if (packet.disconti) {
2084                         ms->SetDiscontinuity(TRUE);
2085                 } else {
2086                         ms->SetDiscontinuity(FALSE);
2087                 }*/
2088                 //if (packet.synched) {
2089
2090                         //lastreftimePTS=packet.pts;
2091                    if (omx_first_frame) { // TODO time
2092                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2093                            omx_first_frame=false;
2094                    } else
2095
2096                 //}
2097                 //else
2098                 //{
2099                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2100
2101
2102                         //  ms->SetSyncPoint(TRUE);
2103                 //}
2104
2105         }
2106         unsigned int haveToCopy=packet.length-*samplepos;
2107
2108         while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
2109                 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
2110                 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
2111                 haveToCopy-=cancopy;
2112                 cur_input_buf_omx->nFilledLen+=cancopy;
2113                 *samplepos+=cancopy;
2114                 // push old buffer out
2115
2116                 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2117                 if (error!=OMX_ErrorNone){
2118                         Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2119                 }
2120                 // get5 new buffer
2121                 input_bufs_omx_mutex.Lock();
2122                 if (input_bufs_omx_free.size()==0) {
2123                         input_bufs_omx_mutex.Unlock();
2124                         //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2125                         return *samplepos; // we do not have a free media sample
2126                 }
2127                 cur_input_buf_omx=input_bufs_omx_free.front();
2128                 cur_input_buf_omx->nFilledLen=0;
2129                 cur_input_buf_omx->nOffset=0;
2130                 cur_input_buf_omx->nTimeStamp=0;
2131                 input_bufs_omx_free.pop_front();
2132                 input_bufs_omx_mutex.Unlock();
2133
2134                 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2135
2136         }
2137         memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
2138                         buffer+packet.pos_buffer+*samplepos,haveToCopy);
2139         cur_input_buf_omx->nFilledLen+=haveToCopy;
2140
2141
2142
2143         *samplepos+=haveToCopy;
2144
2145         return *samplepos;
2146
2147 }
2148
2149 #endif
2150
2151
2152 #ifdef VPE_LIBAV_SUPPORT
2153 int VideoVPEOGL::DecodePacketlibav()
2154 {
2155         unsigned int haveToCopy=incom_packet_libav.size;
2156         if (incom_packet_libav.size==0) return 1; // we are already empty
2157         while (haveToCopy>0) {
2158                 int dec_bytes=0;
2159                 int frame_ready=0;
2160
2161         //      Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
2162
2163 #ifdef BENCHMARK_FPS
2164             int cur_time=getTimeMS();
2165 #endif
2166                 dec_bytes=avcodec_decode_video2(mpeg2codec_context_libav, dec_frame_libav_decoding,
2167                                 &frame_ready, &incom_packet_libav);
2168 #ifdef BENCHMARK_FPS
2169                 time_in_decoder+=getTimeMS()-cur_time;
2170                 if (frame_ready) num_frames++;
2171                 if ((num_frames%100)==0) {
2172                         float fps=1000./(float)(time_in_decoder);
2173                         fps*=((float)num_frames);
2174                         Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
2175                 }
2176 #endif
2177                 if (dec_bytes<0) {
2178                         Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
2179                         return 0;
2180                 }
2181                 haveToCopy-=dec_bytes;
2182                 if (frame_ready) {
2183                 //      Log::getInstance()->log("Video", Log::DEBUG, "We have a frame push it to osd");
2184
2185                         lockFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_decoding->base[0]); //lock for upload, so that ffmpeg does not reuse
2186                         dec_frame_libav_mutex.Lock();
2187                         libavwidth=mpeg2codec_context_libav->width;
2188                         libavheight=mpeg2codec_context_libav->height;
2189                         libavpixfmt=mpeg2codec_context_libav->pix_fmt;
2190                 //      Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",libavwidth,libavheight,libavpixfmt);
2191
2192
2193                         dec_frame_libav_upload_pending.push_back(dec_frame_libav_decoding);
2194                         dec_frame_libav_decoding=NULL;
2195                         if (dec_frame_libav_free.size()>0) {
2196                                 dec_frame_libav_decoding=dec_frame_libav_free.front();
2197                                 dec_frame_libav_free.pop_front();
2198                                 dec_frame_libav_mutex.Unlock();
2199                                 threadSignal();
2200                                 libav_hastime=false;
2201                         } else {
2202                                 libav_hastime=false;
2203                                 dec_frame_libav_mutex.Unlock();
2204                                 // No free buffers
2205                                 return 0;
2206                         }
2207
2208
2209                 }
2210
2211         }
2212         incom_packet_libav.size=0;
2213         return 1;
2214
2215 }
2216
2217
2218 UINT VideoVPEOGL::DeliverMediaPacketlibav(MediaPacket packet,
2219                 const UCHAR* buffer,
2220                 UINT *samplepos)
2221 {
2222         //Later add fail back code for libav
2223         /*if (!videoon) {
2224                 *samplepos+=packet.length;
2225                 return packet.length;
2226         }*/
2227
2228         if (!libav_running) return 0; // if we are not runnig do not do this
2229
2230
2231         if (iframemode) {
2232                 //samplepos=0;
2233                 MILLISLEEP(10);
2234                 return 0; //Not in iframe mode!
2235         }
2236
2237         UINT headerstrip=0;
2238         if (packet.disconti) {
2239                 firstsynched=false;
2240                 if (!DecodePacketlibav()) return 0;
2241         }
2242
2243         /*Inspect PES-Header */
2244         if (!dec_frame_libav_decoding) {
2245                 dec_frame_libav_mutex.Lock();
2246                 if (dec_frame_libav_free.size()>0) {
2247                         dec_frame_libav_decoding=dec_frame_libav_free.front();
2248                         dec_frame_libav_free.pop_front();
2249                         dec_frame_libav_mutex.Unlock();
2250                 } else {
2251                         Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers");
2252                         dec_frame_libav_mutex.Unlock();
2253                         // No free buffers
2254                         return 0;
2255                 }
2256         }
2257
2258
2259
2260         if (*samplepos==0) {//stripheader
2261                 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2262                 *samplepos+=headerstrip;
2263                 if ( packet.synched ) {
2264
2265                         if (!DecodePacketlibav()) return 0; // WriteOut old Data
2266
2267                         libav_time=packet.presentation_time;
2268                         libav_hastime=true;
2269                 //      reftime1=packet.presentation_time;
2270                 //      reftime2=reftime1+1;
2271                         firstsynched=true;
2272                 } else {
2273                         if (!firstsynched) {//
2274                                 *samplepos=packet.length;//if we have not processed at least one
2275                                 return packet.length;//synched packet ignore it!
2276                         }
2277                 }
2278         }
2279
2280
2281
2282
2283
2284
2285         /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2286                 /*if (packet.disconti) {
2287                         ms->SetDiscontinuity(TRUE);
2288                 } else {
2289                         ms->SetDiscontinuity(FALSE);
2290                 }*
2291                 //if (packet.synched) {
2292
2293                         //lastreftimePTS=packet.pts;
2294                    if (omx_first_frame) { // TODO time
2295                            cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2296                            omx_first_frame=false;
2297                    } else
2298
2299                 //}
2300                 //else
2301                 //{
2302                         cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2303
2304
2305                         //  ms->SetSyncPoint(TRUE);
2306                 //}
2307
2308         }*/
2309         unsigned int haveToCopy=packet.length-*samplepos;
2310
2311         if  ((incom_packet_libav_size-incom_packet_libav.size)< haveToCopy) {
2312                 // if the buffer is to small reallocate
2313                 incom_packet_libav_size+=haveToCopy;
2314                 incom_packet_libav.data=(uint8_t*)av_realloc(incom_packet_libav.data,incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
2315                 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_libav_size);
2316         }
2317         memcpy(incom_packet_libav.data+incom_packet_libav.size,buffer+packet.pos_buffer+*samplepos,haveToCopy);
2318         incom_packet_libav.size+=haveToCopy;
2319
2320         *samplepos+=haveToCopy;
2321
2322
2323         return *samplepos;
2324
2325
2326 }
2327
2328 #endif
2329
2330
2331
2332
2333
2334
2335 void VideoVPEOGL::ResetTimeOffsets()
2336 {
2337 }
2338
2339 bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length)
2340 {
2341   //write(fdVideo, buffer, length);
2342         if (!iframemode) EnterIframePlayback();
2343 //      WriteOutTS(buffer,length, h264?MPTYPE_VIDEO_H264 :MPTYPE_VIDEO_MPEG2 );
2344
2345   lastpacketnum=-1;
2346   return true;
2347 }
2348
2349 int VideoVPEOGL::EnterIframePlayback()
2350 {
2351
2352         return 0;
2353 }
2354