ffmpeg YUV420 в RGB24 преобразует только одну строку

Я пытаюсь преобразовать изображение YUV420p в RGB24 в С++ и создать растровое изображение из массива байтов в С#.

Размер моего изображения составляет 1920 Вт * 1020 В, а декодер ffmpeg дает мне 3 плоскости для данных с размерами строк = {1920, 960, 960}. Но после sws_scale я получаю изображение RGB только с одной плоскостью с размером строки = 5760. Это выглядит неправильно: я должен получить (5760 * h), а не только одну строку данных. Что я делаю неправильно?

 //c++ part
    if (avcodec_receive_frame(m_decoderContext, pFrame) == 0)
    {
        //RGB
        sws_ctx = sws_getContext(m_decoderContext->width,
            m_decoderContext->height,
            m_decoderContext->pix_fmt,
            m_decoderContext->width,
            m_decoderContext->height,
            AV_PIX_FMT_RGB24,
            SWS_BILINEAR,
            NULL,
            NULL,
            NULL
        );

        sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data, pFrame->linesize,
            0, pFrame->height,
            pFrameRGB->data, pFrameRGB->linesize);


//c# part (im reading data from pipe and its equal to c++ part)------------------------------------------------------------------
        byte[] rgbch = new byte[frameLen];
        for (int i=0; i<frameLen; i++)
        {
            rgbch[i] = Convert.ToByte(pipe.ReadByte());
        }

        if (rgbch.Length > 0)
        {
            var arrayHandle = System.Runtime.InteropServices.GCHandle.Alloc(rgbch,
    System.Runtime.InteropServices.GCHandleType.Pinned);

            var bmp = new Bitmap(1920, 1080,
                3,
                System.Drawing.Imaging.PixelFormat.Format24bppRgb,
                arrayHandle.AddrOfPinnedObject()
            );

            pictureBox1.Image = bmp;
        }

person Aleksey    schedule 10.08.2016    source источник
comment
Почему вы считаете, что это неправильно? Вы вводите плоские пиксельные данные, получаете чередующиеся пиксельные данные, где каждая строка имеет размер 3 * 1920, а общая область памяти составляет 3 * 1920 * высота.   -  person Rudolfs Bundulis    schedule 10.08.2016
comment
Ну не пойму я где та область памяти 3*1920*высоты. У меня есть только одна строка 3 * 1920 в pFrameRGB->data... Для полного изображения мне нужны все остальные строки?..   -  person Aleksey    schedule 10.08.2016
comment
Каково возвращаемое значение sws_scale ? Должно быть количество строк в выходном буфере - pFrameRGB->data. Если это не 1, то ваше предположение неверно. Если это действительно 1, то что-то идет не так.   -  person Rudolfs Bundulis    schedule 10.08.2016
comment
Я пропустил возвращаемое значение sws_scale. С его помощью я получил правильное количество столбцов в моем буфере... так что, в основном, как я теперь понимаю, linesize не имеет размер data - он просто показывает размер одной строки в data?   -  person Aleksey    schedule 10.08.2016
comment
Да, имя переменной говорит об этом :)   -  person Rudolfs Bundulis    schedule 10.08.2016


Ответы (1)


Ваше предположение о том, что поле linesize в AVFrame представляет собой общий объем данных, неверно. . Как следует из названия переменной, это длина одной строки, а возвращаемое значение sws_scale дает вам количество строк. Таким образом, общий размер диапазона памяти для выходного растрового изображения равен linesize, умноженному на возвращаемое значение.

person Rudolfs Bundulis    schedule 10.08.2016