~ubuntu-dev/mplayer/ubuntu-feisty

« back to all changes in this revision

Viewing changes to libavcodec/apiexample.c

  • Committer: Reinhard Tartler
  • Date: 2006-07-08 08:45:33 UTC
  • Revision ID: siretart@tauware.de-20060708084533-dbc155bde7122e78
imported mplayer_0.99+1.0pre7try2+cvs20060117

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * @file apiexample.c
 
3
 * avcodec API use example.
 
4
 *
 
5
 * Note that this library only handles codecs (mpeg, mpeg4, etc...),
 
6
 * not file formats (avi, vob, etc...). See library 'libavformat' for the
 
7
 * format handling
 
8
 */
 
9
 
 
10
#include <stdlib.h>
 
11
#include <stdio.h>
 
12
#include <string.h>
 
13
#include <math.h>
 
14
 
 
15
#ifdef HAVE_AV_CONFIG_H
 
16
#undef HAVE_AV_CONFIG_H
 
17
#endif
 
18
 
 
19
#include "avcodec.h"
 
20
 
 
21
#define INBUF_SIZE 4096
 
22
 
 
23
/*
 
24
 * Audio encoding example
 
25
 */
 
26
void audio_encode_example(const char *filename)
 
27
{
 
28
    AVCodec *codec;
 
29
    AVCodecContext *c= NULL;
 
30
    int frame_size, i, j, out_size, outbuf_size;
 
31
    FILE *f;
 
32
    short *samples;
 
33
    float t, tincr;
 
34
    uint8_t *outbuf;
 
35
 
 
36
    printf("Audio encoding\n");
 
37
 
 
38
    /* find the MP2 encoder */
 
39
    codec = avcodec_find_encoder(CODEC_ID_MP2);
 
40
    if (!codec) {
 
41
        fprintf(stderr, "codec not found\n");
 
42
        exit(1);
 
43
    }
 
44
 
 
45
    c= avcodec_alloc_context();
 
46
 
 
47
    /* put sample parameters */
 
48
    c->bit_rate = 64000;
 
49
    c->sample_rate = 44100;
 
50
    c->channels = 2;
 
51
 
 
52
    /* open it */
 
53
    if (avcodec_open(c, codec) < 0) {
 
54
        fprintf(stderr, "could not open codec\n");
 
55
        exit(1);
 
56
    }
 
57
 
 
58
    /* the codec gives us the frame size, in samples */
 
59
    frame_size = c->frame_size;
 
60
    samples = malloc(frame_size * 2 * c->channels);
 
61
    outbuf_size = 10000;
 
62
    outbuf = malloc(outbuf_size);
 
63
 
 
64
    f = fopen(filename, "wb");
 
65
    if (!f) {
 
66
        fprintf(stderr, "could not open %s\n", filename);
 
67
        exit(1);
 
68
    }
 
69
 
 
70
    /* encode a single tone sound */
 
71
    t = 0;
 
72
    tincr = 2 * M_PI * 440.0 / c->sample_rate;
 
73
    for(i=0;i<200;i++) {
 
74
        for(j=0;j<frame_size;j++) {
 
75
            samples[2*j] = (int)(sin(t) * 10000);
 
76
            samples[2*j+1] = samples[2*j];
 
77
            t += tincr;
 
78
        }
 
79
        /* encode the samples */
 
80
        out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
 
81
        fwrite(outbuf, 1, out_size, f);
 
82
    }
 
83
    fclose(f);
 
84
    free(outbuf);
 
85
    free(samples);
 
86
 
 
87
    avcodec_close(c);
 
88
    av_free(c);
 
89
}
 
90
 
 
91
/*
 
92
 * Audio decoding.
 
93
 */
 
94
void audio_decode_example(const char *outfilename, const char *filename)
 
95
{
 
96
    AVCodec *codec;
 
97
    AVCodecContext *c= NULL;
 
98
    int out_size, size, len;
 
99
    FILE *f, *outfile;
 
100
    uint8_t *outbuf;
 
101
    uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
 
102
 
 
103
    printf("Audio decoding\n");
 
104
 
 
105
    /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
 
106
    memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
 
107
 
 
108
    /* find the mpeg audio decoder */
 
109
    codec = avcodec_find_decoder(CODEC_ID_MP2);
 
110
    if (!codec) {
 
111
        fprintf(stderr, "codec not found\n");
 
112
        exit(1);
 
113
    }
 
114
 
 
115
    c= avcodec_alloc_context();
 
116
 
 
117
    /* open it */
 
118
    if (avcodec_open(c, codec) < 0) {
 
119
        fprintf(stderr, "could not open codec\n");
 
120
        exit(1);
 
121
    }
 
122
 
 
123
    outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
 
124
 
 
125
    f = fopen(filename, "rb");
 
126
    if (!f) {
 
127
        fprintf(stderr, "could not open %s\n", filename);
 
128
        exit(1);
 
129
    }
 
130
    outfile = fopen(outfilename, "wb");
 
131
    if (!outfile) {
 
132
        av_free(c);
 
133
        exit(1);
 
134
    }
 
135
 
 
136
    /* decode until eof */
 
137
    inbuf_ptr = inbuf;
 
138
    for(;;) {
 
139
        size = fread(inbuf, 1, INBUF_SIZE, f);
 
140
        if (size == 0)
 
141
            break;
 
142
 
 
143
        inbuf_ptr = inbuf;
 
144
        while (size > 0) {
 
145
            len = avcodec_decode_audio(c, (short *)outbuf, &out_size,
 
146
                                       inbuf_ptr, size);
 
147
            if (len < 0) {
 
148
                fprintf(stderr, "Error while decoding\n");
 
149
                exit(1);
 
150
            }
 
151
            if (out_size > 0) {
 
152
                /* if a frame has been decoded, output it */
 
153
                fwrite(outbuf, 1, out_size, outfile);
 
154
            }
 
155
            size -= len;
 
156
            inbuf_ptr += len;
 
157
        }
 
158
    }
 
159
 
 
160
    fclose(outfile);
 
161
    fclose(f);
 
162
    free(outbuf);
 
163
 
 
164
    avcodec_close(c);
 
165
    av_free(c);
 
166
}
 
167
 
 
168
/*
 
169
 * Video encoding example
 
170
 */
 
171
void video_encode_example(const char *filename)
 
172
{
 
173
    AVCodec *codec;
 
174
    AVCodecContext *c= NULL;
 
175
    int i, out_size, size, x, y, outbuf_size;
 
176
    FILE *f;
 
177
    AVFrame *picture;
 
178
    uint8_t *outbuf, *picture_buf;
 
179
 
 
180
    printf("Video encoding\n");
 
181
 
 
182
    /* find the mpeg1 video encoder */
 
183
    codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
 
184
    if (!codec) {
 
185
        fprintf(stderr, "codec not found\n");
 
186
        exit(1);
 
187
    }
 
188
 
 
189
    c= avcodec_alloc_context();
 
190
    picture= avcodec_alloc_frame();
 
191
 
 
192
    /* put sample parameters */
 
193
    c->bit_rate = 400000;
 
194
    /* resolution must be a multiple of two */
 
195
    c->width = 352;
 
196
    c->height = 288;
 
197
    /* frames per second */
 
198
    c->time_base= (AVRational){1,25};
 
199
    c->gop_size = 10; /* emit one intra frame every ten frames */
 
200
    c->max_b_frames=1;
 
201
    c->pix_fmt = PIX_FMT_YUV420P;
 
202
 
 
203
    /* open it */
 
204
    if (avcodec_open(c, codec) < 0) {
 
205
        fprintf(stderr, "could not open codec\n");
 
206
        exit(1);
 
207
    }
 
208
 
 
209
    /* the codec gives us the frame size, in samples */
 
210
 
 
211
    f = fopen(filename, "wb");
 
212
    if (!f) {
 
213
        fprintf(stderr, "could not open %s\n", filename);
 
214
        exit(1);
 
215
    }
 
216
 
 
217
    /* alloc image and output buffer */
 
218
    outbuf_size = 100000;
 
219
    outbuf = malloc(outbuf_size);
 
220
    size = c->width * c->height;
 
221
    picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
 
222
 
 
223
    picture->data[0] = picture_buf;
 
224
    picture->data[1] = picture->data[0] + size;
 
225
    picture->data[2] = picture->data[1] + size / 4;
 
226
    picture->linesize[0] = c->width;
 
227
    picture->linesize[1] = c->width / 2;
 
228
    picture->linesize[2] = c->width / 2;
 
229
 
 
230
    /* encode 1 second of video */
 
231
    for(i=0;i<25;i++) {
 
232
        fflush(stdout);
 
233
        /* prepare a dummy image */
 
234
        /* Y */
 
235
        for(y=0;y<c->height;y++) {
 
236
            for(x=0;x<c->width;x++) {
 
237
                picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
 
238
            }
 
239
        }
 
240
 
 
241
        /* Cb and Cr */
 
242
        for(y=0;y<c->height/2;y++) {
 
243
            for(x=0;x<c->width/2;x++) {
 
244
                picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
 
245
                picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
 
246
            }
 
247
        }
 
248
 
 
249
        /* encode the image */
 
250
        out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
 
251
        printf("encoding frame %3d (size=%5d)\n", i, out_size);
 
252
        fwrite(outbuf, 1, out_size, f);
 
253
    }
 
254
 
 
255
    /* get the delayed frames */
 
256
    for(; out_size; i++) {
 
257
        fflush(stdout);
 
258
 
 
259
        out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
 
260
        printf("write frame %3d (size=%5d)\n", i, out_size);
 
261
        fwrite(outbuf, 1, out_size, f);
 
262
    }
 
263
 
 
264
    /* add sequence end code to have a real mpeg file */
 
265
    outbuf[0] = 0x00;
 
266
    outbuf[1] = 0x00;
 
267
    outbuf[2] = 0x01;
 
268
    outbuf[3] = 0xb7;
 
269
    fwrite(outbuf, 1, 4, f);
 
270
    fclose(f);
 
271
    free(picture_buf);
 
272
    free(outbuf);
 
273
 
 
274
    avcodec_close(c);
 
275
    av_free(c);
 
276
    av_free(picture);
 
277
    printf("\n");
 
278
}
 
279
 
 
280
/*
 
281
 * Video decoding example
 
282
 */
 
283
 
 
284
void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename)
 
285
{
 
286
    FILE *f;
 
287
    int i;
 
288
 
 
289
    f=fopen(filename,"w");
 
290
    fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
 
291
    for(i=0;i<ysize;i++)
 
292
        fwrite(buf + i * wrap,1,xsize,f);
 
293
    fclose(f);
 
294
}
 
295
 
 
296
void video_decode_example(const char *outfilename, const char *filename)
 
297
{
 
298
    AVCodec *codec;
 
299
    AVCodecContext *c= NULL;
 
300
    int frame, size, got_picture, len;
 
301
    FILE *f;
 
302
    AVFrame *picture;
 
303
    uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
 
304
    char buf[1024];
 
305
 
 
306
    /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
 
307
    memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
 
308
 
 
309
    printf("Video decoding\n");
 
310
 
 
311
    /* find the mpeg1 video decoder */
 
312
    codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
 
313
    if (!codec) {
 
314
        fprintf(stderr, "codec not found\n");
 
315
        exit(1);
 
316
    }
 
317
 
 
318
    c= avcodec_alloc_context();
 
319
    picture= avcodec_alloc_frame();
 
320
 
 
321
    if(codec->capabilities&CODEC_CAP_TRUNCATED)
 
322
        c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */
 
323
 
 
324
    /* for some codecs, such as msmpeg4 and mpeg4, width and height
 
325
       MUST be initialized there because these info are not available
 
326
       in the bitstream */
 
327
 
 
328
    /* open it */
 
329
    if (avcodec_open(c, codec) < 0) {
 
330
        fprintf(stderr, "could not open codec\n");
 
331
        exit(1);
 
332
    }
 
333
 
 
334
    /* the codec gives us the frame size, in samples */
 
335
 
 
336
    f = fopen(filename, "rb");
 
337
    if (!f) {
 
338
        fprintf(stderr, "could not open %s\n", filename);
 
339
        exit(1);
 
340
    }
 
341
 
 
342
    frame = 0;
 
343
    for(;;) {
 
344
        size = fread(inbuf, 1, INBUF_SIZE, f);
 
345
        if (size == 0)
 
346
            break;
 
347
 
 
348
        /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
 
349
           and this is the only method to use them because you cannot
 
350
           know the compressed data size before analysing it.
 
351
 
 
352
           BUT some other codecs (msmpeg4, mpeg4) are inherently frame
 
353
           based, so you must call them with all the data for one
 
354
           frame exactly. You must also initialize 'width' and
 
355
           'height' before initializing them. */
 
356
 
 
357
        /* NOTE2: some codecs allow the raw parameters (frame size,
 
358
           sample rate) to be changed at any frame. We handle this, so
 
359
           you should also take care of it */
 
360
 
 
361
        /* here, we use a stream based decoder (mpeg1video), so we
 
362
           feed decoder and see if it could decode a frame */
 
363
        inbuf_ptr = inbuf;
 
364
        while (size > 0) {
 
365
            len = avcodec_decode_video(c, picture, &got_picture,
 
366
                                       inbuf_ptr, size);
 
367
            if (len < 0) {
 
368
                fprintf(stderr, "Error while decoding frame %d\n", frame);
 
369
                exit(1);
 
370
            }
 
371
            if (got_picture) {
 
372
                printf("saving frame %3d\n", frame);
 
373
                fflush(stdout);
 
374
 
 
375
                /* the picture is allocated by the decoder. no need to
 
376
                   free it */
 
377
                snprintf(buf, sizeof(buf), outfilename, frame);
 
378
                pgm_save(picture->data[0], picture->linesize[0],
 
379
                         c->width, c->height, buf);
 
380
                frame++;
 
381
            }
 
382
            size -= len;
 
383
            inbuf_ptr += len;
 
384
        }
 
385
    }
 
386
 
 
387
    /* some codecs, such as MPEG, transmit the I and P frame with a
 
388
       latency of one frame. You must do the following to have a
 
389
       chance to get the last frame of the video */
 
390
    len = avcodec_decode_video(c, picture, &got_picture,
 
391
                               NULL, 0);
 
392
    if (got_picture) {
 
393
        printf("saving last frame %3d\n", frame);
 
394
        fflush(stdout);
 
395
 
 
396
        /* the picture is allocated by the decoder. no need to
 
397
           free it */
 
398
        snprintf(buf, sizeof(buf), outfilename, frame);
 
399
        pgm_save(picture->data[0], picture->linesize[0],
 
400
                 c->width, c->height, buf);
 
401
        frame++;
 
402
    }
 
403
 
 
404
    fclose(f);
 
405
 
 
406
    avcodec_close(c);
 
407
    av_free(c);
 
408
    av_free(picture);
 
409
    printf("\n");
 
410
}
 
411
 
 
412
int main(int argc, char **argv)
 
413
{
 
414
    const char *filename;
 
415
 
 
416
    /* must be called before using avcodec lib */
 
417
    avcodec_init();
 
418
 
 
419
    /* register all the codecs (you can also register only the codec
 
420
       you wish to have smaller code */
 
421
    avcodec_register_all();
 
422
 
 
423
    if (argc <= 1) {
 
424
        audio_encode_example("/tmp/test.mp2");
 
425
        audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
 
426
 
 
427
        video_encode_example("/tmp/test.mpg");
 
428
        filename = "/tmp/test.mpg";
 
429
    } else {
 
430
        filename = argv[1];
 
431
    }
 
432
 
 
433
    //    audio_decode_example("/tmp/test.sw", filename);
 
434
    video_decode_example("/tmp/test%d.pgm", filename);
 
435
 
 
436
    return 0;
 
437
}