On date Wednesday 2008-12-03 13:17:31 +0100, Luca Abeni encoded:
> Stefano Sabatini wrote:
> > Hi all,
> >
> > the following program is meant to be a basic example of the encoding
> > decoding libavcodec API.
> >
> > The problem is that I *always* got an empty frame when decoding the
> > frame.
>
> This does not happen here: the encdec-dst.pgm file I get is just a
> "low quality" version of the encdec-src.pgm file. Probably, the rate
> control mechanism starts encoding the first frame with a low quality
> (and the image you use as input requires a very high bitrate).
Hi Luca, after three days hitting hard my head on the wall, I finally
discovered what was going wrong, in attachement there is a working
version.
And the problem was...
... that apparently libavcodec wasn't working correctly without to
first call av_register_all, a libavformat symbol, maybe the problem
also depends on the fact that I'm using shared libraries.
I still didn't investigate, but I think it is an FFmpeg bug, maybe you
didn't step into the problem because you're using static libraries.
> > Curiosly enough, I also tried the code of apiexample.c, getting
> > weird result, for example:
> >
> > ./apiexample ~/asian-commercials-are-weird.flv
> > Video decoding
>
> What is "asian-commercials-are-weird.flv"? Is it a video elementary
> stream? If not, I do not think you can decode it with apiexample
>
> > No decoding is performed with the video stream (VP6), while it is done
> > with other types of video stream (for example MPEG-1).
>
> Note that the video decoding example is hardcoding MPEG-1 as a video codec...
Yes, you're right on these.
Follows an updated version of the sample program.
-----------------------------8<--------------------------------------
#include <libavutil/avstring.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <stdlib.h>
#include <stdio.h>
static void save_pgm(uint8_t *frame_data, int linesize, int width, int height,
const char *filename)
{
int i;
FILE* file = fopen(filename, "w");
fprintf(file, "P5\n%d %d\n%d\n", width, height, 255);
for (i=0; i < height; i++)
fwrite(frame_data + i * linesize, width, 1, file);
fclose(file);
}
int main()
{
AVCodecContext *enc_ctx, *dec_ctx;
AVCodec *enc, *dec;
int i;
av_register_all();
avcodec_register_all();
/* initialize encoder */
enc_ctx = avcodec_alloc_context();
avcodec_get_context_defaults(enc_ctx);
enc_ctx->codec_type = CODEC_TYPE_VIDEO;
enc_ctx->width = 176;
enc_ctx->height = 144;
enc_ctx->pix_fmt = PIX_FMT_YUV420P;
enc_ctx->codec_id = CODEC_ID_H263;
enc_ctx->time_base = (AVRational) { 1, 30 };
enc_ctx->bit_rate = 400000;
enc = avcodec_find_encoder(enc_ctx->codec_id);
if (!enc) {
fprintf(stderr, "No encoder found\n");
exit(1);
}
if (avcodec_open(enc_ctx, enc) < 0) {
fprintf(stderr, "Impossible to open the encoder\n");
exit(1);
}
/* initialize decoder */
dec_ctx = avcodec_alloc_context();
avcodec_get_context_defaults(dec_ctx);
dec_ctx->codec_type = CODEC_TYPE_VIDEO;
dec_ctx->width = enc_ctx->width;
dec_ctx->height = enc_ctx->height;
dec_ctx->pix_fmt = enc_ctx->pix_fmt;
dec_ctx->codec_id = enc_ctx->codec_id;
dec_ctx->time_base = enc_ctx->time_base;
dec_ctx->bit_rate = 400000;
dec = avcodec_find_decoder(dec_ctx->codec_id);
if (!dec) {
fprintf(stderr, "No decoder found\n");
exit(1);
}
if (avcodec_open(dec_ctx, dec) < 0) {
fprintf(stderr, "Impossible to open the decoder\n");
exit(1);
}
/* create a frame and fill it randomly */
AVFrame * frame = avcodec_alloc_frame();
unsigned int frame_size = avpicture_get_size(enc_ctx->pix_fmt,
enc_ctx->width, enc_ctx->height);
uint8_t* frame_data = (uint8_t*)av_malloc(frame_size);
avpicture_fill((AVPicture*)frame, frame_data,
enc_ctx->pix_fmt, enc_ctx->width, enc_ctx->height);
if (frame_size < 0) {
fprintf(stderr, "Impossible to fill the frame data\n");
exit(1);
}
for (i = 0; i < 256; i++)
{
char filename[128];
int j;
for (j=0; j< frame_size; j++)
*(frame_data + j) = rand() / 256;
snprintf(filename, sizeof(filename), "encdec-src-%03d.pgm", i);
save_pgm(frame->data[0], frame->linesize[0], enc_ctx->width,
enc_ctx->height, filename);
/* encode it */
int enc_data_max_size = 1024 * 256;
uint8_t* enc_data = av_malloc(enc_data_max_size);
int enc_data_size = avcodec_encode_video(enc_ctx, enc_data,
enc_data_max_size, frame);
/* decode it */
AVFrame* frame2 = avcodec_alloc_frame();
int got_frame = 0;
int len;
while ((len = avcodec_decode_video(dec_ctx, frame2, &got_frame,
enc_data, enc_data_size)) > 0 || got_frame) {
enc_data += len;
enc_data_size -= len;
if (got_frame) {
snprintf(filename, sizeof(filename), "encdec-dst-%03d.pgm", i);
save_pgm(frame2->data[0], frame2->linesize[0], enc_ctx->width,
enc_ctx->height, filename);
}
}
}
return 0;
}
-----------------------------8<--------------------------------------
Thanks again, hey here it is as promised the virtual beer! :)
.oo.ooo.oooooooo.
oU U U U U U Uo
| |
| F F M P E G |====\
| | ||
| P A L S | ||
| | ||
| C L U B | ||
| |====/
| B E E R |
===============
Regards!
_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user