Statistics
| Branch: | Revision:

ffmpeg / libavcodec / apiexample.c @ 2d5e962b

History | View | Annotate | Download (13.3 KB)

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 'libav' 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
}