Statistics
| Branch: | Revision:

ffmpeg / libavcodec / api-example.c @ 7c17abaf

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 libavcodec/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

    
34
#ifdef HAVE_AV_CONFIG_H
35
#undef HAVE_AV_CONFIG_H
36
#endif
37

    
38
#include "avcodec.h"
39
#include "libavutil/mathematics.h"
40

    
41
#define INBUF_SIZE 4096
42

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

    
56
    printf("Audio encoding\n");
57

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

    
65
    c= avcodec_alloc_context();
66

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

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

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

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

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

    
107
    avcodec_close(c);
108
    av_free(c);
109
}
110

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

    
123
    printf("Audio decoding\n");
124

    
125
    /* find the mpeg audio decoder */
126
    codec = avcodec_find_decoder(CODEC_ID_MP2);
127
    if (!codec) {
128
        fprintf(stderr, "codec not found\n");
129
        exit(1);
130
    }
131

    
132
    c= avcodec_alloc_context();
133

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

    
140
    outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
141

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
420
    fclose(f);
421

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

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

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

    
435
    /* register all the codecs */
436
    avcodec_register_all();
437

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

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

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

    
451
    return 0;
452
}