From b7b95af71256648291e063b78e08e0af25bd9032 Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Sun, 20 May 2012 19:59:04 +0200 Subject: [PATCH] Preliminray OMX h264 playback stuff not finished yet --- GNUmakefile | 2 +- audiovpe.cc | 6 +- defines.h | 10 + draintarget.h | 2 +- osdopengl.cc | 35 +- osdopengl.h | 8 + player.cc | 0 videovpeogl.cc | 1008 ++++++++++++++++++++++++++++++------------------ videovpeogl.h | 107 ++++- 9 files changed, 773 insertions(+), 405 deletions(-) mode change 100644 => 100755 GNUmakefile mode change 100644 => 100755 audiovpe.cc mode change 100644 => 100755 defines.h mode change 100644 => 100755 draintarget.h mode change 100644 => 100755 player.cc mode change 100644 => 100755 videovpeogl.cc mode change 100644 => 100755 videovpeogl.h diff --git a/GNUmakefile b/GNUmakefile old mode 100644 new mode 100755 index 112207a..1c88c6a --- a/GNUmakefile +++ b/GNUmakefile @@ -55,7 +55,7 @@ endif ifeq ($(vomp_platform),raspberry) $(info Raspberry pi flags) LDFLAGS = -Wall -LIBS = -L/opt/vc/lib -lpthread -lrt -lEGL -lGLESv2 -lbcm_host +LIBS = -L/opt/vc/lib -lpthread -lrt -lEGL -lGLESv2 -lopenmaxil -lbcm_host OBJECTS += main.o threadp.o osdopengl.o surfaceopengl.o ledraspberry.o mtdraspberry.o videovpeogl.o audiovpe.o wjpegsimple.o remotelinux.o LIBS+= -ljpeg diff --git a/audiovpe.cc b/audiovpe.cc old mode 100644 new mode 100755 index 1957b74..26ddaf0 --- a/audiovpe.cc +++ b/audiovpe.cc @@ -118,7 +118,7 @@ int AudioVPE::play() if (!initted) return 0; lastpacketnum=-1; currentpacketnum=-1; - ((VideoVPEOGL*) Video::getInstance())->initMuxer(); + //if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0; return 1; @@ -127,7 +127,6 @@ int AudioVPE::play() int AudioVPE::stop() { if (!initted) return 0; - ((VideoVPEOGL*) Video::getInstance())->deinitMuxer(); //if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0; return 1; @@ -176,7 +175,7 @@ int AudioVPE::reset() if (!initted) return 0; //test(); Log::getInstance()->log("Audio", Log::DEBUG, "reset called"); - ((VideoVPEOGL*) Video::getInstance())->deinitMuxer(); + // if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0; // Log::getInstance()->log("Audio", Log::DEBUG, "reset back"); @@ -292,6 +291,7 @@ UINT AudioVPE::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) *samplepos = written;*/ // Handle a partial write. Is this possible? Should we bother? No! + *samplepos=packet.length; return 1; } diff --git a/defines.h b/defines.h old mode 100644 new mode 100755 index 7a9abbb..c252b79 --- a/defines.h +++ b/defines.h @@ -91,6 +91,16 @@ void MILLISLEEP(ULONG a); #define Audio_TYPE AudioVPE // This is Audio based on VPE (Vomp Presentation Engine) should support OpenMax and Alsa with ffmpeg in the end #define Video_TYPE VideoVPEOGL // This is Video based on VPE (Vomp Presentation Engine) should support OpenMax and ffmpeg and opengl in the end + + + #define VPE_OMX_SUPPORT // Activate support for hardware codec using openmax il + #define VPE_OMX_H264_DECODER "OMX.broadcom.video_decode" + #define VPE_OMX_MPEG2_DECODER "OMX.broadcom.video_decode" + #define VPE_OMX_VIDEO_SCHED "OMX.broadcom.video_scheduler" + #define VPE_OMX_VIDEO_REND "OMX.broadcom.video_render" + #define VPE_OMX_VIDEO_DEINTERLACE "OMX.broadcom.image_fx" + #define VPE_OMX_CLOCK "OMX.broadcom.clock" + #endif #ifdef VOMP_PLATTFORM_MVP #define Remote_TYPE RemoteMVP diff --git a/draintarget.h b/draintarget.h old mode 100644 new mode 100755 index fc19a29..26992bd --- a/draintarget.h +++ b/draintarget.h @@ -44,7 +44,7 @@ struct MediaPacket ULLONG dts; bool synched; int index; -#if defined(WIN32) || defined(__ANDROID__) +#ifndef VOMP_PLATTFORM_MVP long long presentation_time;/* in 100 ns units*/ bool disconti; #endif diff --git a/osdopengl.cc b/osdopengl.cc index 79e79cc..969c12d 100755 --- a/osdopengl.cc +++ b/osdopengl.cc @@ -103,15 +103,24 @@ int OsdOpenGL::init(void* device) egl_display=eglGetDisplay(EGL_DEFAULT_DISPLAY); if (egl_display==EGL_NO_DISPLAY) { - Log::getInstance()->log("OSD", Log::WARN, "Could not get egl display!",eglGetError()); + Log::getInstance()->log("OSD", Log::WARN, "Could not get egl display! %x",eglGetError()); return 0; } + + if (eglInitialize(egl_display, NULL, NULL)==EGL_FALSE) { - Log::getInstance()->log("OSD", Log::WARN, "Initialising display failed! %d",eglGetError()); + Log::getInstance()->log("OSD", Log::WARN, "Initialising display failed! %x",eglGetError()); return 0; } + const char *query_str=eglQueryString(egl_display,EGL_CLIENT_APIS); + if (query_str) Log::getInstance()->log("OSD", Log::NOTICE, "%s",query_str); + else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",eglGetError()); + query_str=eglQueryString(egl_display,EGL_EXTENSIONS); + if (query_str) Log::getInstance()->log("OSD", Log::NOTICE, "%s",query_str); + else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",eglGetError()); + const EGLint attributs[]={ EGL_RED_SIZE,8,EGL_GREEN_SIZE, 8,EGL_BLUE_SIZE, 8,EGL_ALPHA_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, @@ -119,10 +128,10 @@ int OsdOpenGL::init(void* device) EGL_NONE }; // Here, we might have to select the resolution! - EGLConfig ourconfig; //maybe accept more configs? + EGLint number; - if (eglChooseConfig(egl_display, attributs, &ourconfig, 1, &number)==EGL_FALSE) { + if (eglChooseConfig(egl_display, attributs, &egl_ourconfig, 1, &number)==EGL_FALSE) { Log::getInstance()->log("OSD", Log::WARN, "Choosing egl config failed! %d",eglGetError()); return 0; } @@ -132,7 +141,7 @@ int OsdOpenGL::init(void* device) EGL_NONE }; - egl_context=eglCreateContext(egl_display,ourconfig,EGL_NO_CONTEXT,attr_context); + egl_context=eglCreateContext(egl_display,egl_ourconfig,EGL_NO_CONTEXT,attr_context); if (egl_context==EGL_NO_CONTEXT) { Log::getInstance()->log("OSD", Log::WARN, "Creating egl context failed! %d",eglGetError()); return 0; @@ -164,7 +173,7 @@ int OsdOpenGL::init(void* device) nativewindow.height=display_height; nativewindow.width=display_width; - egl_surface = eglCreateWindowSurface(egl_display,ourconfig, &nativewindow,NULL ); + egl_surface = eglCreateWindowSurface(egl_display,egl_ourconfig, &nativewindow,NULL ); if (egl_surface==EGL_NO_SURFACE) { Log::getInstance()->log("OSD", Log::WARN, "Creating egl window surface failed!"); return 0; @@ -222,6 +231,12 @@ int OsdOpenGL::init(void* device) glClearColor(0.0f,0.0f,0.0f,1.f); eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); + + if (((VideoVPEOGL*)Video::getInstance())->initUsingOSDObjects()!=1) { //call Video for init opengl stuff + return 0; + } + + glmutex.Unlock(); threadStart(); @@ -314,6 +329,8 @@ int OsdOpenGL::shutdown() if (!initted) return 0; initted = 0; + (((VideoVPEOGL*)Video::getInstance())->shutdownUsingOSDObjects()); + if (osd_shader!=0) glDeleteShader(osd_shader); if (gen_shader!=0) glDeleteShader(gen_shader); @@ -513,9 +530,11 @@ void OsdOpenGL::InternalRendering(GLuint present){ glUniform1i(osd_sampler_loc,0); - glEnable(GL_BLEND); - glBlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,GL_ZERO,GL_ONE); + if (0) { //This is ok for ffmpeg rendering not OMX + glEnable(GL_BLEND); + glBlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,GL_ZERO,GL_ONE); + } /* glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX), (GLvoid*)(((char*)osdvertices)+3*sizeof(GLfloat))); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE,sizeof(OSDVERTEX), diff --git a/osdopengl.h b/osdopengl.h index 4d7d83d..9694c3f 100755 --- a/osdopengl.h +++ b/osdopengl.h @@ -89,6 +89,13 @@ class OsdOpenGL : public Osd, public Thread_TYPE void setExternalDriving(/*DsAllocator* dsall,*/ unsigned int width, unsigned int height); void Blank(); + void getEGLObjs(EGLDisplay *i_egl_display,EGLSurface *i_egl_surface,EGLContext *i_egl_context){ + *i_egl_display=egl_display; + *i_egl_surface=egl_surface; + *i_egl_context=egl_context; + }; + + EGLConfig getEGLConfig() {return egl_ourconfig;}; @@ -127,6 +134,7 @@ private: EGLDisplay egl_display; EGLSurface egl_surface; EGLContext egl_context; + EGLConfig egl_ourconfig; #ifdef BENCHMARK_FPS long long last_benchmark_time; unsigned int num_benchmark_frames; diff --git a/player.cc b/player.cc old mode 100644 new mode 100755 diff --git a/videovpeogl.cc b/videovpeogl.cc old mode 100644 new mode 100755 index 418a7bb..95bafb2 --- a/videovpeogl.cc +++ b/videovpeogl.cc @@ -22,80 +22,22 @@ #include "audiovpe.h" #include "mtdraspberry.h" #include "demuxer.h" +#include "osdopengl.h" + // temp #include "log.h" - - -//taken from libsi -//taken and adapted from libdtv, (c) Rolf Hakenes -// CRC32 lookup table for polynomial 0x04c11db7 -unsigned int crc_table[256] = { - 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, - 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, - 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, - 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, - 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, - 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, - 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, - 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, - 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, - 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, - 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, - 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, - 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, - 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, - 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, - 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, - 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, - 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, - 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, - 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, - 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, - 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, - 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, - 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, - 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, - 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, - 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, - 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, - 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, - 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, - 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, - 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, - 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, - 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, - 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, - 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, - 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, - 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, - 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, - 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, - 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, - 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, - 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4}; - -unsigned int crc32 (const char *d, int len, unsigned int crc) -{ - register int i; - const unsigned char *u=(unsigned char*)d; // Saves '& 0xff' - - for (i=0; i> 24) ^ *u++)]; - - return crc; -} - - +//A lot of parts of this file are heavily inspired by xbmc omx implementations VideoVPEOGL::VideoVPEOGL() { if (instance) return; - muxout=NULL; - muxnumber=0; + lastpacketnum=-1; - audioconti=videoconti=0; - pmtversion=patversion=0; + omx_running=false; + + omx_vid_dec=0; + cur_input_buf_omx=NULL; } @@ -123,12 +65,94 @@ int VideoVPEOGL::init(UCHAR tformat) /* if (format == PAL) setLetterboxBorder("38"); else setLetterboxBorder("31");*/ + /* new stuff */ + + stop(); return 1; } +int VideoVPEOGL::initUsingOSDObjects() +{ + EGLDisplay i_egl_display; + EGLSurface i_egl_surface; + EGLContext i_egl_context; + OsdOpenGL *osd=(OsdOpenGL*)osd->getInstance(); + osd->getEGLObjs(&i_egl_display,&i_egl_surface,&i_egl_context); + + egl_display=i_egl_display; + egl_surface=i_egl_surface; + egl_context=i_egl_context; + + +#ifdef VPE_OMX_SUPPORT +// we are called before the audio + OMX_ERRORTYPE error; + error=OMX_Init(); + if (error!=OMX_ErrorNone) { + Log::getInstance()->log("Video", Log::DEBUG, "Init OMX failed %x", error); + return 0; + } + + //our callbacks move to play? + + + + +#endif + return 1; +} + + +#ifdef VPE_OMX_SUPPORT + +OMX_ERRORTYPE VideoVPEOGL::EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata, + OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1, + OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data) { + + Log::getInstance()->log("Video", Log::NOTICE, "eventHandler %x %x %x %x %x",handle,event_type,data1,data2,event_data); + +/* switch (event_type) { + case OMX_EventCmdComplete: { + + } break; + }*/ + + return OMX_ErrorNone; + +} + +OMX_ERRORTYPE VideoVPEOGL::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){ + + Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone"); + return OMX_ErrorNone; + +} + + OMX_ERRORTYPE VideoVPEOGL::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) { + Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone"); + return OMX_ErrorNone; +} + +#endif + +int VideoVPEOGL::shutdown() +{ + if (!initted) return 0; + initted = 0; + +#ifdef VPE_OMX_SUPPORT + DeAllocateCodecsOMX(); + OMX_Deinit(); +#endif + eglDestroyContext(egl_display,egl_context); +// close(fdVideo); + return 1; +} + + int VideoVPEOGL::setTVsize(UCHAR ttvsize) @@ -157,13 +181,6 @@ int VideoVPEOGL::setDefaultAspect() return setAspectRatio(tvsize); } -int VideoVPEOGL::shutdown() -{ - if (!initted) return 0; - initted = 0; -// close(fdVideo); - return 1; -} int VideoVPEOGL::setFormat(UCHAR tformat) @@ -301,54 +318,419 @@ int VideoVPEOGL::sync() return 1; } -void VideoVPEOGL::initMuxer(bool iframe) -{ - char buffer[1024]; - lastpacketnum=-1; - iframemode=iframe; - if (muxout) return; - sprintf(buffer,"/share/dev/muxout%d.ts",muxnumber); - filemutex.Lock(); - audioconti=videoconti=0; - muxout=fopen(buffer,"wb"); - filemutex.Unlock(); - WriteOutPATPMT(); - Log::getInstance()->log("Video", Log::DEBUG, - "Create file %s with result %d",buffer,muxout); -} -void VideoVPEOGL::deinitMuxer() -{ - if (muxout) - { - filemutex.Lock(); - FILE*temp=muxout; - muxout=NULL; - audioconti=videoconti=0; - filemutex.Unlock(); - Log::getInstance()->log("Video", Log::DEBUG, - "Close mux"); - - fclose(temp); - muxnumber++; - } -} int VideoVPEOGL::play() { if (!initted) return 0; +#ifdef VPE_OMX_SUPPORT + if (AllocateCodecsOMX()) { - + return 1; + // Otherwise fall back to ffmpeg + } +#endif // if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0; return 1; } +#ifdef VPE_OMX_SUPPORT +int VideoVPEOGL::AllocateCodecsOMX() +{ + OMX_ERRORTYPE error; + static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX}; + + Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX"); + //Clock, move later to audio + + error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks); + + + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "Init OMX clock failed %x", error); + DeAllocateCodecsOMX(); + return 0; + } + + + + OMX_PORT_PARAM_TYPE p_param; + p_param.nSize=sizeof(p_param); + p_param.nVersion.nVersion=OMX_VERSION; + error=OMX_GetParameter(omx_clock,OMX_IndexParamOtherInit,&p_param); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "Init clock OMX_GetParameter failed %x", error); + DeAllocateCodecsOMX(); + return 0; + } + omx_clock_output_port=p_param.nStartPortNumber+1; + + + OMX_TIME_CONFIG_CLOCKSTATETYPE clock_conf; + clock_conf.nSize=sizeof(clock_conf); + clock_conf.nVersion.nVersion=OMX_VERSION; + clock_conf.eState=OMX_TIME_ClockStateWaitingForStartTime; + clock_conf.nStartTime=0; + clock_conf.nOffset=0; + clock_conf.nWaitMask=OMX_CLOCKPORT0; + error=OMX_SetParameter(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error); + } + + + + if (h264) { + error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_H264_DECODER,NULL,&callbacks); + } else { + error=OMX_GetHandle(&omx_vid_dec,VPE_OMX_MPEG2_DECODER,NULL,&callbacks); + } + + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video decoder failed %x", error); + DeAllocateCodecsOMX(); + return 0; + } + + p_param.nSize=sizeof(p_param); + p_param.nVersion.nVersion=OMX_VERSION; + error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoInit,&p_param); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_GetParameter failed %x", error); + DeAllocateCodecsOMX(); + return 0; + } + omx_codec_input_port=p_param.nStartPortNumber; + omx_codec_output_port=p_param.nStartPortNumber+1; + + + error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler failed %x", error); + DeAllocateCodecsOMX(); + return 0; + } + + + + error=OMX_GetParameter(omx_vid_sched,OMX_IndexParamVideoInit,&p_param); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video scheduler OMX_GetParameter failed %x", error); + DeAllocateCodecsOMX(); + return 0; + } + omx_shed_input_port=p_param.nStartPortNumber; + omx_shed_output_port=p_param.nStartPortNumber+1; + omx_shed_clock_port=p_param.nStartPortNumber+2; + + + error=OMX_GetHandle(&omx_vid_rend,VPE_OMX_VIDEO_SCHED,NULL,&callbacks); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend failed %x", error); + DeAllocateCodecsOMX(); + return 0; + } + + error=OMX_GetParameter(omx_vid_rend,OMX_IndexParamVideoInit,&p_param); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "Init OMX video rend OMX_GetParameter failed %x", error); + DeAllocateCodecsOMX(); + return 0; + } + omx_rend_input_port=p_param.nStartPortNumber; + omx_rend_output_port=p_param.nStartPortNumber+1; + + //Setuo chain + + error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,omx_vid_sched,omx_shed_clock_port); + if (error!=OMX_ErrorNone){ + 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); + DeAllocateCodecsOMX(); + return 0; + } + + + error=OMX_SendCommand(omx_clock,OMX_CommandStateSet,OMX_StateExecuting,0); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "clock Send Command to OMX State Executing %x", error); + return 0; + } + + + + + + + + + + + + + + + OMX_VIDEO_PARAM_PORTFORMATTYPE ft_type; + ft_type.nSize=sizeof(ft_type); + ft_type.nVersion.nVersion=OMX_VERSION; + + ft_type.nPortIndex=omx_codec_input_port; + if (h264) { + ft_type.eCompressionFormat=OMX_VIDEO_CodingAVC; + } else { + ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2; + } + + + error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error); + return 0; + } + + Demuxer* demux=Demuxer::getInstance(); + + ft_type.xFramerate=demux->getFrameRate()*(1<<16); + error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexParamVideoPortFormat failed %x", error); + } +/* + if (h264) { + OMX_NALSTREAMFORMATTYPE nalu_type; + nalu_type.nSize=sizeof(nalu_type); + nalu_type.nVersion.nVersion=OMX_VERSION; + nalu_type.nPortIndex=omx_input_port; + + error=OMX_GetParameter(omx_vid_dec,(OMX_INDEXTYPE)OMX_IndexParamNalStreamFormatSupported, &nalu_type); + + if (error!=OMX_ErrorNone) { + Log::getInstance()->log("Video", Log::DEBUG, "Getting Nalutypes failed %x", error); + } + Log::getInstance()->log("Video", Log::DEBUG, "Nalutypes %x", nalu_type.eNaluFormat); + omx_nalu_format=nalu_type.eNaluFormat; + }*/ + + + + if (!PrepareInputBufsOMX()) { + return 0; + } + + + error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_sched,omx_shed_input_port); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to sched failed %x", error); + DeAllocateCodecsOMX(); + return 0; + } + + + + error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel sched to rend failed %x", error); + DeAllocateCodecsOMX(); + return 0; + } + + + + + + +/* + error=OMX_SendCommand(omx_vid_sched,OMX_CommandStateSet,OMX_StateIdle,0); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "vid_rend Send Command to OMX State Idle %x", error); + return 0; + } + + error=OMX_SendCommand(omx_vid_rend,OMX_CommandStateSet,OMX_StateIdle,0); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "vid_rend Send Command to OMX State Idle %x", error); + return 0; + }*/ + + + + + /* Code for querying supported formats well it says everything is supported ? + * ft_type.nIndex=0; + do { + error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamVideoPortFormat,&ft_type); + if (error!=OMX_ErrorNone && error != OMX_ErrorNoMore) { + Log::getInstance()->log("Video", Log::DEBUG, "Init OMX h264 decoder OMX_SetParameter failed %x", error); + omx_can_h264=false; + } else { + Log::getInstance()->log("Video", Log::DEBUG, "OMX format found %x", ft_type.eCompressionFormat); + omx_can_h264=true; + } + ft_type.nIndex++; + }while (error==OMX_ErrorNone);*/ + + + //todo alloc buffers + + + /* + +int getHorizontalSize() { return horizontal_size; } + int getVerticalSize() { return vertical_size; } + int getAspectRatio() { return aspect_ratio; } + int getFrameRate() { return frame_rate; } + + + + + }*/ + + + + + + + + + + return 1; +} + + + +int VideoVPEOGL::PrepareInputBufsOMX() +{ + OMX_ERRORTYPE error; + OMX_PARAM_PORTDEFINITIONTYPE port_def_type; + port_def_type.nSize=sizeof(port_def_type); + port_def_type.nVersion.nVersion=OMX_VERSION; + port_def_type.nPortIndex=omx_codec_input_port; + + error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type); + + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error); + } + input_bufs_omx_mutex.Lock(); + for (unsigned int i=0; i< port_def_type.nBufferCountMin;i++) { + + unsigned char* new_buffer_data=(unsigned char*)malloc(port_def_type.nBufferSize); + OMX_BUFFERHEADERTYPE *buf_head=NULL; + error=OMX_UseBuffer(omx_vid_dec,&buf_head,omx_codec_input_port,NULL,port_def_type.nBufferSize,new_buffer_data); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_UseBuffer failed %x", error); + input_bufs_omx_mutex.Unlock(); + return 0; + } + input_bufs_omx_all.push_back(buf_head); + input_bufs_omx_free.push_back(buf_head); + } + input_bufs_omx_mutex.Unlock(); + omx_first_frame=true; + omx_running=true; + firstsynched=false; + cur_input_buf_omx=NULL; + + return 1; +} + +int VideoVPEOGL::DestroyInputBufsOMX() +{ + OMX_ERRORTYPE error; + + cur_input_buf_omx=NULL; + input_bufs_omx_mutex.Lock(); + for (int i=0; i< input_bufs_omx_all.size();i++) { + free(input_bufs_omx_all[i]->pBuffer); + input_bufs_omx_all[i]->pBuffer=NULL; + error=OMX_FreeBuffer(omx_vid_dec,omx_codec_input_port,input_bufs_omx_all[i]); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error); + input_bufs_omx_mutex.Unlock(); + return 0; + } + } + input_bufs_omx_all.clear(); + input_bufs_omx_free.clear(); + input_bufs_omx_mutex.Unlock(); + +} + + + + +int VideoVPEOGL::DeAllocateCodecsOMX() +{ + OMX_ERRORTYPE error; + if (omx_vid_dec) { + DestroyInputBufsOMX(); + + //todo flushing + error=OMX_SetupTunnel(omx_vid_rend,omx_rend_input_port,NULL,NULL); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error); + + } + error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,NULL,NULL); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error); + + } + error=OMX_SetupTunnel(omx_vid_sched,omx_shed_input_port,NULL,NULL); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error); + + } + error=OMX_SetupTunnel(omx_vid_sched,omx_shed_clock_port,NULL,NULL); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error); + + } + + error=OMX_SetupTunnel(omx_clock,omx_clock_output_port,NULL,NULL); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error); + + } + + error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,NULL,NULL); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error); + + } + error=OMX_SetupTunnel(omx_vid_dec,omx_codec_input_port,NULL,NULL); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error); + + } + + + + error=OMX_FreeHandle(omx_vid_dec); + error=OMX_FreeHandle(omx_vid_sched); + error=OMX_FreeHandle(omx_vid_rend); + error=OMX_FreeHandle(omx_clock); + omx_vid_dec=NULL; + if (error!=OMX_ErrorNone) { + Log::getInstance()->log("Video", Log::DEBUG, "FreeHandle failed %d", error); + } + } + + return 1; +} + +#endif + int VideoVPEOGL::stop() { if (!initted) return 0; +#ifdef VPE_OMX_SUPPORT + //Check if ffmpeg mode + DeAllocateCodecsOMX(); +#endif + // if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0; @@ -460,292 +842,157 @@ void VideoVPEOGL::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepo mediapacket = mplist.front(); } -UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT* samplepos) +UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT *samplepos) { - if (!muxout) return 0; - - AudioVPE *audio=((AudioVPE*)audio->getInstance()); - // Log::getInstance()->log("Video", Log::DEBUG, "lastpacket %d lastbuddypacket %d currentpacket %d",lastpacketnum,audio->getLastPacketNum(),mediapacket.index); - - //format pes - switch (mediapacket.type) { - case MPTYPE_VIDEO_MPEG2: - h264=false; - buffer[mediapacket.pos_buffer + 3]=0xe0; break; - case MPTYPE_VIDEO_H264: - h264=true; - buffer[mediapacket.pos_buffer + 3]=0xe0; break; - }; - - - if (lastpacketnum!=-1 && mediapacket.index-1!=lastpacketnum && mediapacket.index-1>audio->getLastPacketNum() && mediapacket.index>audio->getCurrentPacketNum()) { - Log::getInstance()->log("Video", Log::DEBUG, "Packet not in order, packet num %d, lastpacketnum %d, audio lastpacketnum %d",mediapacket.index,lastpacketnum,audio->getLastPacketNum()); - return 0; //Not in order + DeliverMediaPacket(mediapacket, buffer, samplepos); + if (*samplepos == mediapacket.length) { + *samplepos = 0; + return 1; } - + else return 0; +} -/* filemutex.Lock(); - int written=fwrite(buffer + mediapacket.pos_buffer,1,mediapacket.length,muxout);*/ - if (mediapacket.synched) WriteOutPATPMT(); - int written=WriteOutTS(buffer + mediapacket.pos_buffer,mediapacket.length, mediapacket.type); - lastpacketnum=mediapacket.index; - //filemutex.Unlock(); - //Log::getInstance()->log("Video", Log::DEBUG, "wrote %d bytes to mux",written); - +UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet, + const UCHAR* buffer, + UINT *samplepos) +{ - if (written == (int)mediapacket.length) { *samplepos = 0; return 1;} - if (written <= 0) { - return 0; - } - *samplepos = written; - // Handle a partial write. Is this possible? Should we bother? No! - - return 1; -} -/* + /*First Check, if we have an audio sample*/ -int VideoVPEOGL::WriteOutPCR(ULLONG pts) -{ - unsigned char ts_buffer[188]; - unsigned char ts_crc[4]; - unsigned char conti; - memset(ts_buffer,0xFF,188); - - conti=videoconti; - ts_buffer[0]=0x47; //TS_SYNC - ts_buffer[1]=0x40; //Payload_start - ts_buffer[2]=100; - ts_buffer[3]=0x20| conti; - ts_buffer[4]=183; - ts_buffer[5]=0x10; //PCR! - - - - int tocopy=length; - unsigned char *dest=buffer; - filemutex.Lock(); - unsigned int outlength=184; - while (tocopy>=outlength) { - - ts_buffer[3]=0x10 | conti; - fwrite(ts_buffer,1,4,muxout); //Header out - - fwrite(dest,1, outlength,muxout); - - - dest+=outlength; - tocopy-=outlength; - conti++; - conti&=0x0F; - ts_buffer[1]=0x00; //Payload_start - } - if (tocopy>0) { - ts_buffer[3]=0x30 | conti;//we have an adpation field - fwrite(ts_buffer,1,4,muxout); //Header out - unsigned char adaptionfield[2]={outlength-tocopy-1,0x00}; - if (tocopy<183) fwrite(adaptionfield,1,2,muxout); - else fwrite(adaptionfield,1,1,muxout); - unsigned char paddy=0xFF; - if (outlength>tocopy+2) { - for (int i=0;i<(outlength-tocopy-2);i++) fwrite(&paddy,1,1,muxout); - } - fwrite(dest,1,tocopy,muxout); - } - - - conti++; - conti&=0x0F; - filemutex.Unlock(); - - - videoconti=conti; - -}*/ - -int VideoVPEOGL::WriteOutTS(const unsigned char *buffer,int length, int type) -{ - unsigned char ts_buffer[4]; - unsigned char ts_crc[4]; - unsigned char conti; - ts_buffer[0]=0x47; //TS_SYNC - ts_buffer[1]=0x40; //Payload_start - switch (type) { - case MPTYPE_VIDEO_MPEG2: - case MPTYPE_VIDEO_H264: - conti=videoconti; - ts_buffer[2]=100; break; - - case MPTYPE_MPEG_AUDIO: - conti=audioconti; - ts_buffer[2]=101; break; - case MPTYPE_AC3: - case MPTYPE_AC3_PRE13: - conti=audioconti; - ts_buffer[2]=102; break; - default: - return 0; break; //???? - }; - int tocopy=length; - const unsigned char *dest=buffer; - filemutex.Lock(); - unsigned int outlength=184; - while (tocopy>=outlength) { - - ts_buffer[3]=0x10 | conti; - fwrite(ts_buffer,1,4,muxout); //Header out - - fwrite(dest,1, outlength,muxout); - - - dest+=outlength; - tocopy-=outlength; - conti++; - conti&=0x0F; - ts_buffer[1]=0x00; //Payload_start - } - if (tocopy>0) { - ts_buffer[3]=0x30 | conti;//we have an adpation field - fwrite(ts_buffer,1,4,muxout); //Header out - unsigned char adaptionfield[2]={outlength-tocopy-1,0x00}; - if (tocopy<183) fwrite(adaptionfield,1,2,muxout); - else fwrite(adaptionfield,1,1,muxout); - unsigned char paddy=0xFF; - if (outlength>tocopy+2) { - for (int i=0;i<(outlength-tocopy-2);i++) fwrite(&paddy,1,1,muxout); - } - fwrite(dest,1,tocopy,muxout); - } - - - conti++; - conti&=0x0F; - filemutex.Unlock(); - - switch (type) { - case MPTYPE_VIDEO_MPEG2: - case MPTYPE_VIDEO_H264: - videoconti=conti; break; - - case MPTYPE_MPEG_AUDIO: - case MPTYPE_AC3: - case MPTYPE_AC3_PRE13: - audioconti=conti; - break; - }; - return length; - -} - -void VideoVPEOGL::WriteOutPATPMT() -{ - unsigned char ts_buffer[188]; - //PAT - memset(ts_buffer,0xFF,188); - ts_buffer[0]=0x47; //TS_SYNC - ts_buffer[1]=0x40; //Payload_start - ts_buffer[2]=0x00; - ts_buffer[3]=0x10; - ts_buffer[4]=0x00; - ts_buffer[5]=0x00;//table id - ts_buffer[6]=0xB0; //Section syntax - ts_buffer[7]=13; //Section length - ts_buffer[8]=0x80;//PSID - ts_buffer[9]=0x08;//PSID lo - ts_buffer[10]=0xC1 | (patversion << 1); - ts_buffer[11]=0x00;//section numbrt - ts_buffer[12]=0x00; - ts_buffer[13]=0x00; //hi program number - ts_buffer[14]=98; - ts_buffer[15]=0xe0; - ts_buffer[16]=98; - int crc =crc32((const char *)ts_buffer+5, 12, 0xFFFFFFFF); - int i = 0; - ts_buffer[17] = crc >> 24; - ts_buffer[18] = crc >> 16; - ts_buffer[19] = crc >> 8; - ts_buffer[20] = crc; - patversion++; - patversion&=0x1F; - filemutex.Lock(); - fwrite(ts_buffer,1,188,muxout); //Header out - filemutex.Unlock(); - - //PMT - memset(ts_buffer,0xFF,188); - ts_buffer[0]=0x47; //TS_SYNC - ts_buffer[1]=0x40; //Payload_start - ts_buffer[2]=98; - ts_buffer[3]=0x10; - ts_buffer[4]=0x00; - ts_buffer[5]=0x02;//table id - ts_buffer[6]=0xB0; //Section syntax - ts_buffer[7]=23; //Section length - ts_buffer[8]=0x00;//PSID - ts_buffer[9]=98;//PSID lo - ts_buffer[10]=0xC1 | (pmtversion << 1); - ts_buffer[11]=0x00;//section numbrt - ts_buffer[12]=0x00; - ts_buffer[13]=0xE0 | 0x1F; - ts_buffer[14]=0xFF;//Video is pcr - ts_buffer[15]=0xF0;//dummy - ts_buffer[16]=0x00; //program info - //Video - - if (h264) + if (packet.type == MPTYPE_VIDEO_H264) { - ts_buffer[17] = 0x1B; // stream type video + h264=true; } else { - ts_buffer[17] = 0x02; // stream type video - } - ts_buffer[18] = 0xE0; // - ts_buffer[19]=100; //Video pid - ts_buffer[20]= 0xF0; // - ts_buffer[21]= 0x00; // - // audio - int add_length=0; - unsigned char atype=((AudioVPE*)Audio::getInstance())->getLastAType(); - switch (atype) { - default: - case MPTYPE_MPEG_AUDIO: - ts_buffer[22] = 0x04; // stream type audio - ts_buffer[23] = 0xE0; // - ts_buffer[24]=101; //Audio pid - ts_buffer[25]= 0xF0; // - ts_buffer[26]= 0x00; // - break; - case MPTYPE_AC3: - case MPTYPE_AC3_PRE13: - ts_buffer[22] = 0x06; // stream type private - ts_buffer[23] = 0xE0; // - ts_buffer[24]=102; //ac3 - ts_buffer[25]= 0xF0; // - ts_buffer[26]= 0x03; // - ts_buffer[27] = 0x6A; - ts_buffer[28] = 0x01; // length - ts_buffer[29] = 0x00; - ts_buffer[7]+=3; - add_length=3; - break; - }; - crc =crc32((const char *)ts_buffer+5, 22+add_length, 0xFFFFFFFF); - ts_buffer[27+add_length] = crc >> 24; - ts_buffer[28+add_length] = crc >> 16; - ts_buffer[29+add_length] = crc >> 8; - ts_buffer[30+add_length] = crc; - pmtversion++; - pmtversion&=0x1F; - filemutex.Lock(); - fwrite(ts_buffer,1,188,muxout); //Header out - filemutex.Unlock(); - - - + h264=false; + } + //Later add fail back code for ffmpeg + /*if (!videoon) { + *samplepos+=packet.length; + return packet.length; + }*/ + +#ifdef VPE_OMX_SUPPORT + if (!omx_running) return 0; // if we are not runnig do not do this + + + /*First Check, if we have an audio sample*/ + if (iframemode) { + //samplepos=0; + MILLISLEEP(10); + return 0; //Not in iframe mode! + } + + + + UINT headerstrip=0; + if (packet.disconti) { + firstsynched=false; + if (cur_input_buf_omx) { + OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx); + if (error!=OMX_ErrorNone){ + Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error); + } + cur_input_buf_omx=NULL; + } + } + + /*Inspect PES-Header */ + + + + + if (*samplepos==0) {//stripheader + headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/; + *samplepos+=headerstrip; + if ( packet.synched ) { + if (cur_input_buf_omx) { + OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx); + + cur_input_buf_omx=NULL;//write out old data + } + // reftime1=packet.presentation_time; + // reftime2=reftime1+1; + firstsynched=true; + } else { + if (!firstsynched) {// + *samplepos=packet.length;//if we have not processed at least one + return packet.length;//synched packet ignore it! + } + } + } + + if (!cur_input_buf_omx) { + input_bufs_omx_mutex.Lock(); + if (input_bufs_omx_free.size()==0) { + input_bufs_omx_mutex.Unlock(); + return 0; // we do not have a free media sample + + } + cur_input_buf_omx=input_bufs_omx_free.front(); + cur_input_buf_omx->nFilledLen=0; + cur_input_buf_omx->nOffset=0; + input_bufs_omx_free.pop_front(); + input_bufs_omx_mutex.Unlock(); + } + + + + + + if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet + /*if (packet.disconti) { + ms->SetDiscontinuity(TRUE); + } else { + ms->SetDiscontinuity(FALSE); + }*/ + //if (packet.synched) { + + + //lastreftimePTS=packet.pts; + if (omx_first_frame) { // TODO time + cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_STARTTIME; + } else + + //} + //else + //{ + cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN; + + + // ms->SetSyncPoint(TRUE); + //} + + } + unsigned int haveToCopy=packet.length-*samplepos; + + if (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) { + cur_input_buf_omx->pBuffer=(OMX_U8*)realloc(cur_input_buf_omx->pBuffer,cur_input_buf_omx->nFilledLen+haveToCopy); + cur_input_buf_omx->nAllocLen=cur_input_buf_omx->nFilledLen+haveToCopy; + } + memcpy(cur_input_buf_omx->pBuffer,buffer+packet.pos_buffer+*samplepos,haveToCopy); + cur_input_buf_omx->nFilledLen=cur_input_buf_omx->nFilledLen+haveToCopy; + + + + *samplepos+=haveToCopy; + + return haveToCopy+headerstrip; + +#else + + *samplepos+=packet.length; //yet not implemented//bad idea + return packet.length; +#endif } + + + + void VideoVPEOGL::ResetTimeOffsets() { } @@ -754,7 +1001,7 @@ bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length) { //write(fdVideo, buffer, length); if (!iframemode) EnterIframePlayback(); - WriteOutTS(buffer,length, h264?MPTYPE_VIDEO_H264 :MPTYPE_VIDEO_MPEG2 ); +// WriteOutTS(buffer,length, h264?MPTYPE_VIDEO_H264 :MPTYPE_VIDEO_MPEG2 ); lastpacketnum=-1; return true; @@ -762,8 +1009,7 @@ bool VideoVPEOGL::displayIFrame(const UCHAR* buffer, UINT length) int VideoVPEOGL::EnterIframePlayback() { - deinitMuxer(); - initMuxer(true); + return 0; } diff --git a/videovpeogl.h b/videovpeogl.h old mode 100644 new mode 100755 index f554ad4..98d8e08 --- a/videovpeogl.h +++ b/videovpeogl.h @@ -32,12 +32,40 @@ #include +#include +#include + #include "defines.h" #include "video.h" -#define WRITE_PACKETS 16 -#define WRITE_LENGTH (32*1024) +//#define EGL_EGLEXT_PROTOTYPES + +#include +#include +#include + +#ifdef VPE_OMX_SUPPORT + +#include +#include +#include +#include + +#endif + + +/* +struct VPEOGLFrame { + int type; //1 = RGB, 2 YUV + GLuint textures[3]; // 0=RGB or Y, 1=U 2=V + +#ifdef VPE_OMX_SUPPORT + //OMX + EGLImageKHR khr_image; + OMX_BUFFERHEADERTYPE *omx_buf; +#endif +};*/ class VideoVPEOGL : public Video { @@ -85,10 +113,9 @@ class VideoVPEOGL : public Video void WriteOutPATPMT(); - Mutex *getMuxMutex() {return &filemutex;}; //File must be pointer of pointer Thread safety! - FILE *getMuxFile() {return muxout;}; //File must be pointer of pointer Thread safety! - void initMuxer(bool iframe=false); - void deinitMuxer(); + + + int getLastPacketNum() {return lastpacketnum;}; #ifdef DEV @@ -96,16 +123,74 @@ class VideoVPEOGL : public Video int test2(); #endif + int initUsingOSDObjects(); + int shutdownUsingOSDObjects() {return shutdown();}; + private: int EnterIframePlayback(); bool iframemode; + + UINT DeliverMediaPacket(MediaPacket packet, + const UCHAR* buffer, + UINT *samplepos); + +#ifdef VPE_OMX_SUPPORT + static OMX_ERRORTYPE EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata, + OMX_IN OMX_EVENTTYPE event_type,OMX_IN OMX_U32 data1, + OMX_IN OMX_U32 data2,OMX_IN OMX_PTR event_data); + static OMX_ERRORTYPE EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer); + static OMX_ERRORTYPE FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer); + + + int PrepareInputBufsOMX(); + int DestroyInputBufsOMX(); + + + + OMX_HANDLETYPE omx_vid_dec; + OMX_HANDLETYPE omx_vid_sched; + OMX_HANDLETYPE omx_vid_rend; + OMX_HANDLETYPE omx_clock; + + + OMX_U32 omx_codec_input_port; + OMX_U32 omx_codec_output_port; + OMX_U32 omx_rend_input_port; + OMX_U32 omx_rend_output_port; + OMX_U32 omx_shed_input_port; + OMX_U32 omx_shed_output_port; + OMX_U32 omx_shed_clock_port; + OMX_U32 omx_clock_output_port; + // OMX_NALUFORMATSTYPE omx_nalu_format; + + + + int AllocateCodecsOMX(); + int DeAllocateCodecsOMX(); + + vector input_bufs_omx_all; + list input_bufs_omx_free; + Mutex input_bufs_omx_mutex; + OMX_BUFFERHEADERTYPE* cur_input_buf_omx; + + bool omx_running; + bool omx_first_frame; + + + +#endif - FILE* muxout; - int muxnumber; - Mutex filemutex; + + + bool firstsynched; int lastpacketnum; - unsigned char audioconti,videoconti; - unsigned int patversion,pmtversion; + + EGLDisplay egl_display; + EGLSurface egl_surface; + EGLContext egl_context; + + + MediaPacket mediapacket; }; -- 2.39.2