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

Reply via email to