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.
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.