[Libav-user] decoding H264 frames

Imran Khan imrank at cdac.in
Mon Feb 4 10:42:51 CET 2013


Sir

I have initialized AVCodecContext (avctx) in init_decoder method.Actually
I am not getting error from the decoder method. the return value from
avcodec_decode_video2() is always same as the AVPacket size that I am
passing into method. It is able to decode the frame because method is
never returning zero or minus value. But the frame is containing distorted
image. even if i am commenting the decode method the AVFrame (frame)
contains same distorted image. Can you tell please me what default value
AVFrame contains when it is allocated using avcodec_alloc_frame(). The
decode method is not updating AVFrame while decompression.


On Mon, Feb 4, 2013, srikanta mondal <srkntmondal at gmail.com> said:

> --20cf307f3b345cbb5e04d4e2af87
> Content-Type: text/plain; charset=ISO-8859-1
> 
> The encoded raw data (nal[] units) can decode using ffmpeg library. You
> have to initialize the AVCodecContext there and pass each raw encoded-data
> to avcodec_decode_video2() method.
> 
> On Mon, Feb 4, 2013 at 2:18 PM, Imran Khan <imrank at cdac.in> wrote:
> 
>> 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.
>>
>> -------------------------------------------------------------------------------------------------------------------------------
>>
>> _______________________________________________
>> Libav-user mailing list
>> Libav-user at ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/libav-user
>>
> 
> --20cf307f3b345cbb5e04d4e2af87
> Content-Type: text/html; charset=ISO-8859-1
> Content-Transfer-Encoding: quoted-printable
> 
> The encoded raw data (nal[] units) can decode using ffmpeg library. You hav=
> e to initialize the AVCodecContext there and pass each raw encoded-data to =
> avcodec_decode_video2() method.<br><br><div class=3D"gmail_quote">On Mon, F=
> eb 4, 2013 at 2:18 PM, Imran Khan <span dir=3D"ltr"><<a href=3D"mailto:i=
> mrank at cdac.in" target=3D"_blank">imrank at cdac.in</a>></span> wrote:<br>
> 
> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
> x #ccc solid;padding-left:1ex">Hello All<br>
> <br>
> I am trying to decode raw H264 frames using libavcodec. After getting<br>
> frames from webcam I am encoding it using H264 codec. After that I am<br>
> passing these frames one by one to a H264 decoder. In decoder<br>
> AVCodecContext I am setting width,height and =A0pixel format only. Problem<=
> br>
> is decoder not decompressing the frames. the size of the frame are same as<=
> br>
> the encoded frame size. Can anyone tell me what may be the problem.<br>
> <br>
> Here is my decoder code...<br>
> <br>
> #include "video_decoder.h"<br>
> <br>
> using namespace std;<br>
> <br>
> uint8_t* rgb_bytes;<br>
> <br>
> AVFrame *alloc_dec_picture(enum PixelFormat pix_fmt, int width, int<br>
> height){<br>
> <br>
> =A0 =A0 =A0 =A0 AVFrame *picture;<br>
> <br>
> =A0 =A0 uint8_t *picture_buf;<br>
> <br>
> =A0 =A0 int size;<br>
> =A0 =A0 picture =3D avcodec_alloc_frame();<br>
> <br>
> =A0 =A0 if (!picture)<br>
> =A0 =A0 =A0 =A0 return NULL;<br>
> <br>
> =A0 =A0 size =3D avpicture_get_size(pix_fmt, width, height);<br>
> <br>
> =A0 =A0 picture_buf =3D (uint8_t*)av_malloc(size);<br>
> <br>
> =A0 =A0 if (!picture_buf) {<br>
> <br>
> =A0 =A0 =A0 =A0 av_free(picture);<br>
> <br>
> =A0 =A0 =A0 =A0 return NULL;<br>
> <br>
> =A0 =A0 }<br>
> <br>
> =A0 =A0 avpicture_fill((AVPicture *)picture, picture_buf,pix_fmt, width,<br=
>>
> height);<br>
> <br>
> =A0 =A0 return picture;<br>
> <br>
> }<br>
> <br>
> VideoDecoder::VideoDecoder(){<br>
> <br>
> =A0 =A0 =A0 =A0 avcodec_register_all();<br>
> <br>
> =A0 =A0 =A0 =A0 avctx =3D NULL;<br>
> <br>
> =A0 =A0 =A0 =A0 picture =3D NULL;<br>
> <br>
> =A0 =A0 =A0 =A0 frame =3D NULL;<br>
> <br>
> }<br>
> <br>
> <br>
> char* VideoDecoder::decoder_init(AVCodecID codec_id){<br>
> <br>
> =A0 =A0 =A0 =A0 int error;<br>
> <br>
> =A0 =A0 =A0 =A0 AVCodec* codec;<br>
> <br>
> =A0 =A0 =A0 =A0 av_init_packet(&avpkt);<br>
> <br>
> =A0 =A0 =A0 =A0 codec =3D avcodec_find_decoder(codec_id);<br>
> <br>
> =A0 =A0 =A0 =A0 if(!codec){<br>
> <br>
> =A0 =A0 =A0 =A0 return "codec not found";<br>
> <br>
> <br>
> =A0 =A0 =A0 =A0 }<br>
> <br>
> =A0 =A0 =A0 =A0 avctx =3D avcodec_alloc_context3(codec);<br>
> <br>
> =A0 =A0 =A0 =A0 if(!avctx){<br>
> <br>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return "can not allocate avcontext :: =
> avocdec_alloc_context";<br>
> <br>
> =A0 =A0 =A0 =A0 }<br>
> <br>
> =A0 =A0 =A0 =A0 avctx->width=3D640;<br>
> <br>
> =A0 =A0 =A0 =A0 avctx->height=3D480;<br>
> <br>
> =A0 =A0 =A0 =A0 avctx->pix_fmt=3DAV_PIX_FMT_YUV420P;<br>
> <br>
> =A0 =A0 =A0 =A0 if(codec->capabilities&CODEC_CAP_TRUNCATED)<br>
> =A0 =A0 =A0 =A0 avctx->flags|=3D CODEC_FLAG_TRUNCATED;<br>
> <br>
> =A0 =A0 =A0 =A0 error =3D avcodec_open2(avctx ,codec ,NULL);<br>
> <br>
> =A0 =A0 =A0 =A0 if(error < 0 ){<br>
> <br>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return "can not open codec :: avcodec_=
> open2";<br>
> <br>
> =A0 =A0 =A0 =A0 }<br>
> <br>
> =A0 =A0 =A0 =A0 frame =3D avcodec_alloc_frame();<br>
> <br>
> =A0 =A0 =A0 =A0 picture =3D alloc_dec_picture(PIX_FMT_RGB24, 640, 480);<br>
> <br>
> =A0 =A0 =A0 =A0 return "decoder init completed\n";<br>
> }<br>
> <br>
> char* VideoDecoder::decode_frame(uint8_t *frame_buffer, size_t<br>
> data_length){<br>
> <br>
> =A0 =A0 =A0 =A0 int w =3D 640;<br>
> <br>
> =A0 =A0 int h =3D 480;<br>
> <br>
> =A0 =A0 =A0 =A0 rgb_bytes =3DNULL;<br>
> <br>
> =A0 =A0 =A0 =A0 int memBytes =3D avpicture_get_size(PIX_FMT_RGB24 , avctx-&=
> gt;width ,<br>
> avctx->height );<br>
> <br>
> =A0 =A0 =A0 =A0 int len ,got_frame;<br>
> <br>
> =A0 =A0 =A0 =A0 avpkt.size =3D data_length;<br>
> <br>
> =A0 =A0 =A0 =A0 avpkt.data =3D frame_buffer;<br>
> <br>
> =A0 =A0 =A0 =A0 if(!frame_buffer){<br>
> <br>
> =A0 =A0 =A0 =A0 return "frame buffer empty\n";<br>
> <br>
> =A0 =A0 =A0 =A0 }<br>
> <br>
> =A0 =A0 =A0 =A0 len =3D avcodec_decode_video2(avctx ,frame ,&got_frame =
> ,&avpkt);<br>
> <br>
> =A0 =A0 =A0 =A0 if( len < 0){<br>
> <br>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return "error while decoding\n";<=
> br>
> <br>
> =A0 =A0 =A0 =A0 }<br>
> <br>
> =A0 =A0 =A0 =A0 if( got_frame ){<br>
> <br>
> =A0 =A0 =A0 =A0 static struct SwsContext *img_convert_ctx;<br>
> <br>
> =A0 =A0 =A0if(img_convert_ctx =3D=3D NULL) {<br>
> <br>
> =A0 =A0 =A0 img_convert_ctx =3D sws_getContext(w, h,<br>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 PIX_FMT_YUV420P, avctx->width,<br>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 avctx->height, PIX_FMT_BGR24,<br>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 SWS_BICUBIC, NULL, NULL, NULL);<br>
> <br>
> =A0 =A0 =A0 =A0if(img_convert_ctx =3D=3D NULL) {<br>
> <br>
> =A0 =A0 =A0 =A0 =A0 =A0 return =A0"Cannot initialize the conversion co=
> ntext!\n";<br>
> <br>
> =A0 =A0 =A0 }<br>
> <br>
> =A0 =A0 }<br>
> <br>
> =A0 =A0 =A0 =A0 sws_scale(img_convert_ctx,<br>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 frame->data , frame->linesize ,<br>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 0, h ,picture->data,<br>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 picture->linesize );<br>
> <br>
> =A0 =A0 =A0 =A0 rgb_bytes =3D new uint8_t[memBytes];<br>
> <br>
> =A0 =A0 =A0 =A0 memcpy(rgb_bytes ,picture->data ,memBytes);<br>
> <br>
> =A0 =A0 =A0 =A0 }<br>
> <br>
> =A0 =A0 =A0 =A0 rgb_bytes =3D new uint8_t[memBytes];<br>
> <br>
> =A0 =A0 =A0 =A0 memcpy(rgb_bytes ,frame->data ,memBytes);<br>
> <br>
> <br>
> =A0 =A0 =A0 =A0 av_free_packet(&avpkt);<br>
> <br>
> =A0 =A0 =A0 =A0 return "completed decoding\n";<br>
> }<br>
> <br>
> <br>
> --<br>
> Thanks and Regards<br>
> Imran Khan<br>
> <br>
> <br>
> <br>
> ---------------------------------------------------------------------------=
> ----------------------------------------------------<br>
> <br>
> This e-mail is for the sole use of the intended recipient(s) and may<br>
> contain confidential and privileged information. If you are not the<br>
> intended recipient, please contact the sender by reply e-mail and destroy<b=
> r>
> all copies and the original message. Any unauthorized review, use,<br>
> disclosure, dissemination, forwarding, printing or copying of this email<br=
>>
> is strictly prohibited and appropriate legal action will be taken.<br>
> ---------------------------------------------------------------------------=
> ----------------------------------------------------<br>
> <br>
> _______________________________________________<br>
> Libav-user mailing list<br>
> <a href=3D"mailto:Libav-user at ffmpeg.org">Libav-user at ffmpeg.org</a><br>
> <a href=3D"http://ffmpeg.org/mailman/listinfo/libav-user" target=3D"_blank"=
>>http://ffmpeg.org/mailman/listinfo/libav-user</a><br>
> </blockquote></div><br>
> 
> --20cf307f3b345cbb5e04d4e2af87--
> 

-- 
Thanks and Regards
Imran Khan
Project Engineer
CDAC Hyderabad



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

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