[Libav-user] Not able to seek in audio stream

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
Report Content as Inappropriate

[Libav-user] Not able to seek in audio stream

amey jain
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);
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);
  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);
    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");
      err = av_buffersrc_add_frame(src, frame);
      fprintf(stderr,"DEBUG: Frame added to buffer source with PTS %lu \n",frame->pts);
      if(err < 0) {
        fprintf(stderr,"Error adding frame to source buffer\n");
      size = size - len;
 }while(frame->pts < end_pts);

 while((err = av_buffersink_get_frame(sink,frame)) >= 0){
   if(err < 0){
     fprintf(stderr,"av_buffer_get_frame returns %d %s\n",err,errstr);
   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);


Libav-user mailing list
[hidden email]