From 117c34d17f9cc79cca58743613147799fbbf7619 Mon Sep 17 00:00:00 2001
From: Marten Richter <marten.richter@freenet.de>
Date: Sun, 3 Jun 2012 11:23:26 +0200
Subject: [PATCH] Bugfix + Initial fallback to ffmpeg, no decoding yet

---
 GNUmakefile    |   2 +-
 audiovpe.cc    |   1 -
 defines.h      |   2 +
 videovpeogl.cc | 364 ++++++++++++++++++++++++++++++++++++++++++++-----
 videovpeogl.h  |  26 ++++
 5 files changed, 356 insertions(+), 39 deletions(-)

diff --git a/GNUmakefile b/GNUmakefile
index 1c88c6a..a6bcb26 100755
--- 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 -lopenmaxil -lbcm_host
+LIBS = -L/opt/vc/lib -lpthread -lrt -lEGL -lGLESv2 -lopenmaxil -lbcm_host   -lavcodec -lavformat -lavutil
 
 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
index 26ddaf0..f1dd4be 100755
--- a/audiovpe.cc
+++ b/audiovpe.cc
@@ -24,7 +24,6 @@
 
 AudioVPE::AudioVPE()
 {
-  if (instance) return;
   initted = 0;
   lastpacketnum=-1;
   currentpacketnum=-1;
diff --git a/defines.h b/defines.h
index c252b79..c640c1b 100755
--- a/defines.h
+++ b/defines.h
@@ -101,6 +101,8 @@ void MILLISLEEP(ULONG a);
    #define VPE_OMX_VIDEO_DEINTERLACE "OMX.broadcom.image_fx"
    #define VPE_OMX_CLOCK "OMX.broadcom.clock"
 
+   #define  VPE_FFMPEG_SUPPORT
+
 #endif
 #ifdef VOMP_PLATTFORM_MVP
   #define Remote_TYPE RemoteMVP
diff --git a/videovpeogl.cc b/videovpeogl.cc
index 866b9e9..8d944d8 100755
--- a/videovpeogl.cc
+++ b/videovpeogl.cc
@@ -31,14 +31,20 @@
 
 VideoVPEOGL::VideoVPEOGL()
 {
-  if (instance) return;
-
   lastpacketnum=-1;
+
+#ifdef VPE_OMX_SUPPORT
   omx_running=false;
 
   omx_vid_dec=0;
   cur_input_buf_omx=NULL;
   omx_h264=omx_mpeg2=true;
+#endif
+
+#ifdef VPE_FFMPEG_SUPPORT
+  mpeg2codec_context_ff=NULL;
+  dec_frame_ff=NULL;
+#endif
   
 }
 
@@ -99,8 +105,17 @@ int VideoVPEOGL::initUsingOSDObjects()
 
 	//our callbacks move to play?
 
+#endif
 
+#ifdef VPE_FFMPEG_SUPPORT
 
+	av_register_all();
+	mpeg2codec_ff=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
+	//mpeg2codec_ff=avcodec_find_decoder(CODEC_ID_MPEG2VIDEO_XVMC);
+	if (mpeg2codec_ff==NULL) {
+		Log::getInstance()->log("Video", Log::DEBUG, "Find ffmpeg mpeg2 codec failed");
+		return 0;
+	}
 
 #endif
 	return 1;
@@ -173,9 +188,13 @@ int VideoVPEOGL::shutdown()
   if (!initted) return 0;
   initted = 0;
 
+  decoding_backend=0;
 #ifdef VPE_OMX_SUPPORT
   DeAllocateCodecsOMX();
   OMX_Deinit();
+#endif
+#ifdef VPE_FFMPEG_SUPPORT
+  DeAllocateCodecsFFMPEG();
 #endif
   eglDestroyContext(egl_display,egl_context);
 //  close(fdVideo);
@@ -354,24 +373,41 @@ int VideoVPEOGL::sync()
 int VideoVPEOGL::play()
 {
   if (!initted) return 0;
+  decoding_backend=0;
 #ifdef VPE_OMX_SUPPORT
-  if (AllocateCodecsOMX()) {
-
-	  return 1;
-	  // Otherwise fall back to ffmpeg
+  bool doomx=true;
+  if (h264) {
+	  if (!omx_h264) doomx=false;
   } else {
-	  if (h264) {
-		  omx_h264=false;
-		  Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed asuume h264 unsupported");
+	  if (!omx_mpeg2) doomx=false;
+  }
+  if (doomx) {
+	  if (AllocateCodecsOMX()) {
+		  decoding_backend=VPE_DECODER_OMX;
+		  return 1;
+		  // Otherwise fall back to ffmpeg
 	  } else {
-		  omx_mpeg2=false;
-		  Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed asuume mpeg2 unsupported");
+		  if (h264) {
+			  omx_h264=false;
+			  Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume h264 unsupported");
+		  } else {
+			  omx_mpeg2=false;
+			  Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX failed assume mpeg2 unsupported");
+		  }
 	  }
   }
 #endif
+#ifdef VPE_FFMPEG_SUPPORT
+  if (AllocateCodecsFFMPEG()) {
+	  decoding_backend=VPE_DECODER_FFMPEG;
+	  return 1;
+	  	  // Otherwise fall back to ffmpeg
+  }
+#endif
+  return 0;
+
+
 
-//  if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
-  return 1;
 }
 
 #ifdef VPE_OMX_SUPPORT
@@ -411,6 +447,7 @@ int VideoVPEOGL::AllocateCodecsOMX()
 	for (unsigned int i=0;i<p_param.nPorts;i++) {
 		if (!DisablePort(omx_clock,p_param.nStartPortNumber+i) ) {
 			Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX clock failed %d",i);
+			DeAllocateCodecsOMX();
 			return 0;
 		}
 	}
@@ -427,6 +464,8 @@ int VideoVPEOGL::AllocateCodecsOMX()
 	error=OMX_SetParameter(omx_clock,OMX_IndexConfigTimeClockState,&clock_conf);
 	if (error!=OMX_ErrorNone){
 		Log::getInstance()->log("Video", Log::DEBUG, "Clock IndexConfigTimeClockState failed %x", error);
+		DeAllocateCodecsOMX();
+		return 0;
 	}
 
 
@@ -459,6 +498,7 @@ int VideoVPEOGL::AllocateCodecsOMX()
 
 	if (!DisablePort(omx_vid_dec,omx_codec_input_port) || !DisablePort(omx_vid_dec,omx_codec_output_port)) {
 		Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video decoder failed");
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
@@ -472,6 +512,8 @@ int VideoVPEOGL::AllocateCodecsOMX()
 	error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamBrcmVideoDecodeErrorConcealment,&conceal);
 	if (error!=OMX_ErrorNone){
 		Log::getInstance()->log("Video", Log::DEBUG, "OMX_IndexParamBrcmVideoDecodeErrorConcealment failed %x", error);
+		DeAllocateCodecsOMX();
+		return 0;
 	}
 
 
@@ -506,6 +548,7 @@ int VideoVPEOGL::AllocateCodecsOMX()
 	if (!DisablePort(omx_vid_sched,omx_shed_input_port) || !DisablePort(omx_vid_sched,omx_shed_output_port)
 			|| !DisablePort(omx_vid_sched,omx_shed_clock_port)) {
 		Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video shed failed");
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
@@ -529,8 +572,9 @@ int VideoVPEOGL::AllocateCodecsOMX()
 
 	if (!DisablePort(omx_vid_rend,omx_rend_input_port) /*|| !DisablePort(omx_vid_rend,omx_rend_output_port)*/
 				) {
-			Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
-			return 0;
+		Log::getInstance()->log("Video", Log::DEBUG, "Disable Ports OMX video rend failed");
+		DeAllocateCodecsOMX();
+		return 0;
 	}
 
 	//Setuo chain
@@ -570,23 +614,27 @@ int VideoVPEOGL::AllocateCodecsOMX()
 	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);
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
 
 	if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
 		Log::getInstance()->log("Video", Log::DEBUG, "vid_dec ChangeComponentState");
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
 
 	if (!PrepareInputBufsOMX()) {
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
 
 	if (!ChangeComponentState(omx_clock,OMX_StateIdle)) {
 		Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Idle");
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
@@ -600,10 +648,12 @@ int VideoVPEOGL::AllocateCodecsOMX()
 	if (!EnablePort(omx_clock,omx_clock_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_clock_port,false)
 					) {
 		Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX clock shed failed");
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
 	if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
@@ -619,6 +669,7 @@ int VideoVPEOGL::AllocateCodecsOMX()
 	if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
 						) {
 		Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec shed failed");
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
@@ -626,17 +677,20 @@ int VideoVPEOGL::AllocateCodecsOMX()
 		return 0;
 	}
 	if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
-				Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
-				return 0;
+		Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
+		DeAllocateCodecsOMX();
+		return 0;
 	}
 	if (!CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)
 			||!CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port)){
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
 	if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
-			Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
-			return 0;
+		Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_dec ChangeComponentState Execute");
+		DeAllocateCodecsOMX();
+		return 0;
 	}
 
 	error=OMX_SetupTunnel(omx_vid_sched,omx_shed_output_port,omx_vid_rend,omx_rend_input_port);
@@ -649,27 +703,32 @@ int VideoVPEOGL::AllocateCodecsOMX()
 	if (!EnablePort(omx_vid_sched,omx_shed_output_port,false) || !EnablePort(omx_vid_rend,omx_rend_input_port,false)
 							) {
 		Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX  shed rend failed");
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
 	if (!CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_output_port)
 					|| !CommandFinished(omx_vid_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
-			return 0;
+		DeAllocateCodecsOMX();
+		return 0;
 	}
 
 	if (!ChangeComponentState(omx_vid_rend,OMX_StateIdle)) {
 		Log::getInstance()->log("Video", Log::DEBUG, "vid_rend ChangeComponentState");
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
 
 	if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
 		Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
 	if (!ChangeComponentState(omx_vid_rend,OMX_StateExecuting)) {
 		Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_rend ChangeComponentState Execute");
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
@@ -686,6 +745,7 @@ int VideoVPEOGL::AllocateCodecsOMX()
 	error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
 	if (error!=OMX_ErrorNone){
 		Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
@@ -694,6 +754,7 @@ int VideoVPEOGL::AllocateCodecsOMX()
 	error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
 	if (error!=OMX_ErrorNone){
 		Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
+		DeAllocateCodecsOMX();
 		return 0;
 	}
 
@@ -705,6 +766,7 @@ int VideoVPEOGL::AllocateCodecsOMX()
 	error=OMX_SetParameter(omx_vid_rend,OMX_IndexConfigDisplayRegion,&dispconf);
 	if (error!=OMX_ErrorNone){
 		Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigDisplayRegion failed %x", error);
+		DeAllocateCodecsOMX();
 		return 0;
 	}*/
 
@@ -713,6 +775,7 @@ int VideoVPEOGL::AllocateCodecsOMX()
 
 	if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
 			Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Exccute");
+			DeAllocateCodecsOMX();
 			return 0;
 	}
 
@@ -830,10 +893,9 @@ int VideoVPEOGL::PrepareInputBufsOMX()
 	if (error!=OMX_ErrorNone){
 			Log::getInstance()->log("Video", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
 	}
-	Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
+/*	Log::getInstance()->log("Video", Log::DEBUG, "Port para %d %d %d %d %d %d %d", port_def_type.nBufferCountActual,
 			port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
-			port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);
-	Log::getInstance()->log("Video", Log::DEBUG, "OMX minimum buffer num %d", port_def_type.nBufferCountMin);
+			port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
 
 	port_def_type.nBufferCountActual=60;
 
@@ -844,17 +906,11 @@ int VideoVPEOGL::PrepareInputBufsOMX()
 	}
 
 
-	Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark1");
 	error=OMX_SendCommand(omx_vid_dec,OMX_CommandPortEnable,omx_codec_input_port,0);
 	if (error!=OMX_ErrorNone){
 		Log::getInstance()->log("Video", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
 		return 0;
 	}
-	Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark2");
-
-
-
-	Log::getInstance()->log("Video", Log::DEBUG, "PrepareInputBufsOMX mark2a");
 
 	input_bufs_omx_mutex.Lock();
 	for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
@@ -1073,6 +1129,56 @@ int VideoVPEOGL::DeAllocateCodecsOMX()
 	return 1;
 }
 
+#endif
+
+
+#ifdef VPE_FFMPEG_SUPPORT
+
+int VideoVPEOGL::AllocateCodecsFFMPEG()
+{
+	Log::getInstance()->log("Video", Log::NOTICE, "AllocateCodecsFFmpeg");
+	mpeg2codec_context_ff=avcodec_alloc_context();
+	if (mpeg2codec_context_ff==NULL) {
+		Log::getInstance()->log("Video", Log::DEBUG, "Creating ffmpeg codec context failed");
+		return 0;
+	}
+	if(avcodec_open(mpeg2codec_context_ff, mpeg2codec_ff)<0) {
+		Log::getInstance()->log("Video", Log::DEBUG, "Opening ffmpeg codec  failed");
+		return 0;
+	}
+	dec_frame_ff=avcodec_alloc_frame(); // may be we need multiple frames, if we want to use async texture upload
+	if (!dec_frame_ff) {
+		Log::getInstance()->log("Video", Log::DEBUG, "Allocating dec_frame  failed");
+		return 0;
+	}
+
+	return 1;
+
+}
+
+int VideoVPEOGL::DeAllocateCodecsFFMPEG()
+{
+	Log::getInstance()->log("Video", Log::NOTICE, "DeAllocateCodecsFFmpeg");
+	if (dec_frame_ff) {
+		av_free(dec_frame_ff);
+		dec_frame_ff=NULL;
+	}
+	if (mpeg2codec_context_ff) {
+		avcodec_close(mpeg2codec_context_ff);
+		av_free(mpeg2codec_context_ff);
+		mpeg2codec_context_ff=NULL;
+
+	}
+
+
+
+	return 1;
+}
+
+
+
+
+
 #endif
 
 int VideoVPEOGL::stop()
@@ -1081,7 +1187,9 @@ int VideoVPEOGL::stop()
 
 #ifdef VPE_OMX_SUPPORT
   //Check if ffmpeg mode
-  DeAllocateCodecsOMX();
+  if (decoding_backend==VPE_DECODER_OMX) DeAllocateCodecsOMX();
+  decoding_backend=0;
+
 #endif
 
   
@@ -1205,13 +1313,10 @@ UINT VideoVPEOGL::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
   else return 0;
 }
 
-
-
 UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
 		const UCHAR* buffer,
 		UINT *samplepos)
 {
-
 	if (packet.type == MPTYPE_VIDEO_H264)
 	{
 		h264=true;
@@ -1220,13 +1325,31 @@ UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
 	{
 		h264=false;
 	}
+	switch (decoding_backend) {
+	default: case 0: return 0; // no backend runnigng
+#ifdef VPE_OMX_SUPPORT
+	case VPE_DECODER_OMX: return DeliverMediaPacketOMX(packet,buffer,samplepos);
+#endif
+#ifdef VPE_FFMPEG_SUPPORT
+	case VPE_DECODER_FFMPEG: return DeliverMediaPacketFFMPEG(packet,buffer,samplepos);
+#endif
+	}
+}
+
+#ifdef VPE_OMX_SUPPORT
+UINT VideoVPEOGL::DeliverMediaPacketOMX(MediaPacket packet,
+		const UCHAR* buffer,
+		UINT *samplepos)
+{
+
+
 	//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
 
 
@@ -1376,13 +1499,180 @@ UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
 
 	return *samplepos;
 
-#else
+}
+
+#endif
+
+
+#ifdef VPE_FFMPEG_SUPPORT
+UINT VideoVPEOGL::DeliverMediaPacketFFMPEG(MediaPacket packet,
+		const UCHAR* buffer,
+		UINT *samplepos)
+{
+
+#if 0
+	//Later add fail back code for ffmpeg
+	/*if (!videoon) {
+		*samplepos+=packet.length;
+		return packet.length;
+	}*/
+
+
+	if (!omx_running) return 0; // if we are not runnig do not do this
+
+
+	OMX_ERRORTYPE error;
+
+	OMX_PARAM_PORTDEFINITIONTYPE port_image;
+	memset(&port_image,0,sizeof(port_image));
+	port_image.nSize=sizeof(port_image);
+	port_image.nVersion.nVersion=OMX_VERSION;
+	port_image.nPortIndex =omx_codec_output_port;
+	error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_image);
+	if (error!= OMX_ErrorNone){
+		Log::getInstance()->log("Video", Log::DEBUG, "OMX_GetParameter failed %x", error);
+	}
+	Log::getInstance()->log("Video", Log::DEBUG, "Image port %d %d", port_image.format.video.nFrameWidth , port_image.format.video.nFrameHeight);
+
+	/*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 */
+
+	OMX_STATETYPE temp_state;
+	OMX_GetState(omx_vid_dec,&temp_state);
+
+	if (*samplepos==0) {//stripheader
+		headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
+		//headerstrip+=6; //h264
+		*samplepos+=headerstrip;
+		if ( packet.synched ) {
+
+			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;//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();
+			Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
+			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;
+		cur_input_buf_omx->nTimeStamp=0;
+		input_bufs_omx_free.pop_front();
+		input_bufs_omx_mutex.Unlock();
+	}
+
+
+
 
-	*samplepos+=packet.length; //yet not implemented//bad idea
-	return packet.length;
+	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;
+			   omx_first_frame=false;
+		   } else
+
+		//}
+		//else
+		//{
+			cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
+
+
+			//  ms->SetSyncPoint(TRUE);
+		//}
+
+	}
+	unsigned int haveToCopy=packet.length-*samplepos;
+
+	while (haveToCopy> (cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen)) {
+		unsigned int cancopy=cur_input_buf_omx->nAllocLen-cur_input_buf_omx->nFilledLen;
+		memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,buffer+packet.pos_buffer+*samplepos,cancopy);
+		haveToCopy-=cancopy;
+		cur_input_buf_omx->nFilledLen+=cancopy;
+		*samplepos+=cancopy;
+		// push old buffer out
+
+		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);
+		}
+		// get5 new buffer
+		input_bufs_omx_mutex.Lock();
+		if (input_bufs_omx_free.size()==0) {
+			input_bufs_omx_mutex.Unlock();
+			//Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample");
+			return *samplepos; // 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;
+		cur_input_buf_omx->nTimeStamp=0;
+		input_bufs_omx_free.pop_front();
+		input_bufs_omx_mutex.Unlock();
+
+		cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
+
+	}
+	memcpy(cur_input_buf_omx->pBuffer+cur_input_buf_omx->nFilledLen,
+			buffer+packet.pos_buffer+*samplepos,haveToCopy);
+	cur_input_buf_omx->nFilledLen+=haveToCopy;
+
+
+
+	*samplepos+=haveToCopy;
+
+	return *samplepos;
 #endif
+	return 0;
+
 }
 
+#endif
+
 
 
 
diff --git a/videovpeogl.h b/videovpeogl.h
index e308a1f..855b91a 100755
--- a/videovpeogl.h
+++ b/videovpeogl.h
@@ -63,6 +63,13 @@ struct VPE_OMX_EVENT {
 
 #endif
 
+#ifdef VPE_FFMPEG_SUPPORT
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+}
+#endif
+
 
 
 
@@ -145,6 +152,9 @@ class VideoVPEOGL : public Video
 	   UINT DeliverMediaPacket(MediaPacket packet,
 	                                     const UCHAR* buffer,
 	                                     UINT *samplepos);
+	   int decoding_backend; //1 omx, 2 ffmpeg
+#define VPE_DECODER_OMX 1
+#define VPE_DECODER_FFMPEG 2
 
 #ifdef VPE_OMX_SUPPORT
 	   static OMX_ERRORTYPE EventHandler_OMX(OMX_IN OMX_HANDLETYPE handle,OMX_IN OMX_PTR appdata,
@@ -153,6 +163,9 @@ class VideoVPEOGL : public Video
 	   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);
 
+	   UINT DeliverMediaPacketOMX(MediaPacket packet,
+	  	                                     const UCHAR* buffer,
+	  	                                     UINT *samplepos);
 
 	   int PrepareInputBufsOMX();
 	   int DestroyInputBufsOMX();
@@ -193,6 +206,7 @@ class VideoVPEOGL : public Video
 	   Mutex input_bufs_omx_mutex;
 	   OMX_BUFFERHEADERTYPE* cur_input_buf_omx;
 
+
 	   bool omx_running;
 	   bool omx_first_frame;
 
@@ -207,7 +221,19 @@ class VideoVPEOGL : public Video
 
 
 #endif
+
+#ifdef VPE_FFMPEG_SUPPORT
+	AVCodec *mpeg2codec_ff;
+	AVCodecContext *mpeg2codec_context_ff;
+	AVFrame *dec_frame_ff;
+
+
+
+	UINT DeliverMediaPacketFFMPEG(MediaPacket packet,const UCHAR* buffer,UINT *samplepos);
+	int AllocateCodecsFFMPEG();
+	int DeAllocateCodecsFFMPEG();
 	
+#endif
 
 
    bool firstsynched;
-- 
2.39.5