2 Copyright 2004-2005 Chris Tallon, 2009 Marten Richter
4 This file is part of VOMP.
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.
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.
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.
21 #include "videovpeogl.h"
23 #include "mtdraspberry.h"
25 #include "osdopengl.h"
30 //A lot of parts of this file are heavily inspired by xbmc omx implementations
32 VideoVPEOGL::VideoVPEOGL()
36 #ifdef VPE_OMX_SUPPORT
40 cur_input_buf_omx=NULL;
41 omx_h264=omx_mpeg2=true;
44 #ifdef VPE_LIBAV_SUPPORT
45 mpeg2codec_context_libav=NULL;
47 dec_frame_libav_uploading=NULL;
48 dec_frame_libav_decoding=NULL;
49 ogl_frame_outside=false;
50 //decoding_mode=VPE_NO_XVMC;
51 decoding_mode=VPE_XVMC_MOCOMP;
52 //decoding_mode=VPE_XVMC_IDCT;
64 VideoVPEOGL::~VideoVPEOGL()
69 int VideoVPEOGL::init(UCHAR tformat)
71 if (initted) return 0;
74 // if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
76 if (!setFormat(tformat)) { shutdown(); return 0; }
77 if (!setConnection(COMPOSITERGB)) { shutdown(); return 0; }
78 if (!setAspectRatio(ASPECT4X3)) { shutdown(); return 0; }
79 if (!setMode(NORMAL)) { shutdown(); return 0; }
80 if (!setSource()) { shutdown(); return 0; }
81 if (!attachFrameBuffer()) { shutdown(); return 0; }
85 /* if (format == PAL) setLetterboxBorder("38");
86 else setLetterboxBorder("31");*/
100 int VideoVPEOGL::initUsingOSDObjects()
102 EGLDisplay i_egl_display;
103 EGLSurface i_egl_surface;
104 EGLContext i_egl_context;
105 EGLConfig i_egl_config;
106 OsdOpenGL *osd=(OsdOpenGL*)osd->getInstance();
107 osd->getEGLObjs(&i_egl_display,&i_egl_surface,&i_egl_context, &i_egl_config);
108 const EGLint attr_context[]={
109 EGL_CONTEXT_CLIENT_VERSION,2,
113 egl_display=i_egl_display;
114 egl_context=eglCreateContext(egl_display,i_egl_config,i_egl_context,attr_context);
115 if (egl_context==EGL_NO_CONTEXT) {
116 Log::getInstance()->log("Video", Log::WARN, "Creating egl context failed! %x",eglGetError());
119 // We create a dummy surface here, in order to allow two contexts
120 const EGLint attr_pbuffer[]={
121 EGL_WIDTH, 1, EGL_HEIGHT,1,
124 egl_surface=eglCreatePbufferSurface(egl_display,i_egl_config,attr_pbuffer);
125 if (egl_surface==EGL_NO_SURFACE) {
126 Log::getInstance()->log("Video", Log::WARN, "Creating egl pbuffer failed! %x",eglGetError());
133 //egl_surface=i_egl_surface;
134 //egl_context=i_egl_context;
137 #ifdef VPE_OMX_SUPPORT
138 // we are called before the audio
141 if (error!=OMX_ErrorNone) {
142 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error);
146 //our callbacks move to play?
150 #ifdef VPE_LIBAV_SUPPORT
153 if (decoding_mode==VPE_NO_XVMC) {
154 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
156 mpeg2codec_libav=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_XVMC);
158 if (mpeg2codec_libav==NULL) {
159 Log::getInstance()->log("Video", Log::DEBUG, "Find libav mpeg2 codec failed");
169 #ifdef VPE_OMX_SUPPORT
171 OMX_ERRORTYPE VideoVPEOGL::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
172 OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
173 OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
175 Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
177 struct VPE_OMX_EVENT new_event;
178 new_event.handle=handle;
179 new_event.appdata=appdata;
180 new_event.event_type=event_type;
181 new_event.data1=data1;
182 new_event.data2=data2;
183 new_event.event_data=event_data;
185 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
186 video->AddOmxEvent(new_event);
188 /* switch (event_type) {
189 case OMX_EventCmdComplete: {
194 return OMX_ErrorNone;
198 void VideoVPEOGL::AddOmxEvent(VPE_OMX_EVENT new_event)
200 omx_event_mutex.Lock();
201 omx_events.push_back(new_event);
202 omx_event_mutex.Unlock();
206 OMX_ERRORTYPE VideoVPEOGL::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
208 Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
209 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
210 video->ReturnEmptyOMXBuffer(buffer);
211 return OMX_ErrorNone;
215 void VideoVPEOGL::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
216 input_bufs_omx_mutex.Lock();
217 Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
218 input_bufs_omx_free.push_back(buffer);
219 Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
220 input_bufs_omx_mutex.Unlock();
223 OMX_ERRORTYPE VideoVPEOGL::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
224 Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
225 return OMX_ErrorNone;
230 int VideoVPEOGL::shutdown()
232 if (!initted) return 0;
237 #ifdef VPE_OMX_SUPPORT
238 DeAllocateCodecsOMX();
241 #ifdef VPE_LIBAV_SUPPORT
242 DeAllocateCodecsLibav();
244 eglDestroyContext(egl_display,egl_context);
249 int VideoVPEOGL::AllocateYUV400OglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
251 Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 400");
253 glGenTextures(1, &outframe->textures[0]);
254 glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
255 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride, height, 0, GL_LUMINANCE,
256 GL_UNSIGNED_BYTE, NULL);
258 glGenTextures(1, &outframe->textures[1]);
259 glBindTexture(GL_TEXTURE_2D, outframe->textures[1]);
260 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
261 GL_UNSIGNED_BYTE, NULL);
263 glGenTextures(1, &outframe->textures[2]);
264 glBindTexture(GL_TEXTURE_2D, outframe->textures[2]);
265 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
266 GL_UNSIGNED_BYTE, NULL);
267 outframe->height=height;
268 outframe->width=width;
269 outframe->stride=stride;
274 int VideoVPEOGL::AllocateYUV444OglTexture(VPEOGLFrame* outframe,int width,int height)
276 Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture 444");
278 glGenTextures(1, &outframe->textures[0]);
279 glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
280 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
281 GL_UNSIGNED_BYTE, NULL);
282 outframe->textures[1]=outframe->textures[2]=0; // no handles here
288 outframe->height=height;
289 outframe->width=width;
290 outframe->stride=width; // does not make any sense otherwiese
295 VPEOGLFrame *VideoVPEOGL::getReadyOGLFrame(){
296 VPEOGLFrame *return_obj=NULL;
297 ogl_frame_mutex.Lock();
298 if (ready_ogl_frames.size()>0) {
299 return_obj=ready_ogl_frames.front();
300 ready_ogl_frames.pop_front();
301 ogl_frame_outside=true;
303 ogl_frame_mutex.Unlock();
307 void VideoVPEOGL::returnOGLFrame(VPEOGLFrame *frame)
309 ogl_frame_mutex.Lock();
311 ogl_frame_outside=false;
312 free_ogl_frames.push_back(frame);
314 ogl_frame_mutex.Unlock();
317 void VideoVPEOGL::threadMethod()
319 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
320 Log::getInstance()->log("Video", Log::WARN, "Making egl Current failed in thread %d",eglGetError());
325 #ifdef VPE_LIBAV_SUPPORT
326 dec_frame_libav_mutex.Lock();
327 if (dec_frame_libav_upload_pending.size()>0) {
328 dec_frame_libav_uploading=dec_frame_libav_upload_pending.front();
329 dec_frame_libav_upload_pending.pop_front();
330 if (dec_frame_libav_upload_pending.size()>0) sleep=false;
332 dec_frame_libav_mutex.Unlock();
333 if (dec_frame_libav_uploading) {
334 int width,height,pixfmt;
335 //First get a free ogl image
336 VPEOGLFrame* out_frame=NULL;
338 ogl_frame_mutex.Lock();
339 if (all_ogl_frames.size()==0) {
340 ogl_frame_mutex.Unlock(); break;
343 if (free_ogl_frames.size()>0) {
347 out_frame=free_ogl_frames.front();
348 free_ogl_frames.pop_front();
349 } else MILLISLEEP(2);
350 ogl_frame_mutex.Unlock();
354 if (out_frame->textures[0]==0 || out_frame->width!=width ||
355 out_frame->height!=height || out_frame->stride!=dec_frame_libav_uploading->linesize[0]) {
356 if (out_frame->textures[0]!=0) {
357 glDeleteTextures(1,&out_frame->textures[0]);
358 out_frame->textures[0]=0;
360 if (out_frame->textures[1]!=0) {
361 glDeleteTextures(1,&out_frame->textures[1]);
362 out_frame->textures[1]=0;
364 if (out_frame->textures[2]!=0) {
365 glDeleteTextures(1,&out_frame->textures[2]);
366 out_frame->textures[2]=0;
369 if (decoding_mode==VPE_NO_XVMC) {
370 if (!AllocateYUV400OglTexture(out_frame,width,height,dec_frame_libav_uploading->linesize[0])) failed=true;
372 if (!AllocateYUV444OglTexture(out_frame,width,height)) failed=true; //We use a YUV 444 texture in this case
373 // the shaders are easier to implement
377 //up to now only YUV data, this is for reference only, since the pi is too slow.
378 if (decoding_mode==VPE_NO_XVMC) {
379 glBindTexture(GL_TEXTURE_2D, out_frame->textures[0]);
380 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
381 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
382 out_frame->stride,out_frame->height,
383 GL_LUMINANCE,GL_UNSIGNED_BYTE,
384 dec_frame_libav_uploading->data[0]);
386 glBindTexture(GL_TEXTURE_2D, out_frame->textures[1]);
387 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
388 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
389 out_frame->stride>>1,out_frame->height>>1,
390 GL_LUMINANCE,GL_UNSIGNED_BYTE,
391 dec_frame_libav_uploading->data[1]);
393 glBindTexture(GL_TEXTURE_2D, out_frame->textures[2]);
394 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
395 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
396 out_frame->stride>>1,out_frame->height>>1,
397 GL_LUMINANCE,GL_UNSIGNED_BYTE,
398 dec_frame_libav_uploading->data[2]);
401 xvmc_pix_fmt * pix_fmt=(xvmc_pix_fmt *)dec_frame_libav_uploading->data[2];
402 if (moco_shader && pix_fmt) {
405 moco_shader->uploadDataBlocks(pix_fmt->data_blocks,pix_fmt->next_free_data_block_num,
406 pix_fmt->mv_blocks , pix_fmt->filled_mv_blocks_num );
407 if (decoding_mode==VPE_XVMC_MOCOMP)
414 moco_shader->doMoCo(out_frame);
416 // Excute motion compensation
421 releaseFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_uploading->base[0]);
424 ogl_frame_mutex.Lock();
425 ready_ogl_frames.push_back(out_frame);
426 ogl_frame_mutex.Unlock();
427 ((OsdOpenGL*)Osd::getInstance())->AdviseAboutNewFrame(); //Tell him, that we have a frame waiting
431 dec_frame_libav_mutex.Lock();
432 dec_frame_libav_free.push_back(dec_frame_libav_uploading);
433 dec_frame_libav_uploading=NULL;
434 dec_frame_libav_mutex.Unlock();
447 if (sleep) threadWaitForSignal();
453 void VideoVPEOGL::threadPostStopCleanup()
455 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
456 #ifdef VPE_LIBAV_SUPPORT
457 dec_frame_libav_uploading=NULL;
464 int VideoVPEOGL::setTVsize(UCHAR ttvsize)
468 // Override the aspect ratio usage, temporarily use to set the video chip mode
469 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
471 if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
472 if (!setSource()) { shutdown(); return 0; }
473 if (!attachFramebuffer()) { shutdown(); return 0; }
475 // Reopening the fd causes the scart aspect line to go back to 4:3
476 // Set this again to the same as the tv screen size
477 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
479 // mode == LETTERBOX is invalid if the TV is widescreen
480 if (tvsize == ASPECT16X9) setMode(NORMAL);
485 int VideoVPEOGL::setDefaultAspect()
487 return setAspectRatio(tvsize);
492 int VideoVPEOGL::setFormat(UCHAR tformat)
494 if (!initted) return 0;
495 if ((tformat != PAL) && (tformat != NTSC)) return 0;
498 // if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
514 int VideoVPEOGL::setConnection(UCHAR tconnection)
516 if (!initted) return 0;
517 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
518 connection = tconnection;
520 // if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
524 int VideoVPEOGL::setAspectRatio(UCHAR taspectRatio)
526 if (!initted) return 0;
527 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
528 aspectRatio = taspectRatio;
530 Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
532 // if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
536 int VideoVPEOGL::setMode(UCHAR tmode)
538 if (!initted) return 0;
540 if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
542 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
543 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
546 // if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
550 int VideoVPEOGL::signalOff()
552 // if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
556 int VideoVPEOGL::signalOn()
558 // if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
562 int VideoVPEOGL::setSource()
564 if (!initted) return 0;
566 // What does this do...
567 // if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
571 int VideoVPEOGL::setPosition(int x, int y)
573 if (!initted) return 0;
575 // vid_pos_regs_t pos_d;
579 /* vid_pos_regs_t pos_d;
581 memset(&pos_d, 0, sizeof(pos_d));
606 pos_d.y = 100; // Top left X
607 pos_d.x = 50; // Top left Y
615 // if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
619 int VideoVPEOGL::sync()
621 if (!initted) return 0;
623 // if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
630 int VideoVPEOGL::play()
632 if (!initted) return 0;
634 #ifdef VPE_OMX_SUPPORT
637 if (!omx_h264) doomx=false;
639 if (!omx_mpeg2) doomx=false;
642 if (AllocateCodecsOMX()) {
643 decoding_backend=VPE_DECODER_OMX;
645 // Otherwise fall back to libav
649 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume h264 unsupported");
652 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume mpeg2 unsupported");
657 #ifdef VPE_LIBAV_SUPPORT
658 if (AllocateCodecsLibav()) {
659 decoding_backend=VPE_DECODER_libav;
661 // Otherwise fall back to libav
670 #ifdef VPE_OMX_SUPPORT
671 int VideoVPEOGL::AllocateCodecsOMX()
674 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
676 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
677 //Clock, move later to audio
681 error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
684 if (error!=OMX_ErrorNone){
685 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
686 DeAllocateCodecsOMX();
692 OMX_PORT_PARAM_TYPE p_param;
693 memset(&p_param,0,sizeof(p_param));
694 p_param.nSize=sizeof(p_param);
695 p_param.nVersion.nVersion=OMX_VERSION;
696 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
697 if (error!=OMX_ErrorNone){
698 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
699 DeAllocateCodecsOMX();
702 omx_clock_output_port=p_param.nStartPortNumber;
704 for (unsigned int i=0;i<p_param.nPorts;i++) {
705 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i) ) {
706 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
707 DeAllocateCodecsOMX();
713 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
714 memset(&clock_conf,0,sizeof(clock_conf));
715 clock_conf.nSize=sizeof(clock_conf);
716 clock_conf.nVersion.nVersion=OMX_VERSION;
717 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
718 clock_conf.nStartTime=0;
719 clock_conf.nOffset=0;
720 clock_conf.nWaitMask=OMX_CLOCKPORT0;
721 error=OMX_SetParameter(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
722 if (error!=OMX_ErrorNone){
723 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
724 DeAllocateCodecsOMX();
731 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
733 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
736 if (error!=OMX_ErrorNone){
737 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
738 DeAllocateCodecsOMX();
744 memset(&p_param,0,sizeof(p_param));
745 p_param.nSize=sizeof(p_param);
746 p_param.nVersion.nVersion=OMX_VERSION;
747 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
748 if (error!=OMX_ErrorNone){
749 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
750 DeAllocateCodecsOMX();
753 omx_codec_input_port=p_param.nStartPortNumber;
754 omx_codec_output_port=p_param.nStartPortNumber+1;
756 if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
757 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
758 DeAllocateCodecsOMX();
763 OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
764 memset(&conceal,0,sizeof(conceal));
765 conceal.nSize=sizeof(conceal);
766 conceal.nVersion.nVersion=OMX_VERSION;
767 conceal.bStartWithValidFrame=OMX_FALSE;
769 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
770 if (error!=OMX_ErrorNone){
771 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
772 DeAllocateCodecsOMX();
777 error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
778 if (error!=OMX_ErrorNone){
779 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
780 DeAllocateCodecsOMX();
786 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
787 if (error!=OMX_ErrorNone){
788 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
789 DeAllocateCodecsOMX();
792 omx_shed_input_port=p_param.nStartPortNumber;
793 omx_shed_output_port=p_param.nStartPortNumber+1;
796 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
797 if (error!=OMX_ErrorNone){
798 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
799 DeAllocateCodecsOMX();
802 omx_shed_clock_port=p_param.nStartPortNumber;
805 if (!DisablePort(omx_vid_sched,omx_shed_input_port) || !DisablePort(omx_vid_sched,omx_shed_output_port)
806 || !DisablePort(omx_vid_sched,omx_shed_clock_port)) {
807 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
808 DeAllocateCodecsOMX();
813 error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
814 if (error!=OMX_ErrorNone){
815 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
816 DeAllocateCodecsOMX();
820 error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
821 if (error!=OMX_ErrorNone){
822 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
823 DeAllocateCodecsOMX();
826 omx_rend_input_port=p_param.nStartPortNumber;
827 //omx_rend_output_port=p_param.nStartPortNumber+1;
830 if (!DisablePort(omx_vid_rend,omx_rend_input_port) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
832 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
833 DeAllocateCodecsOMX();
846 /* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
847 if (error!=OMX_ErrorNone){
848 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
855 OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
856 memset(&ft_type,0,sizeof(ft_type));
857 ft_type.nSize=sizeof(ft_type);
858 ft_type.nVersion.nVersion=OMX_VERSION;
860 ft_type.nPortIndex=omx_codec_input_port;
862 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
864 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
867 Demuxer* demux=Demuxer::getInstance();
869 ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
870 Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
871 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
872 if (error!=OMX_ErrorNone){
873 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
874 DeAllocateCodecsOMX();
879 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
880 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
881 DeAllocateCodecsOMX();
886 if (!PrepareInputBufsOMX()) {
887 DeAllocateCodecsOMX();
892 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
893 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle");
894 DeAllocateCodecsOMX();
898 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
899 if (error!=OMX_ErrorNone){
900 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel clock to sched failed %x %d %d", error,omx_clock_output_port,omx_shed_clock_port);
901 DeAllocateCodecsOMX();
905 if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
907 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
908 DeAllocateCodecsOMX();
912 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
913 DeAllocateCodecsOMX();
917 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
918 if (error!=OMX_ErrorNone){
919 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
920 DeAllocateCodecsOMX();
926 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
928 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
929 DeAllocateCodecsOMX();
933 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
936 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
937 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
938 DeAllocateCodecsOMX();
941 if (!CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)
942 ||!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port)){
943 DeAllocateCodecsOMX();
947 if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
948 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
949 DeAllocateCodecsOMX();
953 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
954 if (error!=OMX_ErrorNone){
955 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel sched to rend failed %x", error);
956 DeAllocateCodecsOMX();
960 if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
962 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX shed rend failed");
963 DeAllocateCodecsOMX();
967 if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
968 || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
969 DeAllocateCodecsOMX();
973 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
974 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
975 DeAllocateCodecsOMX();
980 if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
981 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
982 DeAllocateCodecsOMX();
986 if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
987 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
988 DeAllocateCodecsOMX();
993 OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
994 memset(&dispconf,0,sizeof(dispconf));
995 dispconf.nSize=sizeof(dispconf);
996 dispconf.nVersion.nVersion=OMX_VERSION;
998 dispconf.nPortIndex=omx_rend_input_port;
1000 dispconf.set=OMX_DISPLAY_SET_LAYER ;
1002 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1003 if (error!=OMX_ErrorNone){
1004 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1005 DeAllocateCodecsOMX();
1009 /* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
1010 dispconf.fullscreen=OMX_FALSE;
1011 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1012 if (error!=OMX_ErrorNone){
1013 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1014 DeAllocateCodecsOMX();
1018 dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
1019 dispconf.dest_rect.x_offset=100;
1020 dispconf.dest_rect.y_offset=100;
1021 dispconf.dest_rect.width=640;
1022 dispconf.dest_rect.height=480;
1023 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
1024 if (error!=OMX_ErrorNone){
1025 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
1026 DeAllocateCodecsOMX();
1033 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
1034 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Exccute");
1035 DeAllocateCodecsOMX();
1045 int VideoVPEOGL::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type)
1047 OMX_ERRORTYPE error;
1048 error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
1049 if (error!=OMX_ErrorNone){
1050 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
1054 if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1062 int VideoVPEOGL::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1064 OMX_ERRORTYPE error;
1065 error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1066 if (error!=OMX_ErrorNone){
1067 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1071 if (!wait) return 1;
1072 if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1080 int VideoVPEOGL::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1082 OMX_ERRORTYPE error;
1083 error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1084 if (error!=OMX_ErrorNone){
1085 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1089 if (!wait) return 1;
1090 if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1101 int VideoVPEOGL::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2)
1105 omx_event_mutex.Lock();
1106 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1107 while (itty!=omx_events.end()) {
1109 VPE_OMX_EVENT current=*itty;
1110 if (current.handle==handle) { //this is ours
1111 if (current.event_type==OMX_EventError) {
1112 omx_events.erase(itty);
1113 omx_event_mutex.Unlock();
1116 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1117 omx_events.erase(itty);
1118 omx_event_mutex.Unlock();
1125 omx_event_mutex.Unlock();
1130 Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1139 int VideoVPEOGL::PrepareInputBufsOMX()
1141 OMX_ERRORTYPE error;
1142 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1143 memset(&port_def_type,0,sizeof(port_def_type));
1144 port_def_type.nSize=sizeof(port_def_type);
1145 port_def_type.nVersion.nVersion=OMX_VERSION;
1146 port_def_type.nPortIndex=omx_codec_input_port;
1148 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1150 if (error!=OMX_ErrorNone){
1151 Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1153 /* Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1154 port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1155 port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1157 port_def_type.nBufferCountActual=60;
1159 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1161 if (error!=OMX_ErrorNone){
1162 Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1166 error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1167 if (error!=OMX_ErrorNone){
1168 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1172 input_bufs_omx_mutex.Lock();
1173 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1175 // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nbufferSize);
1176 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1177 /* error=OMX_Usebuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nbufferSize,new_buffer_data);
1178 if (error!=OMX_ErrorNone){
1179 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_Usebuffer failed %x", error);
1180 input_bufs_omx_mutex.Unlock();
1183 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1184 if (error!=OMX_ErrorNone){
1185 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1186 input_bufs_omx_mutex.Unlock();
1189 input_bufs_omx_all.push_back(buf_head);
1190 input_bufs_omx_free.push_back(buf_head);
1192 omx_first_frame=true;
1195 cur_input_buf_omx=NULL;
1196 input_bufs_omx_mutex.Unlock();
1199 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1200 if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1203 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1208 int VideoVPEOGL::DestroyInputBufsOMX()
1210 OMX_ERRORTYPE error;
1212 cur_input_buf_omx=NULL;
1213 input_bufs_omx_mutex.Lock();
1214 for (int i=0; i< input_bufs_omx_all.size();i++) {
1215 // free(input_bufs_omx_all[i]->pBuffer);
1216 // input_bufs_omx_all[i]->pBuffer=NULL;
1217 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1218 if (error!=OMX_ErrorNone){
1219 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1220 input_bufs_omx_mutex.Unlock();
1224 input_bufs_omx_all.clear();
1225 input_bufs_omx_free.clear();
1226 input_bufs_omx_mutex.Unlock();
1233 int VideoVPEOGL::DeAllocateCodecsOMX()
1235 OMX_ERRORTYPE error;
1238 // first flush all buffers
1240 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_output_port, NULL);
1241 if (error!=OMX_ErrorNone){
1242 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1246 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_input_port, NULL);
1247 if (error!=OMX_ErrorNone){
1248 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed in failed %x", error);
1252 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_output_port) ||
1253 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_input_port)) {
1254 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec shed failed");
1257 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1258 if (error!=OMX_ErrorNone){
1259 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1263 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
1264 if (error!=OMX_ErrorNone){
1265 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
1269 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1270 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
1271 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
1274 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_output_port, NULL);
1275 if (error!=OMX_ErrorNone) {
1276 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed out failed %x", error);
1280 error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1281 if (error!=OMX_ErrorNone) {
1282 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1286 if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ||
1287 !CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
1288 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
1294 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1295 if (error!=OMX_ErrorNone){
1296 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1301 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_input_port)) {
1302 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec input failed");
1305 DestroyInputBufsOMX();
1308 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
1309 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
1311 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
1312 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
1315 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
1316 if (error!=OMX_ErrorNone){
1317 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1321 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
1322 if (error!=OMX_ErrorNone){
1323 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1327 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
1328 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
1331 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1332 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
1335 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
1336 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
1338 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
1339 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
1344 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
1345 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
1349 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
1350 if (error!=OMX_ErrorNone){
1351 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1354 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
1355 if (error!=OMX_ErrorNone){
1356 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1360 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1361 if (error!=OMX_ErrorNone){
1362 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1366 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
1367 if (error!=OMX_ErrorNone){
1368 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1376 error=OMX_FreeHandle(omx_vid_dec);
1377 error=OMX_FreeHandle(omx_vid_sched);
1378 error=OMX_FreeHandle(omx_vid_rend);
1379 error=OMX_FreeHandle(omx_clock);
1381 if (error!=OMX_ErrorNone) {
1382 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1392 #ifdef VPE_LIBAV_SUPPORT
1394 enum PixelFormat VideoVPEOGL::get_format_libav(struct AVCodecContext *s, const enum PixelFormat *fmt)
1396 int dec_mode=((VideoVPEOGL*)getInstance())->getlibavDecodingMode();
1397 enum PixelFormat ret_pix=PIX_FMT_NONE;
1398 if (dec_mode==VPE_NO_XVMC) return PIX_FMT_NONE;
1399 while (*fmt!=PIX_FMT_NONE) {
1400 if (*fmt== PIX_FMT_XVMC_MPEG2_IDCT && dec_mode==VPE_XVMC_IDCT) {
1401 ret_pix=PIX_FMT_XVMC_MPEG2_IDCT;
1402 } else if (*fmt== PIX_FMT_XVMC_MPEG2_MC && dec_mode==VPE_XVMC_MOCOMP) {
1403 ret_pix=PIX_FMT_XVMC_MPEG2_MC;
1410 int VideoVPEOGL::reget_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1412 Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!Not Implemented!");
1416 int VideoVPEOGL::get_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1418 unsigned int want_sizes[4]={0,0,0,0};
1420 bool normal_pixs=false;
1422 int num_dct_blocks=0;
1425 //reget logic from mplayer
1426 if (pic->opaque && pic->data[0] && (!pic->buffer_hints ||pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE )){
1427 Log::getInstance()->log("Video", Log::ERR, "Buffer reusing! Should not happen!");
1432 if (c->pix_fmt!=PIX_FMT_XVMC_MPEG2_IDCT &&c->pix_fmt!=PIX_FMT_XVMC_MPEG2_MC) {
1434 // standard pixel format
1435 // this is written using much inspiration from libav util.c, so portions from there
1441 avcodec_align_dimensions2(c, &width, &height, s_a);
1442 if ((c->flags & CODEC_FLAG_EMU_EDGE)==0) {
1446 // Now we have to determine alignment size
1447 bool unaligned=true;
1449 av_image_fill_linesizes(pict.linesize, c->pix_fmt, width); //linesizes are derived
1450 width+=width & ~(width-1); //trick from libav, now determine, if the alignment is ok
1452 for (int i=0;i<4;i++) {
1453 if ((pict.linesize[i]%s_a[i])!=0) {
1459 int tot_size=av_image_fill_pointers(pict.data, c->pix_fmt, height, NULL, pict.linesize); //get sizes
1460 for (int i=0;i<4 ;i++) {
1461 if (i<3 && pict.data[i+1]) {
1462 want_sizes[i]=pict.data[i+1]-pict.data[i];
1465 want_sizes[i]=(tot_size-(pict.data[i]-pict.data[0]));
1472 //TODO set linesizes!
1474 num_blocks=((c->width+15)/16)*((c->height+15)/16);
1475 num_dct_blocks=num_blocks*6; //6 blocks per macroblock
1477 want_sizes[2]=sizeof(xvmc_pix_fmt);
1478 want_sizes[1]=sizeof(short)*num_dct_blocks*8*8;
1479 want_sizes[0]=sizeof(XvMCMacroBlock)*num_blocks;
1480 pict.linesize[0]=pict.linesize[1]=pict.linesize[2]=pict.linesize[3]=0;
1484 VPE_FrameBuf *frame_buf=((VideoVPEOGL*)Video::getInstance())->getFrameBuf(want_sizes);
1486 //Log::getInstance()->log("Video", Log::NOTICE, "get buffer %x",frame_buf);
1488 Log::getInstance()->log("Video", Log::ERR, "Getting buffer libav failed");
1494 pic->type=FF_BUFFER_TYPE_USER; // we are controlling the buffers
1495 int hchr_shift,vchr_shift;
1496 avcodec_get_chroma_sub_sample(c->pix_fmt,&hchr_shift,&vchr_shift);
1497 const int pixel_size = av_pix_fmt_descriptors[c->pix_fmt].comp[0].step_minus1+1;
1498 for (int i=0;i<4;i++) {
1499 pic->data[i]=(uint8_t*)frame_buf->data[i];
1500 pic->linesize[i]=pict.linesize[i];
1506 edge_width>>=hchr_shift;
1507 edge_height>>=vchr_shift;
1509 pic->data[i]+=FFALIGN((pic->linesize[i]*16) + (pixel_size*edge_width), s_a[i]);
1513 pic->base[0]=(uint8_t*)frame_buf; // our structure
1514 //pic->extended_data=pic->data;
1515 if(c->pkt) pic->pkt_pts=c->pkt->pts;
1516 else pic->pkt_pts=AV_NOPTS_VALUE;
1517 pic->width=c->width;
1518 pic->height=c->height;
1519 pic->format=c->pix_fmt;
1520 pic->sample_aspect_ratio=c->sample_aspect_ratio;
1521 pic->reordered_opaque= c->reordered_opaque;
1524 xvmc_pix_fmt *pix_xvmc=(xvmc_pix_fmt *)pic->data[2];
1525 pix_xvmc->xvmc_id=AV_XVMC_ID;
1526 pix_xvmc->data_blocks=(short*)pic->data[1];
1527 pix_xvmc->mv_blocks=(XvMCMacroBlock*)pic->data[0];
1528 pix_xvmc->allocated_mv_blocks=num_blocks;
1529 pix_xvmc->allocated_data_blocks=num_dct_blocks;
1530 if (c->pix_fmt==PIX_FMT_XVMC_MPEG2_IDCT) pix_xvmc->idct=1;
1531 else pix_xvmc->idct=0;
1532 pix_xvmc->unsigned_intra=1; // let see what happens
1533 pix_xvmc->p_surface=(XvMCSurface*)frame_buf->pict_num;
1534 pix_xvmc->start_mv_blocks_num=0;
1535 pix_xvmc->filled_mv_blocks_num=0;
1536 pix_xvmc->next_free_data_block_num=0;
1546 void VideoVPEOGL::release_buffer_libav(struct AVCodecContext *c, AVFrame *pic)
1548 // Log::getInstance()->log("Video", Log::NOTICE, "release buffer %x",pic->base[0]);
1549 ((VideoVPEOGL*)Video::getInstance())->releaseFrameBufLibav((VPE_FrameBuf*) pic->base[0]);
1551 pic->data[0]=pic->data[1]=pic->data[2]=pic->data[3]=NULL;
1556 int VideoVPEOGL::AllocateCodecsLibav()
1558 libav_hastime=false;
1559 Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecslibav");
1560 mpeg2codec_context_libav=avcodec_alloc_context();
1561 if (mpeg2codec_context_libav==NULL) {
1562 Log::getInstance()->log("Video", Log::DEBUG, "Creating libav codec context failed");
1565 if (decoding_mode!=VPE_NO_XVMC) {
1566 mpeg2codec_context_libav->slice_flags=SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD;
1567 if (decoding_mode==VPE_XVMC_MOCOMP) mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_MC;
1568 else mpeg2codec_context_libav->pix_fmt=PIX_FMT_XVMC_MPEG2_IDCT;
1569 mpeg2codec_context_libav->get_format=get_format_libav;
1572 mpeg2codec_context_libav->get_buffer=get_buffer_libav;
1573 mpeg2codec_context_libav->reget_buffer=reget_buffer_libav;
1574 mpeg2codec_context_libav->release_buffer=release_buffer_libav;
1577 int avc_ret=avcodec_open(mpeg2codec_context_libav, mpeg2codec_libav);
1579 Log::getInstance()->log("Video", Log::DEBUG, "Opening libav codec failed ");
1582 memset(&incom_packet_libav,0,sizeof(incom_packet_libav));
1583 incom_packet_libav_size=200000;
1584 incom_packet_libav.data=(uint8_t*)av_malloc(incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
1586 dec_frame_libav_mutex.Lock();
1587 for (int i=0;i<3;i++) {
1588 AVFrame *dec_frame_libav=avcodec_alloc_frame(); // may be we need multiple frames, if we want to use async texture upload
1589 if (!dec_frame_libav) {
1590 Log::getInstance()->log("Video", Log::DEBUG, "Allocating dec_frame failed");
1593 dec_frame_libav_all.push_back(dec_frame_libav);
1594 dec_frame_libav_free.push_back(dec_frame_libav);
1596 dec_frame_libav_decoding=NULL;
1597 dec_frame_libav_mutex.Unlock();
1599 ogl_frame_mutex.Lock();
1600 //Allocate texture structs, since we do not know the sizes, we do not allocate the textures yet
1601 for (int i=0;i<3;i++) {
1602 VPEOGLFrame *new_frame=(VPEOGLFrame *)malloc(sizeof(VPEOGLFrame));
1603 new_frame->type=1; //1 = YUV, 2 RGB
1604 new_frame->textures[0]=0;
1605 new_frame->textures[1]=0;
1606 new_frame->textures[2]=0;
1607 new_frame->width=new_frame->height=0;
1608 all_ogl_frames.push_back(new_frame);
1609 free_ogl_frames.push_back(new_frame);
1612 ogl_frame_outside=false;
1614 ogl_frame_mutex.Unlock();
1616 if (decoding_mode==VPE_XVMC_MOCOMP) {
1617 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
1618 osd->BeginPainting(); // get OpenGl context
1619 moco_shader=new GLMocoShader();
1620 moco_shader->init();
1630 int VideoVPEOGL::DeAllocateCodecsLibav()
1632 libav_running=false;
1633 Log::getInstance()->log("Video", Log::NOTICE, "DeAllocateCodecslibav");
1634 dec_frame_libav_mutex.Lock();
1635 dec_frame_libav_upload_pending.clear();
1636 dec_frame_libav_free.clear();
1637 dec_frame_libav_mutex.Unlock();
1638 while (dec_frame_libav_uploading) {
1639 Log::getInstance()->log("Video", Log::NOTICE, "Wait for uploading to finish");
1642 dec_frame_libav_mutex.Lock();
1643 for (int i=0; i< dec_frame_libav_all.size();i++) {
1644 av_free(dec_frame_libav_all[i]);
1647 dec_frame_libav_all.clear();
1649 av_free(incom_packet_libav.data);
1650 incom_packet_libav.data=NULL;
1651 incom_packet_libav_size=0;
1653 dec_frame_libav_mutex.Unlock();
1654 dec_frame_libav_decoding=NULL;
1655 while (ogl_frame_outside) {
1656 Log::getInstance()->log("Video", Log::NOTICE, "Wait for ogl frame from outside");
1660 ((OsdOpenGL*)Osd::getInstance())->BeginPainting(); // get osd's context
1661 ogl_frame_mutex.Lock();
1662 for (int i=0; i< dec_frame_libav_all.size();i++) {
1663 VPEOGLFrame * del_frame=all_ogl_frames[i];
1664 if (del_frame->textures[0]==0) {
1665 glDeleteTextures(1,&del_frame->textures[0]);
1666 del_frame->textures[0]=0;
1668 if (del_frame->textures[1]==0) {
1669 glDeleteTextures(1,&del_frame->textures[1]);
1670 del_frame->textures[1]=0;
1672 if (del_frame->textures[2]==0) {
1673 glDeleteTextures(1,&del_frame->textures[2]);
1674 del_frame->textures[2]=0;
1677 free(all_ogl_frames[i]);
1679 all_ogl_frames.clear();
1680 free_ogl_frames.clear();
1681 ready_ogl_frames.clear();
1682 ogl_frame_mutex.Unlock();
1683 ((OsdOpenGL*)Osd::getInstance())->EndPainting();
1686 if (mpeg2codec_context_libav) {
1687 avcodec_close(mpeg2codec_context_libav);
1688 av_free(mpeg2codec_context_libav);
1689 mpeg2codec_context_libav=NULL;
1695 vpe_framebuf_mutex.Lock();
1697 for (int i=0;i<all_frame_bufs.size();i++) {
1698 VPE_FrameBuf* current=all_frame_bufs[i];
1699 for (int x=0;x<4;x++) {
1700 if (current->data[x]) {
1701 av_free(current->data[x]);
1706 all_frame_bufs.clear();
1707 free_frame_bufs.clear();
1708 locked_libav_frame_buf.clear();
1709 locked_uploading_frame_buf.clear();
1711 vpe_framebuf_mutex.Unlock();
1716 OsdOpenGL* osd=(OsdOpenGL*)osd->getInstance();
1717 osd->BeginPainting(); // get OpenGl context
1718 moco_shader->deinit();
1732 VPE_FrameBuf *VideoVPEOGL::getFrameBuf(unsigned int *size)
1734 VPE_FrameBuf* current=NULL;
1735 vpe_framebuf_mutex.Lock();
1736 if (free_frame_bufs.size()>0) {
1737 current=free_frame_bufs.front();
1738 free_frame_bufs.pop_front();
1739 } else if (all_frame_bufs.size()<6) {
1740 current=(VPE_FrameBuf*)malloc(sizeof(VPE_FrameBuf));
1741 memset(current,0,sizeof(VPE_FrameBuf));
1743 Log::getInstance()->log("Video", Log::NOTICE, "Framebuffer underrun!");
1744 vpe_framebuf_mutex.Unlock();
1745 return NULL; // We do not have a frame buffer
1747 locked_libav_frame_buf.push_back(current);
1748 vpe_framebuf_mutex.Unlock();
1749 //check if we need reallocation
1750 for (int x=0;x<4;x++) {
1751 if (current->size[x]!=size[x]) {
1752 current->data[x]=av_realloc(current->data[x],size[x]);
1753 current->size[x]=size[x];
1756 framebuf_framenum++;
1757 current->pict_num=framebuf_framenum; //This is used for tracking reference frames through the conversion pipeline
1762 void VideoVPEOGL::lockFrameBufUpload(VPE_FrameBuf* buf)
1764 // first find frame_buf memory
1766 //Log::getInstance()->log("Video", Log::NOTICE, "lock buffer upload %x",buf);
1767 VPE_FrameBuf* current=buf;
1768 vpe_framebuf_mutex.Lock();
1769 if (current) locked_uploading_frame_buf.push_back(current); //locked
1770 vpe_framebuf_mutex.Unlock();
1775 void VideoVPEOGL::releaseFrameBufLibav(VPE_FrameBuf* buf)
1777 // first find frame_buf memory
1778 //Log::getInstance()->log("Video", Log::NOTICE, "release buffer libav %x",buf);
1779 VPE_FrameBuf* current=buf;
1780 vpe_framebuf_mutex.Lock();
1782 locked_libav_frame_buf.remove(current); //unlocked
1783 list<VPE_FrameBuf*>::iterator itty=locked_uploading_frame_buf.begin();
1785 while (itty!=locked_uploading_frame_buf.end()) {
1786 if (*itty==current) {
1793 free_frame_bufs.push_back(current);
1796 vpe_framebuf_mutex.Unlock();
1799 void VideoVPEOGL::releaseFrameBufUpload(VPE_FrameBuf* buf)
1801 // first find frame_buf memory
1802 VPE_FrameBuf* current=buf;
1803 //Log::getInstance()->log("Video", Log::NOTICE, "release buffer upload %x",buf);
1804 vpe_framebuf_mutex.Lock();
1806 locked_uploading_frame_buf.remove(current); //unlocked
1807 list<VPE_FrameBuf*>::iterator itty=locked_libav_frame_buf.begin();
1809 while (itty!=locked_libav_frame_buf.end()) {
1810 if (*itty==current) {
1817 free_frame_bufs.push_back(current);
1820 vpe_framebuf_mutex.Unlock();
1830 int VideoVPEOGL::stop()
1832 if (!initted) return 0;
1834 #ifdef VPE_OMX_SUPPORT
1835 //Check if libav mode
1836 if (decoding_backend==VPE_DECODER_OMX) DeAllocateCodecsOMX();
1843 // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
1847 int VideoVPEOGL::reset()
1849 if (!initted) return 0;
1851 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
1855 int VideoVPEOGL::pause()
1857 if (!initted) return 0;
1859 // if (ioctl(fdVideo, AV_SET_VID_PAUSE, 0) != 0) return 0;
1863 int VideoVPEOGL::unPause() // FIXME get rid - same as play!!
1865 if (!initted) return 0;
1866 // if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
1870 int VideoVPEOGL::fastForward()
1872 if (!initted) return 0;
1874 // if (ioctl(fdVideo, AV_SET_VID_libavWD, 1) != 0) return 0;
1878 int VideoVPEOGL::unFastForward()
1880 if (!initted) return 0;
1882 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
1884 //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
1888 int VideoVPEOGL::attachFrameBuffer()
1890 if (!initted) return 0;
1892 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
1896 int VideoVPEOGL::blank(void)
1898 // if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
1899 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
1903 ULLONG VideoVPEOGL::getCurrentTimestamp()
1905 /* sync_data_t timestamps;
1906 if (ioctl(fdVideo, AV_GET_VID_TIMESTAMPS, ×tamps) == 0)
1908 // FIXME are these the right way around?
1910 timestamps.stc = (timestamps.stc >> 31 ) | (timestamps.stc & 1);
1911 timestamps.pts = (timestamps.pts >> 31 ) | (timestamps.pts & 1);
1913 return timestamps.stc;
1922 ULONG VideoVPEOGL::timecodeToFrameNumber(ULLONG timecode)
1924 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
1925 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
1929 int VideoVPEOGL::test()
1934 // return ioctl(fdVideo, AV_SET_VID_STC, &stc);
1941 int VideoVPEOGL::test2()
1947 void VideoVPEOGL::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1949 mediapacket = mplist.front();
1952 UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
1954 DeliverMediaPacket(mediapacket, buffer, samplepos);
1955 if (*samplepos == mediapacket.length) {
1962 UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
1963 const UCHAR* buffer,
1966 if (packet.type == MPTYPE_VIDEO_H264)
1974 switch (decoding_backend) {
1975 default: case 0: return 0; // no backend runnigng
1976 #ifdef VPE_OMX_SUPPORT
1977 case VPE_DECODER_OMX: return DeliverMediaPacketOMX(packet,buffer,samplepos);
1979 #ifdef VPE_LIBAV_SUPPORT
1980 case VPE_DECODER_libav: return DeliverMediaPacketlibav(packet,buffer,samplepos);
1985 #ifdef VPE_OMX_SUPPORT
1986 UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
1987 const UCHAR* buffer,
1992 //Later add fail back code for libav
1994 *samplepos+=packet.length;
1995 return packet.length;
1999 if (!omx_running) return 0; // if we are not runnig do not do this
2002 OMX_ERRORTYPE error;
2004 /* OMX_PARAM_PORTDEFINITIONTYPE port_image;
2005 memset(&port_image,0,sizeof(port_image));
2006 port_image.nSize=sizeof(port_image);
2007 port_image.nVersion.nVersion=OMX_VERSION;
2008 port_image.nPortIndex =omx_codec_output_port;
2009 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_image);
2010 if (error!= OMX_ErrorNone){
2011 Log::getInstance()->log("Video", Log::DEBUG, "OMX_GetParameter failed %x", error);
2013 Log::getInstance()->log("Video", Log::DEBUG, "Image port %d %d", port_image.format.video.nFrameWidth , port_image.format.video.nFrameHeight);*/
2015 /*First Check, if we have an audio sample*/
2019 return 0; //Not in iframe mode!
2023 if (packet.disconti) {
2025 if (cur_input_buf_omx) {
2026 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2027 if (error!=OMX_ErrorNone){
2028 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2030 cur_input_buf_omx=NULL;
2034 /*Inspect PES-Header */
2036 // OMX_STATETYPE temp_state;
2037 // OMX_GetState(omx_vid_dec,&temp_state);
2039 if (*samplepos==0) {//stripheader
2040 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2041 *samplepos+=headerstrip;
2042 if ( packet.synched ) {
2044 if (cur_input_buf_omx) {
2045 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2046 if (error!=OMX_ErrorNone){
2047 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2050 cur_input_buf_omx=NULL;//write out old data
2052 // reftime1=packet.presentation_time;
2053 // reftime2=reftime1+1;
2056 if (!firstsynched) {//
2057 *samplepos=packet.length;//if we have not processed at least one
2058 return packet.length;//synched packet ignore it!
2063 if (!cur_input_buf_omx) {
2064 input_bufs_omx_mutex.Lock();
2065 if (input_bufs_omx_free.size()==0) {
2066 input_bufs_omx_mutex.Unlock();
2067 Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2068 return 0; // we do not have a free media sample
2071 cur_input_buf_omx=input_bufs_omx_free.front();
2072 cur_input_buf_omx->nFilledLen=0;
2073 cur_input_buf_omx->nOffset=0;
2074 cur_input_buf_omx->nTimeStamp=0;
2075 input_bufs_omx_free.pop_front();
2076 input_bufs_omx_mutex.Unlock();
2082 if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2083 /*if (packet.disconti) {
2084 ms->SetDiscontinuity(TRUE);
2086 ms->SetDiscontinuity(FALSE);
2088 //if (packet.synched) {
2090 //lastreftimePTS=packet.pts;
2091 if (omx_first_frame) { // TODO time
2092 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2093 omx_first_frame=false;
2099 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2102 // ms->SetSyncPoint(TRUE);
2106 unsigned int haveToCopy=packet.length-*samplepos;
2108 while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
2109 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
2110 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
2111 haveToCopy-=cancopy;
2112 cur_input_buf_omx->nFilledLen+=cancopy;
2113 *samplepos+=cancopy;
2114 // push old buffer out
2116 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
2117 if (error!=OMX_ErrorNone){
2118 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
2121 input_bufs_omx_mutex.Lock();
2122 if (input_bufs_omx_free.size()==0) {
2123 input_bufs_omx_mutex.Unlock();
2124 //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
2125 return *samplepos; // we do not have a free media sample
2127 cur_input_buf_omx=input_bufs_omx_free.front();
2128 cur_input_buf_omx->nFilledLen=0;
2129 cur_input_buf_omx->nOffset=0;
2130 cur_input_buf_omx->nTimeStamp=0;
2131 input_bufs_omx_free.pop_front();
2132 input_bufs_omx_mutex.Unlock();
2134 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2137 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
2138 buffer+packet.pos_buffer+*samplepos,haveToCopy);
2139 cur_input_buf_omx->nFilledLen+=haveToCopy;
2143 *samplepos+=haveToCopy;
2152 #ifdef VPE_LIBAV_SUPPORT
2153 int VideoVPEOGL::DecodePacketlibav()
2155 unsigned int haveToCopy=incom_packet_libav.size;
2156 if (incom_packet_libav.size==0) return 1; // we are already empty
2157 while (haveToCopy>0) {
2161 // Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
2163 #ifdef BENCHMARK_FPS
2164 int cur_time=getTimeMS();
2166 dec_bytes=avcodec_decode_video2(mpeg2codec_context_libav, dec_frame_libav_decoding,
2167 &frame_ready, &incom_packet_libav);
2168 #ifdef BENCHMARK_FPS
2169 time_in_decoder+=getTimeMS()-cur_time;
2170 if (frame_ready) num_frames++;
2171 if ((num_frames%100)==0) {
2172 float fps=1000./(float)(time_in_decoder);
2173 fps*=((float)num_frames);
2174 Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
2178 Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
2181 haveToCopy-=dec_bytes;
2183 // Log::getInstance()->log("Video", Log::DEBUG, "We have a frame push it to osd");
2185 lockFrameBufUpload((VPE_FrameBuf*)dec_frame_libav_decoding->base[0]); //lock for upload, so that ffmpeg does not reuse
2186 dec_frame_libav_mutex.Lock();
2187 libavwidth=mpeg2codec_context_libav->width;
2188 libavheight=mpeg2codec_context_libav->height;
2189 libavpixfmt=mpeg2codec_context_libav->pix_fmt;
2190 // Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",libavwidth,libavheight,libavpixfmt);
2193 dec_frame_libav_upload_pending.push_back(dec_frame_libav_decoding);
2194 dec_frame_libav_decoding=NULL;
2195 if (dec_frame_libav_free.size()>0) {
2196 dec_frame_libav_decoding=dec_frame_libav_free.front();
2197 dec_frame_libav_free.pop_front();
2198 dec_frame_libav_mutex.Unlock();
2200 libav_hastime=false;
2202 libav_hastime=false;
2203 dec_frame_libav_mutex.Unlock();
2212 incom_packet_libav.size=0;
2218 UINT VideoVPEOGL::DeliverMediaPacketlibav(MediaPacket packet,
2219 const UCHAR* buffer,
2222 //Later add fail back code for libav
2224 *samplepos+=packet.length;
2225 return packet.length;
2228 if (!libav_running) return 0; // if we are not runnig do not do this
2234 return 0; //Not in iframe mode!
2238 if (packet.disconti) {
2240 if (!DecodePacketlibav()) return 0;
2243 /*Inspect PES-Header */
2244 if (!dec_frame_libav_decoding) {
2245 dec_frame_libav_mutex.Lock();
2246 if (dec_frame_libav_free.size()>0) {
2247 dec_frame_libav_decoding=dec_frame_libav_free.front();
2248 dec_frame_libav_free.pop_front();
2249 dec_frame_libav_mutex.Unlock();
2251 Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers");
2252 dec_frame_libav_mutex.Unlock();
2260 if (*samplepos==0) {//stripheader
2261 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
2262 *samplepos+=headerstrip;
2263 if ( packet.synched ) {
2265 if (!DecodePacketlibav()) return 0; // WriteOut old Data
2267 libav_time=packet.presentation_time;
2269 // reftime1=packet.presentation_time;
2270 // reftime2=reftime1+1;
2273 if (!firstsynched) {//
2274 *samplepos=packet.length;//if we have not processed at least one
2275 return packet.length;//synched packet ignore it!
2285 /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
2286 /*if (packet.disconti) {
2287 ms->SetDiscontinuity(TRUE);
2289 ms->SetDiscontinuity(FALSE);
2291 //if (packet.synched) {
2293 //lastreftimePTS=packet.pts;
2294 if (omx_first_frame) { // TODO time
2295 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
2296 omx_first_frame=false;
2302 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
2305 // ms->SetSyncPoint(TRUE);
2309 unsigned int haveToCopy=packet.length-*samplepos;
2311 if ((incom_packet_libav_size-incom_packet_libav.size)< haveToCopy) {
2312 // if the buffer is to small reallocate
2313 incom_packet_libav_size+=haveToCopy;
2314 incom_packet_libav.data=(uint8_t*)av_realloc(incom_packet_libav.data,incom_packet_libav_size+FF_INPUT_BUFFER_PADDING_SIZE);
2315 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_libav_size);
2317 memcpy(incom_packet_libav.data+incom_packet_libav.size,buffer+packet.pos_buffer+*samplepos,haveToCopy);
2318 incom_packet_libav.size+=haveToCopy;
2320 *samplepos+=haveToCopy;
2335 void VideoVPEOGL::ResetTimeOffsets()
2339 bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length)
2341 //write(fdVideo, buffer, length);
2342 if (!iframemode) EnterIframePlayback();
2343 // WriteOutTS(buffer,length, h264?MPTYPE_VIDEO_H264 :MPTYPE_VIDEO_MPEG2 );
2349 int VideoVPEOGL::EnterIframePlayback()