Statistics
| Branch: | Revision:

ffmpeg / libavcodec / apiexample.c @ 755bfeab

History | View | Annotate | Download (12 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
    /* find the mpeg audio decoder */
128
    codec = avcodec_find_decoder(CODEC_ID_MP2);
129
    if (!codec) {
130
        fprintf(stderr, "codec not found\n");
131
        exit(1);
132
    }
133

    
134
    c= avcodec_alloc_context();
135

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

    
142
    outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
143

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

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

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

    
179
    fclose(outfile);
180
    fclose(f);
181
    free(outbuf);
182

    
183
    avcodec_close(c);
184
    av_free(c);
185
}
186

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

    
199
    printf("Video encoding\n");
200

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

    
208
    c= avcodec_alloc_context();
209
    picture= avcodec_alloc_frame();
210

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

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

    
228
    f = fopen(filename, "wb");
229
    if (!f) {
230
        fprintf(stderr, "could not open %s\n", filename);
231
        exit(1);
232
    }
233

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

    
240
    picture->data[0] = picture_buf;
241
    picture->data[1] = picture->data[0] + size;
242
    picture->data[2] = picture->data[1] + size / 4;
243
    picture->linesize[0] = c->width;
244
    picture->linesize[1] = c->width / 2;
245
    picture->linesize[2] = c->width / 2;
246

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

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

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

    
272
    /* get the delayed frames */
273
    for(; out_size; i++) {
274
        fflush(stdout);
275

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

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

    
291
    avcodec_close(c);
292
    av_free(c);
293
    av_free(picture);
294
    printf("\n");
295
}
296

    
297
/*
298
 * Video decoding example
299
 */
300

    
301
void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename)
302
{
303
    FILE *f;
304
    int i;
305

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

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

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

    
326
    printf("Video decoding\n");
327

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

    
335
    c= avcodec_alloc_context();
336
    picture= avcodec_alloc_frame();
337

    
338
    if(codec->capabilities&CODEC_CAP_TRUNCATED)
339
        c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
340

    
341
    /* For some codecs, such as msmpeg4 and mpeg4, width and height
342
       MUST be initialized there because this information is not
343
       available in the bitstream. */
344

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

    
351
    /* the codec gives us the frame size, in samples */
352

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

    
359
    frame = 0;
360
    for(;;) {
361
        size = fread(inbuf, 1, INBUF_SIZE, f);
362
        if (size == 0)
363
            break;
364

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

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

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

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

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

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

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

    
421
    fclose(f);
422

    
423
    avcodec_close(c);
424
    av_free(c);
425
    av_free(picture);
426
    printf("\n");
427
}
428

    
429
int main(int argc, char **argv)
430
{
431
    const char *filename;
432

    
433
    /* must be called before using avcodec lib */
434
    avcodec_init();
435

    
436
    /* register all the codecs (you can also register only the codec
437
       you wish to have smaller code */
438
    avcodec_register_all();
439

    
440
    if (argc <= 1) {
441
        audio_encode_example("/tmp/test.mp2");
442
        audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
443

    
444
        video_encode_example("/tmp/test.mpg");
445
        filename = "/tmp/test.mpg";
446
    } else {
447
        filename = argv[1];
448
    }
449

    
450
    //    audio_decode_example("/tmp/test.sw", filename);
451
    video_decode_example("/tmp/test%d.pgm", filename);
452

    
453
    return 0;
454
}