FFmpeg перейти к последнему кадру - PullRequest
1 голос
/ 07 марта 2019

Я ищу некоторую помощь с пропуском / пропуском кадров FFmpeg. Я работаю над потоками живого видео, которое, когда приложение переходит в фоновый режим, после возвращения в активное состояние видеопоток тратит много времени на то, чтобы переместиться к текущему кадру. Это не идеально, и я стремлюсь к тому, чтобы приложение сразу переходило к самому последнему кадру.

Что мне нужно сделать, это отбросить количество кадров, которые быстро пересылаются, чтобы догнать самый последний кадр. Это возможно? Вот мой текущий код, который декодирует кадры:

- (NSArray *) decodeFrames: (CGFloat) minDuration
{
    NSMutableArray *result = [NSMutableArray array];

    @synchronized (lock) {

        if([_reading integerValue] != 1){

            _reading = [NSNumber numberWithInt:1];

            @synchronized (_seekPosition) {
                if([_seekPosition integerValue] != -1 && _seekPosition){
                    [self seekDecoder:[_seekPosition longLongValue]];
                    _seekPosition = [NSNumber numberWithInt:-1];
                }
            }

            if (_videoStream == -1 &&
                _audioStream == -1)
                return nil;

            AVPacket packet;

            CGFloat decodedDuration = 0;

            CGFloat totalDuration = [TimeHelper calculateTimeDifference];

            do {

                BOOL finished = NO;
                int count = 0;


                while (!finished) {

                    if (av_read_frame(_formatCtx, &packet) < 0) {
                        _isEOF = YES;
                        [self endOfFileReached];
                        break;
                    }

                    [self frameRead];

                    if (packet.stream_index ==_videoStream) {

                        int pktSize = packet.size;

                        while (pktSize > 0) {

                            int gotframe = 0;
                            int len = avcodec_decode_video2(_videoCodecCtx,
                                                            _videoFrame,
                                                            &gotframe,
                                                            &packet);

                            if (len < 0) {
                                LoggerVideo(0, @"decode video error, skip packet");
                                break;
                            }

                            if (gotframe) {


                                    if (!_disableDeinterlacing &&
                                        _videoFrame->interlaced_frame) {

                                        avpicture_deinterlace((AVPicture*)_videoFrame,
                                                              (AVPicture*)_videoFrame,
                                                              _videoCodecCtx->pix_fmt,
                                                              _videoCodecCtx->width,
                                                              _videoCodecCtx->height);
                                    }

                                    KxVideoFrame *frame = [self handleVideoFrame];
                                    if (frame) {

                                        [result addObject:frame];
                                        _position = frame.position;
                                        decodedDuration += frame.duration;
                                        if (decodedDuration > minDuration)
                                            finished = YES;
                            }



                            } else {
                                count++;
                            }

                            if (0 == len)
                                break;

                            pktSize -= len;
                        }
                    }
                    av_free_packet(&packet);
                }
            } while (totalDuration > 0);
            _reading = [NSNumber numberWithInt:0];
            return result;
        }

    }

    return result;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...