[Libav-user] High consumption while seeking

Safi safiuddinkhan at gmail.com
Thu Oct 3 21:07:03 CEST 2013


hello i am building a media player for my project . almost everything is 
working fine and i am able to read and sync files correctly for playblack .

the problem i am having is that after i do seeking 
"avcodec_decode_video2" consumes allot of cpu time after it process 
initial packets received after seeking ..... the problem was much worse 
before but i wrote a small code which dumps all frames after seeking 
until keyframe is reached even though the problem has some what gone 
better but i am still experiencing high cpu consumption by 
"avcodec_decode_video2" .................... what i could understand 
from all of this is that it has something to do with GOP and intra 
frames but i don't have much knowledge since i am a beginner . if 
someone is able to guide me what should i do i will be very much thankful

here is my code for seeking

if(sc->seek == 1){

sc->status = MP_SEEKING;
sc->pausetoggle = 1;  /// Pausing both video playback and audio playback 
threads  ... when video and audio playback threads go to pause , demux 
thread also automatically goes to pause
while(true){    // waiting for both video and audio playback threads to 
pause
usleep(300);
if(sc->videostream == -1){
if(sc->audiopause == 1)
break;
}else if(sc->audiostream == -1){
   if(sc->videopause == 1)
break;
}else{
if(sc->audiopause == 1 && sc->videopause == 1)
break;
}
}

vtimestamp = (sc->videopts + sc->seektime) * AV_TIME_BASE;


int flag;
//if(sc->seektime > 0){
//  flag = 0;
//}else{
   flag = AVSEEK_FLAG_BACKWARD;
//}

ret = av_seek_frame(sc->pFormatCtx, -1, vtimestamp , flag);

if(ret < 0){
     sc->status = MP_ERROR;
}


if(sc->videostream != -1)
avcodec_flush_buffers(sc->videoctx);
if(sc->audiostream != -1)
avcodec_flush_buffers(sc->audioctx);


empty_buffers(sc); // Empty Video and Audio Buffers


//// Flushing all packets until we reach keyframe after seek point
///////////////////////////////////////////////////////////////////
cout <<"----------------------------------"<<endl;
cout <<"Seek Time Requested:"<<sc->seektime<<endl;
cout <<"----------------------------------"<<endl;

while(true){
  usleep(30);
  if(av_read_frame(sc->pFormatCtx, &packet)<0)
break;

if(packet.stream_index==sc->videostream){
////////////
if(packet.pts == AV_NOPTS_VALUE){
videopts = videopts + (double)(packet.duration * sc->videobasetime);
}else{
videopts = (double)(packet.pts * sc->videobasetime);
}
////////////

videokeyframe = packet.flags;

cout <<"-- video pts:"<<videopts<<" - keyframe:"<<videokeyframe<<" - 
"<<(double)(packet.dts * sc->videobasetime)<<" - Size:"<<packet.size<<endl;
if(videokeyframe == AV_PKT_FLAG_KEY){
video_firstpts = videopts;
vk = 1;
}

if(vk == 1){
pthread_mutex_lock(&sc->videolock);
sc->videobuffer.push(packet);
pthread_mutex_unlock(&sc->videolock);
}else{
av_free_packet(&packet);
}

}else if(packet.stream_index==sc->audiostream){
////////////
if(packet.pts == AV_NOPTS_VALUE)
audiopts = audiopts + (double)(packet.duration * sc->audiobasetime);
else
audiopts = (double)(packet.pts * sc->audiobasetime);
////////////

audiokeyframe = packet.flags;

cout <<"-- audio pts:"<<audiopts<<" - keyframe:"<<audiokeyframe<<" - 
"<<(double)(packet.dts * sc->audiobasetime)<<endl;

if(sc->videostream == -1){
if(audiokeyframe == AV_PKT_FLAG_KEY){
ak = 1;
firstpts = audiopts;
}
}else{
if(audiokeyframe == AV_PKT_FLAG_KEY && vk == 1){
ak = 1;
firstpts = audiopts;
}
}

if(ak == 1){
pthread_mutex_lock(&sc->audiolock);
sc->audiobuffer.push(packet);
pthread_mutex_unlock(&sc->audiolock);
}else{
av_free_packet(&packet);
}


}else{
   av_free_packet(&packet);
}

if(sc->videostream == -1){

if(ak == 1)
break;

}else if(sc->audiostream == -1){

if(vk == 1)
break;

}else{
if(vk == 1 && ak == 1)
break;

}

}

vk = 0;
ak = 0;

///////////////////////////////////////////////////////////////////
sc->masterclock->settime(firstpts);
sc->masterclock->reset();

sc->seek = 0;
sc->pausetoggle = 0;
pthread_mutex_lock(&sc->pauselock);
pthread_cond_broadcast(&sc->pausecond);
pthread_mutex_unlock(&sc->pauselock);


here is the video decoding function

nt mediaplayer::getdecodedvideoframe(stream_context *sc,AVFrame *vidframe){
int vidframefinished;
AVPacket packet;
while(true){

if(sc->videobuffer.size() == 0)
while(sc->videobuffer.size() < 20){

if(sc->pausetoggle == 1)
return -2;

if(sc->endthread == 1){
   cout <<" Video Decoding Ended..."<<endl;
return -1;
}
pthread_mutex_lock(&sc->demuxlock);
pthread_cond_broadcast(&sc->demuxcond);
pthread_mutex_unlock(&sc->demuxlock);
}

pthread_mutex_lock(&sc->videolock);
packet = sc->videobuffer.front();
sc->videobuffer.pop();
pthread_mutex_unlock(&sc->videolock);

if(avcodec_decode_video2(sc->videoctx, vidframe, 
&vidframefinished,&packet) < 0)
break;

av_free_packet(&packet);


if(vidframefinished){
return 0;
}

}

av_free_packet(&packet);
return -3;
}



More information about the Libav-user mailing list