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