您的位置:首页 > 编程语言

V4L2应用编程之huffman table don't exist,empty input file问题解决办法

2013-12-04 22:49 253 查看
最近在开始研究V4L2应用编程,网上找来一个embedsky的应用程序进行preview,第一次打开的时候是可以正常的preview,但是再次打开的时候提示:huffman table don't exist,empty input file。

我想之所以会报错huffman table don't exist,是在下面这个判断函数中,从缓冲区取出的图像数据buffers中不符合下面这个条件,也就是缓冲区取出的数据有错

//check huffman table,these code are optional
for (i1=0; i1<buf.bytesused; i1++)
{
if ((buffers[numBufs].start[i1] == 0x000000FF) && (buffers[numBufs].start[i1+1] == 0x000000C4))
{
break;
}
}
if (i1 == buf.bytesused)
{
printf("huffman table don't exist! \n");
goto next_frame;

//添加这句话表示如果huffman table don't exist的话表示采集的第一帧图像有问题,则跳转到next_frame的位置去执行

//在next_frame位置,会重新将刚才从缓冲队列中取出的数据放入缓冲队列,等待下一次被取出
}


那么我就暂时不用这次缓冲区取出的数据,重新将这个缓冲区放入到缓冲队列中去,等待下一次从缓冲队列中取出数据,解决的办法是在输出huffman table don't exist的地方让程序跳转到next_frame位置,在next_frame位置的函数将刚才取出的队列重新放入缓冲区

next_frame:
//将取出的图像放回缓冲区
memset(&buf, 0 ,sizeof(buf));
buf.index = numBufs;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
if (ioctl(fd, VIDIOC_QBUF, &buf) < 0)
{
printf("VIDIOC_QBUF error\n");
return -1;
}


这样再次打开preview的时候还能继续preview,不知各位还有什么更好的解决办法?

下面是代码片段,完整的程序在:http://download.csdn.net/detail/luckywang1103/6664249




//预览采集到的图像
while (1)
{
//如果把处理JPEG格式的数据和显示程序分离,把处理JPEG部分的数据作成一个新的线程,预览时会更加流畅。
for (numBufs = 0; numBufs < req.count; numBufs++)
{
if ((fd_y_file = fopen(s, "wb")) < 0)
{
printf("Unable to create y frame recording file\n");
return -1;
}

memset(&buf, 0, sizeof(buf));
buf.index = numBufs;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //取得原始采集数据
buf.memory = V4L2_MEMORY_MMAP; //存储类型:V4L2_MEMORY_MMAP(内存映射)或V4L2_MEMORY_USERPTR(用户指针)
if (ioctl(fd, VIDIOC_DQBUF, &buf) < 0) //从缓冲队列中取出数据
{
perror("VIDIOC_DQBUF failed.\n");
return -1;
}

unsigned char *ptcur = buffers[numBufs].start; //开始霍夫曼解码
int i1;
//check huffman table,these code are optional
for (i1=0; i1<buf.bytesused; i1++)
{
if ((buffers[numBufs].start[i1] == 0x000000FF) && (buffers[numBufs].start[i1+1] == 0x000000C4))
{
break;
}
}
if (i1 == buf.bytesused)
{
printf("huffman table don't exist! \n");
goto next_frame;
}
int i;
//SOI = Start Of Image = "FFD8", EOI = End Of Image = "FFD9"
for (i=0; i<buf.bytesused; i++)
{
if ((buffers[numBufs].start[i] == 0x000000FF) && (buffers[numBufs].start[i+1] == 0x000000D8))
break;
ptcur++;
}
int imagesize = buf.bytesused - i;

fwrite(ptcur, imagesize, 1, fd_y_file); //开始向LCD发送数据显示采集到的图像
fclose(fd_y_file);

if ((infile = fopen(s, "rb")) == NULL)
{
fprintf(stderr, "open %s failed\n", s);
exit(-1);
}
cinfo.err = jpeg_std_error(&jerr);

jpeg_create_decompress(&cinfo);

//导入要解压的Jpeg文件infile
jpeg_stdio_src(&cinfo, infile);

//读取jpeg文件的文件头
jpeg_read_header(&cinfo, TRUE);

//开始解压Jpeg文件,解压后将分配给scanline缓冲区,
jpeg_start_decompress(&cinfo);

buffer = (unsigned char *) malloc(cinfo.output_width * cinfo.output_components);
y = 0;
while (cinfo.output_scanline < cinfo.output_height)
{
jpeg_read_scanlines(&cinfo, &buffer, 1);
if (fbdev.fb_bpp == 16)
{
unsigned short color;
for (x = 0; x < cinfo.output_width; x++)
{
color = RGB888toRGB565(buffer[x * 3],buffer[x * 3 + 1], buffer[x * 3 + 2]);
fb_pixel(fbdev.fb_mem, fbdev.fb_width, fbdev.fb_height, x, y, color);///
}
}
else if (fbdev.fb_bpp == 24)
{
memcpy((unsigned char *)fbdev.fb_mem + y * fbdev.fb_width * 3, buffer,
cinfo.output_width * cinfo.output_components);
}
y++;//下一个scanline
}

//完成Jpeg解码,释放Jpeg文件
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);

//释放帧缓冲区
free(buffer);

//关闭Jpeg输入文件
fclose(infile);

next_frame: //将取出的图像放回缓冲区 memset(&buf, 0 ,sizeof(buf)); buf.index = numBufs; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) { printf("VIDIOC_QBUF error\n"); return -1; }
}

//printf("start the next frame\n");
if(stop_flag)
break;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐