Esempio n. 1
0
inline void CvCapture_FFMPEG::seek(s64 _frame_number)
{
    _frame_number = std::min(_frame_number, get_total_frames());
    int delta = 16;

    // if we have not grabbed a single frame before first seek, let's read the first frame
    // and get some valuable information during the process
    if( first_frame_number < 0 && get_total_frames() > 1 )
        grabFrame();

    for(;;)
    {
        s64 _frame_number_temp = std::max(_frame_number-delta, (s64)0);
        double sec = (double)_frame_number_temp / get_fps();
        s64 time_stamp = ic->streams[video_stream]->start_time;
        double  time_base  = r2d(ic->streams[video_stream]->time_base);
        time_stamp += (s64)(sec / time_base + 0.5);
        if (get_total_frames() > 1) av_seek_frame(ic, video_stream, time_stamp, AVSEEK_FLAG_BACKWARD);
        avcodec_flush_buffers(ic->streams[video_stream]->codec);
        if( _frame_number > 0 )
        {
            grabFrame();

            if( _frame_number > 1 )
            {
                frame_number = dts_to_frame_number(picture_pts) - first_frame_number;
                //printf("_frame_number = %d, frame_number = %d, delta = %d\n",
                //       (int)_frame_number, (int)frame_number, delta);

                if( frame_number < 0 || frame_number > _frame_number-1 )
                {
                    if( _frame_number_temp == 0 || delta >= INT_MAX/4 )
                        break;
                    delta = delta < 16 ? delta*2 : delta*3/2;
                    continue;
                }
                while( frame_number < _frame_number-1 )
                {
                    if(!grabFrame())
                        break;
                }
                frame_number++;
                break;
            }
            else
            {
                frame_number = 1;
                break;
            }
        }
        else
        {
            frame_number = 0;
            break;
        }
    }
}
Esempio n. 2
0
inline bool CvCapture_FFMPEG::grabFrame()
{
    bool valid = false;
    int got_picture;

    int count_errs = 0;
    const int max_number_of_attempts = 1 << 16;

    if( !ic || !video_st )  return false;

    if( ic->streams[video_stream]->nb_frames > 0 &&
        frame_number > ic->streams[video_stream]->nb_frames )
        return false;

    av_free_packet (&packet);

    picture_pts = AV_NOPTS_VALUE_;

    unsigned long start;
    unsigned long end;

    // get the next frame
    while (!valid)
    {
        start = GetTickCount();
        //while (1){
        int ret = av_read_frame(ic, &packet);

        //printf("(%s,%d) Size %d ret %d %d\n", __FUNCTION__, __LINE__, packet.size, ret,
    //      GetTickCount() - start);

        //DumpHex((char *)(packet.data), 20);
        if (ret == AVERROR(-1)) continue;

    //  }

        /* else if (ret < 0) break; */

        if( packet.stream_index != video_stream )
        {
         //printf("(%s,%d)\n", __FUNCTION__, __LINE__);
            av_free_packet (&packet);
            count_errs++;
            if (count_errs > max_number_of_attempts)
                break;
            continue;
        }

        start = GetTickCount();
        // Decode video frame
        #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
            avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet);
        #elif LIBAVFORMAT_BUILD > 4628
                avcodec_decode_video(video_st->codec,
                                     picture, &got_picture,
                                     packet.data, packet.size);
        #else
                avcodec_decode_video(&video_st->codec,
                                     picture, &got_picture,
                                     packet.data, packet.size);
        #endif
        //printf("(%s,%d) avcodec_decode_video2  %d\n", __FUNCTION__, __LINE__,
    //      GetTickCount() - start);
        // Did we get a video frame?
        if(got_picture)
        {
         //printf("(%s,%d) got_picture  %d\n", __FUNCTION__, __LINE__,
    //      GetTickCount() - start);
            //picture_pts = picture->best_effort_timestamp;
            if( picture_pts == AV_NOPTS_VALUE_ )
                picture_pts = packet.pts != AV_NOPTS_VALUE_ && packet.pts != 0 ? packet.pts : packet.dts;
            frame_number++;
            valid = true;
        }
        else
        {
            count_errs++;
            if (count_errs > max_number_of_attempts)
                break;
        }

        av_free_packet (&packet);
    }

    if( valid && first_frame_number < 0 )
        first_frame_number = dts_to_frame_number(picture_pts);


    // return if we have a new picture or not
    return valid;
}
Esempio n. 3
0
bool CvCapture_FFMPEG::grabFrame()
{
    bool valid = false;
    int got_picture;

    int count_errs = 0;
    const int max_number_of_attempts = 1 << 16;

    if( !ic || !video_st )  return false;
    
    if( ic->streams[video_stream]->nb_frames > 0 &&
        frame_number > ic->streams[video_stream]->nb_frames )
        return false;

    av_free_packet (&packet);
    
    picture_pts = AV_NOPTS_VALUE_;

    // get the next frame
    while (!valid)
    {
        int ret = av_read_frame(ic, &packet);
        if (ret == AVERROR(EAGAIN)) continue;

        /* else if (ret < 0) break; */

        if( packet.stream_index != video_stream )
        {
            av_free_packet (&packet);
            count_errs++;
            if (count_errs > max_number_of_attempts)
                break;
            continue;
        }
        
        // Decode video frame
        #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
            avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet);
        #elif LIBAVFORMAT_BUILD > 4628
                avcodec_decode_video(video_st->codec,
                                     picture, &got_picture,
                                     packet.data, packet.size);
        #else
                avcodec_decode_video(&video_st->codec,
                                     picture, &got_picture,
                                     packet.data, packet.size);
        #endif

        // Did we get a video frame?
        if(got_picture)
        {
            //picture_pts = picture->best_effort_timestamp;
            if( picture_pts == AV_NOPTS_VALUE_ )
                picture_pts = packet.pts != AV_NOPTS_VALUE_ && packet.pts != 0 ? packet.pts : packet.dts;
            frame_number++;
            valid = true;
        }
        else
        {
            count_errs++;
            if (count_errs > max_number_of_attempts)
                break;
        }

        av_free_packet (&packet);
    }

    if( valid && first_frame_number < 0 )
        first_frame_number = dts_to_frame_number(picture_pts);
    
    // return if we have a new picture or not
    return valid;
}