Log in

View Full Version : Encode bmp sequence with libavcodec...Help!


rick666
9th August 2006, 16:46
Hi to all of you,
I'm new to this forum and this is my first thread.
I'm developing an application for live streaming but until now I'm using only mjpeg. Now I'm trying to create a mpeg4 stream, but first I want to start with something simplest like create a mpeg video from a sequence of bitmap with libavcodec.
I'm working with vc++ 6.0, sp5, processorPack, winxp+sp2.
I've tried with DIB (with MFC) and also with OpenCV (intel library for accessing image data).
Here's the OpenCv attempt:

#define BYTEPIC 352*288*3


FILE *f;
f = fopen("Test.mpeg", "wb");
if (!f) {
AfxMessageBox("error file");
return;
}
//Handle of the YUV 4:2:0P image
AVFrame *picture;
//Handle of the BGR image
AVFrame *pictureBGR;

//Handle of the codec
AVCodec *codec;
//Handle of the struct. for using the codec
AVCodecContext *cx;
uint8_t *outbuf;


av_register_all();


codec = avcodec_find_encoder(CODEC_ID_MPEG4);
if (!codec) {
//Encoder Mpeg4 not found
return -1;
}

IplImage *img = cvLoadImage("bitmap.bmp");

cx = avcodec_alloc_context();
cx->bit_rate = 400000;
cx->pix_fmt = PIX_FMT_YUV420P;
cx->width = img->width;
cx->height = img->height;
cx->time_base.den = 1;
cx->time_base.num = 25;
cx->gop_size = 10;
cx->max_b_frames = 1;

if (avcodec_open(cx,codec) < 0) {
//Could not open Encoder Mpeg4
cvReleaseImage(&img);
return -1;
}

outbuf = (uint8_t *)malloc(BYTEPIC );

//This 2 func are described below
pictureBGR = Alloc_pictureBGR24(img->width, img->height);
picture = Alloc_picture420P(img->width, img->height);


for (int i = 0; i < img->imageSize; i++) {
pictureBGR->data[0][i] = img->imageData[i];
}

img_convert((AVPicture *)picture, PIX_FMT_YUV420P,
(AVPicture*)pictureBGR, PIX_FMT_BGR24, img->width, img->height);
out_size = avcodec_encode_video(cx, outbuf, BYTEPIC, picture);

fwrite(outbuf, 1, out_size, f);

free(picture->data[0]);
av_free(picture);
free(pictureBGR->data[0]);
av_free(pictureBGR);
free(outbuf);

return 0;
}


AVFrame Alloc_picture420P(int width, int height) {
AVFrame *picture;
uint8_t *picture_buf;
int size;
int pix_fmt = PIX_FMT_YUV420P;
picture = avcodec_alloc_frame();
if (!picture) return NULL;
size = avpicture_get_size(pix_fmt, width, height);
picture_buf = (uint8_t *) malloc(size);
if (!picture_buf) {
av_free(picture);
return NULL;
}
avpicture_fill((AVPicture *)picture, picture_buf, pix_fmt, width,
height);
return picture;
}

AVFrame Alloc_pictureBGR24(int width, int height) {
AVFrame *pFrameRGB = avcodec_alloc_frame();
if(pFrameRGB==NULL) return NULL;
int numBytes = avpicture_get_size(PIX_FMT_BGR24, width, height);
uint8_t *buffer=(uint8_t *)malloc(numBytes);
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_BGR24, width,
height);
return pFrameRGB;
}

But the result of avcodec_encode_video is always 0.
In the real code there's a loop for read all the image of the sequence, but for now I can't encode either a single bitmap.
Is there some big error?...I'm going crazy... :confused:
If someone had do it with MFC I'll post my attempt with this library...

Regards.

Inc
9th August 2006, 18:58
You're actually writing a raw bitstream into your target file. No Header, no trailer like shown in the "output_example.c" code of Libavcodec.
That one shows you how to properly write a coded seqence into a file. Or is your purpose to end up with raw streams for later muxing in Avimux, MKVmerge or mp4Box ?

Nice sources where encoding via Libavcodec is shown are ...

- output_example.c (from libavcodec package) <--- Thats your candidate
- API_example.c (from libavcodec package) <--- also this one
- Qenc
- FreeEnc,

rick666
10th August 2006, 11:52
thank's, I've already checked output_example.c with no great success but if it's the best resource for understanding libavcodec then I'll try again.

rick666
10th August 2006, 17:08
I'm playing with output_example and there's a strange behaviour: with the standard codec that use the program based on the output file all works fine and I've a 5 sec video of random color (yuv), but if I force the program to use mpeg4 codec the result is a bigger file and vlc can't open it. Someone can tell me why?

rick666
10th August 2006, 18:33
I'm playing with output_example and there's a strange behaviour: with the standard codec that use the program based on the output file all works fine and I've a 5 sec video of random color (yuv), but if I force the program to use mpeg4 codec the result is a bigger file and vlc can't open it. Someone can tell me why?

However...I did it!But my video is black and white even if the images are 24bit...I can't understand if this is a mistake with "data" parameter of AVFrame.