void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
input_bufs_omx_mutex.Lock();
- //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.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();
iframemode=false;
omx_running=true;
clock_mutex.Unlock();
+ threadStart();
setClockExecutingandRunning();
port_def_type.nBufferCountMin,port_def_type.nBufferSize,port_def_type.bEnabled,port_def_type.bPopulated,
port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
- port_def_type.nBufferCountActual=60;
+ port_def_type.nBufferCountActual=100;
port_def_type.nBufferSize=max(port_def_type.nBufferSize,200000); // for transcoder important
error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
}
input_bufs_omx_all.clear();
input_bufs_omx_free.clear();
+ input_bufs_omx_present.clear();
+ input_time_present.clear();
input_bufs_omx_mutex.Unlock();
}
OMX_ERRORTYPE error;
omx_running=false;
Log::getInstance()->log("Video", Log::DEBUG, "enter deallocatecodecsomx");
+ threadStop();
if (cur_input_buf_omx) {
struct timespec interval;
interval.tv_sec=time/10000000LL;
interval.tv_nsec=(time %10000000LL)*100LL;
- while (clock_nanosleep(CLOCK_MONOTONIC,TIMER_ABSTIME,&interval,NULL)==EINTR) {};
+ while (clock_nanosleep(CLOCK_MONOTONIC,TIMER_ABSTIME,&interval,NULL)==EINTR) {
+ //Log::getInstance()->log("Video", Log::DEBUG, "Wait until multi");
+
+ };
+}
+
+bool VideoOMX::FrameSkip(long long pts)
+{
+ //ok first calculate the absolute time
+ bool skip=false;
+ long long target_time=pts-playbacktimeoffset;
+ // we have to wait untile the next frame
+ long long offset=Demuxer::getInstance()->getFrameRate();
+ if (offset==0) offset=25;
+ offset=10000000LL/offset;
+ target_time+=offset;
+ long long current_time=GetCurrentSystemTime();
+ if (!skipping) {
+ if ((target_time-current_time)<-1000000LL) {
+ skip=true; // we are too slow
+ skipping=true;
+ /* Log::getInstance()->log("Video", Log::DEBUG,
+ "Skipping frames1 %lld %lld",target_time-current_time,pts);
+ 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 {
+ skipping=false;
+ }
+ } else {
+ if ((target_time - current_time) < 0LL) {
+ 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, "skip detail pts: %lld target: %lld sys: %lld off: %lld diff %lld",pts,target_time,current_time,offset,
+ target_time-current_time);*/
+ } else {
+ skipping = false;
+ }
+
+ }
+
+ return skip;
}
void VideoOMX::FrameWaitforDisplay(long long pts)
// we have to wait untile the next frame
long long offset=Demuxer::getInstance()->getFrameRate();
long long current_time=GetCurrentSystemTime();
- if ((target_time-current_time)>5000000LL) target_time=current_time+5000000LL; // something is wrong do not wait too long
if (offset==0) offset=25;
offset=10000000LL/offset;
target_time+=offset;
- Log::getInstance()->log("Video", Log::DEBUG, "Wait for display pts: %lld target: %lld sys: %lld off: %lld diff %lld",pts,target_time,current_time,offset,
- target_time-current_time);
+ if ((target_time-current_time)>1000000LL) target_time=current_time+1000000LL; // something is wrong do not wait too long
+ //Log::getInstance()->log("Video", Log::DEBUG, "Wait for display pts: %lld target: %lld sys: %lld off: %lld diff %lld",pts,target_time,current_time,offset,
+ // target_time-current_time);
WaitUntil(target_time);
- Log::getInstance()->log("Video", Log::DEBUG, "Wait for display out %lld",GetCurrentSystemTime());
+ //Log::getInstance()->log("Video", Log::DEBUG, "Wait for display out %lld",GetCurrentSystemTime());
}
void VideoOMX::AdjustAudioPTS(long long pts)
//}
}
+void VideoOMX::threadPostStopCleanup()
+{
+ //Doing nothing
+ //goo;
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "end thread");
+}
+
+
+void VideoOMX::threadMethod()
+{
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "start thread");
+ while (true) {
+
+ OMX_BUFFERHEADERTYPE* pict=NULL;
+ long long time;
+ 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();
+ input_bufs_omx_present.pop_front();
+ input_time_present.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)) {
+
+ input_bufs_omx_mutex.Lock();
+ input_bufs_omx_free.push_back(pict);
+ input_bufs_omx_mutex.Unlock();
+
+ } else {
+ OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, pict);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "OMX_EmptyThisBuffer failed %x", error);
+ }
+ if (time!=0) FrameWaitforDisplay(time);
+ }
+ } else {
+ MILLISLEEP(5);
+ }
+
+ threadCheckExit();
+ }
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "end thread");
+}
+
+void VideoOMX::PutBufferToPres(OMX_BUFFERHEADERTYPE* buffer, long long time)
+{
+ input_bufs_omx_mutex.Lock();
+ input_bufs_omx_present.push_back(buffer);
+ input_time_present.push_back(time);
+ input_bufs_omx_mutex.Unlock();
+
+}
+
OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer)
{
// protect the call to empty this buffer
if (paused) return 0; //Block if we pause
long long current_media_time=GetCurrentSystemTime()+playbacktimeoffset;
- if (packet.synched &&
+/* if (packet.synched &&
(packet.presentation_time<0 /*|| // preroll skip frames
- (packet.presentation_time+5000000LL)<(current_media_time)*/)) { // we are late skip
+ (packet.presentation_time+5000000LL)<(current_media_time)*)) { // we are late skip
Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX Preroll or too late %lld %lld; %lld", packet.presentation_time,current_media_time,playbacktimeoffset);
*samplepos=packet.length;
return packet.length;
- }
+ }*/
OMX_ERRORTYPE error;
if (packet.disconti) {
firstsynched=false;
if (cur_input_buf_omx) {
- OMX_ERRORTYPE error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
- if (error!=OMX_ErrorNone){
- Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
- }
- FrameWaitforDisplay(lastreftimeOMX);
+ PutBufferToPres(cur_input_buf_omx, lastreftimeOMX);
cur_input_buf_omx=NULL;
}
}
if (*samplepos==0) {//stripheader
headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
- if (h264) Log::getInstance()->log("Video", Log::DEBUG, "PES info %x %x %x %x",
- buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
+ // if (h264) Log::getInstance()->log("Video", Log::DEBUG, "PES info %x %x %x %x",
+ // buffer[packet.pos_buffer+0],buffer[packet.pos_buffer+1],buffer[packet.pos_buffer+2],buffer[packet.pos_buffer+3]);
*samplepos+=headerstrip;
if ( packet.synched ) {
if (cur_input_buf_omx) {
cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
- OMX_ERRORTYPE error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
- if (error!=OMX_ErrorNone){
- Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
- }
+ PutBufferToPres(cur_input_buf_omx, lastreftimeOMX);
cur_input_buf_omx=NULL;//write out old data
- FrameWaitforDisplay(lastreftimeOMX);
}
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 sample");
return 0; // we do not have a free media sample
}
if (cur_input_buf_omx->nFilledLen==0) {//will only be changed on first packet
if (packet.synched) {
- Log::getInstance()->log("Video", Log::DEBUG, "packet synched marker");
+ // Log::getInstance()->log("Video", Log::DEBUG, "packet synched marker");
//lastreftimePTS=packet.pts;
if (omx_first_frame) { // TODO time
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;
}
*samplepos+=cancopy;
// push old buffer out
- OMX_ERRORTYPE error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
- if (error!=OMX_ErrorNone){
- Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
- }
+ PutBufferToPres(cur_input_buf_omx, 0LL);
// get5 new buffer
input_bufs_omx_mutex.Lock();
if (input_bufs_omx_free.size()==0) {
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 sample");
return false; // we do not have a free media sample
}
}
cur_input_buf_omx->nTimeStamp = 0;
- OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec,
- cur_input_buf_omx);
- if (error != OMX_ErrorNone) {
- Log::getInstance()->log("Video", Log::DEBUG,
- "OMX_EmptyThisBuffer failed %x", error);
- }
+ PutBufferToPres(cur_input_buf_omx, 0);
cur_input_buf_omx = NULL;
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,
- "Ifrane no free sample");
+ // Log::getInstance()->log("Video", Log::DEBUG,
+ // "Ifrane no free sample");
MILLISLEEP(5);
if (!omx_running) return false;
continue;
}
cur_input_buf_omx->nTimeStamp = 0;
- OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, cur_input_buf_omx);
- if (error != OMX_ErrorNone) {
- Log::getInstance()->log("Video", Log::DEBUG,
- "OMX_EmptyThisBuffer failed %x", error);
- }
+ PutBufferToPres(cur_input_buf_omx, 0);
cur_input_buf_omx = NULL;
{
clock_mutex.Lock();
if (cur_input_buf_omx) {
- clock_mutex.Unlock();
- OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec,
- cur_input_buf_omx);
- clock_mutex.Lock();
- if (error != OMX_ErrorNone) {
- Log::getInstance()->log("Video", Log::DEBUG,
- "OMX_EmptyThisBuffer failed %x", error);
- }
+ PutBufferToPres(cur_input_buf_omx, lastreftimeOMX);
cur_input_buf_omx = NULL;
}