Statistics
| Branch: | Revision:

ffmpeg / libavcodec / apiexample.c @ 9b2bb403

History | View | Annotate | Download (12.2 KB)

1
/*
2
 * copyright (c) 2001 Fabrice Bellard
3
 *
4
 * This file is part of FFmpeg.
5
 *
6
 * FFmpeg is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * FFmpeg is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with FFmpeg; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20

    
21
/**
22
 * @file apiexample.c
23
 * avcodec API use example.
24
 *
25
 * Note that this library only handles codecs (mpeg, mpeg4, etc...),
26
 * not file formats (avi, vob, etc...). See library 'libavformat' for the
27
 * format handling
28
 */
29

    
30
#include <stdlib.h>
31
#include <stdio.h>
32
#include <string.h>
33
#include <math.h>
34

    
35
#define PI 3.14159265358979323846
36

    
37
#ifdef HAVE_AV_CONFIG_H
38
#undef HAVE_AV_CONFIG_H
39
#endif
40

    
41
#include "avcodec.h"
42

    
43
#define INBUF_SIZE 4096
44

    
45
/*
46
 * Audio encoding example
47
 */
48
void audio_encode_example(const char *filename)
49
{
50
    AVCodec *codec;
51
    AVCodecContext *c= NULL;
52
    int frame_size, i, j, out_size, outbuf_size;
53
    FILE *f;
54
    short *samples;
55
    float t, tincr;
56
    uint8_t *outbuf;
57

    
58
    printf("Audio encoding\n");
59

    
60
    /* find the MP2 encoder */
61
    codec = avcodec_find_encoder(CODEC_ID_MP2);
62
    if (!codec) {
63
        fprintf(stderr, "codec not found\n");
64
        exit(1);
65
    }
66

    
67
    c= avcodec_alloc_context();
68

    
69
    /* put sample parameters */
70
    c->bit_rate = 64000;
71
    c->sample_rate = 44100;
72
    c->channels = 2;
73

    
74
    /* open it */
75
    if (avcodec_open(c, codec) < 0) {
76
        fprintf(stderr, "could not open codec\n");
77
        exit(1);
78
    }
79

    
80
    /* the codec gives us the frame size, in samples */
81
    frame_size = c->frame_size;
82
    samples = malloc(frame_size * 2 * c->channels);
83
    outbuf_size = 10000;
84
    outbuf = malloc(outbuf_size);
85

    
86
    f = fopen(filename, "wb");
87
    if (!f) {
88
        fprintf(stderr, "could not open %s\n", filename);
89
        exit(1);
90
    }
91

    
92
    /* encode a single tone sound */
93
    t = 0;
94
    tincr = 2 * PI * 440.0 / c->sample_rate;
95
    for(i=0;i<200;i++) {
96
        for(j=0;j<frame_size;j++) {
97
            samples[2*j] = (int)(sin(t) * 10000);
98
            samples[2*j+1] = samples[2*j];
99
            t += tincr;
100
        }
101
        /* encode the samples */
102
        out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
103
        fwrite(outbuf, 1, out_size, f);
104
    }
105
    fclose(f);
106
    free(outbuf);
107
    free(samples);
108

    
109
    avcodec_close(c);
110
    av_free(c);
111
}
112

    
113
/*
114
 * Audio decoding.
115
 */
116
void audio_decode_example(const char *outfilename, const char *filename)
117
{
118
    AVCodec *codec;
119
    AVCodecContext *c= NULL;
120
    int out_size, size, len;
121
    FILE *f, *outfile;
122
    uint8_t *outbuf;
123
    uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
124

    
125
    printf("Audio decoding\n");
126

    
127
    /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
128
    memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
129

    
130
    /* find the mpeg audio decoder */
131
    codec = avcodec_find_decoder(CODEC_ID_MP2);
132
    if (!codec) {
133
        fprintf(stderr, "codec not found\n");
134
        exit(1);
135
    }
136

    
137
    c= avcodec_alloc_context();
138

    
139
    /* open it */
140
    if (avcodec_open(c, codec) < 0) {
141
        fprintf(stderr, "could not open codec\n");
142
        exit(1);
143
    }
144

    
145
    outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
146

    
147
    f = fopen(filename, "rb");
148
    if (!f) {
149
        fprintf(stderr, "could not open %s\n", filename);
150
        exit(1);
151
    }
152
    outfile = fopen(outfilename, "wb");
153
    if (!outfile) {
154
        av_free(c);
155
        exit(1);
156
    }
157

    
158
    /* decode until eof */
159
    inbuf_ptr = inbuf;
160
    for(;;) {
161
        size = fread(inbuf, 1, INBUF_SIZE, f);
162
        if (size == 0)
163
            break;
164

    
165
        inbuf_ptr = inbuf;
166
        while (size > 0) {
167
            len = avcodec_decode_audio(c, (short *)outbuf, &out_size,
168
                                       inbuf_ptr, size);
169
            if (len < 0) {
170
                fprintf(stderr, "Error while decoding\n");
171
                exit(1);
172
            }
173
            if (out_size > 0) {
174
                /* if a frame has been decoded, output it */
175
                fwrite(outbuf, 1, out_size, outfile);
176
            }
177
            size -= len;
178
            inbuf_ptr += len;
179
        }
180
    }
181

    
182
    fclose(outfile);
183
    fclose(f);
184
    free(outbuf);
185

    
186
    avcodec_close(c);
187
    av_free(c);
188
}
189

    
190
/*
191
 * Video encoding example
192
 */
193
void video_encode_example(const char *filename)
194
{
195
    AVCodec *codec;
196
    AVCodecContext *c= NULL;
197
    int i, out_size, size, x, y, outbuf_size;
198
    FILE *f;
199
    AVFrame *picture;
200
    uint8_t *outbuf, *picture_buf;
201

    
202
    printf("Video encoding\n");
203

    
204
    /* find the mpeg1 video encoder */
205
    codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
206
    if (!codec) {
207
        fprintf(stderr, "codec not found\n");
208
        exit(1);
209
    }
210

    
211
    c= avcodec_alloc_context();
212
    picture= avcodec_alloc_frame();
213

    
214
    /* put sample parameters */
215
    c->bit_rate = 400000;
216
    /* resolution must be a multiple of two */
217
    c->width = 352;
218
    c->height = 288;
219
    /* frames per second */
220
    c->time_base= (AVRational){1,25};
221
    c->gop_size = 10; /* emit one intra frame every ten frames */
222
    c->max_b_frames=1;
223
    c->pix_fmt = PIX_FMT_YUV420P;
224

    
225
    /* open it */
226
    if (avcodec_open(c, codec) < 0) {
227
        fprintf(stderr, "could not open codec\n");
228
        exit(1);
229
    }
230

    
231
    /* the codec gives us the frame size, in samples */
232

    
233
    f = fopen(filename, "wb");
234
    if (!f) {
235
        fprintf(stderr, "could not open %s\n", filename);
236
        exit(1);
237
    }
238

    
239
    /* alloc image and output buffer */
240
    outbuf_size = 100000;
241
    outbuf = malloc(outbuf_size);
242
    size = c->width * c->height;
243
    picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
244

    
245
    picture->data[0] = picture_buf;
246
    picture->data[1] = picture->data[0] + size;
247
    picture->data[2] = picture->data[1] + size / 4;
248
    picture->linesize[0] = c->width;
249
    picture->linesize[1] = c->width / 2;
250
    picture->linesize[2] = c->width / 2;
251

    
252
    /* encode 1 second of video */
253
    for(i=0;i<25;i++) {
254
        fflush(stdout);
255
        /* prepare a dummy image */
256
        /* Y */
257
        for(y=0;y<c->height;y++) {
258
            for(x=0;x<c->width;x++) {
259
                picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
260
            }
261
        }
262

    
263
        /* Cb and Cr */
264
        for(y=0;y<c->height/2;y++) {
265
            for(x=0;x<c->width/2;x++) {
266
                picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
267
                picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
268
            }
269
        }
270

    
271
        /* encode the image */
272
        out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
273
        printf("encoding frame %3d (size=%5d)\n", i, out_size);
274
        fwrite(outbuf, 1, out_size, f);
275
    }
276

    
277
    /* get the delayed frames */
278
    for(; out_size; i++) {
279
        fflush(stdout);
280

    
281
        out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
282
        printf("write frame %3d (size=%5d)\n", i, out_size);
283
        fwrite(outbuf, 1, out_size, f);
284
    }
285

    
286
    /* add sequence end code to have a real mpeg file */
287
    outbuf[0] = 0x00;
288
    outbuf[1] = 0x00;
289
    outbuf[2] = 0x01;
290
    outbuf[3] = 0xb7;
291
    fwrite(outbuf, 1, 4, f);
292
    fclose(f);
293
    free(picture_buf);
294
    free(outbuf);
295

    
296
    avcodec_close(c);
297
    av_free(c);
298
    av_free(picture);
299
    printf("\n");
300
}
301

    
302
/*
303
 * Video decoding example
304
 */
305

    
306
void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename)
307
{
308
    FILE *f;
309
    int i;
310

    
311
    f=fopen(filename,"w");
312
    fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
313
    for(i=0;i<ysize;i++)
314
        fwrite(buf + i * wrap,1,xsize,f);
315
    fclose(f);
316
}
317

    
318
void video_decode_example(const char *outfilename, const char *filename)
319
{
320
    AVCodec *codec;
321
    AVCodecContext *c= NULL;
322
    int frame, size, got_picture, len;
323
    FILE *f;
324
    AVFrame *picture;
325
    uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
326
    char buf[1024];
327

    
328
    /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
329
    memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
330

    
331
    printf("Video decoding\n");
332

    
333
    /* find the mpeg1 video decoder */
334
    codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
335
    if (!codec) {
336
        fprintf(stderr, "codec not found\n");
337
        exit(1);
338
    }
339

    
340
    c= avcodec_alloc_context();
341
    picture= avcodec_alloc_frame();
342

    
343
    if(codec->capabilities&CODEC_CAP_TRUNCATED)
344
        c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */
345

    
346
    /* for some codecs, such as msmpeg4 and mpeg4, width and height
347
       MUST be initialized there because these info are not available
348
       in the bitstream */
349

    
350
    /* open it */
351
    if (avcodec_open(c, codec) < 0) {
352
        fprintf(stderr, "could not open codec\n");
353
        exit(1);
354
    }
355

    
356
    /* the codec gives us the frame size, in samples */
357

    
358
    f = fopen(filename, "rb");
359
    if (!f) {
360
        fprintf(stderr, "could not open %s\n", filename);
361
        exit(1);
362
    }
363

    
364
    frame = 0;
365
    for(;;) {
366
        size = fread(inbuf, 1, INBUF_SIZE, f);
367
        if (size == 0)
368
            break;
369

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

374
           BUT some other codecs (msmpeg4, mpeg4) are inherently frame
375
           based, so you must call them with all the data for one
376
           frame exactly. You must also initialize 'width' and
377
           'height' before initializing them. */
378

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

    
383
        /* here, we use a stream based decoder (mpeg1video), so we
384
           feed decoder and see if it could decode a frame */
385
        inbuf_ptr = inbuf;
386
        while (size > 0) {
387
            len = avcodec_decode_video(c, picture, &got_picture,
388
                                       inbuf_ptr, size);
389
            if (len < 0) {
390
                fprintf(stderr, "Error while decoding frame %d\n", frame);
391
                exit(1);
392
            }
393
            if (got_picture) {
394
                printf("saving frame %3d\n", frame);
395
                fflush(stdout);
396

    
397
                /* the picture is allocated by the decoder. no need to
398
                   free it */
399
                snprintf(buf, sizeof(buf), outfilename, frame);
400
                pgm_save(picture->data[0], picture->linesize[0],
401
                         c->width, c->height, buf);
402
                frame++;
403
            }
404
            size -= len;
405
            inbuf_ptr += len;
406
        }
407
    }
408

    
409
    /* some codecs, such as MPEG, transmit the I and P frame with a
410
       latency of one frame. You must do the following to have a
411
       chance to get the last frame of the video */
412
    len = avcodec_decode_video(c, picture, &got_picture,
413
                               NULL, 0);
414
    if (got_picture) {
415
        printf("saving last frame %3d\n", frame);
416
        fflush(stdout);
417

    
418
        /* the picture is allocated by the decoder. no need to
419
           free it */
420
        snprintf(buf, sizeof(buf), outfilename, frame);
421
        pgm_save(picture->data[0], picture->linesize[0],
422
                 c->width, c->height, buf);
423
        frame++;
424
    }
425

    
426
    fclose(f);
427

    
428
    avcodec_close(c);
429
    av_free(c);
430
    av_free(picture);
431
    printf("\n");
432
}
433

    
434
int main(int argc, char **argv)
435
{
436
    const char *filename;
437

    
438
    /* must be called before using avcodec lib */
439
    avcodec_init();
440

    
441
    /* register all the codecs (you can also register only the codec
442
       you wish to have smaller code */
443
    avcodec_register_all();
444

    
445
    if (argc <= 1) {
446
        audio_encode_example("/tmp/test.mp2");
447
        audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
448

    
449
        video_encode_example("/tmp/test.mpg");
450
        filename = "/tmp/test.mpg";
451
    } else {
452
        filename = argv[1];
453
    }
454

    
455
    //    audio_decode_example("/tmp/test.sw", filename);
456
    video_decode_example("/tmp/test%d.pgm", filename);
457

    
458
    return 0;
459
}