How to convert jpeg to bitmap with libav in c++

160 views Asked by At

I am really new to image processing. In C++ app, I have a snapshot from an IP Camera as a JPEG image (as an array of bytes) and I need to make calculation on pixels.

The proposed way is to use libav to convert the JPEG to a bitmap.

Can somebody please explain which libav API's should I use? Maybe there are some examples?

Thank you!

1

There are 1 answers

0
user3518295 On

Here is the main part of the function:

avcodec_register_all();

AVCodecContext* codec_ctx = NULL;
AVFrame* frame = NULL;
try {

    // Find JPEG decoder to use it after
    AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);
    if (codec == NULL) {
        throw "Failed to find JPEG decoder";
    }

    // Create AVCodecContext using the codec
    codec_ctx = avcodec_alloc_context3(codec);
    if (codec_ctx == NULL) {
        throw "Failed to allocate codec context";
    }

    // Open codec with default options (when fails, only returns negative value, no exact error)
    if (avcodec_open2(codec_ctx, codec, NULL) < 0) {
        throw "Failed to open codec";
    }

    // Create and initialize AVPacket to hold the compressed data
    AVPacket packet;
    av_init_packet(&packet);
    packet.data = (uint8_t*)jpeg_data;
    packet.size = jpeg_size;

    // Decode the compressed data
    int ret = avcodec_send_packet(codec_ctx, &packet);
    if (ret < 0) {
        PrintAvlibErrorno(ret);
        throw "Error sending a packet for decoding";
    }

    // Create AVFrame to hold the decoded frame
    frame = av_frame_alloc();
    if (frame == NULL) {
        throw "Failed to allocate frame";
    }

    ret = avcodec_receive_frame(codec_ctx, frame);
    if (ret < 0) {
        PrintAvlibErrorno(ret);
        throw "Error receiving a frame from the decoder";
    }


    frame -> is the decoded frame! 

    // clean resources
    av_frame_free(&frame);
    avcodec_free_context(&codec_ctx);
}
catch (const char* szMsg) {
    OS->Err("Error JPEG to bitmap conversion: %s", szMsg);
    // clean resources
    av_frame_free(&frame);
    avcodec_free_context(&codec_ctx);       
    throw;
}