Statistics
| Branch: | Revision:

ffmpeg / libavcodec / api-example.c @ 2912e87a

History | View | Annotate | Download (12.5 KB)

1
/*
2
 * copyright (c) 2001 Fabrice Bellard
3
 *
4
 * This file is part of Libav.
5
 *
6
 * Libav 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
 * Libav 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 Libav; 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
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 "libavcodec/avcodec.h"
39
#include "libavutil/mathematics.h"
40

    
41
#define INBUF_SIZE 4096
42
#define AUDIO_INBUF_SIZE 20480
43
#define AUDIO_REFILL_THRESH 4096
44

    
45
/*
46
 * Audio encoding example
47
 */
48
static 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 * M_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
static void audio_decode_example(const char *outfilename, const char *filename)
117
{
118
    AVCodec *codec;
119
    AVCodecContext *c= NULL;
120
    int out_size, len;
121
    FILE *f, *outfile;
122
    uint8_t *outbuf;
123
    uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
124
    AVPacket avpkt;
125

    
126
    av_init_packet(&avpkt);
127

    
128
    printf("Audio decoding\n");
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
    avpkt.data = inbuf;
160
    avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
161

    
162
    while (avpkt.size > 0) {
163
        out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
164
        len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &avpkt);
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
        avpkt.size -= len;
174
        avpkt.data += len;
175
        if (avpkt.size < AUDIO_REFILL_THRESH) {
176
            /* Refill the input buffer, to avoid trying to decode
177
             * incomplete frames. Instead of this, one could also use
178
             * a parser, or use a proper container format through
179
             * libavformat. */
180
            memmove(inbuf, avpkt.data, avpkt.size);
181
            avpkt.data = inbuf;
182
            len = fread(avpkt.data + avpkt.size, 1,
183
                        AUDIO_INBUF_SIZE - avpkt.size, f);
184
            if (len > 0)
185
                avpkt.size += len;
186
        }
187
    }
188

    
189
    fclose(outfile);
190
    fclose(f);
191
    free(outbuf);
192

    
193
    avcodec_close(c);
194
    av_free(c);
195
}
196

    
197
/*
198
 * Video encoding example
199
 */
200
static void video_encode_example(const char *filename)
201
{
202
    AVCodec *codec;
203
    AVCodecContext *c= NULL;
204
    int i, out_size, size, x, y, outbuf_size;
205
    FILE *f;
206
    AVFrame *picture;
207
    uint8_t *outbuf, *picture_buf;
208

    
209
    printf("Video encoding\n");
210

    
211
    /* find the mpeg1 video encoder */
212
    codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
213
    if (!codec) {
214
        fprintf(stderr, "codec not found\n");
215
        exit(1);
216
    }
217

    
218
    c= avcodec_alloc_context();
219
    picture= avcodec_alloc_frame();
220

    
221
    /* put sample parameters */
222
    c->bit_rate = 400000;
223
    /* resolution must be a multiple of two */
224
    c->width = 352;
225
    c->height = 288;
226
    /* frames per second */
227
    c->time_base= (AVRational){1,25};
228
    c->gop_size = 10; /* emit one intra frame every ten frames */
229
    c->max_b_frames=1;
230
    c->pix_fmt = PIX_FMT_YUV420P;
231

    
232
    /* open it */
233
    if (avcodec_open(c, codec) < 0) {
234
        fprintf(stderr, "could not open codec\n");
235
        exit(1);
236
    }
237

    
238
    f = fopen(filename, "wb");
239
    if (!f) {
240
        fprintf(stderr, "could not open %s\n", filename);
241
        exit(1);
242
    }
243

    
244
    /* alloc image and output buffer */
245
    outbuf_size = 100000;
246
    outbuf = malloc(outbuf_size);
247
    size = c->width * c->height;
248
    picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
249

    
250
    picture->data[0] = picture_buf;
251
    picture->data[1] = picture->data[0] + size;
252
    picture->data[2] = picture->data[1] + size / 4;
253
    picture->linesize[0] = c->width;
254
    picture->linesize[1] = c->width / 2;
255
    picture->linesize[2] = c->width / 2;
256

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

    
268
        /* Cb and Cr */
269
        for(y=0;y<c->height/2;y++) {
270
            for(x=0;x<c->width/2;x++) {
271
                picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
272
                picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
273
            }
274
        }
275

    
276
        /* encode the image */
277
        out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
278
        printf("encoding frame %3d (size=%5d)\n", i, out_size);
279
        fwrite(outbuf, 1, out_size, f);
280
    }
281

    
282
    /* get the delayed frames */
283
    for(; out_size; i++) {
284
        fflush(stdout);
285

    
286
        out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
287
        printf("write frame %3d (size=%5d)\n", i, out_size);
288
        fwrite(outbuf, 1, out_size, f);
289
    }
290

    
291
    /* add sequence end code to have a real mpeg file */
292
    outbuf[0] = 0x00;
293
    outbuf[1] = 0x00;
294
    outbuf[2] = 0x01;
295
    outbuf[3] = 0xb7;
296
    fwrite(outbuf, 1, 4, f);
297
    fclose(f);
298
    free(picture_buf);
299
    free(outbuf);
300

    
301
    avcodec_close(c);
302
    av_free(c);
303
    av_free(picture);
304
    printf("\n");
305
}
306

    
307
/*
308
 * Video decoding example
309
 */
310

    
311
static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
312
                     char *filename)
313
{
314
    FILE *f;
315
    int i;
316

    
317
    f=fopen(filename,"w");
318
    fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
319
    for(i=0;i<ysize;i++)
320
        fwrite(buf + i * wrap,1,xsize,f);
321
    fclose(f);
322
}
323

    
324
static void video_decode_example(const char *outfilename, const char *filename)
325
{
326
    AVCodec *codec;
327
    AVCodecContext *c= NULL;
328
    int frame, got_picture, len;
329
    FILE *f;
330
    AVFrame *picture;
331
    uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
332
    char buf[1024];
333
    AVPacket avpkt;
334

    
335
    av_init_packet(&avpkt);
336

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

    
340
    printf("Video decoding\n");
341

    
342
    /* find the mpeg1 video decoder */
343
    codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
344
    if (!codec) {
345
        fprintf(stderr, "codec not found\n");
346
        exit(1);
347
    }
348

    
349
    c= avcodec_alloc_context();
350
    picture= avcodec_alloc_frame();
351

    
352
    if(codec->capabilities&CODEC_CAP_TRUNCATED)
353
        c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
354

    
355
    /* For some codecs, such as msmpeg4 and mpeg4, width and height
356
       MUST be initialized there because this information is not
357
       available in the bitstream. */
358

    
359
    /* open it */
360
    if (avcodec_open(c, codec) < 0) {
361
        fprintf(stderr, "could not open codec\n");
362
        exit(1);
363
    }
364

    
365
    /* the codec gives us the frame size, in samples */
366

    
367
    f = fopen(filename, "rb");
368
    if (!f) {
369
        fprintf(stderr, "could not open %s\n", filename);
370
        exit(1);
371
    }
372

    
373
    frame = 0;
374
    for(;;) {
375
        avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
376
        if (avpkt.size == 0)
377
            break;
378

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

383
           BUT some other codecs (msmpeg4, mpeg4) are inherently frame
384
           based, so you must call them with all the data for one
385
           frame exactly. You must also initialize 'width' and
386
           'height' before initializing them. */
387

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

    
392
        /* here, we use a stream based decoder (mpeg1video), so we
393
           feed decoder and see if it could decode a frame */
394
        avpkt.data = inbuf;
395
        while (avpkt.size > 0) {
396
            len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
397
            if (len < 0) {
398
                fprintf(stderr, "Error while decoding frame %d\n", frame);
399
                exit(1);
400
            }
401
            if (got_picture) {
402
                printf("saving frame %3d\n", frame);
403
                fflush(stdout);
404

    
405
                /* the picture is allocated by the decoder. no need to
406
                   free it */
407
                snprintf(buf, sizeof(buf), outfilename, frame);
408
                pgm_save(picture->data[0], picture->linesize[0],
409
                         c->width, c->height, buf);
410
                frame++;
411
            }
412
            avpkt.size -= len;
413
            avpkt.data += len;
414
        }
415
    }
416

    
417
    /* some codecs, such as MPEG, transmit the I and P frame with a
418
       latency of one frame. You must do the following to have a
419
       chance to get the last frame of the video */
420
    avpkt.data = NULL;
421
    avpkt.size = 0;
422
    len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
423
    if (got_picture) {
424
        printf("saving last frame %3d\n", frame);
425
        fflush(stdout);
426

    
427
        /* the picture is allocated by the decoder. no need to
428
           free it */
429
        snprintf(buf, sizeof(buf), outfilename, frame);
430
        pgm_save(picture->data[0], picture->linesize[0],
431
                 c->width, c->height, buf);
432
        frame++;
433
    }
434

    
435
    fclose(f);
436

    
437
    avcodec_close(c);
438
    av_free(c);
439
    av_free(picture);
440
    printf("\n");
441
}
442

    
443
int main(int argc, char **argv)
444
{
445
    const char *filename;
446

    
447
    /* must be called before using avcodec lib */
448
    avcodec_init();
449

    
450
    /* register all the codecs */
451
    avcodec_register_all();
452

    
453
    if (argc <= 1) {
454
        audio_encode_example("/tmp/test.mp2");
455
        audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
456

    
457
        video_encode_example("/tmp/test.mpg");
458
        filename = "/tmp/test.mpg";
459
    } else {
460
        filename = argv[1];
461
    }
462

    
463
    //    audio_decode_example("/tmp/test.sw", filename);
464
    video_decode_example("/tmp/test%d.pgm", filename);
465

    
466
    return 0;
467
}