Statistics
| Branch: | Revision:

ffmpeg / libavcodec / apiexample.c @ d771bcae

History | View | Annotate | Download (10.6 KB)

1 de6d9b64 Fabrice Bellard
/* 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
#include "avcodec.h"
13
14
#define INBUF_SIZE 4096
15
16
/*
17
 * Audio encoding example 
18
 */
19
void audio_encode_example(const char *filename)
20
{
21
    AVCodec *codec;
22
    AVCodecContext codec_context, *c = &codec_context;
23
    int frame_size, i, j, out_size, outbuf_size;
24
    FILE *f;
25
    short *samples;
26
    float t, tincr;
27
    UINT8 *outbuf;
28
29
    printf("Audio encoding\n");
30
31
    /* find the MP2 encoder */
32
    codec = avcodec_find_encoder(CODEC_ID_MP2);
33
    if (!codec) {
34
        fprintf(stderr, "codec not found\n");
35
        exit(1);
36
    }
37
38
    /* put default values */
39
    memset(c, 0, sizeof(*c));
40
41
    /* put sample parameters */
42
    c->bit_rate = 64000;
43
    c->sample_rate = 44100;
44
    c->channels = 2;
45
46
    /* open it */
47
    if (avcodec_open(c, codec) < 0) {
48
        fprintf(stderr, "could not open codec\n");
49
        exit(1);
50
    }
51
    
52
    /* the codec gives us the frame size, in samples */
53
    frame_size = c->frame_size;
54
    samples = malloc(frame_size * 2 * c->channels);
55
    outbuf_size = 10000;
56
    outbuf = malloc(outbuf_size);
57
58
    f = fopen(filename, "w");
59
    if (!f) {
60
        fprintf(stderr, "could not open %s\n", filename);
61
        exit(1);
62
    }
63
        
64
    /* encode a single tone sound */
65
    t = 0;
66
    tincr = 2 * M_PI * 440.0 / c->sample_rate;
67
    for(i=0;i<200;i++) {
68
        for(j=0;j<frame_size;j++) {
69
            samples[2*j] = (int)(sin(t) * 10000);
70
            samples[2*j+1] = samples[2*j];
71
            t += tincr;
72
        }
73
        /* encode the samples */
74
        out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
75
        fwrite(outbuf, 1, out_size, f);
76
    }
77
    fclose(f);
78
    free(outbuf);
79
    free(samples);
80
81
    avcodec_close(c);
82
}
83
84
/*
85
 * Audio decoding. 
86
 */
87
void audio_decode_example(const char *outfilename, const char *filename)
88
{
89
    AVCodec *codec;
90
    AVCodecContext codec_context, *c = &codec_context;
91
    int out_size, size, len;
92
    FILE *f, *outfile;
93
    UINT8 *outbuf;
94
    UINT8 inbuf[INBUF_SIZE], *inbuf_ptr;
95
96
    printf("Audio decoding\n");
97
98
    /* find the mpeg audio decoder */
99
    codec = avcodec_find_decoder(CODEC_ID_MP2);
100
    if (!codec) {
101
        fprintf(stderr, "codec not found\n");
102
        exit(1);
103
    }
104
105
    /* put default values */
106
    memset(c, 0, sizeof(*c));
107
108
    /* open it */
109
    if (avcodec_open(c, codec) < 0) {
110
        fprintf(stderr, "could not open codec\n");
111
        exit(1);
112
    }
113
    
114
    outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
115
116
    f = fopen(filename, "r");
117
    if (!f) {
118
        fprintf(stderr, "could not open %s\n", filename);
119
        exit(1);
120
    }
121
    outfile = fopen(outfilename, "w");
122
    if (!outfile) {
123
        fprintf(stderr, "could not open %s\n", outfilename);
124
        exit(1);
125
    }
126
        
127
    /* decode until eof */
128
    inbuf_ptr = inbuf;
129
    for(;;) {
130
        size = fread(inbuf, 1, INBUF_SIZE, f);
131
        if (size == 0)
132
            break;
133
134
        inbuf_ptr = inbuf;
135
        while (size > 0) {
136
            len = avcodec_decode_audio(c, (short *)outbuf, &out_size, 
137
                                       inbuf_ptr, size);
138
            if (len < 0) {
139
                fprintf(stderr, "Error while decoding\n");
140
                exit(1);
141
            }
142
            if (out_size > 0) {
143
                /* if a frame has been decoded, output it */
144
                fwrite(outbuf, 1, out_size, outfile);
145
            }
146
            size -= len;
147
            inbuf_ptr += len;
148
        }
149
    }
150
151
    fclose(outfile);
152
    fclose(f);
153
    free(outbuf);
154
155
    avcodec_close(c);
156
}
157
158
/*
159
 * Video encoding example 
160
 */
161
void video_encode_example(const char *filename)
162
{
163
    AVCodec *codec;
164
    AVCodecContext codec_context, *c = &codec_context;
165
    int i, out_size, size, x, y, outbuf_size;
166
    FILE *f;
167
    AVPicture picture;
168
    UINT8 *outbuf, *picture_buf;
169
170
    printf("Video encoding\n");
171
172
    /* find the mpeg1 video encoder */
173
    codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
174
    if (!codec) {
175
        fprintf(stderr, "codec not found\n");
176
        exit(1);
177
    }
178
179
    /* put default values */
180
    memset(c, 0, sizeof(*c));
181
182
    /* put sample parameters */
183
    c->bit_rate = 400000;
184
    /* resolution must be a multiple of two */
185
    c->width = 352;  
186
    c->height = 288;
187
    /* frames per second */
188
    c->frame_rate = 25 * FRAME_RATE_BASE;  
189
    c->gop_size = 10; /* emit one intra frame every ten frames */
190
191
    /* open it */
192
    if (avcodec_open(c, codec) < 0) {
193
        fprintf(stderr, "could not open codec\n");
194
        exit(1);
195
    }
196
    
197
    /* the codec gives us the frame size, in samples */
198
199
    f = fopen(filename, "w");
200
    if (!f) {
201
        fprintf(stderr, "could not open %s\n", filename);
202
        exit(1);
203
    }
204
    
205
    /* alloc image and output buffer */
206
    outbuf_size = 100000;
207
    outbuf = malloc(outbuf_size);
208
    size = c->width * c->height;
209
    picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
210
    
211
    picture.data[0] = picture_buf;
212
    picture.data[1] = picture.data[0] + size;
213
    picture.data[2] = picture.data[1] + size / 4;
214
    picture.linesize[0] = c->width;
215
    picture.linesize[1] = c->width / 2;
216
    picture.linesize[2] = c->width / 2;
217
218
    /* encode 1 second of video */
219
    for(i=0;i<25;i++) {
220
        printf("encoding frame %3d\r", i);
221
        fflush(stdout);
222
        /* prepare a dummy image */
223
        /* Y */
224
        for(y=0;y<c->height;y++) {
225
            for(x=0;x<c->width;x++) {
226
                picture.data[0][y * picture.linesize[0] + x] = x + y + i * 3;
227
            }
228
        }
229
230
        /* Cb and Cr */
231
        for(y=0;y<c->height/2;y++) {
232
            for(x=0;x<c->width/2;x++) {
233
                picture.data[1][y * picture.linesize[1] + x] = 128 + y + i * 2;
234
                picture.data[2][y * picture.linesize[2] + x] = 64 + x + i * 5;
235
            }
236
        }
237
238
        /* encode the image */
239
        out_size = avcodec_encode_video(c, outbuf, outbuf_size, &picture);
240
        fwrite(outbuf, 1, out_size, f);
241
    }
242
243
    /* add sequence end code to have a real mpeg file */
244
    outbuf[0] = 0x00;
245
    outbuf[1] = 0x00;
246
    outbuf[2] = 0x01;
247
    outbuf[3] = 0xb7;
248
    fwrite(outbuf, 1, 4, f);
249
    fclose(f);
250
    free(picture_buf);
251
    free(outbuf);
252
253
    avcodec_close(c);
254
    printf("\n");
255
}
256
257
/*
258
 * Video decoding example 
259
 */
260
261
void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename) 
262
{
263
    FILE *f;
264
    int i;
265
266
    f=fopen(filename,"w");
267
    fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
268
    for(i=0;i<ysize;i++)
269
        fwrite(buf + i * wrap,1,xsize,f);
270
    fclose(f);
271
}
272
273
void video_decode_example(const char *outfilename, const char *filename)
274
{
275
    AVCodec *codec;
276
    AVCodecContext codec_context, *c = &codec_context;
277
    int frame, size, got_picture, len;
278
    FILE *f;
279
    AVPicture picture;
280
    UINT8 inbuf[INBUF_SIZE], *inbuf_ptr;
281
    char buf[1024];
282
283
    printf("Video decoding\n");
284
285
    /* find the mpeg1 video decoder */
286
    codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
287
    if (!codec) {
288
        fprintf(stderr, "codec not found\n");
289
        exit(1);
290
    }
291
292
    /* put default values */
293
    memset(c, 0, sizeof(*c));
294
295
    /* for some codecs, such as msmpeg4 and opendivx, width and height
296
       MUST be initialized there because these info are not available
297
       in the bitstream */
298
299
    /* open it */
300
    if (avcodec_open(c, codec) < 0) {
301
        fprintf(stderr, "could not open codec\n");
302
        exit(1);
303
    }
304
    
305
    /* the codec gives us the frame size, in samples */
306
307
    f = fopen(filename, "r");
308
    if (!f) {
309
        fprintf(stderr, "could not open %s\n", filename);
310
        exit(1);
311
    }
312
    
313
    frame = 0;
314
    for(;;) {
315
        size = fread(inbuf, 1, INBUF_SIZE, f);
316
        if (size == 0)
317
            break;
318
319
        /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
320
           and this is the only method to use them because you cannot
321
           know the compressed data size before analysing it. 
322

323
           BUT some other codecs (msmpeg4, opendivx) are inherently
324
           frame based, so you must call them with all the data for
325
           one frame exactly. You must also initialize 'width' and
326
           'height' before initializing them. */
327
328
        /* NOTE2: some codecs allow the raw parameters (frame size,
329
           sample rate) to be changed at any frame. We handle this, so
330
           you should also take care of it */
331
332
        /* here, we use a stream based decoder (mpeg1video), so we
333
           feed decoder and see if it could decode a frame */
334
        inbuf_ptr = inbuf;
335
        while (size > 0) {
336
            len = avcodec_decode_video(c, &picture, &got_picture, 
337
                                       inbuf_ptr, size);
338
            if (len < 0) {
339
                fprintf(stderr, "Error while decoding frame %d\n", frame);
340
                exit(1);
341
            }
342
            if (got_picture) {
343
                printf("saving frame %3d\r", frame);
344
                fflush(stdout);
345
346
                /* the picture is allocated by the decoder. no need to
347
                   free it */
348
                snprintf(buf, sizeof(buf), outfilename, frame);
349
                pgm_save(picture.data[0], picture.linesize[0], 
350
                         c->width, c->height, buf);
351
                frame++;
352
            }
353
            size -= len;
354
            inbuf_ptr += len;
355
        }
356
    }
357
358
    /* some codecs, such as MPEG, transmit the I and P frame with a
359
       latency of one frame. You must do the following to have a
360
       chance to get the last frame of the video */
361
    len = avcodec_decode_video(c, &picture, &got_picture, 
362
                               NULL, 0);
363
    if (got_picture) {
364
        printf("saving frame %3d\r", frame);
365
        fflush(stdout);
366
        
367
        /* the picture is allocated by the decoder. no need to
368
           free it */
369
        snprintf(buf, sizeof(buf), outfilename, frame);
370
        pgm_save(picture.data[0], picture.linesize[0], 
371
                 c->width, c->height, buf);
372
        frame++;
373
    }
374
        
375
    fclose(f);
376
377
    avcodec_close(c);
378
    printf("\n");
379
}
380
381
382
int main(int argc, char **argv)
383
{
384
    const char *filename;
385
386
    /* must be called before using avcodec lib */
387
    avcodec_init();
388
389
    /* register all the codecs (you can also register only the codec
390
       you wish to have smaller code */
391
    avcodec_register_all();
392
    
393
    if (argc <= 1) {
394
        audio_encode_example("/tmp/test.mp2");
395
        audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
396
397
        video_encode_example("/tmp/test.mpg");
398
        filename = "/tmp/test.mpg";
399
    } else {
400
        filename = argv[1];
401
    }
402
403
    //    audio_decode_example("/tmp/test.sw", filename);
404
    video_decode_example("/tmp/test%d.pgm", filename);
405
406
    return 0;
407
}