[Libav-user] Not able to seek in audio stream
amey jain
amey.jain7 at gmail.com
Sat Jun 24 22:40:07 EEST 2017
Hi all,
I am trying to seek to particular locations(where subs/CC present) in audio
stream in different formats of videos using av_seek_frame. I am getting
result for just one video of MPEG2-TS format by using (ts = time_in_sec *
INPUT_TIMEBASE.denominator). For all others they are just seeking to last
PTS same as that in stream->duration. I searched for solutions, and got
some mentioning av_rescale_q(time_in_sec,AV_TIME_BASE_Q,INPUT_TIME_BASE)
but that doesn't works. I have following questions 1) What method should I
use to convert time in seconds to in time_base units for an audio stream.
2) For rest videos the seeked frames have PTS as same as duration. 3) Does
function av_seek_frame has some drawbacks or formats to which it is not
applicable or doesn't works well. What does that means? Here is code I am
sharing with you.
void process_frame_by_pts(uint16_t index,int64_t time_to_seek_ms)
{
int64_t start_pts =(int64_t) (time_to_seek_ms/1000) * INPUT_TIMEBASE.den ;
int64_t end_pts = ((time_to_seek_ms + 1500)/1000) * INPUT_TIMEBASE.den;
int i = 0, count = 0,temp = 0,out_count = 0,in_count = 0;
AVPacket pkt;
int got_frame,ret;
AVFrame *frame = av_frame_alloc();
int size,len,buf_size;
int err;
char errstr[128];
if(end_pts > fmt_ctx->streams[audio_stream_index]->duration){
printf("Error: End PTS(%lu) greater then duration of
stream(%lu)\n",end_pts,fmt_ctx->streams[audio_stream_index]->duration);
return;
}
ret =
av_seek_frame(fmt_ctx,audio_stream_index,start_pts,AVSEEK_FLAG_BACKWARD);
//get one frame before timing to cover all
if( ret < 0 ){
fprintf(stderr,"av_seek_frame failed with error code %d\n",ret);
return;
}
fprintf(stdout,"Start PTS: %lu End PTS: %lu\n",start_pts,end_pts);
do{ //outer do-while to read packets
ret = av_read_frame(fmt_ctx, &pkt);
if(ret < 0){
printf("Unable to read frame:%d \n",ret);
break;
}
if(pkt.stream_index == audio_stream_index){ // processing audio packets
size = pkt.size;
while(size > 0){ // inner while to decode frames, if more than one
are present in a single packet
got_frame = 0;
fprintf(stderr,"DEBUG: Packet PTS:%lu\n",pkt.pts);
len = avcodec_decode_audio4(dec_ctx, frame, &got_frame, &pkt);
if(len < 0){
printf("Error while decoding\n");
}
if(got_frame){
err = av_buffersrc_add_frame(src, frame);
fprintf(stderr,"DEBUG: Frame added to buffer source with PTS %lu
\n",frame->pts);
if(err < 0) {
av_frame_unref(frame);
fprintf(stderr,"Error adding frame to source buffer\n");
return;
}
size = size - len;
}
}
}
}while(frame->pts < end_pts);
while((err = av_buffersink_get_frame(sink,frame)) >= 0){
if(err < 0){
av_strerror(err,errstr,128);
fprintf(stderr,"av_buffer_get_frame returns %d %s\n",err,errstr);
break;
}
fprintf(stdout,"frame_pts %lu frame->duration(PTS) %d frame->duration:
%f with sample rate as:%d number of samples
%d\n",frame->pts,frame->pkt_duration,((double)frame->pkt_duration/frame->sample_rate)
* 1000,frame->sample_rate,frame->nb_samples);
}
av_frame_free(&frame);
return;
}
Regards
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20170625/6964cc95/attachment.html>
More information about the Libav-user
mailing list