Statistics
| Branch: | Revision:

ffmpeg / libavcodec / apiexample.c @ fe1b62fb

History | View | Annotate | Download (12.5 KB)

1
/* avcodec API use example.
2
 *
3
 * Note that this library only handles codecs (mpeg, mpeg4, etc...),
4
 * not file formats (avi, vob, etc...). See library 'libav' for the
5
 * format handling 
6
 */
7
#include <stdlib.h>
8
#include <stdio.h>
9
#include <string.h>
10
#include <math.h>
11

    
12
#ifdef HAVE_AV_CONFIG_H
13
#undef HAVE_AV_CONFIG_H
14
#endif
15

    
16
#include "avcodec.h"
17

    
18
#define INBUF_SIZE 4096
19

    
20
/*
21
 * Audio encoding example 
22
 */
23
void audio_encode_example(const char *filename)
24
{
25
    AVCodec *codec;
26
    AVCodecContext *c= NULL;
27
    int frame_size, i, j, out_size, outbuf_size;
28
    FILE *f;
29
    short *samples;
30
    float t, tincr;
31
    UINT8 *outbuf;
32

    
33
    printf("Audio encoding\n");
34

    
35
    /* find the MP2 encoder */
36
    codec = avcodec_find_encoder(CODEC_ID_MP2);
37
    if (!codec) {
38
        fprintf(stderr, "codec not found\n");
39
        exit(1);
40
    }
41

    
42
    c= avcodec_alloc_context();
43
    
44
    /* put sample parameters */
45
    c->bit_rate = 64000;
46
    c->sample_rate = 44100;
47
    c->channels = 2;
48

    
49
    /* open it */
50
    if (avcodec_open(c, codec) < 0) {
51
        fprintf(stderr, "could not open codec\n");
52
        exit(1);
53
    }
54
    
55
    /* the codec gives us the frame size, in samples */
56
    frame_size = c->frame_size;
57
    samples = malloc(frame_size * 2 * c->channels);
58
    outbuf_size = 10000;
59
    outbuf = malloc(outbuf_size);
60

    
61
    f = fopen(filename, "w");
62
    if (!f) {
63
        fprintf(stderr, "could not open %s\n", filename);
64
        exit(1);
65
    }
66
        
67
    /* encode a single tone sound */
68
    t = 0;
69
    tincr = 2 * M_PI * 440.0 / c->sample_rate;
70
    for(i=0;i<200;i++) {
71
        for(j=0;j<frame_size;j++) {
72
            samples[2*j] = (int)(sin(t) * 10000);
73
            samples[2*j+1] = samples[2*j];
74
            t += tincr;
75
        }
76
        /* encode the samples */
77
        out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
78
        fwrite(outbuf, 1, out_size, f);
79
    }
80
    fclose(f);
81
    free(outbuf);
82
    free(samples);
83

    
84
    avcodec_close(c);
85
    free(c);
86
}
87

    
88
/*
89
 * Audio decoding. 
90
 */
91
void audio_decode_example(const char *outfilename, const char *filename)
92
{
93
    AVCodec *codec;
94
    AVCodecContext *c= NULL;
95
    int out_size, size, len;
96
    FILE *f, *outfile;
97
    UINT8 *outbuf;
98
    UINT8 inbuf[INBUF_SIZE], *inbuf_ptr;
99

    
100
    printf("Audio decoding\n");
101

    
102
    /* find the mpeg audio decoder */
103
    codec = avcodec_find_decoder(CODEC_ID_MP2);
104
    if (!codec) {
105
        fprintf(stderr, "codec not found\n");
106
        exit(1);
107
    }
108

    
109
    c= avcodec_alloc_context();
110

    
111
    /* open it */
112
    if (avcodec_open(c, codec) < 0) {
113
        fprintf(stderr, "could not open codec\n");
114
        exit(1);
115
    }
116
    
117
    outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
118

    
119
    f = fopen(filename, "r");
120
    if (!f) {
121
        fprintf(stderr, "could not open %s\n", filename);
122
        exit(1);
123
    }
124
    outfile = fopen(outfilename, "w");
125
    if (!outfile) {
126
        free(c);
127
        exit(1);
128
    }
129
        
130
    /* decode until eof */
131
    inbuf_ptr = inbuf;
132
    for(;;) {
133
        size = fread(inbuf, 1, INBUF_SIZE, f);
134
        if (size == 0)
135
            break;
136

    
137
        inbuf_ptr = inbuf;
138
        while (size > 0) {
139
            len = avcodec_decode_audio(c, (short *)outbuf, &out_size, 
140
                                       inbuf_ptr, size);
141
            if (len < 0) {
142
                fprintf(stderr, "Error while decoding\n");
143
                exit(1);
144
            }
145
            if (out_size > 0) {
146
                /* if a frame has been decoded, output it */
147
                fwrite(outbuf, 1, out_size, outfile);
148
            }
149
            size -= len;
150
            inbuf_ptr += len;
151
        }
152
    }
153

    
154
    fclose(outfile);
155
    fclose(f);
156
    free(outbuf);
157

    
158
    avcodec_close(c);
159
    free(c);
160
}
161

    
162
/*
163
 * Video encoding example 
164
 */
165
void video_encode_example(const char *filename)
166
{
167
    AVCodec *codec;
168
    AVCodecContext *c= NULL;
169
    int i, out_size, size, x, y, outbuf_size;
170
    FILE *f;
171
    AVFrame *picture;
172
    UINT8 *outbuf, *picture_buf;
173

    
174
    printf("Video encoding\n");
175

    
176
    /* find the mpeg1 video encoder */
177
    codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
178
    if (!codec) {
179
        fprintf(stderr, "codec not found\n");
180
        exit(1);
181
    }
182

    
183
    c= avcodec_alloc_context();
184
    picture= avcodec_alloc_frame();
185
    
186
    /* put sample parameters */
187
    c->bit_rate = 400000;
188
    /* resolution must be a multiple of two */
189
    c->width = 352;  
190
    c->height = 288;
191
    /* frames per second */
192
    c->frame_rate = 25 * FRAME_RATE_BASE;  
193
    c->gop_size = 10; /* emit one intra frame every ten frames */
194

    
195
    /* open it */
196
    if (avcodec_open(c, codec) < 0) {
197
        fprintf(stderr, "could not open codec\n");
198
        exit(1);
199
    }
200
    
201
    /* the codec gives us the frame size, in samples */
202

    
203
    f = fopen(filename, "w");
204
    if (!f) {
205
        fprintf(stderr, "could not open %s\n", filename);
206
        exit(1);
207
    }
208
    
209
    /* alloc image and output buffer */
210
    outbuf_size = 100000;
211
    outbuf = malloc(outbuf_size);
212
    size = c->width * c->height;
213
    picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
214
    
215
    picture->data[0] = picture_buf;
216
    picture->data[1] = picture->data[0] + size;
217
    picture->data[2] = picture->data[1] + size / 4;
218
    picture->linesize[0] = c->width;
219
    picture->linesize[1] = c->width / 2;
220
    picture->linesize[2] = c->width / 2;
221

    
222
    /* encode 1 second of video */
223
    for(i=0;i<25;i++) {
224
        printf("encoding frame %3d\r", i);
225
        fflush(stdout);
226
        /* prepare a dummy image */
227
        /* Y */
228
        for(y=0;y<c->height;y++) {
229
            for(x=0;x<c->width;x++) {
230
                picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
231
            }
232
        }
233

    
234
        /* Cb and Cr */
235
        for(y=0;y<c->height/2;y++) {
236
            for(x=0;x<c->width/2;x++) {
237
                picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
238
                picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
239
            }
240
        }
241

    
242
        /* encode the image */
243
        out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
244
        fwrite(outbuf, 1, out_size, f);
245
    }
246

    
247
    /* add sequence end code to have a real mpeg file */
248
    outbuf[0] = 0x00;
249
    outbuf[1] = 0x00;
250
    outbuf[2] = 0x01;
251
    outbuf[3] = 0xb7;
252
    fwrite(outbuf, 1, 4, f);
253
    fclose(f);
254
    free(picture_buf);
255
    free(outbuf);
256

    
257
    avcodec_close(c);
258
    free(c);
259
    free(picture);
260
    printf("\n");
261
}
262

    
263
/*
264
 * Video decoding example 
265
 */
266

    
267
void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename) 
268
{
269
    FILE *f;
270
    int i;
271

    
272
    f=fopen(filename,"w");
273
    fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
274
    for(i=0;i<ysize;i++)
275
        fwrite(buf + i * wrap,1,xsize,f);
276
    fclose(f);
277
}
278

    
279
void video_decode_example(const char *outfilename, const char *filename)
280
{
281
    AVCodec *codec;
282
    AVCodecContext *c= NULL;
283
    int frame, size, got_picture, len;
284
    FILE *f;
285
    AVFrame *picture;
286
    UINT8 inbuf[INBUF_SIZE], *inbuf_ptr;
287
    char buf[1024];
288

    
289
    printf("Video decoding\n");
290

    
291
    /* find the mpeg1 video decoder */
292
    codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
293
    if (!codec) {
294
        fprintf(stderr, "codec not found\n");
295
        exit(1);
296
    }
297

    
298
    c= avcodec_alloc_context();
299
    picture= avcodec_alloc_frame();
300

    
301
    if(codec->capabilities&CODEC_CAP_TRUNCATED)
302
        c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */
303

    
304
    /* for some codecs, such as msmpeg4 and mpeg4, width and height
305
       MUST be initialized there because these info are not available
306
       in the bitstream */
307

    
308
    /* open it */
309
    if (avcodec_open(c, codec) < 0) {
310
        fprintf(stderr, "could not open codec\n");
311
        exit(1);
312
    }
313
    
314
    /* the codec gives us the frame size, in samples */
315

    
316
    f = fopen(filename, "r");
317
    if (!f) {
318
        fprintf(stderr, "could not open %s\n", filename);
319
        exit(1);
320
    }
321
    
322
    frame = 0;
323
    for(;;) {
324
        size = fread(inbuf, 1, INBUF_SIZE, f);
325
        if (size == 0)
326
            break;
327

    
328
        /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
329
           and this is the only method to use them because you cannot
330
           know the compressed data size before analysing it. 
331

332
           BUT some other codecs (msmpeg4, mpeg4) are inherently frame
333
           based, so you must call them with all the data for one
334
           frame exactly. You must also initialize 'width' and
335
           'height' before initializing them. */
336

    
337
        /* NOTE2: some codecs allow the raw parameters (frame size,
338
           sample rate) to be changed at any frame. We handle this, so
339
           you should also take care of it */
340

    
341
        /* here, we use a stream based decoder (mpeg1video), so we
342
           feed decoder and see if it could decode a frame */
343
        inbuf_ptr = inbuf;
344
        while (size > 0) {
345
            len = avcodec_decode_video(c, picture, &got_picture, 
346
                                       inbuf_ptr, size);
347
            if (len < 0) {
348
                fprintf(stderr, "Error while decoding frame %d\n", frame);
349
                exit(1);
350
            }
351
            if (got_picture) {
352
                printf("saving frame %3d\r", frame);
353
                fflush(stdout);
354

    
355
                /* the picture is allocated by the decoder. no need to
356
                   free it */
357
                snprintf(buf, sizeof(buf), outfilename, frame);
358
                pgm_save(picture->data[0], picture->linesize[0], 
359
                         c->width, c->height, buf);
360
                frame++;
361
            }
362
            size -= len;
363
            inbuf_ptr += len;
364
        }
365
    }
366

    
367
    /* some codecs, such as MPEG, transmit the I and P frame with a
368
       latency of one frame. You must do the following to have a
369
       chance to get the last frame of the video */
370
    len = avcodec_decode_video(c, picture, &got_picture, 
371
                               NULL, 0);
372
    if (got_picture) {
373
        printf("saving frame %3d\r", frame);
374
        fflush(stdout);
375
        
376
        /* the picture is allocated by the decoder. no need to
377
           free it */
378
        snprintf(buf, sizeof(buf), outfilename, frame);
379
        pgm_save(picture->data[0], picture->linesize[0], 
380
                 c->width, c->height, buf);
381
        frame++;
382
    }
383
        
384
    fclose(f);
385

    
386
    avcodec_close(c);
387
    free(c);
388
    free(picture);
389
    printf("\n");
390
}
391

    
392
// simple example how the options could be used
393
int options_example(int argc, char* argv[])
394
{
395
    AVCodec* codec = avcodec_find_encoder_by_name((argc > 1) ? argv[2] : "mpeg4");
396
    const AVOption* c;
397
    AVCodecContext* avctx;
398
    char* def = av_malloc(5000);
399
    const char* col = "";
400
    int i = 0;
401

    
402
    if (!codec)
403
        return -1;
404
    c = codec->options;
405
    avctx = avcodec_alloc_context();
406
    *def = 0;
407

    
408
    if (c) {
409
        const AVOption *stack[FF_OPT_MAX_DEPTH];
410
        int depth = 0;
411
        for (;;) {
412
            if (!c->name) {
413
                if (c->sub) {
414
                    stack[depth++] = c;
415
                    c = c->sub;
416
                } else {
417
                    if (depth == 0)
418
                        break; // finished
419
                    c = stack[--depth];
420
                    c++;
421
                }
422
            } else {
423
                int t = c->type & FF_OPT_TYPE_MASK;
424
                printf("Config   %s  %s\n",
425
                       t == FF_OPT_TYPE_BOOL ? "bool   " :
426
                       t == FF_OPT_TYPE_DOUBLE ? "double  " :
427
                       t == FF_OPT_TYPE_INT ? "integer" :
428
                       t == FF_OPT_TYPE_STRING ? "string " :
429
                       "unknown??", c->name);
430
                switch (t) {
431
                case FF_OPT_TYPE_BOOL:
432
                    i += sprintf(def + i, "%s%s=%s",
433
                                 col, c->name,
434
                                 c->defval != 0. ? "on" : "off");
435
                    break;
436
                case FF_OPT_TYPE_DOUBLE:
437
                    i += sprintf(def + i, "%s%s=%f",
438
                                 col, c->name, c->defval);
439
                    break;
440
                case FF_OPT_TYPE_INT:
441
                    i += sprintf(def + i, "%s%s=%d",
442
                                 col, c->name, (int) c->defval);
443
                    break;
444
                case FF_OPT_TYPE_STRING:
445
                    if (c->defstr) {
446
                        char* d = av_strdup(c->defstr);
447
                        char* f = strchr(d, ',');
448
                        if (f)
449
                            *f = 0;
450
                        i += sprintf(def + i, "%s%s=%s",
451
                                     col, c->name, d);
452
                        av_free(d);
453
                    }
454
                    break;
455
                }
456
                col = ":";
457
                c++;
458
            }
459
        }
460
    }
461
    printf("Default Options: %s\n", def);
462
    av_free(def);
463
    return 0;
464
}
465

    
466

    
467
int main(int argc, char **argv)
468
{
469
    const char *filename;
470

    
471
    /* must be called before using avcodec lib */
472
    avcodec_init();
473

    
474
    /* register all the codecs (you can also register only the codec
475
       you wish to have smaller code */
476
    avcodec_register_all();
477

    
478
#ifdef OPT_TEST
479
    options_example(argc, argv);
480
#else
481
    if (argc <= 1) {
482
        audio_encode_example("/tmp/test.mp2");
483
        audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
484

    
485
        video_encode_example("/tmp/test.mpg");
486
        filename = "/tmp/test.mpg";
487
    } else {
488
        filename = argv[1];
489
    }
490

    
491
    //    audio_decode_example("/tmp/test.sw", filename);
492
    video_decode_example("/tmp/test%d.pgm", filename);
493
#endif
494

    
495
    return 0;
496
}