Statistics
| Branch: | Revision:

ffmpeg / libavcodec / apiexample.c @ 58f26ba9

History | View | Annotate | Download (10.6 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
#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 mpeg4, 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, mpeg4) are inherently frame
324
           based, so you must call them with all the data for one
325
           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
}