我正在使用libjpeg(Windows Mobile 6.5上的C / C++编程),以便将IP摄像机中的图像解码(以MJPEG流形式发送),然后再将其推送到DirectShow图形中。

到目前为止,我一直使用一个函数:接收流,手动解析流(以便找到JPEG数据的起点和终点),解码数据(即初始化libjpeg结构,读取JPEG header ,进行实际的解码...),最后将其推入图表。这可以正常工作,但是为了使事情更顺畅和整洁,我想使用一个函数来接收,该函数调用另一个函数(以后称为线程)进行解码/推送。

因此,作为第一步,不是在找到流中的数据之后立即完成所有JPEG工作,而是简单地调用另一个负责JPEG结构初始化/ header 读取/解码/推送的函数。

这是我无法解密的错误:“在状态205中对jpeg库的不正确调用”。

//编辑的清晰度

现在,我的代码如下所示:

无效的receive1(){
while(1)
{
if(recvfrom(/ * ... * /)> 0)
{
/ *解析接收到的数据的JPEG开头和结尾* /

/ *解码JPEG * /
//声明
struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;

//步骤1:分配/初始化
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
如果(setjmp(jerr.setjmp_buffer))
{
printf(“-ERROR LIBJPEG \ n”);
/ *使用错误代码退出* /
}

//下一步:继续解码并显示...
jpeg_create_decompress(&cinfo);
/ * ... * /
}
}
}

我想让我的代码看起来像:

无效的receive2(){
while(1)
{
if(recvfrom(/ * ... * /)> 0)
{
/ *解析接收到的数据的JPEG开头和结尾* /

解码(数据);
}
}
}

int解码(char *数据){
/ *解码JPEG * /
//声明
struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;

//步骤1:分配/初始化
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if(setjmp(jerr.setjmp_buffer))//这是发生“状态205”错误的地方
{
printf(“-ERROR LIBJPEG \ n”);
/ *使用错误代码退出* /
}

//下一步:继续解码并显示...
jpeg_create_decompress(&cinfo);
/ * ... * /

返回0;
}

任何帮助将不胜感激。非常感谢 !

//编辑

我意识到我在原始帖子中省略了很多信息。以下是一些(也许)有用的细节:

  • 我正在使用VS2008,但是由于许多原因,我没有使用内置的调试器或仿真器。而是,使用自定义的dos类命令提示符将exe文件直接部署在Windows Mobile设备上并进行测试。
  • libjpeg最初是从文件读取和写入的,但是我使用的是补丁程序(和自定义错误处理程序),可以直接从缓冲区读取数据,而无需打开文件。可以在here中找到代码,它使用以这种方式定义的“扩展错误处理程序”:

  • typedef struct my_error_mgr * my_error_ptr;

    结构my_error_mgr
    {
    struct jpeg_error_mgr pub;
    jmp_buf setjmp_buffer;
    };

    METHODDEF(void)my_error_exit(j_common_ptr cinfo)
    {
    my_error_ptr myerr =(my_error_ptr)cinfo-> err;

    / *始终显示消息。 * /
    (* cinfo-> err-> output_message)(cinfo);

    / *将控制权返回到setjmp点* /
    longjmp(myerr-> setjmp_buffer,1);
    }

    最佳答案

    205是0xCD,这是VS在 Debug模式下将VS放入标准内存中的标准值,因此我认为在调用解码器时,您的cinfo没有正确初始化。使用时发布代码。

    另外,您使用的setjump()让我认为它是IJG库。请小心,因为它不是标准功能。它会记住您进行调用时线程和堆栈的确切状态,并且能够从任何地方返回该位置,除非该状态不再有效,例如:

    int init_fn(){
         if (setjump(my_state)){
            // ERROR!
         };
    return 0;
    };
    
    int decode(){
         init_fn();
         do_work();
    };
    

    在这里,保存的状态在您调用实际的解码器时无效。对于MT情况,您必须从与setjump()相同的线程中调用longjmp()

    10-08 09:40