Statistics
| Branch: | Revision:

ffmpeg / libavcodec / apiexample.c @ f6618b0f

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
    f = fopen(filename, "wb");
232
    if (!f) {
233
        fprintf(stderr, "could not open %s\n", filename);
234
        exit(1);
235
    }
236

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

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

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

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

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

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

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

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

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

    
300
/*
301
 * Video decoding example
302
 */
303

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

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

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

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

    
329
    printf("Video decoding\n");
330

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

    
338
    c= avcodec_alloc_context();
339
    picture= avcodec_alloc_frame();
340

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

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

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

    
354
    /* the codec gives us the frame size, in samples */
355

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

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

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

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

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

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

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

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

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

    
424
    fclose(f);
425

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

    
432
int main(int argc, char **argv)
433
{
434
    const char *filename;
435

    
436
    /* must be called before using avcodec lib */
437
    avcodec_init();
438

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

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

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

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

    
456
    return 0;
457
}