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
}
//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;
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);
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
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;
}
}
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;
}
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;
}
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;
}
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;
}
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
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;
}
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;
}
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;
}
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);
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;
}
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;
}
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;
}
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;
}*/
if (!ChangeComponentState(omx_clock,OMX_StateExecuting)) {
Log::getInstance()->log("Video", Log::DEBUG, "omx_clock ChangeComponentState Exccute");
+ DeAllocateCodecsOMX();
return 0;
}
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;
}
- 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++) {
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()
#ifdef VPE_OMX_SUPPORT
//Check if ffmpeg mode
- DeAllocateCodecsOMX();
+ if (decoding_backend==VPE_DECODER_OMX) DeAllocateCodecsOMX();
+ decoding_backend=0;
+
#endif
else return 0;
}
-
-
UINT VideoVPEOGL::DeliverMediaPacket(MediaPacket packet,
const UCHAR* buffer,
UINT *samplepos)
{
-
if (packet.type == MPTYPE_VIDEO_H264)
{
h264=true;
{
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
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
+