FFMPEG decoder decode half of the frame

347 views
Skip to first unread message

Mohammad Omar Faruk

unread,
Feb 4, 2016, 2:02:57 AM2/4/16
to javacv
Hi all

I am using FFMPEG for video encoding, decoding(H264). After decoding, my frame height is reduced but width is perfect.

here is my code:

int FFMPEGDecode::initDecoder(int codec, int width, int height)
{
    if (codec == CODEC_H263)
    {
        decoder = avcodec_find_decoder(AV_CODEC_ID_H263);
    }
    else if (codec == CODEC_H263P)
    {
        decoder = avcodec_find_decoder(AV_CODEC_ID_H263P);
    }
    else if (codec == CODEC_H264)
    {
        decoder = avcodec_find_decoder(AV_CODEC_ID_H264);
    }
    else
    {
        LOGE("Codec not recognised!! Please select a valid codec.");
        return -1;
    }
    if (decoder == NULL)
    {
        LOGE("decoder not found");
        return -3;
    }

    decoderContext = avcodec_alloc_context3(decoder);

    // set properties for decoder. h264 packet contains information how it has been decoded. we dont need to specify them as we already did that part in initencoder function

    decoderContext->pix_fmt = AV_PIX_FMT_YUV420P;
    decoderContext->width = width;
    decoderContext->height = height;
    if (decoder->capabilities & CODEC_CAP_TRUNCATED)
            decoderContext->flags |= CODEC_FLAG_TRUNCATED;

    decoderContext->flags2 |= CODEC_FLAG2_FAST;

    decoderScaleContext = sws_getCachedContext(decoderScaleContext, width,
            height, AV_PIX_FMT_YUV420P, width, height, AV_PIX_FMT_RGB32,
            SWS_FAST_BILINEAR, NULL, NULL, NULL);

    if (avcodec_open2(decoderContext, decoder, NULL) < 0)
    {
        LOGE("decoder not opened");
        return -4;
    }

    return 1;
}

int FFMPEGDecode::decode(byte* encodedData, int encodedDataSize,
        int* decodedData)
{
    static verylong st, et;
    st = getCurrentSystemTimeMicro();
    int decode;
    int got_frame;

    byte *rgb_buffer;
    AVFrame *dframe;
    AVFrame *dframergb;
    AVPacket dc_packet;

    dframe = av_frame_alloc(); // this frame contains output value after decoding
    dframe->format = decoderContext->pix_fmt; //pixel format is yuv420p
    dframe->width = decoderContext->width;
    dframe->height = decoderContext->height;

    dframergb = av_frame_alloc(); // we use this frame for yuv to rgb conversion, used in sws_scale() function as destination
    dframergb->format = AV_PIX_FMT_RGB32; // pixel format rgb32. in java code we have used Bitmap.Config.ARGB_8888 to create bitmap.
    // ARGB_8888 configuration assumes rgb pixel data is stored in 4 bytes. so we need to use rgb32 here
    dframergb->width = decoderContext->width;
    dframergb->height = decoderContext->height;

    int num_bytes = avpicture_get_size(AV_PIX_FMT_RGB32, decoderContext->width,
            decoderContext->height);
    rgb_buffer = (byte *) av_malloc(num_bytes);

    avpicture_fill((AVPicture*) dframergb, rgb_buffer, PIX_FMT_RGB32,
            decoderContext->width, decoderContext->height); // filled frame with a blank picture.

    av_init_packet(&dc_packet); // crate a new packet with encoded data and size
    // initialize packet
    dc_packet.data = (byte*) encodedData;
    dc_packet.size = encodedDataSize;
    decode = avcodec_decode_video2(decoderContext, dframe, &got_frame,
            &dc_packet);

    if (got_frame > 0)
    {

        int h = sws_scale(decoderScaleContext, (const uint8_t * const *) dframe->data,
                dframe->linesize, 0, decoderContext->height, dframergb->data,
                dframergb->linesize); // frame conversion yuv to rgb
        memcpy(decodedData, dframergb->data[0],
                decoderContext->width * decoderContext->height);
        if(h != dframe->height){
            LOGD("Decoded NALU successfully HEIGHT NOT MATCH.....");
        }else{
            LOGD("Decoded NALU successfully");
        }
    }
    else
    {
        LOGE("Could not decode frame.. :(");
    }

    av_free_packet(&dc_packet);
    av_free(rgb_buffer);
    av_free(dframergb);
    av_free(dframe);

    et = getCurrentSystemTimeMicro();
    LOGD("Decoding time: %llu", (et - st));

    if (got_frame)
    {
        return decoderContext->height * decoderContext->width;
    }
    else
    {
        return 0;
    }

}

Samuel Audet

unread,
Feb 6, 2016, 2:24:35 AM2/6/16
to jav...@googlegroups.com
On 02/04/2016 04:02 PM, Mohammad Omar Faruk wrote:
> I am using FFMPEG for video encoding, decoding(H264). After decoding, my frame height is reduced but width is perfect.

Does the same thing happen if you use FFmpegFrameGrabber?

Samuel

Mohammad Omar Faruk

unread,
Feb 6, 2016, 10:33:33 PM2/6/16
to javacv
Actually I am not using JavaCV as I have needed raw data after encoding and decoding. I am trying to build FFmpeg using Android NDK and called native function to encode and decode. Another important fact is  that, If I give the encoded data to Android mediacodec then it can decode full frame but FFmpeg can not. But I need FFmpeg for both encoding and decoding as Android mediacodec is not works so well in all devices.

Samuel Audet

unread,
Feb 7, 2016, 2:53:44 AM2/7/16
to javacv

I understand that, but to debug your issue it would help to know if the same thing happens with FFmpegFrameGrabber. If it does not, then you could copy FFmpegFrameGrabber, and it will work the same!

Samuel

2016/02/07 12:33 "Mohammad Omar Faruk" <omar.fa...@gmail.com>:
--

---
You received this message because you are subscribed to the Google Groups "javacv" group.
To unsubscribe from this group and stop receiving emails from it, send an email to javacv+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages