openh264 - bEnableFrameSkip=0, битрейт нельзя контролировать

Есть много вопросов, касающихся opencv + H.264, но ни один из них не дал подробного объяснения.

я использую openh264(openh264-1.4.0-win32msvc.dll) вместе с opencv 3.1(пользовательская сборка cmake с включенным ffmpeg) в visual studio, я хотел сохранить видео с веб-камеры в формате mp4 с компрессией H.264

VideoWriter write = VideoWriter("D:/movie.mp4", CV_FOURCC('H', '2', '6', '4'), 10,0, cv::Size(192, 144), true);

перед использованием openh264 в окне консоли я увидел предупреждение "Не удалось загрузить библиотеку openh264: openh264-1.4.0-win32msvc.dll, проверьте свою среду и / или загрузите ее отсюда: https://github.com/cisco/openh264/releases" (также видео не было сохранено)

поэтому я скачал dll и держал в папке с моим программным файлом (exe) теперь, когда я запускаю программу, я вижу другую ошибку "[OpenH264] this = 0x0DE312C0, предупреждение: bEnabledFrameSkip=0, битрейт не может контролироваться для RC_QUALITY_MODE и RC_TIMESTAMP_MODE без включения пропуска фрейма " (сейчас видео сохраняется, но размер очень большой! скорость передачи данных составляет около 1200 Кбит / с)

для меня единственная цель использования h264 - уменьшить размер файла.. я думаю, что мне, возможно, придется собрать openh264 самостоятельно с некоторыми изменениями, чтобы удалить эту ошибку, кто-нибудь может мне помочь, как? или скажите, есть ли способ как-то снизить скорость передачи данных через код?

PS: я попытался дать -1 вместо CV_FOURCC(), в моей системе появилось окно "установленные кодеки", я не смог найти h264 или x264 или h264vfw, хотя я установил множество пакетов кодеков и h264 отсюда

С уважением

2 ответа

Решение

Если вы хотите контролировать битрейт, вы должны использовать оба

encoderParemeters.iRCMode = RC_OFF_MODE;
encoderParemeters.bEnableFrameSkip = true; 


Здесь я показываю все параметры кодирования Openh264 в качестве примера:

long nReturnedValueFromEncoder = WelsCreateSVCEncoder(&m_pSVCVideoEncoder);


    m_nVideoWidth = 352;
    m_nVideoHeight = 288;

    SEncParamExt encoderParemeters;

    memset(&encoderParemeters, 0, sizeof(SEncParamExt));

    m_pSVCVideoEncoder->GetDefaultParams(&encoderParemeters);

    encoderParemeters.iUsageType = CAMERA_VIDEO_REAL_TIME;
    encoderParemeters.iTemporalLayerNum = 0;
    encoderParemeters.uiIntraPeriod = 15;
    encoderParemeters.eSpsPpsIdStrategy = INCREASING_ID;
    encoderParemeters.bEnableSSEI = false;
    encoderParemeters.bEnableFrameCroppingFlag = true;
    encoderParemeters.iLoopFilterDisableIdc = 0;
    encoderParemeters.iLoopFilterAlphaC0Offset = 0;
    encoderParemeters.iLoopFilterBetaOffset = 0;
    encoderParemeters.iMultipleThreadIdc = 0;

    encoderParemeters.iRCMode = RC_BITRATE_MODE;
    encoderParemeters.iMinQp = 0;
    encoderParemeters.iMaxQp = 52;



    encoderParemeters.bEnableDenoise = false;
    encoderParemeters.bEnableSceneChangeDetect = false;
    encoderParemeters.bEnableBackgroundDetection = true;
    encoderParemeters.bEnableAdaptiveQuant = false;
    encoderParemeters.bEnableFrameSkip = true;
    encoderParemeters.bEnableLongTermReference = true;
    encoderParemeters.iLtrMarkPeriod = 20;
    encoderParemeters.bPrefixNalAddingCtrl = false;
    encoderParemeters.iSpatialLayerNum = 1;


    SSpatialLayerConfig *spartialLayerConfiguration = &encoderParemeters.sSpatialLayers[0];

    spartialLayerConfiguration->uiProfileIdc = PRO_BASELINE;//;

    encoderParemeters.iPicWidth = spartialLayerConfiguration->iVideoWidth = m_nVideoWidth;
    encoderParemeters.iPicHeight = spartialLayerConfiguration->iVideoHeight = m_nVideoHeight;
    encoderParemeters.fMaxFrameRate = spartialLayerConfiguration->fFrameRate = (float)30;

    encoderParemeters.iTargetBitrate = spartialLayerConfiguration->iSpatialBitrate = 500000;
    encoderParemeters.iTargetBitrate = spartialLayerConfiguration->iMaxSpatialBitrate = 500000;


    spartialLayerConfiguration->iDLayerQp = 24;
    //spartialLayerConfiguration->sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
    spartialLayerConfiguration->sSliceArgument.uiSliceMode = SM_SINGLE_SLICE;


    nReturnedValueFromEncoder = m_pSVCVideoEncoder->InitializeExt(&encoderParemeters);

Надеюсь, это поможет вам.

Вы можете просто контролировать скорость передачи данных, используя RC_BITRATE_MODE и включив bEnableFrameSkip в Openh264.

Другие вопросы по тегам