В этой статье рассматриваются все операции масштабирования в Intel Media SDK. Масштабирование — одна из самых распространенных операций при обработке видео. Приложение может задать нужную область для каждого видео с помощью конвейера обработки видео (VPP). Используя Intel Media SDK VPP, можно выполнять различные операции масштабирования. Здесь мы описываем две наиболее часто используемые операции и их результаты.

На КДПВ приведена простая блок-схема, показывающая конвейер функций, задействованных при масштабировании.

Обнаружение свободной поверхности кадра — используются поверхности из пула поверхностей, заблокированные поверхности нельзя использовать, поэтому выполняется поиск неиспользуемой поверхности.

int GetFreeSurfaceIndex(mfxFrameSurface1** pSurfacesPool, mfxU16 nPoolSize)
{
    if (pSurfacesPool)
        for (mfxU16 i = 0; i < nPoolSize; i++)
            if (0 == pSurfacesPool[i]->Data.Locked)
                return i;
    return MFX_ERR_NOT_FOUND;
}

Загрузка необработанного кадра на поверхность — для необработанного кадра считываются плоскости освещенности и цветности, затем загружаются на поверхность.

mfxStatus LoadRawFrame(mfxFrameSurface1* pSurface, FILE* fSource)
{
    w = pInfo->Width;
	    h = pInfo->Height;
    pitch = pData->Pitch;
	    ptr = pData->Y;
    //read luminance plane
    for (i = 0; i < h; i++) {
        nBytesRead = (mfxU32) fread(ptr + i * pitch, 1, w, fSource);
        if (w != nBytesRead)
            return MFX_ERR_MORE_DATA;
    }
    mfxU8 buf[2048];        // maximum supported chroma width for nv12
    w /= 2;
    h /= 2;
    	ptr = pData->UV;

    // load U
    sts = ReadPlaneData(w, h, buf, ptr, pitch, 0, fSource);
    if (MFX_ERR_NONE != sts)
        return sts;
    // load V
    ReadPlaneData(w, h, buf, ptr, pitch, 1, fSource);
    if (MFX_ERR_NONE != sts)
        return sts;
}

Операция записи на выходную поверхность — после операции RunFrameVPPSync, асинхронно обрабатывающей кадр. Операция синхронизации вызывается для получения всех выходных данных для их обратной записи в необработанный кадр.

mfxStatus WriteRawFrame(mfxFrameSurface1* pSurface, FILE* fSink)
{
    mfxFrameInfo* pInfo = &pSurface->Info;
    mfxFrameData* pData = &pSurface->Data;
    mfxU32 i, j, h, w;
    mfxStatus sts = MFX_ERR_NONE;

	    for (i = 0; i < pInfo->Height; i++)
		    sts =
    WriteSection(pData->Y, 1, pInfo->Width, pInfo, pData, i, 0,
		    fSink);

			    h = pInfo->Height / 2;
			    w = pInfo->Width;

    for (i = 0; i < h; i++)
        for (j = 0; j < w; j += 2)
            sts =
                WriteSection(pData->UV, 2, 1, pInfo, pData, i, j,
                             fSink);
    for (i = 0; i < h; i++)
        for (j = 1; j < w; j += 2)
            sts =
                WriteSection(pData->UV, 2, 1, pInfo, pData, i, j,
                             fSink);
    return sts;
}

Мы будем использовать sample_vpp из учебного руководства на странице Media Solution Portal. Входной файл foreman.yuv можно получить здесь. Загруженный файл будет в формате Y4M, его нужно будет преобразовать в формат YV12 с помощью ffmpeg.

ffmpeg -i input.y4m output.yuv

Для операций масштабирования используются шесть параметров VPP.
  • CropX, CropY, CropW, CropH определяют расположение входного и выходного кадров, которое требуется задать явным образом для получения результата.
  • Параметры Width и Height следует задать явным образом и для входного, и для выходного кадра. При этом значения высоты и ширины должны быть кратны 16 для кадровых изображений и кратны 32 для полей.

Обрезка — это одна из самых распространенных операций по обработке видео, она часто используется для определения рабочей области (ROI). С ее помощью также можно изменить соотношение сторон видео. Наиболее распространенные изменения: 16:9->4:3 и 4:3->16:9. При изменении соотношения сторон к изображению добавляются черные полосы либо сверху и снизу, либо справа и слева. Ниже приведена таблица входных параметров для обрезки, изменения соотношения сторон с добавлением черных полос сверху и снизу, справа и слева в sample_vpp.
CropX CropY CropW CropH Ширина Высота
Input 128 128 1024 464 1280 720
Output_Crop 0 0 1024 464 1024 464
Output_PillarBoxing 128 0 1024 720 1280 720
Output_LetterBoxing 0 128 1280 464 1280 720
Вот какие результаты вы получите при использовании этих параметров.







Изменение размера — еще одна операция обработки видео, используемая для получения видео изображения нужного размера. Но в этом случае к изображению не добавляются никакие полосы, просто изменяется его разрешение на выходе. Изменение размера возможно и в двух измерениях, и только в одном (можно изменять только ширину или только высоту видео, что соответствует растяжению по горизонтали и по вертикали). Ниже приведена таблица входных параметров изменения размера и растяжения в sample_vpp.
CropX CropY CropW CropH Ширина Высота
Input 0 0 640 480 640 480
Output_Re-size 0 0 1280 720 1280 720
Output_VerticalStretch 0 0 640 608 640 608
Output_HorizontalStretch 0 0 720 480 720 480
Вот какие результаты вы получите при использовании этих параметров.







Более подробные сведения о параметрах и функциях вы найдете в руководстве пользователя, которое находится в папке документов установленной копии MSDK или доступно здесь.

Дополнительные сведения об оптимизации компиляторов см. в нашем уведомлении об оптимизации.

Дополнительные ссылки


Комментарии (2)


  1. xaoc80
    15.04.2015 13:13

    Наш профайлер показывает, что до 60-70%% процессорного времени занимают операции по копированию фреймов (
    Вы не пробовали у себя (в т.ч. в примерах) оптимизировать эти операции?
    У меня с разверткой циклов, вставками ассемблерных инструкций получалось до 50% оптимизировать, но, похоже это потолок (
    А это очень важно, когда речь идет о кодировании десятков каналов на одном сервере
    Не получается GPU утилизировать на 100%


  1. MariannaSvetlosanova
    16.04.2015 14:47

    Дублирую ответ от инженеров Intel)

    Вместо собственных функций копирования поверхностей нужно использовать инициализацию MediaSDK компонент (кодеков, VPP) с нужным типом памяти.
    Если мы говорим о HW имплементации и вам необходимы данные в системной памяти – инициализация с системной памятью, если о SW имплементации и данные необходимы в видео памяти – инициализация с видео памятью

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

    Есть тонкость: для YV12 GPU копирование не работает.