2010-10-25 43 views
1

爲了解碼來自IP攝像機的圖像(在MJPEG流中發送),在將它們推入DirectShow之前,我正在使用libjpeg(Windows Mobile 6.5上的C/C++編程)圖形。到目前爲止,我一直在使用單個函數來接收流,手動解析它(爲了找到JPEG數據的起點和終點),解碼數據(即初始化libjpeg結構,閱讀JPEG標頭,進行實際的解碼...),最後將其推入圖形。這工作正常,但爲了使事情更平滑和整齊,我想使用一個函數接收,調用另一個函數(稍後,一個線程)進行解碼/推送。Libjpeg錯誤 - 狀態不正確呼叫205

因此,作爲第一步,我不需要在查找流中的數據後立即完成所有JPEG工作,而只需調用另一個負責JPEG結構init /頭讀取/解碼/推送的函數。

這是我得到一個錯誤,我不能解碼:「不正確的調用jpeg庫在狀態205」

//編輯的CLARITY

現在,我的代碼如下所示:

 
void receive1() { 
    while(1) 
    { 
     if(recvfrom(/* ... */) > 0) 
     { 
      /* parse the received data for JPEG start and end */ 

      /* decode the JPEG */ 
      //Declarations 
      struct jpeg_decompress_struct cinfo; 
      struct my_error_mgr jerr; 

      // Step 1: allocation/initialization 
      cinfo.err = jpeg_std_error(&jerr.pub); 
      jerr.pub.error_exit = my_error_exit; 
      if(setjmp(jerr.setjmp_buffer)) 
      { 
       printf("--ERROR LIBJPEG\n"); 
       /* quit with error code */ 
      } 

      // Next steps : proceed with the decoding and displaying... 
      jpeg_create_decompress(&cinfo); 
      /* ... */ 
     } 
    } 
}

我想有我的代碼如下所示:

 
void receive2() { 
    while(1) 
    { 
    if(recvfrom(/* ... */) > 0) 
    { 
     /* parse the received data for JPEG start and end */ 

     decode(data); 
    } 
    } 
} 

int decode(char* data) { 
    /* decode the JPEG */ 
    //Declarations 
    struct jpeg_decompress_struct cinfo; 
    struct my_error_mgr jerr; 

    // Step 1: allocation/initialization 
    cinfo.err = jpeg_std_error(&jerr.pub); 
    jerr.pub.error_exit = my_error_exit; 
    if(setjmp(jerr.setjmp_buffer)) // This is where the "state 205" error occurs 
    { 
     printf("--ERROR LIBJPEG\n"); 
     /* quit with error code */ 
    } 

    // Next steps : proceed with the decoding and displaying... 
    jpeg_create_decompress(&cinfo); 
    /* ... */ 

    return 0; 
}

任何幫助將是在這裏讚賞。非常感謝 !

//編輯

我意識到我省略了很多的信息在我原來的職位。這裏有一些(可能)有用的細節:

  • 我使用VS2008,但由於很多原因,我不使用內置的調試器或模擬器。相反,該exe文件是直接部署和測試在Windows Mobile設備上,使用自定義DOS類似的命令提示符。
  • libjpeg最初是從文件中讀取和寫入的,但是我使用的補丁(和自定義錯誤處理程序)能夠直接從緩衝區中讀取數據,而無需打開文件。代碼可以發現here,它使用一個「擴展錯誤處理程序」這樣定義的:
typedef struct my_error_mgr * my_error_ptr; 

struct 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; 

    /* Always display the message. */ 
    (*cinfo->err->output_message) (cinfo); 

    /* Return control to the setjmp point */ 
    longjmp(myerr->setjmp_buffer, 1); 
}
+0

此外,我可以,避免setjmp()和longjmp()。如果你真的需要他們,那麼他們會很好,否則會很痛苦。 – 2010-10-25 11:33:36

+0

感謝您的建議。我將嘗試在沒有它的情況下使用lib。 我必須承認我使用IJG的libjpeg中的示例,其中使用了setjmp()而沒有明確的解釋... – BlueCookie 2010-10-25 11:53:23

+1

您無法在IJG中避免它們,因爲它的錯誤報告函數並不意味着返回:'printf( 「錯誤。\ n」);放棄(1);',並且調用者不期望從它返回。因此,通常它會從程序流的其餘部分完全返回。 – ruslik 2010-10-25 12:54:45

回答

1

205 0XCD,即通過VS在未初始化內存放調試模式下的標準值,所以我覺得您的cinfo在您調用解碼器的那一刻未被正確初始化。在使用它時發佈代碼。

此外,您使用的setjump()讓我覺得它是IJG庫。小心它,因爲它不是一個標準功能。它會記住線程和堆棧的確切狀態時,你所做的呼叫,並能夠從任何地方返回到那個位置,除非情況下,當這種狀態不再有效,如:

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

int decode(){ 
    init_fn(); 
    do_work(); 
}; 

這裏保存狀態在您調用實際解碼器時無效。對於MT情況下,您必須從與longjmp()相同的線索調用setjump()

+0

是的,這是IJG圖書館。當我有任何消息時,我會更深入地瞭解這些內容併發帖,非常感謝! – BlueCookie 2010-10-25 10:22:12

+0

剛剛編輯原文。我不認爲我試圖從不同的函數/線程調用setjmp()和longjmp()。 (不是C或CRT專家,這個問題很混亂......) – BlueCookie 2010-10-25 13:39:26

+0

感謝關於cinfo的提示 - 即使問題在以後仍然存在,這是實際的答案。 – BlueCookie 2010-10-27 09:23:07

0

找到了我的問題的答案,部分得益於ruslik。事實證明,我確實在兩個函數之間初始化了cinfo和jerr。

但是,當我糾正這一點,我仍然有「國205」的錯誤,並認爲它是在同一個地方。挖掘我的日誌,我發現錯誤消息稍後在代碼執行中發出,並且由函數指針的問題引起。我自己的醜陋的錯誤...

無論如何非常感謝!

+0

這些是'jpeg_source_mgr'結構中的函數指針,是嗎?我剛剛遇到了一個問題,因爲我未能正確填充這些指針,所以出現了'狀態205錯誤的JPEG庫調用錯誤'錯誤。 – njahnke 2014-03-02 01:18:19