Ошибка Libjpeg - неправильный вызов в состоянии 205 - PullRequest
1 голос
/ 25 октября 2010

Я использую libjpeg (программирование на C / C ++ для Windows Mobile 6.5), чтобы декодировать изображения с IP-камеры (отправленной в потоке MJPEG), прежде чем помещать их в граф DirectShow.

До сих пор я использовал одну функцию для: получения потока, его синтаксического анализа вручную (для нахождения начальной и конечной точки данных JPEG), декодирования данных (т.е. инициализации структур libjpeg, чтения Заголовок JPEG, выполняющий фактическое декодирование ...) и, наконец, вставляющий его в график. Это работает правильно, но для того, чтобы сделать вещи более плавными и аккуратными, я хотел бы использовать функцию для получения, которая вызывает другую функцию (позже - поток) для декодирования / отправки.

Итак, в качестве первого шага, вместо того, чтобы выполнять всю работу JPEG сразу после нахождения данных в потоке, я просто вызываю другую функцию, которая отвечает за структуру JPEG: чтение / декодирование / нажатие заголовков.

И вот здесь я получаю сообщение об ошибке, которое не могу расшифровать: "неправильный вызов библиотеки jpeg в состоянии 205" .

// РЕДАКТИРОВАНИЕ ДЛЯ ЯРКОСТИ

Пока мой код выглядит так:

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 изначально читает и записывает в файлы, но я использую патч (и пользовательский обработчик ошибок), позволяющий читать данные непосредственно из буфера, не открывая файл. Код можно найти здесь , и он использует «расширенный обработчик ошибок», определенный следующим образом:
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);
}

Ответы [ 2 ]

1 голос
/ 25 октября 2010

205 - это 0xCD, то есть стандартное значение, введенное VS в режиме отладки в унифицированной памяти, поэтому я думаю, что ваш cinfo не был правильно инициализирован в тот момент, когда вы вызвали декодер.Отправьте код, когда вы его используете.

Кроме того, setjump(), который вы используете, заставляет меня думать, что это библиотека IJG.Будьте осторожны с этим, потому что это не стандартная функция.Он запоминает точное состояние потока и стека, когда вы сделали вызов, и может вернуться к этой позиции из любого места, кроме случаев, когда это состояние больше не является допустимым, например:

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

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

здесь сохраненное состояние недействительно во время вызова фактического декодера.В случае МТ вы должны вызвать setjump() из того же потока, что и longjmp().

0 голосов
/ 27 октября 2010

Нашел ответ на мою проблему, отчасти благодаря руслик. Оказывается, я действительно плохо инициализировал cinfo и jerr между двумя функциями.

Но когда я исправил эту точку, у меня все еще была ошибка «состояние 205», и я подумал, что она там же. Копаясь в моих журналах, я обнаружил, что сообщение об ошибке выдается позже при выполнении кода и вызвано проблемами с указателями на функции. Моя собственная безобразная ошибка ...

Большое спасибо в любом случае!

...