linux 摄像头传输,Linux下摄像头采集图像的帧格式从YUYV转换成MJPEG(转)

在做网络视频监控系统时,摄像头有的不支持v4l2_pix_fmt_mjpeg格式,只能支持v4l2_pix_fmt_yuyv格式,这样的话,不适合于在网络上的传输。为了将YUYV转换成MJPEG,我借助于jpeg库。

)jpeg源码包通过下面这个网址下载

http://www.ijg.org/files/jpegsrc.v8b.tar.gz

2)解压源码包

$ tar xzvf

jpegsrc.v8b.tar.gz

$ cd jpeg-8b

$

./configure --prefix=/usr/local/jpeg

$ make

$ make install

2)具体用法:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "print.h"

#define OUTPUT_BUF_SIZE  4096

#define WIDTH 640

#define HEIGHT 480

struct buffer {

void *  start;

size_t  length;

};

typedef struct {

struct jpeg_destination_mgr

pub;

JOCTET *

buffer;

unsigned char *outbuffer;

int outbuffer_size;

unsigned char

*outbuffer_cursor;

int

*written;

}mjpg_destination_mgr;

typedef mjpg_destination_mgr *mjpg_dest_ptr;

static int  fd= -1;

struct buffer *buffers= NULL;

static unsigned int  n_buffers= 0;

char *temp_buffer  =NULL;

METHODDEF(void) init_destination(j_compress_ptr cinfo)

{

mjpg_dest_ptr dest = (mjpg_dest_ptr)

cinfo->dest;

dest->buffer = (JOCTET

*)(*cinfo->mem->alloc_small)

((j_common_ptr) cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE *

sizeof(JOCTET));

*(dest->written) =

0;

dest->pub.next_output_byte =

dest->buffer;

dest->pub.free_in_buffer

= OUTPUT_BUF_SIZE;

}

METHODDEF(boolean) empty_output_buffer(j_compress_ptr

cinfo) {

mjpg_dest_ptr dest = (mjpg_dest_ptr)

cinfo->dest;

memcpy(dest->outbuffer_cursor,

dest->buffer, OUTPUT_BUF_SIZE);

dest->outbuffer_cursor

+= OUTPUT_BUF_SIZE;

*(dest->written) +=

OUTPUT_BUF_SIZE;

dest->pub.next_output_byte =

dest->buffer;

dest->pub.free_in_buffer

= OUTPUT_BUF_SIZE;

return TRUE;

}

METHODDEF(void) term_destination(j_compress_ptr cinfo)

{

mjpg_dest_ptr dest = (mjpg_dest_ptr)

cinfo->dest;

size_t datacount = OUTPUT_BUF_SIZE -

dest->pub.free_in_buffer;

memcpy(dest->outbuffer_cursor,

dest->buffer, datacount);

dest->outbuffer_cursor

+= datacount;

*(dest->written) +=

datacount;

}

void dest_buffer(j_compress_ptr cinfo, unsigned char

*buffer, int size, int *written) {

mjpg_dest_ptr dest;

if (cinfo->dest == NULL)

{

cinfo->dest = (struct jpeg_destination_mgr

*)(*cinfo->mem->alloc_small)

((j_common_ptr) cinfo, JPOOL_PERMANENT,

sizeof(mjpg_destination_mgr));

}

dest =

(mjpg_dest_ptr)cinfo->dest;

dest->pub.init_destination =

init_destination;

dest->pub.empty_output_buffer =

empty_output_buffer;

dest->pub.term_destination =

term_destination;

dest->outbuffer =

buffer;

dest->outbuffer_size =

size;

dest->outbuffer_cursor =

buffer;

dest->written =

written;

}

//摄像头采集帧图像的YUYV格式转换为JPEG格式

int compress_yuyv_to_jpeg(unsigned char *buf, unsigned

char *buffer, int size, int quality) {

struct jpeg_compress_struct

cinfo;

struct jpeg_error_mgr jerr;

JSAMPROW row_pointer[1];

unsigned char *line_buffer,

*yuyv;

int z;

static int written;

//int count = 0;

//printf("%s\n", buf);

line_buffer = calloc (WIDTH * 3,

1);

yuyv =

buf;//将YUYV格式的图片数据赋给YUYV指针

printf("compress

start...\n");

cinfo.err = jpeg_std_error

(&jerr);

jpeg_create_compress

(&cinfo);

dest_buffer(&cinfo,

buffer, size, &written);

cinfo.image_width = WIDTH;

cinfo.image_height = HEIGHT;

cinfo.input_components = 3;

cinfo.in_color_space =

JCS_RGB;

jpeg_set_defaults

(&cinfo);

jpeg_set_quality

(&cinfo, quality, TRUE);

jpeg_start_compress

(&cinfo, TRUE);

z = 0;

while (cinfo.next_scanline

< HEIGHT) {

int x;

unsigned char *ptr =

line_buffer;

for (x = 0; x

< WIDTH; x++) {

int r, g, b;

int y, u, v;

if (!z)

y = yuyv[0] <<

8;

else

y = yuyv[2] <<

8;

u

= yuyv[1] - 128;

v

= yuyv[3] - 128;

r

= (y + (359 * v)) >> 8;

g

= (y - (88 * u) - (183 * v)) >>

8;

b

= (y + (454 * u)) >> 8;

*(ptr++) = (r > 255) ? 255 : ((r < 0)

? 0 : r);

*(ptr++) = (g > 255) ? 255 : ((g < 0)

? 0 : g);

*(ptr++) = (b > 255) ? 255 : ((b < 0)

? 0 : b);

if (z++) {

z = 0;

yuyv += 4;

}

}

row_pointer[0] =

line_buffer;

jpeg_write_scanlines

(&cinfo, row_pointer, 1);

}

jpeg_finish_compress

(&cinfo);

jpeg_destroy_compress

(&cinfo);

free (line_buffer);

return (written);

}

....

....

....

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值