[Ffmpeg-devel] av_seek_frame problem

tenze at libero.it tenze
Wed Mar 28 14:27:46 CEST 2007


Hi all,

I followed the Martin Boehme tutorial to set up a C code to read a mpeg video stream.
I used within the code the av_seek_frame function in order to search for a given frame. I tested the code with mpeg4 and all seemed to be ok.
Now I tested the code with an mpeg1 stream and I found a lot of problems: the av_seek_frame seems to return a "good" result (it should return the nearest keyframe with respect to the timestamp), but when I call che avcodec_decode_video, the decoded frames do not start from the given position. Moreover every timestamp seems to be a keyframe, but the decoder does not return the right frame after decode_video call; usually the frame is a bit backward. I used the av_index_search_timestamp function to found the position of the nearest keyframe and the result is always the timestamp I am searching for: I do not understand.

May you help me? 

Thanks in advance.
Livius

---------------------------------------------------
// Assign appropriate parts of buffer to image planes in pFrameRGB
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
pCodecCtx->width, pCodecCtx->height);
 timestamp_step=pFormatCtx->streams[videoStream]->time_base.den/pFormatCtx->streams[videoStream]->r_frame_rate.num;

// Here I set the position given by the argv[2]
int64_t timestamp=properties->startFrame*timestamp_step+pFormatCtx->streams[videoStream]->index_entries[0].timestamp;
> // add the stream start time
> // if (pFormatCtx->start_time != AV_NOPTS_VALUE)
> // timestamp += pFormatCtx->start_time;
> firstKeyFrame=av_index_search_timestamp(pFormatCtx->streams[videoStream],
> timestamp,
> AVSEEK_FLAG_BACKWARD);
>
> printf("gop %d\n",pCodecCtx->gop_size);
>
> printf("%d/%d %lld/%lld or %d %lld %lld keyframes=%lld\n%lld\n",pFormatCtx->streams[videoStream]->time_base.num,pFormatCtx->streams[videoStream]->time_base.den,
> pFormatCtx->streams[videoStream]->r_frame_rate.num,pFormatCtx->streams[videoStream]->r_frame_rate.den,
> AV_TIME_BASE,pFormatCtx->start_time,firstKeyFrame,firstKeyFrame,pFormatCtx->start_time);
>
> printf("keyframe=%d min_distance=%d\n",pFormatCtx->streams[videoStream]->index_entries[0].flags,pFormatCtx->streams[videoStream]->index_entries[0].min_distance);
>
> firstKeyFrame=pFormatCtx->streams[videoStream]->index_entries[firstKeyFrame].timestamp;
>
> printf("\n%lld %lld\n%lld<->%lld\n",firstKeyFrame,pFormatCtx->streams[videoStream]->index_entries[0].timestamp,timestamp,firstKeyFrame);
>
> ret = av_seek_frame(pFormatCtx, videoStream,timestamp, AVSEEK_FLAG_BACKWARD);
> if (ret < 0) {
> fprintf(stderr, "%s: could not seek to position %0.3f\n",
> properties->getFileName(), (double)timestamp / AV_TIME_BASE);
> }
>
> avcodec_flush_buffers(pFormatCtx->streams[videoStream]->codec);
>
> // Read frames and save first five frames to disk
> i=0;
> while(av_read_frame(pFormatCtx, &packet)>=0 && (i<=nFramesToGet))
> {
> // VIDEO
> // Is this a packet from the video stream?
> if(packet.stream_index==videoStream)
> {
> #if 1//def _DEBUG_
> printf("video %lld %lld %d %d %d\n",
> packet.pts,
> packet.dts,
> pCodecCtx->time_base.num,
> pCodecCtx->time_base.den,
> packet.flags);
> #endif
> // Decode video frame
> avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,packet.data, packet.size);
>
> // Did we get a video frame?
> if(frameFinished)
> {
> printf("ok\n");
> if (firstKeyFrame/*packet.pts*/ < timestamp){
> firstKeyFrame+=timestamp_step;
> printf(".");
> goto next_frame;
> }
> // Convert the image from its native format to RGB
> img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24,
> (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width,
> pCodecCtx->height);
>
> // Save the frame to disk
> i++;
> SaveFrame(properties, pFrameRGB, pCodecCtx->width, pCodecCtx->height,i);
> }
> }
> // AUDIO
> else if (packet.stream_index==audioStream)
> {
> uint8_t *outbuf;
> outbuf=(uint8_t*)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
> memset(outbuf,0,AVCODEC_MAX_AUDIO_FRAME_SIZE);
> int out_size=0,len;
> len = avcodec_decode_audio(pAudioCodecCtx,
> (short*)outbuf, &out_size,
> packet.data, packet.size);
> #ifdef _DEBUG_
> printf("audio %d %lld %lld %d %d %d %d %d %d\n",out_size,
> packet.pts,
> packet.dts,
> pAudioCodecCtx->time_base.num,pAudioCodecCtx->time_base.den,
> packet.duration,
> pAudioCodecCtx->bit_rate,
> pAudioCodecCtx->sample_rate,
> pAudioCodecCtx->channels);
> #endif
> properties->appendAudio((int16_t*)outbuf,out_size,GO_FORWARD);
> free(outbuf);
> outbuf=NULL;
> }
>
> next_frame:
> // Free the packet that was allocated by av_read_frame
> av_free_packet(&packet);
> }


------------------------------------------------------
Passa a Infostrada. ADSL e Telefono senza limiti e senza canone Telecom
http://click.libero.it/infostrada






More information about the ffmpeg-devel mailing list