LINUX.ORG.RU

Очистить буферы libav/ffmpeg?

 ,


0

1

Приветствую.

Вдрух кто знает - выполняю пересжатие из мжпег или х264 снова в х264, затем через локальный интерфейс отправляю в свой же rtsp сервер - никак не удается понять, почему при остановке стрима и его запуске вижу 1-2 секунды предыдущего стрима.

Все делаю через api ффмпега.

Думал кодер нужно сбрасывать через avcodec_flush_buffers в ответ ошибка Ignoring attempt to flush encoder that doesn't support it, может быть в декодере х264 накопилось - так нет, для мжпег те же 1-2 секунды предыдущих мусорных кадров, попытался сбросить входящий буфер ртсп сервера через avformat_flush(f) толку нет, варианты av_write_frame(f, NULL) avcodec_send_frame(c, NULL) и тп тоже ничего не сбрасывают.

Да важно - на кодер в начале стрима всегда поступает не сжатый кадр с признаками что он ключевой и типом I, поэтому стрим начинается всегда мгновенно, НО откуда то 1-2 секунды от предыдущего ((

★★★

Последнее исправление: Dimez (всего исправлений: 3)

Рандомно передергивать ручки не помогло. Что такое остановка стрима? Почему ты не убиваешь все свои кодеры в этой твоей «остановке» и не создаешь свое пересжатие по новой?

anonymous
()
Ответ на: комментарий от anonymous

вашу рандомную ручку про пересоздание я тоже попробовал - тогда получается задержка начала трансляции, причем дольше чем увидеть кусок предыдущего стрима )

остановка значит клиент отключился, но потом обязательно когда то вернется.

wolverin ★★★
() автор топика
Ответ на: комментарий от anonymous

даже коД выложу этой ручки

    AVCodecContext * ctx = avcodec_alloc_context3(pCdcCtxOut->codec);
    if (ctx)
    {
        AVCodecParameters * par = avcodec_parameters_alloc();
        if (par)
        {
            if ((rt = avcodec_parameters_from_context(par, pCdcCtxOut)) >= 0)
                if ((rt = avcodec_parameters_to_context(ctx, par)) >= 0)
                {
                    ctx->time_base = pCdcCtxOut->time_base;
                    if ((rt = avcodec_open2(ctx, NULL, NULL)) == 0)
                    {
                        avcodec_free_context(&pCdcCtxOut);
                        avcodec_parameters_free(&par);
                        pCdcCtxOut = ctx;
                        return;
                    }
                }
            avcodec_parameters_free(&par);
        }
        avcodec_free_context(&ctx);
    }

wolverin ★★★
() автор топика
Ответ на: комментарий от wolverin

тогда получается задержка начала трансляции

эээ..а делать «ручку заранее», в свободное время ? то есть будут AVCodecContext *ctx,*ctx_next,*ctx_trash; тогда всё экстренное переключение: ctx_trash=ctx, ctx=ctx_next, ctx_next=NULL; а как время выдастся - ctx_trash удалить, ctx_next аллоцировать...

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

Важно быстро стартануть каждый раз после любой остановки, когда не нужно тяжёлое пересжатия, сейчас происходит все просто мега быстро, проблема только в непонятно откуда берущихся старых кадрах

Смотрю тем же ffprobe - все четка первый же кадр приходит ключевой, но почему он старый вот как то до меня не доходит.

wolverin ★★★
() автор топика