2

DirectShow グラフにプッシュする前に、IP カメラからの画像 (MJPEG ストリームで送信) をデコードするために、libjpeg (Windows Mobile 6.5 での C/C++ プログラミング) を使用しています。

これまで、私は単一の関数を使用してきました: ストリームの受信、手動での解析 (JPEG データの開始点と終了点を見つけるため)、データのデコード (つまり、libjpeg 構造の初期化、JPEG ヘッダーの読み取り、実際のデコードを行います...)そして最後にそれをグラフにプッシュします。これは適切に機能しますが、物事をよりスムーズで整頓するために、デコード/プッシュ用に別の関数 (後でスレッド) を呼び出す受信用の関数を使用したいと思います。

したがって、最初のステップとして、ストリーム内のデータを見つけた直後にすべての JPEG 作業を行う代わりに、JPEG 構造の init / ヘッダーの読み取り / デコード / プッシュを担当する別の関数を呼び出すだけです。

そして、これは私が解読できないエラーが発生する場所です:「状態205のjpegライブラリへの不適切な呼び出し」

// わかりやすくするために編集

今のところ、私のコードは次のようになります。

void receive1() {
    ながら(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;
            if(setjmp(jerr.setjmp_buffer))
            {
                printf("--エラー LIBJPEG\n");
                /* エラーコードで終了 */
            }

            // 次のステップ: デコードと表示に進みます...
            jpeg_create_decompress(&cinfo);
            /* ... */
        }
    }
}

コードを次のようにしたい:

void receive2() {
  ながら(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("--エラー LIBJPEG\n");
        /* エラーコードで終了 */
    }

    // 次のステップ: デコードと表示に進みます...
    jpeg_create_decompress(&cinfo);
    /* ... */

    0 を返します。
}

ここで何か助けていただければ幸いです。どうもありがとう !

// 編集

元の投稿でかなり多くの情報を省略していることに気付きました。ここにいくつかの(おそらく)役立つ詳細があります:

  • 私は VS2008 を使用していますが、さまざまな理由から、組み込みのデバッガーやエミュレーターは使用していません。代わりに、カスタム dos に似たコマンド プロンプトを使用して、exe ファイルが Windows Mobile デバイスに直接展開され、テストされます。
  • libjpeg はもともとファイルの読み取りと書き込みを行いますが、パッチ (およびカスタム エラー ハンドラー) を使用して、ファイルを開かずにバッファーから直接データを読み取ることができるようにしています。コードはここにあります。この方法で定義された「拡張エラー ハンドラ」を使用します。
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);
}
4

2 に答える 2

1

205 は 0xCD です。これは、デバッグ モードで VS によって初期化されたメモリに配置される標準値であるためcinfo、デコーダを呼び出した時点で適切に初期化されていなかったと思います。使用時にコードを投稿してください。

また、setjump()あなたが使っているのはIJGライブラリだと思います。標準機能ではないので注意。呼び出しを行ったときのスレッドとスタックの正確な状態を記憶し、次のように、この状態が有効でなくなった場合を除き、どこからでもその位置に戻ることができます。

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

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

ここで、保存された状態は、実際のデコーダーを呼び出した時点では有効ではありません。MT の場合setjump()、 と同じスレッドからを呼び出す必要がありますlongjmp()

于 2010-10-25T10:15:49.027 に答える
0

ruslik のおかげもあって、私の問題に対する答えが見つかりました。2 つの関数間で cinfo と jerr を正しく初期化していなかったことがわかりました。

しかし、この点を修正すると、「state 205」エラーがまだ残っており、同じ場所にあると思いました。ログを調べたところ、エラー メッセージはコード実行の後半で発行され、関数ポインターの問題が原因であることがわかりました。自分の醜いミス...

とにかくどうもありがとう!

于 2010-10-27T09:21:34.417 に答える