Как записать AVFrame в виде изображения JPEG

Я пишу программу для извлечения изображений из видеопотока. Пока я понял, как искать правильные кадры, декодировать видеопоток и собирать соответствующие данные в структуру AVFrame. Сейчас я пытаюсь записать данные в виде изображения в формате JPEG, но мой код не работает. Код, который я получил, взят отсюда: https://gist.github.com/RLovelett/67856c5bfdf5739944ed

int save_frame_as_jpeg(AVCodecContext *pCodecCtx, AVFrame *pFrame, int FrameNo) {
    AVCodec *jpegCodec = avcodec_find_encoder(AV_CODEC_ID_JPEG2000);
    if (!jpegCodec) {
        return -1;
    }
    AVCodecContext *jpegContext = avcodec_alloc_context3(jpegCodec);
    if (!jpegContext) {
        return -1;
    }

    jpegContext->pix_fmt = pCodecCtx->pix_fmt;
    jpegContext->height = pFrame->height;
    jpegContext->width = pFrame->width;

    if (avcodec_open2(jpegContext, jpegCodec, NULL) < 0) {
        return -1;
    }
    FILE *JPEGFile;
    char JPEGFName[256];

    AVPacket packet = {.data = NULL, .size = 0};
    av_init_packet(&packet);
    int gotFrame;

    if (avcodec_encode_video2(jpegContext, &packet, pFrame, &gotFrame) < 0) {
        return -1;
    }

    sprintf(JPEGFName, "dvr-%06d.jpg", FrameNo);
    JPEGFile = fopen(JPEGFName, "wb");
    fwrite(packet.data, 1, packet.size, JPEGFile);
    fclose(JPEGFile);

    av_free_packet(&packet);
    avcodec_close(jpegContext);
    return 0;
}

Если я использую этот код, первая ошибка, которую я получаю, связана с тем, что time_base на AVCodecContext не установлен. Я установил это на временную базу моей структуры AVCodecContext декодирования видео. Теперь я получаю другую ошибку

[jpeg2000 @ 0x7fd6a4015200] dimensions not set
[jpeg2000 @ 0x7fd6a307c400] dimensions not set
[jpeg2000 @ 0x7fd6a5800000] dimensions not set
[jpeg2000 @ 0x7fd6a307ca00] dimensions not set
[jpeg2000 @ 0x7fd6a3092400] dimensions not set

и изображения все еще не пишутся. Из этого Github Gist один комментатор заявил, что метаданные не записываются в изображение JPEG, но как мне записать эти метаданные? Я установил ширину и высоту контекста кодирования, поэтому я не уверен, почему он утверждает, что размеры не установлены.


person John Allard    schedule 07.11.2016    source источник
comment
Если вы распечатаете ширину и высоту, имеют ли значение полученные значения? Также вы сделали что-нибудь, чтобы проверить правильность поступающих кадров?   -  person Chris    schedule 08.11.2016


Ответы (1)


JPEG2000 — это не JPEG. Для кодирования изображений JPEG используйте AV_CODEC_ID_MJPEG. MJPEG расшифровывается как «Motion JPEG», так обычно называется последовательность изображений JPEG, составляющих видеопоток.

person Ronald S. Bultje    schedule 10.11.2016
comment
Благодарю вас! Я закончил тем, что использовал MJPEG, и он заработал. - person John Allard; 16.12.2016