#include "mtdraspberry.h"
#include "demuxer.h"
#include "osdopengl.h"
+#include "vdr.h"
+#include "woptionpane.h"
// temp
#include "log.h"
mode=NORMAL;
xpos=ypos=0.f;
+ deinterlace=2; //advanced
}
void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
input_bufs_omx_mutex.Lock();
-// Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d %d %d",input_bufs_omx_free.size(),input_bufs_omx_present.size(),input_bufs_omx_all.size());
+ //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d %d %d",input_bufs_omx_free.size(),input_bufs_omx_present.size(),input_bufs_omx_all.size());
input_bufs_omx_free.push_back(buffer);
//Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
input_bufs_omx_mutex.Unlock();
}
+
+bool VideoOMX::loadOptionsfromServer(VDR* vdr)
+{
+ Log::getInstance()->log("Video", Log::DEBUG, "VideoOMX config load");
+ char *name=vdr->configLoad("VideoOMX","SDDeinterlacing");
+
+ if (name != NULL) {
+ if (STRCASECMP(name, "None") == 0) {
+ deinterlace = 0;
+ }/* else if (STRCASECMP(name, "LineDouble") == 0) {
+ deinterlace = 1;
+ }*/ else if (STRCASECMP(name, "Advanced") == 0) {
+ deinterlace = 2;
+ } /*else if (STRCASECMP(name, "Crazy") == 0) {
+ deinterlace = 3; // this does not activate deinterlacing but a image filter, just for fun
+ }*/
+ Log::getInstance()->log("Video", Log::DEBUG, "Set deinterlacing to %s %d",name,deinterlace);
+ }
+
+ return true;
+
+}
+
+bool VideoOMX::handleOptionChanges(Option* option)
+{
+ if (Video::handleOptionChanges(option))
+ return true;
+ switch (option->id) {
+ case 1: {
+ if (STRCASECMP(option->options[option->userSetChoice], "None") == 0) {
+ deinterlace = 0;
+ } /*else if (STRCASECMP(option->options[option->userSetChoice], "LineDouble")
+ == 0) {
+ deinterlace = 1;
+ }*/ else if (STRCASECMP(option->options[option->userSetChoice], "Advanced")
+ == 0) {
+ deinterlace = 2;
+ } /*else if (STRCASECMP(option->options[option->userSetChoice], "Crazy")
+ == 0) {
+ deinterlace = 3;
+ }*/
+ Log::getInstance()->log("Video", Log::DEBUG, "Set deinterlacing to %s %d",option->options[option->userSetChoice],deinterlace);
+ return true;
+ }
+ break;
+ };
+ return false;
+
+}
+
+bool VideoOMX::saveOptionstoServer()
+{
+
+ switch (deinterlace) {
+ case 0:
+ VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "None");
+ break;
+ /*case 1:
+ VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "LineDouble");
+ break;*/
+ case 2:
+ VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Advanced");
+ break;
+ /*case 3:
+ VDR::getInstance()->configSave("VideoOMX","SDDeinterlacing", "Crazy");
+ break;*/
+ };
+
+ return true;
+}
+
+/*Option(UINT id, const char* displayText, const char* configSection, const char* configKey, UINT optionType,
+ UINT numChoices, UINT defaultChoice, UINT startInt,
+ const char * const * options, const char * const * optionkeys = NULL, AbstractOption* handler=NULL);*/
+
+bool VideoOMX::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
+{
+ if (!Video::addOptionsToPanes(panenumber,options,pane)) return false;
+
+
+ Option* option;
+ if (panenumber == 2)
+ {
+ static const char* deinterlaceopts[]={"None",/*"LineDouble",*/"Advanced"/*,"Crazy"*/};
+ option = new Option(1,tr("SD Deinterlacing"), "VideoOMX","SDDeinterlacing",Option::TYPE_TEXT,/*4,2*/2,1,0,deinterlaceopts,NULL,false,this);
+ options->push_back(option);
+ pane->addOptionLine(option);
+ }
+
+ return true;
+}
+
+
+
int VideoOMX::setTVsize(UCHAR ttvsize)
{
/* tvsize = ttvsize;
OMX_ERRORTYPE error;
static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
+ Demuxer* demux=Demuxer::getInstance();
+
+ dodeint=false;
+
Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX");
//Clock, move later to audio including events
- Log::getInstance()->log("Video", Log::DEBUG, "Nmark1 ");
+ if (deinterlace!=0 && demux->getHorizontalSize()<=720) { //only deinterlace SD material
+ dodeint=true;
+ deint_first_frame=true;
+
+ Log::getInstance()->log("Video", Log::NOTICE, "Deinterlacing activated %d",deinterlace);
+
+ }
+
+
if (!getClockVideoandInit()){
return 0;// get the clock and init it if necessary
}
- Log::getInstance()->log("Video", Log::DEBUG, "Nmark2 ");
+
if (!idleClock()) {
Log::getInstance()->log("Video", Log::DEBUG, "idleClock failed");
return 0;
}
+ if (dodeint) {
+ error = OMX_GetHandle(&omx_vid_deint, VPE_OMX_VIDEO_DEINTERLACE, NULL,
+ &callbacks);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "Init OMX video deinterlacer failed %x", error);
+ clock_mutex.Unlock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+ error = OMX_GetParameter(omx_vid_deint, OMX_IndexParamImageInit,
+ &p_param);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "Init OMX video deinterlacer OMX_GetParameter failed %x",
+ error);
+ clock_mutex.Unlock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+ omx_deint_input_port = p_param.nStartPortNumber;
+ omx_deint_output_port = p_param.nStartPortNumber + 1;
+
+ if (!DisablePort(omx_vid_deint, omx_deint_input_port, true)
+ || !DisablePort(omx_vid_deint, omx_deint_output_port, true)) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "Disable Ports OMX video deint failed");
+ clock_mutex.Unlock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+ }
+
error=OMX_GetHandle(&omx_vid_sched,VPE_OMX_VIDEO_SCHED,NULL,&callbacks);
if (error!=OMX_ErrorNone){
ft_type.eCompressionFormat=OMX_VIDEO_CodingMPEG2;
}
- Demuxer* demux=Demuxer::getInstance();
+
ft_type.xFramerate=0;//25*(1<<16);//demux->getFrameRate()*(1<<16);
Log::getInstance()->log("Video", Log::DEBUG, "Framerate: %d",demux->getFrameRate());
return 0;
}
+ if (!dodeint) {
+ 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);
+ clock_mutex.Unlock();
+ DeAllocateCodecsOMX();
+ 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);
- clock_mutex.Unlock();
- 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");
+ clock_mutex.Unlock();
+ 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");
- clock_mutex.Unlock();
- DeAllocateCodecsOMX();
- return 0;
- }
+ if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
+ clock_mutex.Unlock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+ } else {
+
+ error=OMX_SetupTunnel(omx_vid_dec,omx_codec_output_port,omx_vid_deint,omx_deint_input_port);
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel dec to deint failed %x", error);
+ clock_mutex.Unlock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+
+
+ if (!EnablePort(omx_vid_dec,omx_codec_output_port,false) || !EnablePort(omx_vid_deint,omx_deint_input_port,false)
+ ) {
+ Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX codec deint failed");
+ clock_mutex.Unlock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+ if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_input_port)) {
+ clock_mutex.Unlock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+ if (!ChangeComponentState(omx_vid_deint,OMX_StateIdle)) {
+ Log::getInstance()->log("Video", Log::DEBUG, "vid_deint ChangeComponentState");
+ clock_mutex.Unlock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+ OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter;
+ memset(&imagefilter,0,sizeof(imagefilter));
+ imagefilter.nSize=sizeof(imagefilter);
+ imagefilter.nVersion.nVersion=OMX_VERSION;
+
+ imagefilter.nPortIndex=omx_deint_output_port;
+ imagefilter.nNumParams=1;
+ imagefilter.nParams[0]=3;//???
+ switch (deinterlace) {
+ case 1:
+ imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceLineDouble; break;
+ case 2:
+ imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceAdvanced; break;
+ case 3:
+ imagefilter.eImageFilter=OMX_ImageFilterFilm; break;
+ }
+
+
+ error=OMX_SetConfig(omx_vid_deint,OMX_IndexConfigCommonImageFilterParameters,&imagefilter);
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigCommonImageFilterParameters failed %x", error);
+ clock_mutex.Unlock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+
+ error=OMX_SetupTunnel(omx_vid_deint,omx_deint_output_port,omx_vid_sched,omx_shed_input_port);
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Video", Log::DEBUG, "OMX_Setup tunnel deint to sched failed %x", error);
+ clock_mutex.Unlock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+ if (!EnablePort(omx_vid_deint,omx_deint_output_port,false) || !EnablePort(omx_vid_sched,omx_shed_input_port,false)
+ ) {
+ Log::getInstance()->log("Video", Log::DEBUG, "Enable Ports OMX deint shed failed");
+ clock_mutex.Unlock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+ if ( !CommandFinished(omx_vid_deint,OMX_CommandPortEnable,omx_deint_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
+ clock_mutex.Unlock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
- if ( !CommandFinished(omx_vid_dec,OMX_CommandPortEnable,omx_codec_output_port) || !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_input_port)) {
- clock_mutex.Unlock();
- DeAllocateCodecsOMX();
- return 0;
}
if (!ChangeComponentState(omx_vid_dec,OMX_StateExecuting)) {
return 0;
}
+ if (dodeint) {
+ if (!ChangeComponentState(omx_vid_deint,OMX_StateExecuting)) {
+ Log::getInstance()->log("Video", Log::DEBUG, "vid_vid_deint ChangeComponentState");
+ clock_mutex.Unlock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+ DisablePort(omx_vid_deint,omx_deint_output_port,false);
+ DisablePort(omx_vid_deint,omx_deint_input_port,false);
+ }
if (!ChangeComponentState(omx_vid_sched,OMX_StateExecuting)) {
Log::getInstance()->log("Video", Log::DEBUG, "omx_vid_sched ChangeComponentState Execute");
return 1;
}
+int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event) //needs to be called with locked mutex
+{
+ int i=0;
+ while (i<1000) {
+ omx_event_mutex.Lock();
+ list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
+ while (itty!=omx_events.end()) {
+
+ VPE_OMX_EVENT current=*itty;
+ if (current.handle==handle) { //this is ours
+ if (current.event_type==OMX_EventError) {
+ omx_events.erase(itty);
+ omx_event_mutex.Unlock();
+ Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished on Error");
+ return 0;
+ } else if (current.event_type==event) {
+ omx_events.erase(itty);
+ omx_event_mutex.Unlock();
+ Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent Finished Completed");
+ return 1;
+ }
+ }
+ itty++;
+
+ }
+ omx_event_mutex.Unlock();
+ MILLISLEEP(2);
+ i++;
+
+ }
+ Log::getInstance()->log("Video", Log::DEBUG, "WaitForEvent waited too long %x %x",handle,event);
+ return 0;
+
+}
int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex
input_bufs_omx_free.clear();
input_bufs_omx_present.clear();
input_time_present.clear();
+ input_is_last.clear();
input_bufs_omx_mutex.Unlock();
}
idleClock();
clock_mutex.Lock();
+ if (dodeint) {
+ if (!ChangeComponentState(omx_vid_deint, OMX_StateIdle)) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "vid_deint ChangeComponentState");
+
+ }
+ }
+
if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
Log::getInstance()->log("Video", Log::DEBUG, "vid_shed ChangeComponentState");
// TODO proper deinit sequence
// first flush all buffers
+ if (!dodeint) {
- error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
- omx_codec_output_port, NULL);
- if (error != OMX_ErrorNone) {
- Log::getInstance()->log("Video", Log::DEBUG,
- "OMX_Flush codec out failed %x", error);
+ error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
+ omx_codec_output_port, NULL);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "OMX_Flush codec out failed %x", error);
- }
+ }
- error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
- omx_shed_input_port, NULL);
- if (error != OMX_ErrorNone) {
- Log::getInstance()->log("Video", Log::DEBUG,
- "OMX_Flush shed in failed %x", error);
+ error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
+ omx_shed_input_port, NULL);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "OMX_Flush shed in failed %x", error);
+
+ }
+
+ if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
+ omx_codec_output_port)) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "flush cmd codec failed");
+ }
+
+ if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
+ omx_shed_input_port)) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "flush cmd shed failed");
+ }
+ } else {
+ error = OMX_SendCommand(omx_vid_dec, OMX_CommandFlush,
+ omx_codec_output_port, NULL);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "OMX_Flush codec out failed %x", error);
+
+ }
+
+ error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
+ omx_deint_input_port, NULL);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "OMX_Flush deint in failed %x", error);
+
+ }
+
+ if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
+ omx_codec_output_port)) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "flush cmd codec failed");
+ }
+
+ if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
+ omx_deint_input_port)) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "flush cmd deint failed");
+ }
+
+ //m
+ error = OMX_SendCommand(omx_vid_deint, OMX_CommandFlush,
+ omx_deint_output_port, NULL);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "OMX_Flush deint out failed %x", error);
+
+ }
+
+ error = OMX_SendCommand(omx_vid_sched, OMX_CommandFlush,
+ omx_shed_input_port, NULL);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "OMX_Flush shed in failed %x", error);
+
+ }
+
+ if (!CommandFinished(omx_vid_deint, OMX_CommandFlush,
+ omx_deint_output_port)) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "flush cmd deint failed");
+ }
+
+ if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
+ omx_shed_input_port)) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "flush cmd shed failed");
+ }
- }
- if (!CommandFinished(omx_vid_dec, OMX_CommandFlush,
- omx_codec_output_port)) {
- Log::getInstance()->log("Video", Log::DEBUG,
- "flush cmd codec failed");
- }
- if (!CommandFinished(omx_vid_sched, OMX_CommandFlush,
- omx_shed_input_port)) {
- Log::getInstance()->log("Video", Log::DEBUG,
- "flush cmd shed failed");
}
Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7");
}
+ if (dodeint) {
+ if (!DisablePort(omx_vid_deint,omx_deint_output_port,true)) {
+ Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 6a");
+ }
+
+
+
+ if (!DisablePort(omx_vid_deint,omx_deint_input_port,true)) {
+ Log::getInstance()->log("Video", Log::DEBUG, "Disable Tunnel Port failed 7a");
+ }
+ }
}
+ if (dodeint) {
+ error=OMX_SetupTunnel(omx_vid_deint,omx_deint_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_deint,omx_deint_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_FreeHandle(omx_vid_dec);
error=OMX_FreeHandle(omx_vid_sched);
error=OMX_FreeHandle(omx_vid_rend);
+ if (dodeint) error=OMX_FreeHandle(omx_vid_deint);
omx_vid_dec=NULL;
clock_mutex.Unlock();
destroyClock();
skip=true; // we are too slow
skipping=true;
/* Log::getInstance()->log("Video", Log::DEBUG,
- "Skipping frames1 %lld %lld",target_time-current_time,pts);
+ "Skipping frames1 %lld %lld %d",target_time-current_time,pts,Demuxer::getInstance()->getFrameRate());
Log::getInstance()->log("Video", Log::DEBUG, "skip detail pts: %lld target: %lld sys: %lld off: %lld diff %lld",pts,target_time,current_time,offset,
target_time-current_time);*/
} else {
if ((target_time - current_time) < 0000LL) { //skip a bit more
skip = true; // we are too slow
skipping = true;
- /* Log::getInstance()->log("Video", Log::DEBUG,"Skipping frames2 %lld %lld",target_time-current_time,pts);
+ /* Log::getInstance()->log("Video", Log::DEBUG,"Skipping frames2 %lld %lld %d",target_time-current_time,pts,Demuxer::getInstance()->getFrameRate());
Log::getInstance()->log("Video", Log::DEBUG, "skip detail pts: %lld target: %lld sys: %lld off: %lld diff %lld",pts,target_time,current_time,offset,
target_time-current_time);*/
} else {
OMX_BUFFERHEADERTYPE* pict=NULL;
long long time;
+ bool islast;
if (!paused) {
input_bufs_omx_mutex.Lock();
if (input_bufs_omx_present.size()>0) {
pict=input_bufs_omx_present.front();
time=input_time_present.front();
+ islast=input_is_last.front();
input_bufs_omx_present.pop_front();
input_time_present.pop_front();
+ input_is_last.pop_front();
}
input_bufs_omx_mutex.Unlock();
}
if ( pict) {
//Log::getInstance()->log("Video", Log::DEBUG,
// "Got pict");
- if (time!=0 &&FrameSkip(time) && !(pict->nFlags &OMX_BUFFERFLAG_STARTTIME)) {
+ if (time!=0 && FrameSkip(time) && !(pict->nFlags &OMX_BUFFERFLAG_STARTTIME)) {
input_bufs_omx_mutex.Lock();
input_bufs_omx_free.push_back(pict);
Log::getInstance()->log("Video", Log::DEBUG,
"OMX_EmptyThisBuffer failed %x", error);
}
- if (time!=0) FrameWaitforDisplay(time);
+ if (deint_first_frame && dodeint) DeinterlaceFix();
+ if (islast) FrameWaitforDisplay(time);
}
} else {
MILLISLEEP(5);
"end thread");
}
-void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer, long long time)
+void VideoOMX::DeinterlaceFix()
+{
+
+ Demuxer* demux=Demuxer::getInstance();
+ clock_mutex.Lock();
+ OMX_ERRORTYPE error;
+ OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
+ memset(&port_def_type,0,sizeof(port_def_type));
+ port_def_type.nSize=sizeof(port_def_type);
+ port_def_type.nVersion.nVersion=OMX_VERSION;
+ port_def_type.nPortIndex=omx_codec_output_port;
+
+ error=OMX_GetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "OMX_IndexParamPortDefinition fix failed %x", error);
+ clock_mutex.Unlock();
+ return;
+ }
+
+ if (port_def_type.format.video.nFrameWidth == demux->getHorizontalSize()
+ && port_def_type.format.video.nFrameHeight == demux->getVerticalSize()){
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "Deinit first frame fix");
+ deint_first_frame=false;
+
+ WaitForEvent(omx_vid_dec,OMX_EventPortSettingsChanged);
+ DisablePort(omx_vid_dec,omx_codec_output_port,false);
+ DisablePort(omx_vid_sched,omx_shed_input_port,false);
+ DisablePort(omx_vid_deint,omx_deint_output_port,false);
+ DisablePort(omx_vid_deint,omx_deint_input_port,false);
+
+ port_def_type.nPortIndex=omx_deint_input_port;
+ error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
+ &port_def_type);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "Set OMX_IndexParamPortDefinition1 failed %x", error);
+ clock_mutex.Unlock();
+ return;
+ }
+
+ port_def_type.nPortIndex=omx_deint_output_port;
+ error = OMX_SetParameter(omx_vid_deint, OMX_IndexParamPortDefinition,
+ &port_def_type);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "Set OMX_IndexParamPortDefinition2 failed %x", error);
+ clock_mutex.Unlock();
+ return;
+ }
+
+
+ EnablePort(omx_vid_dec,omx_codec_output_port,false);
+ EnablePort(omx_vid_deint,omx_deint_input_port,false);
+ EnablePort(omx_vid_deint,omx_deint_output_port,false);
+ EnablePort(omx_vid_sched,omx_shed_input_port,false);
+ }
+ clock_mutex.Unlock();
+
+
+}
+
+
+void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer, long long time,bool islast)
{
input_bufs_omx_mutex.Lock();
input_bufs_omx_present.push_back(buffer);
input_time_present.push_back(time);
+ input_is_last.push_back(islast);
input_bufs_omx_mutex.Unlock();
}
void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
{
- mediapacket = mplist.front();
+ mediapackets.clear();
+ list<MediaPacket>::const_iterator begin=mplist.begin();
+ list<MediaPacket>::const_iterator itty=mplist.begin();
+ advance(itty,min(mplist.size(),50));
+ mediapackets.insert(mediapackets.begin(),begin,itty);//front
}
UINT VideoOMX::DeliverMediaSample(UCHAR* buffer, UINT *samplepos)
{
- DeliverMediaPacket(mediapacket, buffer, samplepos);
- if (*samplepos == mediapacket.length) {
- *samplepos = 0;
- return 1;
- }
- else return 0;
+ int consumed=0;
+ while (mediapackets.size()) {
+ MediaPacket mediapacket=mediapackets.front();
+ DeliverMediaPacket(mediapacket, buffer, samplepos);
+ if (*samplepos == mediapacket.length) {
+ *samplepos = 0;
+ mediapackets.pop_front();
+ consumed++;
+ //return 1;
+ } else return consumed;
+ }
+ return consumed;
}
UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
if (packet.disconti) {
firstsynched=false;
if (cur_input_buf_omx) {
- PutBufferToPres(cur_input_buf_omx, lastreftimeOMX);
+ PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,true);
cur_input_buf_omx=NULL;
}
}
if ( packet.synched ) {
if (cur_input_buf_omx) {
cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
- PutBufferToPres(cur_input_buf_omx, lastreftimeOMX);
+ PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,true);
cur_input_buf_omx=NULL;//write out old data
cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_TIME_UNKNOWN;
}
lastreftimeOMX=packet.presentation_time;
- // Log::getInstance()->log("Video", Log::DEBUG, "Time code %lld pts %lld", lastreftimeOMX,packet.pts);
+ // Log::getInstance()->log("Video", Log::DEBUG, "Time code %lld pts %lld", lastreftimeOMX,packet.pts);
lastreftimePTS=packet.pts;
cur_input_buf_omx->nTimeStamp=0;//lastreftimeOMX; // the clock component is faulty;
}
{
cur_input_buf_omx->nFlags=OMX_BUFFERFLAG_TIME_UNKNOWN;
cur_input_buf_omx->nTimeStamp=0;
-
-
+ //Log::getInstance()->log("Video", Log::DEBUG, "packet unsynched marker");
// ms->SetSyncPoint(TRUE);
}
if (packet.disconti) cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_DISCONTINUITY;
*samplepos+=cancopy;
// push old buffer out
- PutBufferToPres(cur_input_buf_omx, 0LL);
+ PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,false);
// 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");
+ // Log::getInstance()->log("Video", Log::DEBUG, "Deliver MediaPacket no free sample2");
return *samplepos; // we do not have a free media sample
}
cur_input_buf_omx=input_bufs_omx_free.front();
}
cur_input_buf_omx->nTimeStamp = 0;
- PutBufferToPres(cur_input_buf_omx, 0);
+ PutBufferToPres(cur_input_buf_omx, 0,false);
cur_input_buf_omx = NULL;
if (!cur_input_buf_omx) {
}
cur_input_buf_omx->nTimeStamp = 0;
- PutBufferToPres(cur_input_buf_omx, 0);
+ PutBufferToPres(cur_input_buf_omx, 0,false);
cur_input_buf_omx = NULL;
{
clock_mutex.Lock();
if (cur_input_buf_omx) {
- PutBufferToPres(cur_input_buf_omx, lastreftimeOMX);
+ PutBufferToPres(cur_input_buf_omx, lastreftimeOMX,true);
cur_input_buf_omx = NULL;
}