2013-10-18 1 views
4

Я пытаюсь захватить вывод камеры и сделать видео с помощью libavcodec. В качестве примера, как это сделать, я использовал ffmpeg muxing example.Чрезвычайно высокая скорость передачи данных при кодировании видео с помощью libavcodec

Проблема заключается в том, что видео в течение 4 секунд имеет размер ~ 15 МБ и бит ~ 30000 кбит/с, хотя я установил битрейт на AVCodecContext на 400000 (я считаю, что это значение в битах/сек, а не кб/с).

Я также попытался записать видео с использованием ffmpeg из командной строки и имеет бит ~ 700 кбит/с.

Есть ли у кого-нибудь идея, почему битрейт не сохраняется и, следовательно, результирующий файл очень большой? Код, который я использовал для инициализации контекста кодека ниже:

инициализации части:

avformat_alloc_output_context2(&m_formatContext, NULL, NULL, filename); 
outputFormat = m_formatContext->oformat; 

codec = avcodec_find_encoder(outputFormat->video_codec); 

m_videoStream = avformat_new_stream(m_formatContext, codec); 

m_videoStream->id = m_formatContext->nb_streams - 1; 

codecContext = m_videoStream->codec; 

codecContext->codec_id = outputFormat->video_codec; 

codecContext->width = m_videoResolution.width(); 
codecContext->height = m_videoResolution.height(); 

int m_bitRate = 400000; 
codecContext->bit_rate = m_bitRate; 
codecContext->rc_min_rate = m_bitRate; 
codecContext->rc_max_rate = m_bitRate; 
codecContext->bit_rate_tolerance = 0; 

codecContext->time_base.den = 20; 
codecContext->time_base.num = 1; 

codecContext->pix_fmt = AV_PIX_FMT_YUV422P; 

if (m_formatContext->oformat->flags & AVFMT_GLOBALHEADER) 
    codecContext->flags |= CODEC_FLAG_GLOBAL_HEADER; 
/* open it */ 
ret = avcodec_open2(codecContext, codec, NULL); 

avFrame = avcodec_alloc_frame(); 

ret = avpicture_alloc(&avPicture, codecContext->pix_fmt, codecContext->width, codecContext->height); 

*((AVPicture *)avFrame) = avPicture; 

av_dump_format(m_formatContext, 0, filename, 1); 

if (!(outputFormat->flags & AVFMT_NOFILE)) { 
    ret = avio_open(&m_formatContext->pb, filename, AVIO_FLAG_WRITE); 
} 

ret = avformat_write_header(m_formatContext, NULL); 

if (avFrame) 
    avFrame->pts = 0; 

ответ

2

Поскольку каждый датчик имеет свой собственный профиль и битрейт обеспечить намек. Если ваш битрейт является допустимым значением (не слишком маленьким и не слишком большим), кодек просто выберет поддерживаемый битрейт в своем списке профилей.

«Возможности» кодека также могут влиять на битрейт, но это насколько я знаю.

профили Кодек определяют корреляцию между, по меньшей мере:

  • Размер кадра (ширина, heigth)
  • битрейт
  • формат пикселей
  • частота кадров

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

с кодом

codecContext->bit_rate = 1; 
avcodec_open2(codecContext, codec, NULL); 

FFmpeg кодек войти жалобу и список допустимых кортежей перечисленных выше.

Примечание: только с кодеками, которые не требуют внешних библиотек

Смежные вопросы