~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to ffmpeg/libavcodec/apiexample.c

  • Committer: Bazaar Package Importer
  • Author(s): Christian Marillat
  • Date: 2004-08-29 10:53:42 UTC
  • Revision ID: james.westby@ubuntu.com-20040829105342-qgmnry37eadfkoxx
Tags: upstream-1.1.3
ImportĀ upstreamĀ versionĀ 1.1.3

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, "w");
 
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
    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, "r");
 
126
    if (!f) {
 
127
        fprintf(stderr, "could not open %s\n", filename);
 
128
        exit(1);
 
129
    }
 
130
    outfile = fopen(outfilename, "w");
 
131
    if (!outfile) {
 
132
        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
    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->frame_rate = 25;  
 
199
    c->frame_rate_base= 1;
 
200
    c->gop_size = 10; /* emit one intra frame every ten frames */
 
201
    c->max_b_frames=1;
 
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, "w");
 
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
    free(c);
 
276
    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, "r");
 
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
    free(c);
 
408
    free(picture);
 
409
    printf("\n");
 
410
}
 
411
 
 
412
// simple example how the options could be used
 
413
int options_example(int argc, char* argv[])
 
414
{
 
415
    AVCodec* codec = avcodec_find_encoder_by_name((argc > 1) ? argv[2] : "mpeg4");
 
416
    const AVOption* c;
 
417
    AVCodecContext* avctx;
 
418
    char* def = av_malloc(5000);
 
419
    const char* col = "";
 
420
    int i = 0;
 
421
 
 
422
    if (!codec)
 
423
        return -1;
 
424
    c = codec->options;
 
425
    avctx = avcodec_alloc_context();
 
426
    *def = 0;
 
427
 
 
428
    if (c) {
 
429
        const AVOption *stack[FF_OPT_MAX_DEPTH];
 
430
        int depth = 0;
 
431
        for (;;) {
 
432
            if (!c->name) {
 
433
                if (c->help) {
 
434
                    stack[depth++] = c;
 
435
                    c = (const AVOption*)c->help;
 
436
                } else {
 
437
                    if (depth == 0)
 
438
                        break; // finished
 
439
                    c = stack[--depth];
 
440
                    c++;
 
441
                }
 
442
            } else {
 
443
                int t = c->type & FF_OPT_TYPE_MASK;
 
444
                printf("Config   %s  %s\n",
 
445
                       t == FF_OPT_TYPE_BOOL ? "bool   " :
 
446
                       t == FF_OPT_TYPE_DOUBLE ? "double  " :
 
447
                       t == FF_OPT_TYPE_INT ? "integer" :
 
448
                       t == FF_OPT_TYPE_STRING ? "string " :
 
449
                       "unknown??", c->name);
 
450
                switch (t) {
 
451
                case FF_OPT_TYPE_BOOL:
 
452
                    i += sprintf(def + i, "%s%s=%s",
 
453
                                 col, c->name,
 
454
                                 c->defval != 0. ? "on" : "off");
 
455
                    break;
 
456
                case FF_OPT_TYPE_DOUBLE:
 
457
                    i += sprintf(def + i, "%s%s=%f",
 
458
                                 col, c->name, c->defval);
 
459
                    break;
 
460
                case FF_OPT_TYPE_INT:
 
461
                    i += sprintf(def + i, "%s%s=%d",
 
462
                                 col, c->name, (int) c->defval);
 
463
                    break;
 
464
                case FF_OPT_TYPE_STRING:
 
465
                    if (c->defstr) {
 
466
                        char* d = av_strdup(c->defstr);
 
467
                        char* f = strchr(d, ',');
 
468
                        if (f)
 
469
                            *f = 0;
 
470
                        i += sprintf(def + i, "%s%s=%s",
 
471
                                     col, c->name, d);
 
472
                        av_free(d);
 
473
                    }
 
474
                    break;
 
475
                }
 
476
                col = ":";
 
477
                c++;
 
478
            }
 
479
        }
 
480
    }
 
481
    printf("Default Options: %s\n", def);
 
482
    av_free(def);
 
483
    return 0;
 
484
}
 
485
 
 
486
 
 
487
int main(int argc, char **argv)
 
488
{
 
489
    const char *filename;
 
490
 
 
491
    /* must be called before using avcodec lib */
 
492
    avcodec_init();
 
493
 
 
494
    /* register all the codecs (you can also register only the codec
 
495
       you wish to have smaller code */
 
496
    avcodec_register_all();
 
497
 
 
498
#ifdef OPT_TEST
 
499
    options_example(argc, argv);
 
500
#else
 
501
    if (argc <= 1) {
 
502
        audio_encode_example("/tmp/test.mp2");
 
503
        audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
 
504
 
 
505
        video_encode_example("/tmp/test.mpg");
 
506
        filename = "/tmp/test.mpg";
 
507
    } else {
 
508
        filename = argv[1];
 
509
    }
 
510
 
 
511
    //    audio_decode_example("/tmp/test.sw", filename);
 
512
    video_decode_example("/tmp/test%d.pgm", filename);
 
513
#endif
 
514
 
 
515
    return 0;
 
516
}