[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);
    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

_______________________________________________
Libav-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user
Loading...