Statistics
| Branch: | Revision:

ffmpeg / libavcodec / apiexample.c @ f78ebb51

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 *c= NULL;
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
    c= avcodec_alloc_context();
39
    
40
    /* 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
    free(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 *c= NULL;
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
    c= avcodec_alloc_context();
106

    
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
        free(c);
123
        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
    free(c);
156
}
157

    
158
/*
159
 * Video encoding example 
160
 */
161
void video_encode_example(const char *filename)
162
{
163
    AVCodec *codec;
164
    AVCodecContext *c= NULL;
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
    c= avcodec_alloc_context();
180
    
181
    /* 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
    free(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 *c= NULL;
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
    c= avcodec_alloc_context();
293

    
294
    if(codec->capabilities&CODEC_CAP_TRUNCATED)
295
        c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */
296

    
297
    /* for some codecs, such as msmpeg4 and mpeg4, width and height
298
       MUST be initialized there because these info are not available
299
       in the bitstream */
300

    
301
    /* open it */
302
    if (avcodec_open(c, codec) < 0) {
303
        fprintf(stderr, "could not open codec\n");
304
        exit(1);
305
    }
306
    
307
    /* the codec gives us the frame size, in samples */
308

    
309
    f = fopen(filename, "r");
310
    if (!f) {
311
        fprintf(stderr, "could not open %s\n", filename);
312
        exit(1);
313
    }
314
    
315
    frame = 0;
316
    for(;;) {
317
        size = fread(inbuf, 1, INBUF_SIZE, f);
318
        if (size == 0)
319
            break;
320

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

325
           BUT some other codecs (msmpeg4, mpeg4) are inherently frame
326
           based, so you must call them with all the data for one
327
           frame exactly. You must also initialize 'width' and
328
           'height' before initializing them. */
329

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

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

    
348
                /* the picture is allocated by the decoder. no need to
349
                   free it */
350
                snprintf(buf, sizeof(buf), outfilename, frame);
351
                pgm_save(picture.data[0], picture.linesize[0], 
352
                         c->width, c->height, buf);
353
                frame++;
354
            }
355
            size -= len;
356
            inbuf_ptr += len;
357
        }
358
    }
359

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

    
379
    avcodec_close(c);
380
    free(c);
381
    printf("\n");
382
}
383

    
384

    
385
int main(int argc, char **argv)
386
{
387
    const char *filename;
388

    
389
    /* must be called before using avcodec lib */
390
    avcodec_init();
391

    
392
    /* register all the codecs (you can also register only the codec
393
       you wish to have smaller code */
394
    avcodec_register_all();
395
    
396
    if (argc <= 1) {
397
        audio_encode_example("/tmp/test.mp2");
398
        audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
399

    
400
        video_encode_example("/tmp/test.mpg");
401
        filename = "/tmp/test.mpg";
402
    } else {
403
        filename = argv[1];
404
    }
405

    
406
    //    audio_decode_example("/tmp/test.sw", filename);
407
    video_decode_example("/tmp/test%d.pgm", filename);
408

    
409
    return 0;
410
}