Statistics
| Branch: | Revision:

ffmpeg / libavcodec / apiexample.c @ af27aea9

History | View | Annotate | Download (10.4 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 e8b62df6 Michael Niedermayer
    AVCodecContext *c= NULL;
23 de6d9b64 Fabrice Bellard
    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 e8b62df6 Michael Niedermayer
    c= avcodec_alloc_context();
39
    
40 de6d9b64 Fabrice Bellard
    /* put sample parameters */
41
    c->bit_rate = 64000;
42
    c->sample_rate = 44100;
43
    c->channels = 2;
44
45
    /* open it */
46
    if (avcodec_open(c, codec) < 0) {
47
        fprintf(stderr, "could not open codec\n");
48
        exit(1);
49
    }
50
    
51
    /* the codec gives us the frame size, in samples */
52
    frame_size = c->frame_size;
53
    samples = malloc(frame_size * 2 * c->channels);
54
    outbuf_size = 10000;
55
    outbuf = malloc(outbuf_size);
56
57
    f = fopen(filename, "w");
58
    if (!f) {
59
        fprintf(stderr, "could not open %s\n", filename);
60
        exit(1);
61
    }
62
        
63
    /* encode a single tone sound */
64
    t = 0;
65
    tincr = 2 * M_PI * 440.0 / c->sample_rate;
66
    for(i=0;i<200;i++) {
67
        for(j=0;j<frame_size;j++) {
68
            samples[2*j] = (int)(sin(t) * 10000);
69
            samples[2*j+1] = samples[2*j];
70
            t += tincr;
71
        }
72
        /* encode the samples */
73
        out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
74
        fwrite(outbuf, 1, out_size, f);
75
    }
76
    fclose(f);
77
    free(outbuf);
78
    free(samples);
79
80
    avcodec_close(c);
81 e8b62df6 Michael Niedermayer
    free(c);
82 de6d9b64 Fabrice Bellard
}
83
84
/*
85
 * Audio decoding. 
86
 */
87
void audio_decode_example(const char *outfilename, const char *filename)
88
{
89
    AVCodec *codec;
90 e8b62df6 Michael Niedermayer
    AVCodecContext *c= NULL;
91 de6d9b64 Fabrice Bellard
    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 e8b62df6 Michael Niedermayer
    c= avcodec_alloc_context();
106 de6d9b64 Fabrice Bellard
107
    /* open it */
108
    if (avcodec_open(c, codec) < 0) {
109
        fprintf(stderr, "could not open codec\n");
110
        exit(1);
111
    }
112
    
113
    outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
114
115
    f = fopen(filename, "r");
116
    if (!f) {
117
        fprintf(stderr, "could not open %s\n", filename);
118
        exit(1);
119
    }
120
    outfile = fopen(outfilename, "w");
121
    if (!outfile) {
122 e8b62df6 Michael Niedermayer
        free(c);
123 de6d9b64 Fabrice Bellard
        exit(1);
124
    }
125
        
126
    /* decode until eof */
127
    inbuf_ptr = inbuf;
128
    for(;;) {
129
        size = fread(inbuf, 1, INBUF_SIZE, f);
130
        if (size == 0)
131
            break;
132
133
        inbuf_ptr = inbuf;
134
        while (size > 0) {
135
            len = avcodec_decode_audio(c, (short *)outbuf, &out_size, 
136
                                       inbuf_ptr, size);
137
            if (len < 0) {
138
                fprintf(stderr, "Error while decoding\n");
139
                exit(1);
140
            }
141
            if (out_size > 0) {
142
                /* if a frame has been decoded, output it */
143
                fwrite(outbuf, 1, out_size, outfile);
144
            }
145
            size -= len;
146
            inbuf_ptr += len;
147
        }
148
    }
149
150
    fclose(outfile);
151
    fclose(f);
152
    free(outbuf);
153
154
    avcodec_close(c);
155 e8b62df6 Michael Niedermayer
    free(c);
156 de6d9b64 Fabrice Bellard
}
157
158
/*
159
 * Video encoding example 
160
 */
161
void video_encode_example(const char *filename)
162
{
163
    AVCodec *codec;
164 e8b62df6 Michael Niedermayer
    AVCodecContext *c= NULL;
165 de6d9b64 Fabrice Bellard
    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 e8b62df6 Michael Niedermayer
    c= avcodec_alloc_context();
180
    
181 de6d9b64 Fabrice Bellard
    /* put sample parameters */
182
    c->bit_rate = 400000;
183
    /* resolution must be a multiple of two */
184
    c->width = 352;  
185
    c->height = 288;
186
    /* frames per second */
187
    c->frame_rate = 25 * FRAME_RATE_BASE;  
188
    c->gop_size = 10; /* emit one intra frame every ten frames */
189
190
    /* open it */
191
    if (avcodec_open(c, codec) < 0) {
192
        fprintf(stderr, "could not open codec\n");
193
        exit(1);
194
    }
195
    
196
    /* the codec gives us the frame size, in samples */
197
198
    f = fopen(filename, "w");
199
    if (!f) {
200
        fprintf(stderr, "could not open %s\n", filename);
201
        exit(1);
202
    }
203
    
204
    /* alloc image and output buffer */
205
    outbuf_size = 100000;
206
    outbuf = malloc(outbuf_size);
207
    size = c->width * c->height;
208
    picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
209
    
210
    picture.data[0] = picture_buf;
211
    picture.data[1] = picture.data[0] + size;
212
    picture.data[2] = picture.data[1] + size / 4;
213
    picture.linesize[0] = c->width;
214
    picture.linesize[1] = c->width / 2;
215
    picture.linesize[2] = c->width / 2;
216
217
    /* encode 1 second of video */
218
    for(i=0;i<25;i++) {
219
        printf("encoding frame %3d\r", i);
220
        fflush(stdout);
221
        /* prepare a dummy image */
222
        /* Y */
223
        for(y=0;y<c->height;y++) {
224
            for(x=0;x<c->width;x++) {
225
                picture.data[0][y * picture.linesize[0] + x] = x + y + i * 3;
226
            }
227
        }
228
229
        /* Cb and Cr */
230
        for(y=0;y<c->height/2;y++) {
231
            for(x=0;x<c->width/2;x++) {
232
                picture.data[1][y * picture.linesize[1] + x] = 128 + y + i * 2;
233
                picture.data[2][y * picture.linesize[2] + x] = 64 + x + i * 5;
234
            }
235
        }
236
237
        /* encode the image */
238
        out_size = avcodec_encode_video(c, outbuf, outbuf_size, &picture);
239
        fwrite(outbuf, 1, out_size, f);
240
    }
241
242
    /* add sequence end code to have a real mpeg file */
243
    outbuf[0] = 0x00;
244
    outbuf[1] = 0x00;
245
    outbuf[2] = 0x01;
246
    outbuf[3] = 0xb7;
247
    fwrite(outbuf, 1, 4, f);
248
    fclose(f);
249
    free(picture_buf);
250
    free(outbuf);
251
252
    avcodec_close(c);
253 e8b62df6 Michael Niedermayer
    free(c);
254 de6d9b64 Fabrice Bellard
    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 e8b62df6 Michael Niedermayer
    AVCodecContext *c= NULL;
277 de6d9b64 Fabrice Bellard
    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 e8b62df6 Michael Niedermayer
    c= avcodec_alloc_context();
293 de6d9b64 Fabrice Bellard
294 58f26ba9 Fabrice Bellard
    /* for some codecs, such as msmpeg4 and mpeg4, width and height
295 de6d9b64 Fabrice Bellard
       MUST be initialized there because these info are not available
296
       in the bitstream */
297
298
    /* open it */
299
    if (avcodec_open(c, codec) < 0) {
300
        fprintf(stderr, "could not open codec\n");
301
        exit(1);
302
    }
303
    
304
    /* the codec gives us the frame size, in samples */
305
306
    f = fopen(filename, "r");
307
    if (!f) {
308
        fprintf(stderr, "could not open %s\n", filename);
309
        exit(1);
310
    }
311
    
312
    frame = 0;
313
    for(;;) {
314
        size = fread(inbuf, 1, INBUF_SIZE, f);
315
        if (size == 0)
316
            break;
317
318
        /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
319
           and this is the only method to use them because you cannot
320
           know the compressed data size before analysing it. 
321

322 58f26ba9 Fabrice Bellard
           BUT some other codecs (msmpeg4, mpeg4) are inherently frame
323
           based, so you must call them with all the data for one
324
           frame exactly. You must also initialize 'width' and
325 de6d9b64 Fabrice Bellard
           'height' before initializing them. */
326
327
        /* NOTE2: some codecs allow the raw parameters (frame size,
328
           sample rate) to be changed at any frame. We handle this, so
329
           you should also take care of it */
330
331
        /* here, we use a stream based decoder (mpeg1video), so we
332
           feed decoder and see if it could decode a frame */
333
        inbuf_ptr = inbuf;
334
        while (size > 0) {
335
            len = avcodec_decode_video(c, &picture, &got_picture, 
336
                                       inbuf_ptr, size);
337
            if (len < 0) {
338
                fprintf(stderr, "Error while decoding frame %d\n", frame);
339
                exit(1);
340
            }
341
            if (got_picture) {
342
                printf("saving frame %3d\r", frame);
343
                fflush(stdout);
344
345
                /* the picture is allocated by the decoder. no need to
346
                   free it */
347
                snprintf(buf, sizeof(buf), outfilename, frame);
348
                pgm_save(picture.data[0], picture.linesize[0], 
349
                         c->width, c->height, buf);
350
                frame++;
351
            }
352
            size -= len;
353
            inbuf_ptr += len;
354
        }
355
    }
356
357
    /* some codecs, such as MPEG, transmit the I and P frame with a
358
       latency of one frame. You must do the following to have a
359
       chance to get the last frame of the video */
360
    len = avcodec_decode_video(c, &picture, &got_picture, 
361
                               NULL, 0);
362
    if (got_picture) {
363
        printf("saving frame %3d\r", frame);
364
        fflush(stdout);
365
        
366
        /* the picture is allocated by the decoder. no need to
367
           free it */
368
        snprintf(buf, sizeof(buf), outfilename, frame);
369
        pgm_save(picture.data[0], picture.linesize[0], 
370
                 c->width, c->height, buf);
371
        frame++;
372
    }
373
        
374
    fclose(f);
375
376
    avcodec_close(c);
377 e8b62df6 Michael Niedermayer
    free(c);
378 de6d9b64 Fabrice Bellard
    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
}