Statistics
| Branch: | Revision:

ffmpeg / libavcodec / apiexample.c @ 20646267

History | View | Annotate | Download (13.3 KB)

1 983e3246 Michael Niedermayer
/**
2
 * @file apiexample.c
3
 * avcodec API use example.
4 de6d9b64 Fabrice Bellard
 *
5
 * Note that this library only handles codecs (mpeg, mpeg4, etc...),
6 d99ce8d7 Fabrice Bellard
 * not file formats (avi, vob, etc...). See library 'libavformat' for the
7 de6d9b64 Fabrice Bellard
 * format handling 
8
 */
9 983e3246 Michael Niedermayer
10 de6d9b64 Fabrice Bellard
#include <stdlib.h>
11
#include <stdio.h>
12
#include <string.h>
13
#include <math.h>
14
15 fe1b62fb Zdenek Kabelac
#ifdef HAVE_AV_CONFIG_H
16
#undef HAVE_AV_CONFIG_H
17
#endif
18
19 de6d9b64 Fabrice Bellard
#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 e8b62df6 Michael Niedermayer
    AVCodecContext *c= NULL;
30 de6d9b64 Fabrice Bellard
    int frame_size, i, j, out_size, outbuf_size;
31
    FILE *f;
32
    short *samples;
33
    float t, tincr;
34 0c1a9eda Zdenek Kabelac
    uint8_t *outbuf;
35 de6d9b64 Fabrice Bellard
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 e8b62df6 Michael Niedermayer
    c= avcodec_alloc_context();
46
    
47 de6d9b64 Fabrice Bellard
    /* 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 1c0e205f Matthias Fritschi
    f = fopen(filename, "wb");
65 de6d9b64 Fabrice Bellard
    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 e8b62df6 Michael Niedermayer
    free(c);
89 de6d9b64 Fabrice Bellard
}
90
91
/*
92
 * Audio decoding. 
93
 */
94
void audio_decode_example(const char *outfilename, const char *filename)
95
{
96
    AVCodec *codec;
97 e8b62df6 Michael Niedermayer
    AVCodecContext *c= NULL;
98 de6d9b64 Fabrice Bellard
    int out_size, size, len;
99
    FILE *f, *outfile;
100 0c1a9eda Zdenek Kabelac
    uint8_t *outbuf;
101 6a686d58 Michael Niedermayer
    uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
102 de6d9b64 Fabrice Bellard
103
    printf("Audio decoding\n");
104 6a686d58 Michael Niedermayer
    
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 de6d9b64 Fabrice Bellard
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 e8b62df6 Michael Niedermayer
    c= avcodec_alloc_context();
116 de6d9b64 Fabrice Bellard
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 1c0e205f Matthias Fritschi
    f = fopen(filename, "rb");
126 de6d9b64 Fabrice Bellard
    if (!f) {
127
        fprintf(stderr, "could not open %s\n", filename);
128
        exit(1);
129
    }
130 1c0e205f Matthias Fritschi
    outfile = fopen(outfilename, "wb");
131 de6d9b64 Fabrice Bellard
    if (!outfile) {
132 e8b62df6 Michael Niedermayer
        free(c);
133 de6d9b64 Fabrice Bellard
        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 e8b62df6 Michael Niedermayer
    free(c);
166 de6d9b64 Fabrice Bellard
}
167
168
/*
169
 * Video encoding example 
170
 */
171
void video_encode_example(const char *filename)
172
{
173
    AVCodec *codec;
174 e8b62df6 Michael Niedermayer
    AVCodecContext *c= NULL;
175 de6d9b64 Fabrice Bellard
    int i, out_size, size, x, y, outbuf_size;
176
    FILE *f;
177 492cd3a9 Michael Niedermayer
    AVFrame *picture;
178 0c1a9eda Zdenek Kabelac
    uint8_t *outbuf, *picture_buf;
179 de6d9b64 Fabrice Bellard
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 e8b62df6 Michael Niedermayer
    c= avcodec_alloc_context();
190 492cd3a9 Michael Niedermayer
    picture= avcodec_alloc_frame();
191 e8b62df6 Michael Niedermayer
    
192 de6d9b64 Fabrice Bellard
    /* 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 14bea432 Michael Niedermayer
    c->frame_rate = 25;  
199
    c->frame_rate_base= 1;
200 de6d9b64 Fabrice Bellard
    c->gop_size = 10; /* emit one intra frame every ten frames */
201 17d71fb9 Michael Niedermayer
    c->max_b_frames=1;
202 de6d9b64 Fabrice Bellard
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 1c0e205f Matthias Fritschi
    f = fopen(filename, "wb");
212 de6d9b64 Fabrice Bellard
    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 6c16199b Michael Niedermayer
    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 de6d9b64 Fabrice Bellard
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 6c16199b Michael Niedermayer
                picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
238 de6d9b64 Fabrice Bellard
            }
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 6c16199b Michael Niedermayer
                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 de6d9b64 Fabrice Bellard
            }
247
        }
248
249
        /* encode the image */
250 6c16199b Michael Niedermayer
        out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
251 17d71fb9 Michael Niedermayer
        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 de6d9b64 Fabrice Bellard
        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 e8b62df6 Michael Niedermayer
    free(c);
276 6c16199b Michael Niedermayer
    free(picture);
277 de6d9b64 Fabrice Bellard
    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 e8b62df6 Michael Niedermayer
    AVCodecContext *c= NULL;
300 de6d9b64 Fabrice Bellard
    int frame, size, got_picture, len;
301
    FILE *f;
302 492cd3a9 Michael Niedermayer
    AVFrame *picture;
303 6a686d58 Michael Niedermayer
    uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
304 de6d9b64 Fabrice Bellard
    char buf[1024];
305
306 6a686d58 Michael Niedermayer
    /* 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 de6d9b64 Fabrice Bellard
    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 e8b62df6 Michael Niedermayer
    c= avcodec_alloc_context();
319 492cd3a9 Michael Niedermayer
    picture= avcodec_alloc_frame();
320 de6d9b64 Fabrice Bellard
321 f78ebb51 Michael Niedermayer
    if(codec->capabilities&CODEC_CAP_TRUNCATED)
322
        c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */
323
324 58f26ba9 Fabrice Bellard
    /* for some codecs, such as msmpeg4 and mpeg4, width and height
325 de6d9b64 Fabrice Bellard
       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 1c0e205f Matthias Fritschi
    f = fopen(filename, "rb");
337 de6d9b64 Fabrice Bellard
    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 58f26ba9 Fabrice Bellard
           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 de6d9b64 Fabrice Bellard
           '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 6c16199b Michael Niedermayer
            len = avcodec_decode_video(c, picture, &got_picture, 
366 de6d9b64 Fabrice Bellard
                                       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 17d71fb9 Michael Niedermayer
                printf("saving frame %3d\n", frame);
373 de6d9b64 Fabrice Bellard
                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 6c16199b Michael Niedermayer
                pgm_save(picture->data[0], picture->linesize[0], 
379 de6d9b64 Fabrice Bellard
                         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 6c16199b Michael Niedermayer
    len = avcodec_decode_video(c, picture, &got_picture, 
391 de6d9b64 Fabrice Bellard
                               NULL, 0);
392
    if (got_picture) {
393 17d71fb9 Michael Niedermayer
        printf("saving last frame %3d\n", frame);
394 de6d9b64 Fabrice Bellard
        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 6c16199b Michael Niedermayer
        pgm_save(picture->data[0], picture->linesize[0], 
400 de6d9b64 Fabrice Bellard
                 c->width, c->height, buf);
401
        frame++;
402
    }
403
        
404
    fclose(f);
405
406
    avcodec_close(c);
407 e8b62df6 Michael Niedermayer
    free(c);
408 6c16199b Michael Niedermayer
    free(picture);
409 de6d9b64 Fabrice Bellard
    printf("\n");
410
}
411
412 fe1b62fb Zdenek Kabelac
// 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 bec89a84 Zdenek Kabelac
                if (c->help) {
434 fe1b62fb Zdenek Kabelac
                    stack[depth++] = c;
435 bec89a84 Zdenek Kabelac
                    c = (const AVOption*)c->help;
436 fe1b62fb Zdenek Kabelac
                } 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 de6d9b64 Fabrice Bellard
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 fe1b62fb Zdenek Kabelac
498
#ifdef OPT_TEST
499
    options_example(argc, argv);
500
#else
501 de6d9b64 Fabrice Bellard
    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 fe1b62fb Zdenek Kabelac
#endif
514 de6d9b64 Fabrice Bellard
515
    return 0;
516
}