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_FFMPEG_SUPPORT
45 mpeg2codec_context_ff=NULL;
47 dec_frame_ff_uploading=NULL;
48 dec_frame_ff_decoding=NULL;
53 VideoVPEOGL::~VideoVPEOGL()
58 int VideoVPEOGL::init(UCHAR tformat)
60 if (initted) return 0;
63 // if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
65 if (!setFormat(tformat)) { shutdown(); return 0; }
66 if (!setConnection(COMPOSITERGB)) { shutdown(); return 0; }
67 if (!setAspectRatio(ASPECT4X3)) { shutdown(); return 0; }
68 if (!setMode(NORMAL)) { shutdown(); return 0; }
69 if (!setSource()) { shutdown(); return 0; }
70 if (!attachFrameBuffer()) { shutdown(); return 0; }
74 /* if (format == PAL) setLetterboxBorder("38");
75 else setLetterboxBorder("31");*/
89 int VideoVPEOGL::initUsingOSDObjects()
91 EGLDisplay i_egl_display;
92 EGLSurface i_egl_surface;
93 EGLContext i_egl_context;
94 EGLConfig i_egl_config;
95 OsdOpenGL *osd=(OsdOpenGL*)osd->getInstance();
96 osd->getEGLObjs(&i_egl_display,&i_egl_surface,&i_egl_context, &i_egl_config);
97 const EGLint attr_context[]={
98 EGL_CONTEXT_CLIENT_VERSION,2,
102 egl_display=i_egl_display;
103 egl_context=eglCreateContext(egl_display,i_egl_config,i_egl_context,attr_context);
104 if (egl_context==EGL_NO_CONTEXT) {
105 Log::getInstance()->log("Video", Log::WARN, "Creating egl context failed! %d",eglGetError());
108 // We create a dummy surface here, in order to allow two contexts
109 const EGLint attr_pbuffer[]={
110 EGL_WIDTH, 1, EGL_HEIGHT,1,
113 egl_surface=eglCreatePbufferSurface(egl_display,i_egl_config,attr_pbuffer);
114 if (egl_surface==EGL_NO_SURFACE) {
115 Log::getInstance()->log("Video", Log::WARN, "Creating egl pbuffer failed! %d",eglGetError());
122 //egl_surface=i_egl_surface;
123 //egl_context=i_egl_context;
126 #ifdef VPE_OMX_SUPPORT
127 // we are called before the audio
130 if (error!=OMX_ErrorNone) {
131 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error);
135 //our callbacks move to play?
139 #ifdef VPE_FFMPEG_SUPPORT
142 mpeg2codec_ff=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
143 //mpeg2codec_ff=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_XVMC);
144 if (mpeg2codec_ff==NULL) {
145 Log::getInstance()->log("Video", Log::DEBUG, "Find ffmpeg mpeg2 codec failed");
155 #ifdef VPE_OMX_SUPPORT
157 OMX_ERRORTYPE VideoVPEOGL::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
158 OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
159 OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
161 Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
163 struct VPE_OMX_EVENT new_event;
164 new_event.handle=handle;
165 new_event.appdata=appdata;
166 new_event.event_type=event_type;
167 new_event.data1=data1;
168 new_event.data2=data2;
169 new_event.event_data=event_data;
171 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
172 video->AddOmxEvent(new_event);
174 /* switch (event_type) {
175 case OMX_EventCmdComplete: {
180 return OMX_ErrorNone;
184 void VideoVPEOGL::AddOmxEvent(VPE_OMX_EVENT new_event)
186 omx_event_mutex.Lock();
187 omx_events.push_back(new_event);
188 omx_event_mutex.Unlock();
192 OMX_ERRORTYPE VideoVPEOGL::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
194 Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
195 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
196 video->ReturnEmptyOMXBuffer(buffer);
197 return OMX_ErrorNone;
201 void VideoVPEOGL::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
202 input_bufs_omx_mutex.Lock();
203 Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
204 input_bufs_omx_free.push_back(buffer);
205 Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
206 input_bufs_omx_mutex.Unlock();
209 OMX_ERRORTYPE VideoVPEOGL::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
210 Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
211 return OMX_ErrorNone;
216 int VideoVPEOGL::shutdown()
218 if (!initted) return 0;
223 #ifdef VPE_OMX_SUPPORT
224 DeAllocateCodecsOMX();
227 #ifdef VPE_FFMPEG_SUPPORT
228 DeAllocateCodecsFFMPEG();
230 eglDestroyContext(egl_display,egl_context);
235 int VideoVPEOGL::AllocateYUVOglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
237 Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture");
239 glGenTextures(1, &outframe->textures[0]);
240 glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
241 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride, height, 0, GL_LUMINANCE,
242 GL_UNSIGNED_BYTE, NULL);
244 glGenTextures(1, &outframe->textures[1]);
245 glBindTexture(GL_TEXTURE_2D, outframe->textures[1]);
246 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
247 GL_UNSIGNED_BYTE, NULL);
249 glGenTextures(1, &outframe->textures[2]);
250 glBindTexture(GL_TEXTURE_2D, outframe->textures[2]);
251 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
252 GL_UNSIGNED_BYTE, NULL);
253 outframe->height=height;
254 outframe->width=width;
255 outframe->stride=stride;
260 VPEOGLFrame *VideoVPEOGL::getReadyOGLFrame(){
261 VPEOGLFrame *return_obj=NULL;
262 ogl_frame_mutex.Lock();
263 if (ready_ogl_frames.size()>0) {
264 return_obj=ready_ogl_frames.front();
265 ready_ogl_frames.pop_front();
266 ogl_frame_outside=true;
268 ogl_frame_mutex.Unlock();
272 void VideoVPEOGL::returnOGLFrame(VPEOGLFrame *frame)
274 ogl_frame_mutex.Lock();
276 ogl_frame_outside=false;
277 free_ogl_frames.push_back(frame);
279 ogl_frame_mutex.Unlock();
282 void VideoVPEOGL::threadMethod()
284 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
285 Log::getInstance()->log("Video", Log::WARN, "Making egl Current failed in thread %d",eglGetError());
290 #ifdef VPE_FFMPEG_SUPPORT
291 dec_frame_ff_mutex.Lock();
292 if (dec_frame_ff_upload_pending.size()>0) {
293 dec_frame_ff_uploading=dec_frame_ff_upload_pending.front();
294 dec_frame_ff_upload_pending.pop_front();
295 if (dec_frame_ff_upload_pending.size()>0) sleep=false;
297 dec_frame_ff_mutex.Unlock();
298 if (dec_frame_ff_uploading) {
299 int width,height,pixfmt;
300 //First get a free ogl image
301 VPEOGLFrame* out_frame=NULL;
303 ogl_frame_mutex.Lock();
304 if (all_ogl_frames.size()==0) {
305 ogl_frame_mutex.Unlock(); break;
308 if (free_ogl_frames.size()>0) {
312 out_frame=free_ogl_frames.front();
313 free_ogl_frames.pop_front();
314 } else MILLISLEEP(2);
315 ogl_frame_mutex.Unlock();
319 if (out_frame->textures[0]==0 || out_frame->width!=width ||
320 out_frame->height!=height || out_frame->stride!=dec_frame_ff_uploading->linesize[0]) {
321 if (out_frame->textures[0]==0) {
322 glDeleteTextures(1,&out_frame->textures[0]);
323 out_frame->textures[0]=0;
325 if (out_frame->textures[1]==0) {
326 glDeleteTextures(1,&out_frame->textures[1]);
327 out_frame->textures[1]=0;
329 if (out_frame->textures[2]==0) {
330 glDeleteTextures(1,&out_frame->textures[2]);
331 out_frame->textures[2]=0;
333 if (!AllocateYUVOglTexture(out_frame,width,height,dec_frame_ff_uploading->linesize[0])) failed=true;
336 //up to now only YUV data, this is for reference only, since the pi is too slow.
337 glBindTexture(GL_TEXTURE_2D, out_frame->textures[0]);
338 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
340 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
341 dec_frame_ff_uploading->linesize[0],height,
342 GL_LUMINANCE,GL_UNSIGNED_BYTE,
343 dec_frame_ff_uploading->data[0]);
346 glBindTexture(GL_TEXTURE_2D, out_frame->textures[1]);
347 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
348 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
349 dec_frame_ff_uploading->linesize[1],height>>1,
350 GL_LUMINANCE,GL_UNSIGNED_BYTE,
351 dec_frame_ff_uploading->data[1]);
353 glBindTexture(GL_TEXTURE_2D, out_frame->textures[2]);
354 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
355 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
356 dec_frame_ff_uploading->linesize[2],height>>1,
357 GL_LUMINANCE,GL_UNSIGNED_BYTE,
358 dec_frame_ff_uploading->data[2]);
359 ogl_frame_mutex.Lock();
360 ready_ogl_frames.push_back(out_frame);
361 ogl_frame_mutex.Unlock();
362 ((OsdOpenGL*)Osd::getInstance())->AdviseAboutNewFrame(); //Tell him, that we have a frame waiting
366 dec_frame_ff_mutex.Lock();
367 dec_frame_ff_free.push_back(dec_frame_ff_uploading);
368 dec_frame_ff_uploading=NULL;
369 dec_frame_ff_mutex.Unlock();
382 if (sleep) threadWaitForSignal();
388 void VideoVPEOGL::threadPostStopCleanup()
390 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
391 #ifdef VPE_FFMPEG_SUPPORT
392 dec_frame_ff_uploading=NULL;
399 int VideoVPEOGL::setTVsize(UCHAR ttvsize)
403 // Override the aspect ratio usage, temporarily use to set the video chip mode
404 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
406 if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
407 if (!setSource()) { shutdown(); return 0; }
408 if (!attachFrameBuffer()) { shutdown(); return 0; }
410 // Reopening the fd causes the scart aspect line to go back to 4:3
411 // Set this again to the same as the tv screen size
412 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
414 // mode == LETTERBOX is invalid if the TV is widescreen
415 if (tvsize == ASPECT16X9) setMode(NORMAL);
420 int VideoVPEOGL::setDefaultAspect()
422 return setAspectRatio(tvsize);
427 int VideoVPEOGL::setFormat(UCHAR tformat)
429 if (!initted) return 0;
430 if ((tformat != PAL) && (tformat != NTSC)) return 0;
433 // if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
449 int VideoVPEOGL::setConnection(UCHAR tconnection)
451 if (!initted) return 0;
452 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
453 connection = tconnection;
455 // if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
459 int VideoVPEOGL::setAspectRatio(UCHAR taspectRatio)
461 if (!initted) return 0;
462 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
463 aspectRatio = taspectRatio;
465 Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
467 // if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
471 int VideoVPEOGL::setMode(UCHAR tmode)
473 if (!initted) return 0;
475 if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
477 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
478 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
481 // if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
485 int VideoVPEOGL::signalOff()
487 // if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
491 int VideoVPEOGL::signalOn()
493 // if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
497 int VideoVPEOGL::setSource()
499 if (!initted) return 0;
501 // What does this do...
502 // if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
506 int VideoVPEOGL::setPosition(int x, int y)
508 if (!initted) return 0;
510 // vid_pos_regs_t pos_d;
514 /* vid_pos_regs_t pos_d;
516 memset(&pos_d, 0, sizeof(pos_d));
541 pos_d.y = 100; // Top left X
542 pos_d.x = 50; // Top left Y
550 // if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
554 int VideoVPEOGL::sync()
556 if (!initted) return 0;
558 // if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
565 int VideoVPEOGL::play()
567 if (!initted) return 0;
569 #ifdef VPE_OMX_SUPPORT
572 if (!omx_h264) doomx=false;
574 if (!omx_mpeg2) doomx=false;
577 if (AllocateCodecsOMX()) {
578 decoding_backend=VPE_DECODER_OMX;
580 // Otherwise fall back to ffmpeg
584 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume h264 unsupported");
587 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume mpeg2 unsupported");
592 #ifdef VPE_FFMPEG_SUPPORT
593 if (AllocateCodecsFFMPEG()) {
594 decoding_backend=VPE_DECODER_FFMPEG;
596 // Otherwise fall back to ffmpeg
605 #ifdef VPE_OMX_SUPPORT
606 int VideoVPEOGL::AllocateCodecsOMX()
609 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
611 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
612 //Clock, move later to audio
616 error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
619 if (error!=OMX_ErrorNone){
620 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
621 DeAllocateCodecsOMX();
627 OMX_PORT_PARAM_TYPE p_param;
628 memset(&p_param,0,sizeof(p_param));
629 p_param.nSize=sizeof(p_param);
630 p_param.nVersion.nVersion=OMX_VERSION;
631 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
632 if (error!=OMX_ErrorNone){
633 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
634 DeAllocateCodecsOMX();
637 omx_clock_output_port=p_param.nStartPortNumber;
639 for (unsigned int i=0;i<p_param.nPorts;i++) {
640 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i) ) {
641 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
642 DeAllocateCodecsOMX();
648 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
649 memset(&clock_conf,0,sizeof(clock_conf));
650 clock_conf.nSize=sizeof(clock_conf);
651 clock_conf.nVersion.nVersion=OMX_VERSION;
652 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
653 clock_conf.nStartTime=0;
654 clock_conf.nOffset=0;
655 clock_conf.nWaitMask=OMX_CLOCKPORT0;
656 error=OMX_SetParameter(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
657 if (error!=OMX_ErrorNone){
658 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
659 DeAllocateCodecsOMX();
666 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
668 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
671 if (error!=OMX_ErrorNone){
672 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
673 DeAllocateCodecsOMX();
679 memset(&p_param,0,sizeof(p_param));
680 p_param.nSize=sizeof(p_param);
681 p_param.nVersion.nVersion=OMX_VERSION;
682 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
683 if (error!=OMX_ErrorNone){
684 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
685 DeAllocateCodecsOMX();
688 omx_codec_input_port=p_param.nStartPortNumber;
689 omx_codec_output_port=p_param.nStartPortNumber+1;
691 if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
692 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
693 DeAllocateCodecsOMX();
698 OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
699 memset(&conceal,0,sizeof(conceal));
700 conceal.nSize=sizeof(conceal);
701 conceal.nVersion.nVersion=OMX_VERSION;
702 conceal.bStartWithValidFrame=OMX_FALSE;
704 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
705 if (error!=OMX_ErrorNone){
706 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
707 DeAllocateCodecsOMX();
712 error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
713 if (error!=OMX_ErrorNone){
714 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
715 DeAllocateCodecsOMX();
721 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
722 if (error!=OMX_ErrorNone){
723 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
724 DeAllocateCodecsOMX();
727 omx_shed_input_port=p_param.nStartPortNumber;
728 omx_shed_output_port=p_param.nStartPortNumber+1;
731 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
732 if (error!=OMX_ErrorNone){
733 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
734 DeAllocateCodecsOMX();
737 omx_shed_clock_port=p_param.nStartPortNumber;
740 if (!DisablePort(omx_vid_sched,omx_shed_input_port) || !DisablePort(omx_vid_sched,omx_shed_output_port)
741 || !DisablePort(omx_vid_sched,omx_shed_clock_port)) {
742 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
743 DeAllocateCodecsOMX();
748 error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
749 if (error!=OMX_ErrorNone){
750 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
751 DeAllocateCodecsOMX();
755 error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
756 if (error!=OMX_ErrorNone){
757 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
758 DeAllocateCodecsOMX();
761 omx_rend_input_port=p_param.nStartPortNumber;
762 //omx_rend_output_port=p_param.nStartPortNumber+1;
765 if (!DisablePort(omx_vid_rend,omx_rend_input_port) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
767 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
768 DeAllocateCodecsOMX();
781 /* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
782 if (error!=OMX_ErrorNone){
783 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
790 OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
791 memset(&ft_type,0,sizeof(ft_type));
792 ft_type.nSize=sizeof(ft_type);
793 ft_type.nVersion.nVersion=OMX_VERSION;
795 ft_type.nPortIndex=omx_codec_input_port;
797 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
799 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
802 Demuxer* demux=Demuxer::getInstance();
804 ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
805 Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
806 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
807 if (error!=OMX_ErrorNone){
808 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
809 DeAllocateCodecsOMX();
814 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
815 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
816 DeAllocateCodecsOMX();
821 if (!PrepareInputBufsOMX()) {
822 DeAllocateCodecsOMX();
827 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
828 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle");
829 DeAllocateCodecsOMX();
833 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
834 if (error!=OMX_ErrorNone){
835 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);
836 DeAllocateCodecsOMX();
840 if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
842 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
843 DeAllocateCodecsOMX();
847 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
848 DeAllocateCodecsOMX();
852 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
853 if (error!=OMX_ErrorNone){
854 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
855 DeAllocateCodecsOMX();
861 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
863 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
864 DeAllocateCodecsOMX();
868 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
871 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
872 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
873 DeAllocateCodecsOMX();
876 if (!CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)
877 ||!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port)){
878 DeAllocateCodecsOMX();
882 if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
883 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
884 DeAllocateCodecsOMX();
888 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
889 if (error!=OMX_ErrorNone){
890 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel sched to rend failed %x", error);
891 DeAllocateCodecsOMX();
895 if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
897 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX shed rend failed");
898 DeAllocateCodecsOMX();
902 if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
903 || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
904 DeAllocateCodecsOMX();
908 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
909 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
910 DeAllocateCodecsOMX();
915 if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
916 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
917 DeAllocateCodecsOMX();
921 if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
922 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
923 DeAllocateCodecsOMX();
928 OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
929 memset(&dispconf,0,sizeof(dispconf));
930 dispconf.nSize=sizeof(dispconf);
931 dispconf.nVersion.nVersion=OMX_VERSION;
933 dispconf.nPortIndex=omx_rend_input_port;
935 dispconf.set=OMX_DISPLAY_SET_LAYER ;
937 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
938 if (error!=OMX_ErrorNone){
939 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
940 DeAllocateCodecsOMX();
944 /* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
945 dispconf.fullscreen=OMX_FALSE;
946 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
947 if (error!=OMX_ErrorNone){
948 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
949 DeAllocateCodecsOMX();
953 dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
954 dispconf.dest_rect.x_offset=100;
955 dispconf.dest_rect.y_offset=100;
956 dispconf.dest_rect.width=640;
957 dispconf.dest_rect.height=480;
958 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
959 if (error!=OMX_ErrorNone){
960 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
961 DeAllocateCodecsOMX();
968 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
969 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Exccute");
970 DeAllocateCodecsOMX();
980 int VideoVPEOGL::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type)
983 error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
984 if (error!=OMX_ErrorNone){
985 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
989 if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
997 int VideoVPEOGL::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1000 error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1001 if (error!=OMX_ErrorNone){
1002 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1006 if (!wait) return 1;
1007 if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1015 int VideoVPEOGL::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1017 OMX_ERRORTYPE error;
1018 error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1019 if (error!=OMX_ErrorNone){
1020 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1024 if (!wait) return 1;
1025 if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1036 int VideoVPEOGL::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2)
1040 omx_event_mutex.Lock();
1041 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1042 while (itty!=omx_events.end()) {
1044 VPE_OMX_EVENT current=*itty;
1045 if (current.handle==handle) { //this is ours
1046 if (current.event_type==OMX_EventError) {
1047 omx_events.erase(itty);
1048 omx_event_mutex.Unlock();
1051 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1052 omx_events.erase(itty);
1053 omx_event_mutex.Unlock();
1060 omx_event_mutex.Unlock();
1065 Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1074 int VideoVPEOGL::PrepareInputBufsOMX()
1076 OMX_ERRORTYPE error;
1077 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1078 memset(&port_def_type,0,sizeof(port_def_type));
1079 port_def_type.nSize=sizeof(port_def_type);
1080 port_def_type.nVersion.nVersion=OMX_VERSION;
1081 port_def_type.nPortIndex=omx_codec_input_port;
1083 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1085 if (error!=OMX_ErrorNone){
1086 Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1088 /* Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1089 port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1090 port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1092 port_def_type.nBufferCountActual=60;
1094 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1096 if (error!=OMX_ErrorNone){
1097 Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1101 error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1102 if (error!=OMX_ErrorNone){
1103 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1107 input_bufs_omx_mutex.Lock();
1108 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1110 // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nBufferSize);
1111 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1112 /* error=OMX_UseBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize,new_buffer_data);
1113 if (error!=OMX_ErrorNone){
1114 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_UseBuffer failed %x", error);
1115 input_bufs_omx_mutex.Unlock();
1118 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1119 if (error!=OMX_ErrorNone){
1120 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1121 input_bufs_omx_mutex.Unlock();
1124 input_bufs_omx_all.push_back(buf_head);
1125 input_bufs_omx_free.push_back(buf_head);
1127 omx_first_frame=true;
1130 cur_input_buf_omx=NULL;
1131 input_bufs_omx_mutex.Unlock();
1134 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1135 if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1138 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1143 int VideoVPEOGL::DestroyInputBufsOMX()
1145 OMX_ERRORTYPE error;
1147 cur_input_buf_omx=NULL;
1148 input_bufs_omx_mutex.Lock();
1149 for (int i=0; i< input_bufs_omx_all.size();i++) {
1150 // free(input_bufs_omx_all[i]->pBuffer);
1151 // input_bufs_omx_all[i]->pBuffer=NULL;
1152 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1153 if (error!=OMX_ErrorNone){
1154 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1155 input_bufs_omx_mutex.Unlock();
1159 input_bufs_omx_all.clear();
1160 input_bufs_omx_free.clear();
1161 input_bufs_omx_mutex.Unlock();
1168 int VideoVPEOGL::DeAllocateCodecsOMX()
1170 OMX_ERRORTYPE error;
1173 // first flush all buffers
1175 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_output_port, NULL);
1176 if (error!=OMX_ErrorNone){
1177 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1181 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_input_port, NULL);
1182 if (error!=OMX_ErrorNone){
1183 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed in failed %x", error);
1187 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_output_port) ||
1188 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_input_port)) {
1189 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec shed failed");
1192 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1193 if (error!=OMX_ErrorNone){
1194 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1198 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
1199 if (error!=OMX_ErrorNone){
1200 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
1204 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1205 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
1206 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
1209 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_output_port, NULL);
1210 if (error!=OMX_ErrorNone) {
1211 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed out failed %x", error);
1215 error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1216 if (error!=OMX_ErrorNone) {
1217 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1221 if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ||
1222 !CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
1223 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
1229 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1230 if (error!=OMX_ErrorNone){
1231 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1236 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_input_port)) {
1237 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec input failed");
1240 DestroyInputBufsOMX();
1243 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
1244 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
1246 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
1247 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
1250 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
1251 if (error!=OMX_ErrorNone){
1252 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1256 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
1257 if (error!=OMX_ErrorNone){
1258 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1262 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
1263 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
1266 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1267 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
1270 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
1271 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
1273 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
1274 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
1279 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
1280 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
1284 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
1285 if (error!=OMX_ErrorNone){
1286 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1289 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL);
1290 if (error!=OMX_ErrorNone){
1291 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1295 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL);
1296 if (error!=OMX_ErrorNone){
1297 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1301 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
1302 if (error!=OMX_ErrorNone){
1303 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1311 error=OMX_FreeHandle(omx_vid_dec);
1312 error=OMX_FreeHandle(omx_vid_sched);
1313 error=OMX_FreeHandle(omx_vid_rend);
1314 error=OMX_FreeHandle(omx_clock);
1316 if (error!=OMX_ErrorNone) {
1317 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1327 #ifdef VPE_FFMPEG_SUPPORT
1329 int VideoVPEOGL::AllocateCodecsFFMPEG()
1331 ffmpeg_hastime=false;
1332 Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecsFFmpeg");
1333 mpeg2codec_context_ff=avcodec_alloc_context();
1334 if (mpeg2codec_context_ff==NULL) {
1335 Log::getInstance()->log("Video", Log::DEBUG, "Creating ffmpeg codec context failed");
1338 if(avcodec_open(mpeg2codec_context_ff, mpeg2codec_ff)<0) {
1339 Log::getInstance()->log("Video", Log::DEBUG, "Opening ffmpeg codec failed");
1342 Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecsFFmpeg mark1");
1343 dec_frame_ff_mutex.Lock();
1344 Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecsFFmpeg mark2");
1345 for (int i=0;i<3;i++) {
1346 AVFrame *dec_frame_ff=avcodec_alloc_frame(); // may be we need multiple frames, if we want to use async texture upload
1347 if (!dec_frame_ff) {
1348 Log::getInstance()->log("Video", Log::DEBUG, "Allocating dec_frame failed");
1351 dec_frame_ff_all.push_back(dec_frame_ff);
1352 dec_frame_ff_free.push_back(dec_frame_ff);
1354 dec_frame_ff_decoding=NULL;
1355 Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecsFFmpeg mark 3");
1356 dec_frame_ff_mutex.Unlock();
1358 ogl_frame_mutex.Lock();
1359 //Allocate texture structs, since we do not know the sizes, we do not allocate the textures yet
1360 for (int i=0;i<3;i++) {
1361 VPEOGLFrame *new_frame=(VPEOGLFrame *)malloc(sizeof(VPEOGLFrame));
1362 new_frame->type=1; //1 = YUV, 2 RGB
1363 new_frame->textures[0]=0;
1364 new_frame->textures[1]=0;
1365 new_frame->textures[2]=0;
1366 new_frame->width=new_frame->height=0;
1367 all_ogl_frames.push_back(new_frame);
1368 free_ogl_frames.push_back(new_frame);
1371 ogl_frame_outside=false;
1373 ogl_frame_mutex.Unlock();
1375 ffmpeg_running=true;
1381 int VideoVPEOGL::DeAllocateCodecsFFMPEG()
1383 ffmpeg_running=false;
1384 Log::getInstance()->log("Video", Log::NOTICE, "DeAllocateCodecsFFmpeg");
1385 dec_frame_ff_mutex.Lock();
1386 dec_frame_ff_upload_pending.clear();
1387 dec_frame_ff_free.clear();
1388 dec_frame_ff_mutex.Unlock();
1389 while (dec_frame_ff_uploading) {
1390 Log::getInstance()->log("Video", Log::NOTICE, "Wait for uploading to finish");
1393 dec_frame_ff_mutex.Lock();
1394 for (int i=0; i< dec_frame_ff_all.size();i++) {
1395 av_free(dec_frame_ff_all[i]);
1398 dec_frame_ff_all.clear();
1399 dec_frame_ff_mutex.Unlock();
1400 dec_frame_ff_decoding=NULL;
1402 while (ogl_frame_outside) {
1403 Log::getInstance()->log("Video", Log::NOTICE, "Wait for ogl frame from outside");
1407 ((OsdOpenGL*)Osd::getInstance())->BeginPainting(); // get osd's context
1408 ogl_frame_mutex.Lock();
1409 for (int i=0; i< dec_frame_ff_all.size();i++) {
1410 VPEOGLFrame * del_frame=all_ogl_frames[i];
1411 if (del_frame->textures[0]==0) {
1412 glDeleteTextures(1,&del_frame->textures[0]);
1413 del_frame->textures[0]=0;
1415 if (del_frame->textures[1]==0) {
1416 glDeleteTextures(1,&del_frame->textures[1]);
1417 del_frame->textures[1]=0;
1419 if (del_frame->textures[2]==0) {
1420 glDeleteTextures(1,&del_frame->textures[2]);
1421 del_frame->textures[2]=0;
1423 free(all_ogl_frames[i]);
1425 all_ogl_frames.clear();
1426 free_ogl_frames.clear();
1427 ready_ogl_frames.clear();
1428 ogl_frame_mutex.Unlock();
1429 ((OsdOpenGL*)Osd::getInstance())->EndPainting();
1432 if (mpeg2codec_context_ff) {
1433 avcodec_close(mpeg2codec_context_ff);
1434 av_free(mpeg2codec_context_ff);
1435 mpeg2codec_context_ff=NULL;
1450 int VideoVPEOGL::stop()
1452 if (!initted) return 0;
1454 #ifdef VPE_OMX_SUPPORT
1455 //Check if ffmpeg mode
1456 if (decoding_backend==VPE_DECODER_OMX) DeAllocateCodecsOMX();
1463 // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
1467 int VideoVPEOGL::reset()
1469 if (!initted) return 0;
1471 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
1475 int VideoVPEOGL::pause()
1477 if (!initted) return 0;
1479 // if (ioctl(fdVideo, AV_SET_VID_PAUSE, 0) != 0) return 0;
1483 int VideoVPEOGL::unPause() // FIXME get rid - same as play!!
1485 if (!initted) return 0;
1486 // if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
1490 int VideoVPEOGL::fastForward()
1492 if (!initted) return 0;
1494 // if (ioctl(fdVideo, AV_SET_VID_FFWD, 1) != 0) return 0;
1498 int VideoVPEOGL::unFastForward()
1500 if (!initted) return 0;
1502 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
1504 //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
1508 int VideoVPEOGL::attachFrameBuffer()
1510 if (!initted) return 0;
1512 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
1516 int VideoVPEOGL::blank(void)
1518 // if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
1519 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
1523 ULLONG VideoVPEOGL::getCurrentTimestamp()
1525 /* sync_data_t timestamps;
1526 if (ioctl(fdVideo, AV_GET_VID_TIMESTAMPS, ×tamps) == 0)
1528 // FIXME are these the right way around?
1530 timestamps.stc = (timestamps.stc >> 31 ) | (timestamps.stc & 1);
1531 timestamps.pts = (timestamps.pts >> 31 ) | (timestamps.pts & 1);
1533 return timestamps.stc;
1542 ULONG VideoVPEOGL::timecodeToFrameNumber(ULLONG timecode)
1544 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
1545 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
1549 int VideoVPEOGL::test()
1554 // return ioctl(fdVideo, AV_SET_VID_STC, &stc);
1561 int VideoVPEOGL::test2()
1567 void VideoVPEOGL::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1569 mediapacket = mplist.front();
1572 UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
1574 DeliverMediaPacket(mediapacket, buffer, samplepos);
1575 if (*samplepos == mediapacket.length) {
1582 UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
1583 const UCHAR* buffer,
1586 if (packet.type == MPTYPE_VIDEO_H264)
1594 switch (decoding_backend) {
1595 default: case 0: return 0; // no backend runnigng
1596 #ifdef VPE_OMX_SUPPORT
1597 case VPE_DECODER_OMX: return DeliverMediaPacketOMX(packet,buffer,samplepos);
1599 #ifdef VPE_FFMPEG_SUPPORT
1600 case VPE_DECODER_FFMPEG: return DeliverMediaPacketFFMPEG(packet,buffer,samplepos);
1605 #ifdef VPE_OMX_SUPPORT
1606 UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
1607 const UCHAR* buffer,
1612 //Later add fail back code for ffmpeg
1614 *samplepos+=packet.length;
1615 return packet.length;
1619 if (!omx_running) return 0; // if we are not runnig do not do this
1622 OMX_ERRORTYPE error;
1624 /* OMX_PARAM_PORTDEFINITIONTYPE port_image;
1625 memset(&port_image,0,sizeof(port_image));
1626 port_image.nSize=sizeof(port_image);
1627 port_image.nVersion.nVersion=OMX_VERSION;
1628 port_image.nPortIndex =omx_codec_output_port;
1629 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_image);
1630 if (error!= OMX_ErrorNone){
1631 Log::getInstance()->log("Video", Log::DEBUG, "OMX_GetParameter failed %x", error);
1633 Log::getInstance()->log("Video", Log::DEBUG, "Image port %d %d", port_image.format.video.nFrameWidth , port_image.format.video.nFrameHeight);*/
1635 /*First Check, if we have an audio sample*/
1639 return 0; //Not in iframe mode!
1643 if (packet.disconti) {
1645 if (cur_input_buf_omx) {
1646 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1647 if (error!=OMX_ErrorNone){
1648 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1650 cur_input_buf_omx=NULL;
1654 /*Inspect PES-Header */
1656 // OMX_STATETYPE temp_state;
1657 // OMX_GetState(omx_vid_dec,&temp_state);
1659 if (*samplepos==0) {//stripheader
1660 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
1661 *samplepos+=headerstrip;
1662 if ( packet.synched ) {
1664 if (cur_input_buf_omx) {
1665 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1666 if (error!=OMX_ErrorNone){
1667 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1670 cur_input_buf_omx=NULL;//write out old data
1672 // reftime1=packet.presentation_time;
1673 // reftime2=reftime1+1;
1676 if (!firstsynched) {//
1677 *samplepos=packet.length;//if we have not processed at least one
1678 return packet.length;//synched packet ignore it!
1683 if (!cur_input_buf_omx) {
1684 input_bufs_omx_mutex.Lock();
1685 if (input_bufs_omx_free.size()==0) {
1686 input_bufs_omx_mutex.Unlock();
1687 Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
1688 return 0; // we do not have a free media sample
1691 cur_input_buf_omx=input_bufs_omx_free.front();
1692 cur_input_buf_omx->nFilledLen=0;
1693 cur_input_buf_omx->nOffset=0;
1694 cur_input_buf_omx->nTimeStamp=0;
1695 input_bufs_omx_free.pop_front();
1696 input_bufs_omx_mutex.Unlock();
1702 if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
1703 /*if (packet.disconti) {
1704 ms->SetDiscontinuity(TRUE);
1706 ms->SetDiscontinuity(FALSE);
1708 //if (packet.synched) {
1710 //lastreftimePTS=packet.pts;
1711 if (omx_first_frame) { // TODO time
1712 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
1713 omx_first_frame=false;
1719 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1722 // ms->SetSyncPoint(TRUE);
1726 unsigned int haveToCopy=packet.length-*samplepos;
1728 while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
1729 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
1730 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
1731 haveToCopy-=cancopy;
1732 cur_input_buf_omx->nFilledLen+=cancopy;
1733 *samplepos+=cancopy;
1734 // push old buffer out
1736 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1737 if (error!=OMX_ErrorNone){
1738 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1741 input_bufs_omx_mutex.Lock();
1742 if (input_bufs_omx_free.size()==0) {
1743 input_bufs_omx_mutex.Unlock();
1744 //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
1745 return *samplepos; // we do not have a free media sample
1747 cur_input_buf_omx=input_bufs_omx_free.front();
1748 cur_input_buf_omx->nFilledLen=0;
1749 cur_input_buf_omx->nOffset=0;
1750 cur_input_buf_omx->nTimeStamp=0;
1751 input_bufs_omx_free.pop_front();
1752 input_bufs_omx_mutex.Unlock();
1754 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1757 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
1758 buffer+packet.pos_buffer+*samplepos,haveToCopy);
1759 cur_input_buf_omx->nFilledLen+=haveToCopy;
1763 *samplepos+=haveToCopy;
1772 #ifdef VPE_FFMPEG_SUPPORT
1773 UINT VideoVPEOGL::DeliverMediaPacketFFMPEG(MediaPacket packet,
1774 const UCHAR* buffer,
1777 //Later add fail back code for ffmpeg
1779 *samplepos+=packet.length;
1780 return packet.length;
1783 if (!ffmpeg_running) return 0; // if we are not runnig do not do this
1789 return 0; //Not in iframe mode!
1793 /* if (packet.disconti) {
1795 if (cur_input_buf_omx) {
1796 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1797 if (error!=OMX_ErrorNone){
1798 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1800 cur_input_buf_omx=NULL;
1804 /*Inspect PES-Header */
1805 if (!dec_frame_ff_decoding) {
1806 dec_frame_ff_mutex.Lock();
1807 if (dec_frame_ff_free.size()>0) {
1808 dec_frame_ff_decoding=dec_frame_ff_free.front();
1809 dec_frame_ff_free.pop_front();
1810 dec_frame_ff_mutex.Unlock();
1812 Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers");
1813 dec_frame_ff_mutex.Unlock();
1821 if (*samplepos==0) {//stripheader
1822 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
1823 *samplepos+=headerstrip;
1824 if ( packet.synched ) {
1826 /*if (cur_input_buf_omx) {
1827 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1828 if (error!=OMX_ErrorNone){
1829 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1832 cur_input_buf_omx=NULL;//write out old data
1834 ffmpeg_time=packet.presentation_time;
1835 ffmpeg_hastime=true;
1836 // reftime1=packet.presentation_time;
1837 // reftime2=reftime1+1;
1840 if (!firstsynched) {//
1841 *samplepos=packet.length;//if we have not processed at least one
1842 return packet.length;//synched packet ignore it!
1852 /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
1853 /*if (packet.disconti) {
1854 ms->SetDiscontinuity(TRUE);
1856 ms->SetDiscontinuity(FALSE);
1858 //if (packet.synched) {
1860 //lastreftimePTS=packet.pts;
1861 if (omx_first_frame) { // TODO time
1862 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
1863 omx_first_frame=false;
1869 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1872 // ms->SetSyncPoint(TRUE);
1876 unsigned int haveToCopy=packet.length-*samplepos;
1877 while (haveToCopy>0) {
1881 // Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
1882 dec_bytes=avcodec_decode_video(mpeg2codec_context_ff, dec_frame_ff_decoding,
1883 &frame_ready, buffer+packet.pos_buffer+*samplepos, haveToCopy);
1885 Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
1888 *samplepos+=dec_bytes;
1889 haveToCopy-=dec_bytes;
1891 // Log::getInstance()->log("Video", Log::DEBUG, "We have a frame push it to osd");
1893 dec_frame_ff_mutex.Lock();
1894 ffwidth=mpeg2codec_context_ff->width;
1895 ffheight=mpeg2codec_context_ff->height;
1896 ffpixfmt=mpeg2codec_context_ff->pix_fmt;
1897 // Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",ffwidth,ffheight,ffpixfmt);
1899 dec_frame_ff_upload_pending.push_back(dec_frame_ff_decoding);
1900 dec_frame_ff_decoding=NULL;
1901 if (dec_frame_ff_free.size()>0) {
1902 dec_frame_ff_decoding=dec_frame_ff_free.front();
1903 dec_frame_ff_free.pop_front();
1904 dec_frame_ff_mutex.Unlock();
1906 ffmpeg_hastime=false;
1908 ffmpeg_hastime=false;
1909 dec_frame_ff_mutex.Unlock();
1930 void VideoVPEOGL::ResetTimeOffsets()
1934 bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length)
1936 //write(fdVideo, buffer, length);
1937 if (!iframemode) EnterIframePlayback();
1938 // WriteOutTS(buffer,length, h264?MPTYPE_VIDEO_H264 :MPTYPE_VIDEO_MPEG2 );
1944 int VideoVPEOGL::EnterIframePlayback()