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;
49 ogl_frame_outside=false;
59 VideoVPEOGL::~VideoVPEOGL()
64 int VideoVPEOGL::init(UCHAR tformat)
66 if (initted) return 0;
69 // if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
71 if (!setFormat(tformat)) { shutdown(); return 0; }
72 if (!setConnection(COMPOSITERGB)) { shutdown(); return 0; }
73 if (!setAspectRatio(ASPECT4X3)) { shutdown(); return 0; }
74 if (!setMode(NORMAL)) { shutdown(); return 0; }
75 if (!setSource()) { shutdown(); return 0; }
76 if (!attachFrameBuffer()) { shutdown(); return 0; }
80 /* if (format == PAL) setLetterboxBorder("38");
81 else setLetterboxBorder("31");*/
95 int VideoVPEOGL::initUsingOSDObjects()
97 EGLDisplay i_egl_display;
98 EGLSurface i_egl_surface;
99 EGLContext i_egl_context;
100 EGLConfig i_egl_config;
101 OsdOpenGL *osd=(OsdOpenGL*)osd->getInstance();
102 osd->getEGLObjs(&i_egl_display,&i_egl_surface,&i_egl_context, &i_egl_config);
103 const EGLint attr_context[]={
104 EGL_CONTEXT_CLIENT_VERSION,2,
108 egl_display=i_egl_display;
109 egl_context=eglCreateContext(egl_display,i_egl_config,i_egl_context,attr_context);
110 if (egl_context==EGL_NO_CONTEXT) {
111 Log::getInstance()->log("Video", Log::WARN, "Creating egl context failed! %d",eglGetError());
114 // We create a dummy surface here, in order to allow two contexts
115 const EGLint attr_pbuffer[]={
116 EGL_WIDTH, 1, EGL_HEIGHT,1,
119 egl_surface=eglCreatePbufferSurface(egl_display,i_egl_config,attr_pbuffer);
120 if (egl_surface==EGL_NO_SURFACE) {
121 Log::getInstance()->log("Video", Log::WARN, "Creating egl pbuffer failed! %d",eglGetError());
128 //egl_surface=i_egl_surface;
129 //egl_context=i_egl_context;
132 #ifdef VPE_OMX_SUPPORT
133 // we are called before the audio
136 if (error!=OMX_ErrorNone) {
137 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error);
141 //our callbacks move to play?
145 #ifdef VPE_FFMPEG_SUPPORT
148 mpeg2codec_ff=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
149 //mpeg2codec_ff=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_XVMC);
150 if (mpeg2codec_ff==NULL) {
151 Log::getInstance()->log("Video", Log::DEBUG, "Find ffmpeg mpeg2 codec failed");
161 #ifdef VPE_OMX_SUPPORT
163 OMX_ERRORTYPE VideoVPEOGL::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
164 OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1,
165 OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) {
167 Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data);
169 struct VPE_OMX_EVENT new_event;
170 new_event.handle=handle;
171 new_event.appdata=appdata;
172 new_event.event_type=event_type;
173 new_event.data1=data1;
174 new_event.data2=data2;
175 new_event.event_data=event_data;
177 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
178 video->AddOmxEvent(new_event);
180 /* switch (event_type) {
181 case OMX_EventCmdComplete: {
186 return OMX_ErrorNone;
190 void VideoVPEOGL::AddOmxEvent(VPE_OMX_EVENT new_event)
192 omx_event_mutex.Lock();
193 omx_events.push_back(new_event);
194 omx_event_mutex.Unlock();
198 OMX_ERRORTYPE VideoVPEOGL::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
200 Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
201 VideoVPEOGL *video=(VideoVPEOGL *)getInstance();
202 video->ReturnEmptyOMXBuffer(buffer);
203 return OMX_ErrorNone;
207 void VideoVPEOGL::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
208 input_bufs_omx_mutex.Lock();
209 Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
210 input_bufs_omx_free.push_back(buffer);
211 Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
212 input_bufs_omx_mutex.Unlock();
215 OMX_ERRORTYPE VideoVPEOGL::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
216 Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
217 return OMX_ErrorNone;
222 int VideoVPEOGL::shutdown()
224 if (!initted) return 0;
229 #ifdef VPE_OMX_SUPPORT
230 DeAllocateCodecsOMX();
233 #ifdef VPE_FFMPEG_SUPPORT
234 DeAllocateCodecsFFMPEG();
236 eglDestroyContext(egl_display,egl_context);
241 int VideoVPEOGL::AllocateYUVOglTexture(VPEOGLFrame* outframe,int width,int height,int stride)
243 Log::getInstance()->log("Video", Log::NOTICE, "Allocate ogl texture");
245 glGenTextures(1, &outframe->textures[0]);
246 glBindTexture(GL_TEXTURE_2D, outframe->textures[0]);
247 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride, height, 0, GL_LUMINANCE,
248 GL_UNSIGNED_BYTE, NULL);
250 glGenTextures(1, &outframe->textures[1]);
251 glBindTexture(GL_TEXTURE_2D, outframe->textures[1]);
252 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
253 GL_UNSIGNED_BYTE, NULL);
255 glGenTextures(1, &outframe->textures[2]);
256 glBindTexture(GL_TEXTURE_2D, outframe->textures[2]);
257 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride>>1, height>>1, 0, GL_LUMINANCE,
258 GL_UNSIGNED_BYTE, NULL);
259 outframe->height=height;
260 outframe->width=width;
261 outframe->stride=stride;
266 VPEOGLFrame *VideoVPEOGL::getReadyOGLFrame(){
267 VPEOGLFrame *return_obj=NULL;
268 ogl_frame_mutex.Lock();
269 if (ready_ogl_frames.size()>0) {
270 return_obj=ready_ogl_frames.front();
271 ready_ogl_frames.pop_front();
272 ogl_frame_outside=true;
274 ogl_frame_mutex.Unlock();
278 void VideoVPEOGL::returnOGLFrame(VPEOGLFrame *frame)
280 ogl_frame_mutex.Lock();
282 ogl_frame_outside=false;
283 free_ogl_frames.push_back(frame);
285 ogl_frame_mutex.Unlock();
288 void VideoVPEOGL::threadMethod()
290 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
291 Log::getInstance()->log("Video", Log::WARN, "Making egl Current failed in thread %d",eglGetError());
296 #ifdef VPE_FFMPEG_SUPPORT
297 dec_frame_ff_mutex.Lock();
298 if (dec_frame_ff_upload_pending.size()>0) {
299 dec_frame_ff_uploading=dec_frame_ff_upload_pending.front();
300 dec_frame_ff_upload_pending.pop_front();
301 if (dec_frame_ff_upload_pending.size()>0) sleep=false;
303 dec_frame_ff_mutex.Unlock();
304 if (dec_frame_ff_uploading) {
305 int width,height,pixfmt;
306 //First get a free ogl image
307 VPEOGLFrame* out_frame=NULL;
309 ogl_frame_mutex.Lock();
310 if (all_ogl_frames.size()==0) {
311 ogl_frame_mutex.Unlock(); break;
314 if (free_ogl_frames.size()>0) {
318 out_frame=free_ogl_frames.front();
319 free_ogl_frames.pop_front();
320 } else MILLISLEEP(2);
321 ogl_frame_mutex.Unlock();
325 if (out_frame->textures[0]==0 || out_frame->width!=width ||
326 out_frame->height!=height || out_frame->stride!=dec_frame_ff_uploading->linesize[0]) {
327 if (out_frame->textures[0]==0) {
328 glDeleteTextures(1,&out_frame->textures[0]);
329 out_frame->textures[0]=0;
331 if (out_frame->textures[1]==0) {
332 glDeleteTextures(1,&out_frame->textures[1]);
333 out_frame->textures[1]=0;
335 if (out_frame->textures[2]==0) {
336 glDeleteTextures(1,&out_frame->textures[2]);
337 out_frame->textures[2]=0;
339 if (!AllocateYUVOglTexture(out_frame,width,height,dec_frame_ff_uploading->linesize[0])) failed=true;
342 //up to now only YUV data, this is for reference only, since the pi is too slow.
343 glBindTexture(GL_TEXTURE_2D, out_frame->textures[0]);
344 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
346 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
347 out_frame->stride,out_frame->height,
348 GL_LUMINANCE,GL_UNSIGNED_BYTE,
349 dec_frame_ff_uploading->data[0]);
352 glBindTexture(GL_TEXTURE_2D, out_frame->textures[1]);
353 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
354 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
355 out_frame->stride>>1,out_frame->height>>1,
356 GL_LUMINANCE,GL_UNSIGNED_BYTE,
357 dec_frame_ff_uploading->data[1]);
359 glBindTexture(GL_TEXTURE_2D, out_frame->textures[2]);
360 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
361 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
362 out_frame->stride>>1,out_frame->height>>1,
363 GL_LUMINANCE,GL_UNSIGNED_BYTE,
364 dec_frame_ff_uploading->data[2]);
365 ogl_frame_mutex.Lock();
366 ready_ogl_frames.push_back(out_frame);
367 ogl_frame_mutex.Unlock();
368 ((OsdOpenGL*)Osd::getInstance())->AdviseAboutNewFrame(); //Tell him, that we have a frame waiting
372 dec_frame_ff_mutex.Lock();
373 dec_frame_ff_free.push_back(dec_frame_ff_uploading);
374 dec_frame_ff_uploading=NULL;
375 dec_frame_ff_mutex.Unlock();
388 if (sleep) threadWaitForSignal();
394 void VideoVPEOGL::threadPostStopCleanup()
396 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
397 #ifdef VPE_FFMPEG_SUPPORT
398 dec_frame_ff_uploading=NULL;
405 int VideoVPEOGL::setTVsize(UCHAR ttvsize)
409 // Override the aspect ratio usage, temporarily use to set the video chip mode
410 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
412 if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
413 if (!setSource()) { shutdown(); return 0; }
414 if (!attachFrameBuffer()) { shutdown(); return 0; }
416 // Reopening the fd causes the scart aspect line to go back to 4:3
417 // Set this again to the same as the tv screen size
418 if (!setAspectRatio(tvsize)) { shutdown(); return 0; }
420 // mode == LETTERBOX is invalid if the TV is widescreen
421 if (tvsize == ASPECT16X9) setMode(NORMAL);
426 int VideoVPEOGL::setDefaultAspect()
428 return setAspectRatio(tvsize);
433 int VideoVPEOGL::setFormat(UCHAR tformat)
435 if (!initted) return 0;
436 if ((tformat != PAL) && (tformat != NTSC)) return 0;
439 // if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
455 int VideoVPEOGL::setConnection(UCHAR tconnection)
457 if (!initted) return 0;
458 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
459 connection = tconnection;
461 // if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
465 int VideoVPEOGL::setAspectRatio(UCHAR taspectRatio)
467 if (!initted) return 0;
468 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
469 aspectRatio = taspectRatio;
471 Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
473 // if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
477 int VideoVPEOGL::setMode(UCHAR tmode)
479 if (!initted) return 0;
481 if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
483 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
484 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
487 // if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
491 int VideoVPEOGL::signalOff()
493 // if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
497 int VideoVPEOGL::signalOn()
499 // if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
503 int VideoVPEOGL::setSource()
505 if (!initted) return 0;
507 // What does this do...
508 // if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
512 int VideoVPEOGL::setPosition(int x, int y)
514 if (!initted) return 0;
516 // vid_pos_regs_t pos_d;
520 /* vid_pos_regs_t pos_d;
522 memset(&pos_d, 0, sizeof(pos_d));
547 pos_d.y = 100; // Top left X
548 pos_d.x = 50; // Top left Y
556 // if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
560 int VideoVPEOGL::sync()
562 if (!initted) return 0;
564 // if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
571 int VideoVPEOGL::play()
573 if (!initted) return 0;
575 #ifdef VPE_OMX_SUPPORT
578 if (!omx_h264) doomx=false;
580 if (!omx_mpeg2) doomx=false;
583 if (AllocateCodecsOMX()) {
584 decoding_backend=VPE_DECODER_OMX;
586 // Otherwise fall back to ffmpeg
590 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume h264 unsupported");
593 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume mpeg2 unsupported");
598 #ifdef VPE_FFMPEG_SUPPORT
599 if (AllocateCodecsFFMPEG()) {
600 decoding_backend=VPE_DECODER_FFMPEG;
602 // Otherwise fall back to ffmpeg
611 #ifdef VPE_OMX_SUPPORT
612 int VideoVPEOGL::AllocateCodecsOMX()
615 static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
617 Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
618 //Clock, move later to audio
622 error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks);
625 if (error!=OMX_ErrorNone){
626 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error);
627 DeAllocateCodecsOMX();
633 OMX_PORT_PARAM_TYPE p_param;
634 memset(&p_param,0,sizeof(p_param));
635 p_param.nSize=sizeof(p_param);
636 p_param.nVersion.nVersion=OMX_VERSION;
637 error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param);
638 if (error!=OMX_ErrorNone){
639 Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error);
640 DeAllocateCodecsOMX();
643 omx_clock_output_port=p_param.nStartPortNumber;
645 for (unsigned int i=0;i<p_param.nPorts;i++) {
646 if (!DisablePort(omx_clock,p_param.nStartPortNumber+i) ) {
647 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
648 DeAllocateCodecsOMX();
654 OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf;
655 memset(&clock_conf,0,sizeof(clock_conf));
656 clock_conf.nSize=sizeof(clock_conf);
657 clock_conf.nVersion.nVersion=OMX_VERSION;
658 clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime;
659 clock_conf.nStartTime=0;
660 clock_conf.nOffset=0;
661 clock_conf.nWaitMask=OMX_CLOCKPORT0;
662 error=OMX_SetParameter(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
663 if (error!=OMX_ErrorNone){
664 Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
665 DeAllocateCodecsOMX();
672 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks);
674 error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks);
677 if (error!=OMX_ErrorNone){
678 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error);
679 DeAllocateCodecsOMX();
685 memset(&p_param,0,sizeof(p_param));
686 p_param.nSize=sizeof(p_param);
687 p_param.nVersion.nVersion=OMX_VERSION;
688 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param);
689 if (error!=OMX_ErrorNone){
690 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error);
691 DeAllocateCodecsOMX();
694 omx_codec_input_port=p_param.nStartPortNumber;
695 omx_codec_output_port=p_param.nStartPortNumber+1;
697 if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
698 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
699 DeAllocateCodecsOMX();
704 OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE conceal;
705 memset(&conceal,0,sizeof(conceal));
706 conceal.nSize=sizeof(conceal);
707 conceal.nVersion.nVersion=OMX_VERSION;
708 conceal.bStartWithValidFrame=OMX_FALSE;
710 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
711 if (error!=OMX_ErrorNone){
712 Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
713 DeAllocateCodecsOMX();
718 error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
719 if (error!=OMX_ErrorNone){
720 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error);
721 DeAllocateCodecsOMX();
727 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param);
728 if (error!=OMX_ErrorNone){
729 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
730 DeAllocateCodecsOMX();
733 omx_shed_input_port=p_param.nStartPortNumber;
734 omx_shed_output_port=p_param.nStartPortNumber+1;
737 error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamOtherInit,&p_param);
738 if (error!=OMX_ErrorNone){
739 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error);
740 DeAllocateCodecsOMX();
743 omx_shed_clock_port=p_param.nStartPortNumber;
746 if (!DisablePort(omx_vid_sched,omx_shed_input_port) || !DisablePort(omx_vid_sched,omx_shed_output_port)
747 || !DisablePort(omx_vid_sched,omx_shed_clock_port)) {
748 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
749 DeAllocateCodecsOMX();
754 error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_REND,NULL,&callbacks);
755 if (error!=OMX_ErrorNone){
756 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error);
757 DeAllocateCodecsOMX();
761 error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param);
762 if (error!=OMX_ErrorNone){
763 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error);
764 DeAllocateCodecsOMX();
767 omx_rend_input_port=p_param.nStartPortNumber;
768 //omx_rend_output_port=p_param.nStartPortNumber+1;
771 if (!DisablePort(omx_vid_rend,omx_rend_input_port) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
773 Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
774 DeAllocateCodecsOMX();
787 /* error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
788 if (error!=OMX_ErrorNone){
789 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
796 OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type;
797 memset(&ft_type,0,sizeof(ft_type));
798 ft_type.nSize=sizeof(ft_type);
799 ft_type.nVersion.nVersion=OMX_VERSION;
801 ft_type.nPortIndex=omx_codec_input_port;
803 ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC;
805 ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
808 Demuxer* demux=Demuxer::getInstance();
810 ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
811 Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
812 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type);
813 if (error!=OMX_ErrorNone){
814 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error);
815 DeAllocateCodecsOMX();
820 if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
821 Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
822 DeAllocateCodecsOMX();
827 if (!PrepareInputBufsOMX()) {
828 DeAllocateCodecsOMX();
833 if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
834 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle");
835 DeAllocateCodecsOMX();
839 error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port);
840 if (error!=OMX_ErrorNone){
841 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);
842 DeAllocateCodecsOMX();
846 if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
848 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
849 DeAllocateCodecsOMX();
853 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
854 DeAllocateCodecsOMX();
858 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port);
859 if (error!=OMX_ErrorNone){
860 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error);
861 DeAllocateCodecsOMX();
867 if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
869 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
870 DeAllocateCodecsOMX();
874 if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
877 if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
878 Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
879 DeAllocateCodecsOMX();
882 if (!CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)
883 ||!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port)){
884 DeAllocateCodecsOMX();
888 if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
889 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
890 DeAllocateCodecsOMX();
894 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
895 if (error!=OMX_ErrorNone){
896 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel sched to rend failed %x", error);
897 DeAllocateCodecsOMX();
901 if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
903 Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX shed rend failed");
904 DeAllocateCodecsOMX();
908 if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
909 || !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
910 DeAllocateCodecsOMX();
914 if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
915 Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
916 DeAllocateCodecsOMX();
921 if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
922 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
923 DeAllocateCodecsOMX();
927 if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
928 Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
929 DeAllocateCodecsOMX();
934 OMX_CONFIG_DISPLAYREGIONTYPE dispconf;
935 memset(&dispconf,0,sizeof(dispconf));
936 dispconf.nSize=sizeof(dispconf);
937 dispconf.nVersion.nVersion=OMX_VERSION;
939 dispconf.nPortIndex=omx_rend_input_port;
941 dispconf.set=OMX_DISPLAY_SET_LAYER ;
943 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
944 if (error!=OMX_ErrorNone){
945 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
946 DeAllocateCodecsOMX();
950 /* dispconf.set=OMX_DISPLAY_SET_FULLSCREEN ;
951 dispconf.fullscreen=OMX_FALSE;
952 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
953 if (error!=OMX_ErrorNone){
954 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
955 DeAllocateCodecsOMX();
959 dispconf.set=OMX_DISPLAY_SET_DEST_RECT;
960 dispconf.dest_rect.x_offset=100;
961 dispconf.dest_rect.y_offset=100;
962 dispconf.dest_rect.width=640;
963 dispconf.dest_rect.height=480;
964 error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
965 if (error!=OMX_ErrorNone){
966 Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
967 DeAllocateCodecsOMX();
974 if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
975 Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Exccute");
976 DeAllocateCodecsOMX();
986 int VideoVPEOGL::ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type)
989 error=OMX_SendCommand(handle,OMX_CommandStateSet,type,0);
990 if (error!=OMX_ErrorNone){
991 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to OMX State %x %x",handle,type, error);
995 if (!CommandFinished(handle,OMX_CommandStateSet,type)) {
1003 int VideoVPEOGL::EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1005 OMX_ERRORTYPE error;
1006 error=OMX_SendCommand(handle,OMX_CommandPortEnable,port,0);
1007 if (error!=OMX_ErrorNone){
1008 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to enable port %x %x",handle,port, error);
1012 if (!wait) return 1;
1013 if (!CommandFinished(handle,OMX_CommandPortEnable,port)) {
1021 int VideoVPEOGL::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait)
1023 OMX_ERRORTYPE error;
1024 error=OMX_SendCommand(handle,OMX_CommandPortDisable,port,0);
1025 if (error!=OMX_ErrorNone){
1026 Log::getInstance()->log("Video", Log::DEBUG, "handle %x Send Command to disable port %x %x",handle,port, error);
1030 if (!wait) return 1;
1031 if (!CommandFinished(handle,OMX_CommandPortDisable,port)) {
1042 int VideoVPEOGL::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2)
1046 omx_event_mutex.Lock();
1047 list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
1048 while (itty!=omx_events.end()) {
1050 VPE_OMX_EVENT current=*itty;
1051 if (current.handle==handle) { //this is ours
1052 if (current.event_type==OMX_EventError) {
1053 omx_events.erase(itty);
1054 omx_event_mutex.Unlock();
1057 } else if (current.event_type==OMX_EventCmdComplete && current.data1==command && current.data2==data2) {
1058 omx_events.erase(itty);
1059 omx_event_mutex.Unlock();
1066 omx_event_mutex.Unlock();
1071 Log::getInstance()->log("Video", Log::DEBUG, "CommandFinished waited too long %x %x %x",handle,command, data2);
1080 int VideoVPEOGL::PrepareInputBufsOMX()
1082 OMX_ERRORTYPE error;
1083 OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
1084 memset(&port_def_type,0,sizeof(port_def_type));
1085 port_def_type.nSize=sizeof(port_def_type);
1086 port_def_type.nVersion.nVersion=OMX_VERSION;
1087 port_def_type.nPortIndex=omx_codec_input_port;
1089 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1091 if (error!=OMX_ErrorNone){
1092 Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
1094 /* Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
1095 port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
1096 port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
1098 port_def_type.nBufferCountActual=60;
1100 error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
1102 if (error!=OMX_ErrorNone){
1103 Log::getInstance()->log("Video", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
1107 error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
1108 if (error!=OMX_ErrorNone){
1109 Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
1113 input_bufs_omx_mutex.Lock();
1114 for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
1116 // unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nBufferSize);
1117 OMX_BUFFERHEADERTYPE *buf_head=NULL;
1118 /* error=OMX_UseBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize,new_buffer_data);
1119 if (error!=OMX_ErrorNone){
1120 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_UseBuffer failed %x", error);
1121 input_bufs_omx_mutex.Unlock();
1124 error=OMX_AllocateBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize);
1125 if (error!=OMX_ErrorNone){
1126 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_AllocateBuffer failed %x", error);
1127 input_bufs_omx_mutex.Unlock();
1130 input_bufs_omx_all.push_back(buf_head);
1131 input_bufs_omx_free.push_back(buf_head);
1133 omx_first_frame=true;
1136 cur_input_buf_omx=NULL;
1137 input_bufs_omx_mutex.Unlock();
1140 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark3");
1141 if (!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port)) {
1144 Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark4");
1149 int VideoVPEOGL::DestroyInputBufsOMX()
1151 OMX_ERRORTYPE error;
1153 cur_input_buf_omx=NULL;
1154 input_bufs_omx_mutex.Lock();
1155 for (int i=0; i< input_bufs_omx_all.size();i++) {
1156 // free(input_bufs_omx_all[i]->pBuffer);
1157 // input_bufs_omx_all[i]->pBuffer=NULL;
1158 error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]);
1159 if (error!=OMX_ErrorNone){
1160 Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
1161 input_bufs_omx_mutex.Unlock();
1165 input_bufs_omx_all.clear();
1166 input_bufs_omx_free.clear();
1167 input_bufs_omx_mutex.Unlock();
1174 int VideoVPEOGL::DeAllocateCodecsOMX()
1176 OMX_ERRORTYPE error;
1179 // first flush all buffers
1181 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_output_port, NULL);
1182 if (error!=OMX_ErrorNone){
1183 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1187 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_input_port, NULL);
1188 if (error!=OMX_ErrorNone){
1189 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed in failed %x", error);
1193 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_output_port) ||
1194 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_input_port)) {
1195 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec shed failed");
1198 error=OMX_SendCommand(omx_clock,OMX_CommandFlush, omx_clock_output_port, NULL);
1199 if (error!=OMX_ErrorNone){
1200 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush clock out failed %x", error);
1204 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_clock_port, NULL);
1205 if (error!=OMX_ErrorNone){
1206 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed clock failed %x", error);
1210 if (!CommandFinished(omx_clock,OMX_CommandFlush,omx_clock_output_port) ||
1211 !CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_clock_port)) {
1212 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd clock shed failed");
1215 error=OMX_SendCommand(omx_vid_sched,OMX_CommandFlush, omx_shed_output_port, NULL);
1216 if (error!=OMX_ErrorNone) {
1217 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush shed out failed %x", error);
1221 error=OMX_SendCommand(omx_vid_rend,OMX_CommandFlush, omx_rend_input_port, NULL);
1222 if (error!=OMX_ErrorNone) {
1223 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush rend in failed %x", error);
1227 if (!CommandFinished(omx_vid_sched,OMX_CommandFlush,omx_shed_output_port) ||
1228 !CommandFinished(omx_vid_rend,OMX_CommandFlush,omx_rend_input_port)) {
1229 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd shed rend failed");
1235 error=OMX_SendCommand(omx_vid_dec,OMX_CommandFlush, omx_codec_input_port, NULL);
1236 if (error!=OMX_ErrorNone){
1237 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Flush codec out failed %x", error);
1242 if (!CommandFinished(omx_vid_dec,OMX_CommandFlush,omx_codec_input_port)) {
1243 Log::getInstance()->log("Video", Log::DEBUG, "flush cmd codec input failed");
1246 DestroyInputBufsOMX();
1249 if (!DisablePort(omx_vid_rend,omx_rend_input_port,true)) {
1250 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 1");
1252 if (!DisablePort(omx_vid_sched,omx_shed_output_port,true)) {
1253 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 2 ");
1256 error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL);
1257 if (error!=OMX_ErrorNone){
1258 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1262 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL);
1263 if (error!=OMX_ErrorNone){
1264 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1268 if (!DisablePort(omx_vid_sched,omx_shed_input_port,true)) {
1269 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 3");
1272 if (!DisablePort(omx_vid_sched,omx_shed_clock_port,true)) {
1273 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 4");
1276 if (!DisablePort(omx_clock,omx_clock_output_port,true)) {
1277 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 5");
1279 if (!DisablePort(omx_vid_dec,omx_codec_output_port,true)) {
1280 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6");
1285 if (!DisablePort(omx_vid_dec,omx_codec_input_port,true)) {
1286 Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
1290 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL);
1291 if (error!=OMX_ErrorNone){
1292 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1295 error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_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_clock,omx_clock_output_port,NULL,NULL);
1302 if (error!=OMX_ErrorNone){
1303 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1307 error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL);
1308 if (error!=OMX_ErrorNone){
1309 Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
1317 error=OMX_FreeHandle(omx_vid_dec);
1318 error=OMX_FreeHandle(omx_vid_sched);
1319 error=OMX_FreeHandle(omx_vid_rend);
1320 error=OMX_FreeHandle(omx_clock);
1322 if (error!=OMX_ErrorNone) {
1323 Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error);
1333 #ifdef VPE_FFMPEG_SUPPORT
1335 int VideoVPEOGL::AllocateCodecsFFMPEG()
1337 ffmpeg_hastime=false;
1338 Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecsFFmpeg");
1339 mpeg2codec_context_ff=avcodec_alloc_context();
1340 if (mpeg2codec_context_ff==NULL) {
1341 Log::getInstance()->log("Video", Log::DEBUG, "Creating ffmpeg codec context failed");
1344 if(avcodec_open(mpeg2codec_context_ff, mpeg2codec_ff)<0) {
1345 Log::getInstance()->log("Video", Log::DEBUG, "Opening ffmpeg codec failed");
1348 memset(&incom_packet_ff,0,sizeof(incom_packet_ff));
1349 incom_packet_ff_size=200000;
1350 incom_packet_ff.data=(uint8_t*)av_malloc(incom_packet_ff_size+FF_INPUT_BUFFER_PADDING_SIZE);
1352 dec_frame_ff_mutex.Lock();
1353 for (int i=0;i<3;i++) {
1354 AVFrame *dec_frame_ff=avcodec_alloc_frame(); // may be we need multiple frames, if we want to use async texture upload
1355 if (!dec_frame_ff) {
1356 Log::getInstance()->log("Video", Log::DEBUG, "Allocating dec_frame failed");
1359 dec_frame_ff_all.push_back(dec_frame_ff);
1360 dec_frame_ff_free.push_back(dec_frame_ff);
1362 dec_frame_ff_decoding=NULL;
1363 dec_frame_ff_mutex.Unlock();
1365 ogl_frame_mutex.Lock();
1366 //Allocate texture structs, since we do not know the sizes, we do not allocate the textures yet
1367 for (int i=0;i<3;i++) {
1368 VPEOGLFrame *new_frame=(VPEOGLFrame *)malloc(sizeof(VPEOGLFrame));
1369 new_frame->type=1; //1 = YUV, 2 RGB
1370 new_frame->textures[0]=0;
1371 new_frame->textures[1]=0;
1372 new_frame->textures[2]=0;
1373 new_frame->width=new_frame->height=0;
1374 all_ogl_frames.push_back(new_frame);
1375 free_ogl_frames.push_back(new_frame);
1378 ogl_frame_outside=false;
1380 ogl_frame_mutex.Unlock();
1382 ffmpeg_running=true;
1388 int VideoVPEOGL::DeAllocateCodecsFFMPEG()
1390 ffmpeg_running=false;
1391 Log::getInstance()->log("Video", Log::NOTICE, "DeAllocateCodecsFFmpeg");
1392 dec_frame_ff_mutex.Lock();
1393 dec_frame_ff_upload_pending.clear();
1394 dec_frame_ff_free.clear();
1395 dec_frame_ff_mutex.Unlock();
1396 while (dec_frame_ff_uploading) {
1397 Log::getInstance()->log("Video", Log::NOTICE, "Wait for uploading to finish");
1400 dec_frame_ff_mutex.Lock();
1401 for (int i=0; i< dec_frame_ff_all.size();i++) {
1402 av_free(dec_frame_ff_all[i]);
1405 dec_frame_ff_all.clear();
1407 av_free(incom_packet_ff.data);
1408 incom_packet_ff.data=NULL;
1409 incom_packet_ff_size=0;
1411 dec_frame_ff_mutex.Unlock();
1412 dec_frame_ff_decoding=NULL;
1413 while (ogl_frame_outside) {
1414 Log::getInstance()->log("Video", Log::NOTICE, "Wait for ogl frame from outside");
1418 ((OsdOpenGL*)Osd::getInstance())->BeginPainting(); // get osd's context
1419 ogl_frame_mutex.Lock();
1420 for (int i=0; i< dec_frame_ff_all.size();i++) {
1421 VPEOGLFrame * del_frame=all_ogl_frames[i];
1422 if (del_frame->textures[0]==0) {
1423 glDeleteTextures(1,&del_frame->textures[0]);
1424 del_frame->textures[0]=0;
1426 if (del_frame->textures[1]==0) {
1427 glDeleteTextures(1,&del_frame->textures[1]);
1428 del_frame->textures[1]=0;
1430 if (del_frame->textures[2]==0) {
1431 glDeleteTextures(1,&del_frame->textures[2]);
1432 del_frame->textures[2]=0;
1434 free(all_ogl_frames[i]);
1436 all_ogl_frames.clear();
1437 free_ogl_frames.clear();
1438 ready_ogl_frames.clear();
1439 ogl_frame_mutex.Unlock();
1440 ((OsdOpenGL*)Osd::getInstance())->EndPainting();
1443 if (mpeg2codec_context_ff) {
1444 avcodec_close(mpeg2codec_context_ff);
1445 av_free(mpeg2codec_context_ff);
1446 mpeg2codec_context_ff=NULL;
1461 int VideoVPEOGL::stop()
1463 if (!initted) return 0;
1465 #ifdef VPE_OMX_SUPPORT
1466 //Check if ffmpeg mode
1467 if (decoding_backend==VPE_DECODER_OMX) DeAllocateCodecsOMX();
1474 // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
1478 int VideoVPEOGL::reset()
1480 if (!initted) return 0;
1482 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
1486 int VideoVPEOGL::pause()
1488 if (!initted) return 0;
1490 // if (ioctl(fdVideo, AV_SET_VID_PAUSE, 0) != 0) return 0;
1494 int VideoVPEOGL::unPause() // FIXME get rid - same as play!!
1496 if (!initted) return 0;
1497 // if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
1501 int VideoVPEOGL::fastForward()
1503 if (!initted) return 0;
1505 // if (ioctl(fdVideo, AV_SET_VID_FFWD, 1) != 0) return 0;
1509 int VideoVPEOGL::unFastForward()
1511 if (!initted) return 0;
1513 // if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
1515 //// if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
1519 int VideoVPEOGL::attachFrameBuffer()
1521 if (!initted) return 0;
1523 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
1527 int VideoVPEOGL::blank(void)
1529 // if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
1530 // if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
1534 ULLONG VideoVPEOGL::getCurrentTimestamp()
1536 /* sync_data_t timestamps;
1537 if (ioctl(fdVideo, AV_GET_VID_TIMESTAMPS, ×tamps) == 0)
1539 // FIXME are these the right way around?
1541 timestamps.stc = (timestamps.stc >> 31 ) | (timestamps.stc & 1);
1542 timestamps.pts = (timestamps.pts >> 31 ) | (timestamps.pts & 1);
1544 return timestamps.stc;
1553 ULONG VideoVPEOGL::timecodeToFrameNumber(ULLONG timecode)
1555 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
1556 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
1560 int VideoVPEOGL::test()
1565 // return ioctl(fdVideo, AV_SET_VID_STC, &stc);
1572 int VideoVPEOGL::test2()
1578 void VideoVPEOGL::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
1580 mediapacket = mplist.front();
1583 UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
1585 DeliverMediaPacket(mediapacket, buffer, samplepos);
1586 if (*samplepos == mediapacket.length) {
1593 UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
1594 const UCHAR* buffer,
1597 if (packet.type == MPTYPE_VIDEO_H264)
1605 switch (decoding_backend) {
1606 default: case 0: return 0; // no backend runnigng
1607 #ifdef VPE_OMX_SUPPORT
1608 case VPE_DECODER_OMX: return DeliverMediaPacketOMX(packet,buffer,samplepos);
1610 #ifdef VPE_FFMPEG_SUPPORT
1611 case VPE_DECODER_FFMPEG: return DeliverMediaPacketFFMPEG(packet,buffer,samplepos);
1616 #ifdef VPE_OMX_SUPPORT
1617 UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
1618 const UCHAR* buffer,
1623 //Later add fail back code for ffmpeg
1625 *samplepos+=packet.length;
1626 return packet.length;
1630 if (!omx_running) return 0; // if we are not runnig do not do this
1633 OMX_ERRORTYPE error;
1635 /* OMX_PARAM_PORTDEFINITIONTYPE port_image;
1636 memset(&port_image,0,sizeof(port_image));
1637 port_image.nSize=sizeof(port_image);
1638 port_image.nVersion.nVersion=OMX_VERSION;
1639 port_image.nPortIndex =omx_codec_output_port;
1640 error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_image);
1641 if (error!= OMX_ErrorNone){
1642 Log::getInstance()->log("Video", Log::DEBUG, "OMX_GetParameter failed %x", error);
1644 Log::getInstance()->log("Video", Log::DEBUG, "Image port %d %d", port_image.format.video.nFrameWidth , port_image.format.video.nFrameHeight);*/
1646 /*First Check, if we have an audio sample*/
1650 return 0; //Not in iframe mode!
1654 if (packet.disconti) {
1656 if (cur_input_buf_omx) {
1657 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1658 if (error!=OMX_ErrorNone){
1659 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1661 cur_input_buf_omx=NULL;
1665 /*Inspect PES-Header */
1667 // OMX_STATETYPE temp_state;
1668 // OMX_GetState(omx_vid_dec,&temp_state);
1670 if (*samplepos==0) {//stripheader
1671 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
1672 *samplepos+=headerstrip;
1673 if ( packet.synched ) {
1675 if (cur_input_buf_omx) {
1676 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1677 if (error!=OMX_ErrorNone){
1678 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1681 cur_input_buf_omx=NULL;//write out old data
1683 // reftime1=packet.presentation_time;
1684 // reftime2=reftime1+1;
1687 if (!firstsynched) {//
1688 *samplepos=packet.length;//if we have not processed at least one
1689 return packet.length;//synched packet ignore it!
1694 if (!cur_input_buf_omx) {
1695 input_bufs_omx_mutex.Lock();
1696 if (input_bufs_omx_free.size()==0) {
1697 input_bufs_omx_mutex.Unlock();
1698 Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
1699 return 0; // we do not have a free media sample
1702 cur_input_buf_omx=input_bufs_omx_free.front();
1703 cur_input_buf_omx->nFilledLen=0;
1704 cur_input_buf_omx->nOffset=0;
1705 cur_input_buf_omx->nTimeStamp=0;
1706 input_bufs_omx_free.pop_front();
1707 input_bufs_omx_mutex.Unlock();
1713 if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
1714 /*if (packet.disconti) {
1715 ms->SetDiscontinuity(TRUE);
1717 ms->SetDiscontinuity(FALSE);
1719 //if (packet.synched) {
1721 //lastreftimePTS=packet.pts;
1722 if (omx_first_frame) { // TODO time
1723 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
1724 omx_first_frame=false;
1730 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1733 // ms->SetSyncPoint(TRUE);
1737 unsigned int haveToCopy=packet.length-*samplepos;
1739 while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
1740 unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
1741 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
1742 haveToCopy-=cancopy;
1743 cur_input_buf_omx->nFilledLen+=cancopy;
1744 *samplepos+=cancopy;
1745 // push old buffer out
1747 OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
1748 if (error!=OMX_ErrorNone){
1749 Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
1752 input_bufs_omx_mutex.Lock();
1753 if (input_bufs_omx_free.size()==0) {
1754 input_bufs_omx_mutex.Unlock();
1755 //Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
1756 return *samplepos; // we do not have a free media sample
1758 cur_input_buf_omx=input_bufs_omx_free.front();
1759 cur_input_buf_omx->nFilledLen=0;
1760 cur_input_buf_omx->nOffset=0;
1761 cur_input_buf_omx->nTimeStamp=0;
1762 input_bufs_omx_free.pop_front();
1763 input_bufs_omx_mutex.Unlock();
1765 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1768 memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
1769 buffer+packet.pos_buffer+*samplepos,haveToCopy);
1770 cur_input_buf_omx->nFilledLen+=haveToCopy;
1774 *samplepos+=haveToCopy;
1783 #ifdef VPE_FFMPEG_SUPPORT
1784 int VideoVPEOGL::DecodePacketFFMPEG()
1786 unsigned int haveToCopy=incom_packet_ff.size;
1787 if (incom_packet_ff.size==0) return 1; // we are already empty
1788 while (haveToCopy>0) {
1792 // Log::getInstance()->log("Video", Log::DEBUG, "Push data to decoder");
1794 #ifdef BENCHMARK_FPS
1795 int cur_time=getTimeMS();
1798 dec_bytes=avcodec_decode_video2(mpeg2codec_context_ff, dec_frame_ff_decoding,
1799 &frame_ready, &incom_packet_ff);
1800 #ifdef BENCHMARK_FPS
1801 time_in_decoder+=getTimeMS()-cur_time;
1802 if (frame_ready) num_frames++;
1803 if ((num_frames%100)==0) {
1804 float fps=1000./(float)(time_in_decoder);
1805 fps*=((float)num_frames);
1806 Log::getInstance()->log("Video", Log::NOTICE, "Current Pure Decoding FPS %g", fps);
1810 Log::getInstance()->log("Video", Log::DEBUG, "Decoding frame failed %x", dec_bytes);
1813 haveToCopy-=dec_bytes;
1815 // Log::getInstance()->log("Video", Log::DEBUG, "We have a frame push it to osd");
1817 dec_frame_ff_mutex.Lock();
1818 ffwidth=mpeg2codec_context_ff->width;
1819 ffheight=mpeg2codec_context_ff->height;
1820 ffpixfmt=mpeg2codec_context_ff->pix_fmt;
1821 // Log::getInstance()->log("Video", Log::DEBUG, "Frame info %d %d %d",ffwidth,ffheight,ffpixfmt);
1823 dec_frame_ff_upload_pending.push_back(dec_frame_ff_decoding);
1824 dec_frame_ff_decoding=NULL;
1825 if (dec_frame_ff_free.size()>0) {
1826 dec_frame_ff_decoding=dec_frame_ff_free.front();
1827 dec_frame_ff_free.pop_front();
1828 dec_frame_ff_mutex.Unlock();
1830 ffmpeg_hastime=false;
1832 ffmpeg_hastime=false;
1833 dec_frame_ff_mutex.Unlock();
1842 incom_packet_ff.size=0;
1848 UINT VideoVPEOGL::DeliverMediaPacketFFMPEG(MediaPacket packet,
1849 const UCHAR* buffer,
1852 //Later add fail back code for ffmpeg
1854 *samplepos+=packet.length;
1855 return packet.length;
1858 if (!ffmpeg_running) return 0; // if we are not runnig do not do this
1864 return 0; //Not in iframe mode!
1868 if (packet.disconti) {
1870 if (!DecodePacketFFMPEG()) return 0;
1873 /*Inspect PES-Header */
1874 if (!dec_frame_ff_decoding) {
1875 dec_frame_ff_mutex.Lock();
1876 if (dec_frame_ff_free.size()>0) {
1877 dec_frame_ff_decoding=dec_frame_ff_free.front();
1878 dec_frame_ff_free.pop_front();
1879 dec_frame_ff_mutex.Unlock();
1881 Log::getInstance()->log("Video", Log::DEBUG, "We have no free buffers");
1882 dec_frame_ff_mutex.Unlock();
1890 if (*samplepos==0) {//stripheader
1891 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
1892 *samplepos+=headerstrip;
1893 if ( packet.synched ) {
1895 if (!DecodePacketFFMPEG()) return 0; // WriteOut old Data
1897 ffmpeg_time=packet.presentation_time;
1898 ffmpeg_hastime=true;
1899 // reftime1=packet.presentation_time;
1900 // reftime2=reftime1+1;
1903 if (!firstsynched) {//
1904 *samplepos=packet.length;//if we have not processed at least one
1905 return packet.length;//synched packet ignore it!
1915 /*if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
1916 /*if (packet.disconti) {
1917 ms->SetDiscontinuity(TRUE);
1919 ms->SetDiscontinuity(FALSE);
1921 //if (packet.synched) {
1923 //lastreftimePTS=packet.pts;
1924 if (omx_first_frame) { // TODO time
1925 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME;
1926 omx_first_frame=false;
1932 cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
1935 // ms->SetSyncPoint(TRUE);
1939 unsigned int haveToCopy=packet.length-*samplepos;
1941 if ((incom_packet_ff_size-incom_packet_ff.size)< haveToCopy) {
1942 // if the buffer is to small reallocate
1943 incom_packet_ff_size+=haveToCopy;
1944 incom_packet_ff.data=(uint8_t*)av_realloc(incom_packet_ff.data,incom_packet_ff_size+FF_INPUT_BUFFER_PADDING_SIZE);
1945 Log::getInstance()->log("Video", Log::DEBUG, "Reallocate avpacket buffer to %d", incom_packet_ff_size);
1947 memcpy(incom_packet_ff.data,buffer+packet.pos_buffer+*samplepos,haveToCopy);
1948 incom_packet_ff.size+=haveToCopy;
1950 *samplepos+=haveToCopy;
1965 void VideoVPEOGL::ResetTimeOffsets()
1969 bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length)
1971 //write(fdVideo, buffer, length);
1972 if (!iframemode) EnterIframePlayback();
1973 // WriteOutTS(buffer,length, h264?MPTYPE_VIDEO_H264 :MPTYPE_VIDEO_MPEG2 );
1979 int VideoVPEOGL::EnterIframePlayback()