Statistics
| Branch: | Revision:

ffmpeg / libavcodec / apiexample.c @ 983e3246

History | View | Annotate | Download (12.5 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], *inbuf_ptr;
102

    
103
    printf("Audio decoding\n");
104

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

    
112
    c= avcodec_alloc_context();
113

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

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

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

    
157
    fclose(outfile);
158
    fclose(f);
159
    free(outbuf);
160

    
161
    avcodec_close(c);
162
    free(c);
163
}
164

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

    
177
    printf("Video encoding\n");
178

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

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

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

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

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

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

    
245
        /* encode the image */
246
        out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
247
        fwrite(outbuf, 1, out_size, f);
248
    }
249

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

    
260
    avcodec_close(c);
261
    free(c);
262
    free(picture);
263
    printf("\n");
264
}
265

    
266
/*
267
 * Video decoding example 
268
 */
269

    
270
void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename) 
271
{
272
    FILE *f;
273
    int i;
274

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

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

    
292
    printf("Video decoding\n");
293

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

    
301
    c= avcodec_alloc_context();
302
    picture= avcodec_alloc_frame();
303

    
304
    if(codec->capabilities&CODEC_CAP_TRUNCATED)
305
        c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */
306

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

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

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

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

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

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

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

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

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

    
389
    avcodec_close(c);
390
    free(c);
391
    free(picture);
392
    printf("\n");
393
}
394

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

    
405
    if (!codec)
406
        return -1;
407
    c = codec->options;
408
    avctx = avcodec_alloc_context();
409
    *def = 0;
410

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

    
469

    
470
int main(int argc, char **argv)
471
{
472
    const char *filename;
473

    
474
    /* must be called before using avcodec lib */
475
    avcodec_init();
476

    
477
    /* register all the codecs (you can also register only the codec
478
       you wish to have smaller code */
479
    avcodec_register_all();
480

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

    
488
        video_encode_example("/tmp/test.mpg");
489
        filename = "/tmp/test.mpg";
490
    } else {
491
        filename = argv[1];
492
    }
493

    
494
    //    audio_decode_example("/tmp/test.sw", filename);
495
    video_decode_example("/tmp/test%d.pgm", filename);
496
#endif
497

    
498
    return 0;
499
}