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

          最近在开始研究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;
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luckywang1103

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值