[Libav-user] decoding H264 frames

Imran Khan imrank at cdac.in
Mon Feb 4 09:48:17 CET 2013


Hello All

I am trying to decode raw H264 frames using libavcodec. After getting
frames from webcam I am encoding it using H264 codec. After that I am
passing these frames one by one to a H264 decoder. In decoder
AVCodecContext I am setting width,height and  pixel format only. Problem
is decoder not decompressing the frames. the size of the frame are same as
the encoded frame size. Can anyone tell me what may be the problem.

Here is my decoder code...

#include "video_decoder.h"

using namespace std;

uint8_t* rgb_bytes;

AVFrame *alloc_dec_picture(enum PixelFormat pix_fmt, int width, int
height){
  
	AVFrame *picture;

    uint8_t *picture_buf;

    int size;
    picture = avcodec_alloc_frame();

    if (!picture)
        return NULL;

    size = avpicture_get_size(pix_fmt, width, height);

    picture_buf = (uint8_t*)av_malloc(size);

    if (!picture_buf) {

        av_free(picture);

        return NULL;

    }

    avpicture_fill((AVPicture *)picture, picture_buf,pix_fmt, width,
height);

    return picture;

}

VideoDecoder::VideoDecoder(){

	avcodec_register_all();

	avctx = NULL;

	picture = NULL;

	frame = NULL;

}


char* VideoDecoder::decoder_init(AVCodecID codec_id){

	int error;

	AVCodec* codec;

	av_init_packet(&avpkt);

	codec = avcodec_find_decoder(codec_id);
    
	if(!codec){

	return "codec not found";


	}

	avctx = avcodec_alloc_context3(codec);

	if(!avctx){

		return "can not allocate avcontext :: avocdec_alloc_context";

	}

	avctx->width=640;
	
	avctx->height=480;

	avctx->pix_fmt=AV_PIX_FMT_YUV420P;

	if(codec->capabilities&CODEC_CAP_TRUNCATED)
        avctx->flags|= CODEC_FLAG_TRUNCATED;

	error = avcodec_open2(avctx ,codec ,NULL);

	if(error < 0 ){
	
		return "can not open codec :: avcodec_open2";
	
	}

	frame = avcodec_alloc_frame();

	picture = alloc_dec_picture(PIX_FMT_RGB24, 640, 480);

	return "decoder init completed\n";
}

char* VideoDecoder::decode_frame(uint8_t *frame_buffer, size_t
data_length){

	int w = 640;

    int h = 480;

	rgb_bytes =NULL;

	int memBytes = avpicture_get_size(PIX_FMT_RGB24 , avctx->width ,
avctx->height );

	int len ,got_frame;

	avpkt.size = data_length;

	avpkt.data = frame_buffer;

	if(!frame_buffer){

	return "frame buffer empty\n";

	}

	len = avcodec_decode_video2(avctx ,frame ,&got_frame ,&avpkt);

	if( len < 0){
	
		return "error while decoding\n";
	
	}

	if( got_frame ){

	static struct SwsContext *img_convert_ctx;	

     if(img_convert_ctx == NULL) {

      img_convert_ctx = sws_getContext(w, h, 
		  PIX_FMT_YUV420P, avctx->width,
		  avctx->height, PIX_FMT_BGR24, 
		  SWS_BICUBIC, NULL, NULL, NULL);

       if(img_convert_ctx == NULL) {

	    return  "Cannot initialize the conversion context!\n";

      }

    }

	sws_scale(img_convert_ctx, 
		frame->data , frame->linesize ,
		0, h ,picture->data,
		picture->linesize );

	rgb_bytes = new uint8_t[memBytes];

	memcpy(rgb_bytes ,picture->data ,memBytes);

	}

	rgb_bytes = new uint8_t[memBytes];

	memcpy(rgb_bytes ,frame->data ,memBytes);


	av_free_packet(&avpkt);

	return "completed decoding\n";
}


-- 
Thanks and Regards
Imran Khan



-------------------------------------------------------------------------------------------------------------------------------

This e-mail is for the sole use of the intended recipient(s) and may
contain confidential and privileged information. If you are not the
intended recipient, please contact the sender by reply e-mail and destroy
all copies and the original message. Any unauthorized review, use,
disclosure, dissemination, forwarding, printing or copying of this email
is strictly prohibited and appropriate legal action will be taken.
-------------------------------------------------------------------------------------------------------------------------------



More information about the Libav-user mailing list