首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用rgb24实现mjpeg到原始video4linux

用rgb24实现mjpeg到原始video4linux
EN

Stack Overflow用户
提问于 2012-01-12 14:42:09
回答 2查看 3.7K关注 0票数 4

我正在使用c++编写一个video4linux摄像头查看器。我需要一个RGB24输出(交错的R8B8G8)来显示。我能够获得视频输入几乎所有低分辨率的摄像头,使用YUYV,GREY8或RGB24。但我也需要从高分辨率的网络摄像头获得输入,当需要高帧率时使用MJPEG进行压缩。

我可以使用V4L2_PIX_FMT_MJPEG作为像素格式获得MJPEG流,但是接收到的帧缓冲区是压缩的。

如何快速地将其转换为RGB24?

我能用libjpeg做这个吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-17 17:34:36

我找到的最快的解决方案是从decode_jpeg_rawmjpegtools,它将jpeg数据解码为平面YUV420。然后,通过以下函数完成从yuv420到rgb24的转换:

代码语言:javascript
复制
inline int clip(int value) {
    return (value > 255) ? 255 : (value < 0) ? 0 : value;
}

static void yuv420_to_rgb24(
/* luminance (source) */const uint8_t* const y
/* u chrominance (source) */, const uint8_t* u
/* v chrominance (source) */, const uint8_t* v
/* rgb interleaved (destination) */, uint8_t* const dst
/* jpeg size */, int const size
/* image width */, int const width) {

    const int lineSize = width * 3;

    uint8_t* r1 = dst;
    uint8_t* g1 = r1 + 1;
    uint8_t* b1 = r1 + 2;

    uint8_t* r2 = r1 + lineSize;
    uint8_t* g2 = r2 + 1;
    uint8_t* b2 = r2 + 2;

    const uint8_t* y1 = y;
    const uint8_t* y2 = y + width;

    uint8_t* const end = r1 + size;

    int c1 = 0;
    int c2 = 0;
    int e = 0;
    int d = 0;

    while (r1 != end) {
        uint8_t* const lineEnd = r2;
        /* line by line */
        while (r1 != lineEnd) {
            /* first pixel */
            c1 = *y1 - 16;
            c2 = *y2 - 16;
            d = *u - 128;
            e = *v - 128;

            *r1 = clip(c1 + ((454 * e) >> 8));
            *g1 = clip(c1 - ((88 * e + 183 * d) >> 8));
            *b1 = clip(c1 + ((359 * d) >> 8));

            *r2 = clip(c2 + ((454 * e) >> 8));
            *g2 = clip(c2 - ((88 * e + 183 * d) >> 8));
            *b2 = clip(c2 + ((359 * d) >> 8));

            r1 += 3;
            g1 += 3;
            b1 += 3;

            r2 += 3;
            g2 += 3;
            b2 += 3;

            ++y1;
            ++y2;

            /* second pixel */

            c1 = *y1 - 16;
            c2 = *y2 - 16;
            d = *u - 128;
            e = *v - 128;

            *r1 = clip(c1 + ((454 * e) >> 8));
            *g1 = clip(c1 - ((88 * e + 183 * d) >> 8));
            *b1 = clip(c1 + ((359 * d) >> 8));

            *r2 = clip(c2 + ((454 * e) >> 8));
            *g2 = clip(c2 - ((88 * e + 183 * d) >> 8));
            *b2 = clip(c2 + ((359 * d) >> 8));

            r1 += 3;
            g1 += 3;
            b1 += 3;

            r2 += 3;
            g2 += 3;
            b2 += 3;

            ++y1;
            ++y2;

            ++u;
            ++v;
        }
        r1 += lineSize;
        g1 += lineSize;
        b1 += lineSize;
        r2 += lineSize;
        g2 += lineSize;
        b2 += lineSize;
        y1 += width;
        y2 += width;
    }
}
票数 2
EN

Stack Overflow用户

发布于 2012-01-12 15:00:40

是的,可以使用libjpeg,但通常libjpeg的输出是YUV420或YUV422。您可以使用该代码:http://mxhaard.free.fr/spca50x/Download/gspcav1-20071224.tar.gz (检查译码器的源代码,有一个小的jpeg解码器运行良好,直接处理颜色转换,以便输出在RGB888中)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8836872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档