Кодирование x264 с помощью libav

Я пытаюсь закодировать необработанные данные изображения в x264 с помощью libav:

AVPacket vpkt = { 0 };
av_init_packet(&vpkt);

int got;
int ret = avcodec_encode_video2(vcodec, &vpkt, frameyuv.get(), &got);

if (!ret && got && vpkt.size) {
    if (vpkt.pts != AV_NOPTS_VALUE) {
        vpkt.pts = av_rescale_q(vpkt.pts, vcodec->time_base, videost->time_base);
    }
    if (vpkt.dts != AV_NOPTS_VALUE) {
        vpkt.dts = av_rescale_q(vpkt.dts, vcodec->time_base, videost->time_base);
    }

    vpkt.stream_index = videost->index;

    if(vcodec->coded_frame->key_frame) {
        vpkt.flags |= AV_PKT_FLAG_KEY;
    }
    /* -> will return -22 if max_b_frames > 0 */
    ret = av_interleaved_write_frame(oc, &vpkt);
}

Работает нормально, когда для vcodec->max_b_frames установлено значение 0, но при любом другом значении av_interleaved_write_frame возвращает -22 (недопустимый аргумент).

/* will fail */
c->max_b_frames = 3;
/* -> ok*/
c->max_b_frames = 0;

Почему? Я что-то пропустил?

Параметры кодека

AVDictionary *opts = NULL;
av_dict_set(&opts, "vprofile", "baseline", 0);

/* ... */
c->codec_type = AVMEDIA_TYPE_VIDEO;
c->bit_rate = 500 * 1000;
c->width = VideoWidth;
c->height = VideoHeight;
c->time_base.den = fps;
c->time_base.num = 1;
c->pix_fmt = AV_PIX_FMT_YUV420P;

Формат контейнера mp4.


person user3453729    schedule 24.03.2014    source источник
comment
Скорее всего, это как-то связано со значениями PTS/DTS (что, вероятно, может быть обходным путем, если у вас нет b-кадров/задержки). Я предполагаю, что вы установили их неправильно, и мультиплексор mp4 не имеет флагов AVFMT_NOTIMESTAMPS, поэтому они должны быть правильными.   -  person nobody555    schedule 24.03.2014


Ответы (1)


Вам нужно использовать av_rescale_q во временной базе вашего выходного контекста, а не в видеопотоке. Похоже, что вы ничего не делаете с av_rescale_q. Пытаться:

av_rescale_q(vpkt.pts, vcodec->time_base, [output context]->time_base);

Если у вас продолжают возникать проблемы, почти всегда проблемы с B-кадрами указывают на неправильное значение DTS. Рассмотрите возможность установки DTS в AV_NOPTS_VALUE и позвольте демультиплексору решить это самостоятельно.

Помните, что для декодирования кадра B вы должны знать кадры по обе стороны от него, поэтому они должны быть сначала демультиплексированы, рассмотрим 3 кадра:

I B I

Первым должен быть декодирован первый кадр, затем следует третий и, наконец, второй. Эта информация получена из DTS.

Наконец, выясните, почему вы получаете -22, следуя это переполнение стека. Я был бы шокирован, если бы это не была ошибка «немонотонно возрастающего PTS/DTS».

person Jack    schedule 25.03.2014