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 */
46void 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 */
114void 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            len = avcodec_decode_audio(c, (short *)outbuf, &out_size,
163                                       inbuf_ptr, size);
164            if (len < 0) {
165                fprintf(stderr, "Error while decoding\n");
166                exit(1);
167            }
168            if (out_size > 0) {
169                /* if a frame has been decoded, output it */
170                fwrite(outbuf, 1, out_size, outfile);
171            }
172            size -= len;
173            inbuf_ptr += len;
174        }
175    }
176
177    fclose(outfile);
178    fclose(f);
179    free(outbuf);
180
181    avcodec_close(c);
182    av_free(c);
183}
184
185/*
186 * Video encoding example
187 */
188void video_encode_example(const char *filename)
189{
190    AVCodec *codec;
191    AVCodecContext *c= NULL;
192    int i, out_size, size, x, y, outbuf_size;
193    FILE *f;
194    AVFrame *picture;
195    uint8_t *outbuf, *picture_buf;
196
197    printf("Video encoding\n");
198
199    /* find the mpeg1 video encoder */
200    codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
201    if (!codec) {
202        fprintf(stderr, "codec not found\n");
203        exit(1);
204    }
205
206    c= avcodec_alloc_context();
207    picture= avcodec_alloc_frame();
208
209    /* put sample parameters */
210    c->bit_rate = 400000;
211    /* resolution must be a multiple of two */
212    c->width = 352;
213    c->height = 288;
214    /* frames per second */
215    c->time_base= (AVRational){1,25};
216    c->gop_size = 10; /* emit one intra frame every ten frames */
217    c->max_b_frames=1;
218    c->pix_fmt = PIX_FMT_YUV420P;
219
220    /* open it */
221    if (avcodec_open(c, codec) < 0) {
222        fprintf(stderr, "could not open codec\n");
223        exit(1);
224    }
225
226    f = fopen(filename, "wb");
227    if (!f) {
228        fprintf(stderr, "could not open %s\n", filename);
229        exit(1);
230    }
231
232    /* alloc image and output buffer */
233    outbuf_size = 100000;
234    outbuf = malloc(outbuf_size);
235    size = c->width * c->height;
236    picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
237
238    picture->data[0] = picture_buf;
239    picture->data[1] = picture->data[0] + size;
240    picture->data[2] = picture->data[1] + size / 4;
241    picture->linesize[0] = c->width;
242    picture->linesize[1] = c->width / 2;
243    picture->linesize[2] = c->width / 2;
244
245    /* encode 1 second of video */
246    for(i=0;i<25;i++) {
247        fflush(stdout);
248        /* prepare a dummy image */
249        /* Y */
250        for(y=0;y<c->height;y++) {
251            for(x=0;x<c->width;x++) {
252                picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
253            }
254        }
255
256        /* Cb and Cr */
257        for(y=0;y<c->height/2;y++) {
258            for(x=0;x<c->width/2;x++) {
259                picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
260                picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
261            }
262        }
263
264        /* encode the image */
265        out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
266        printf("encoding frame %3d (size=%5d)\n", i, out_size);
267        fwrite(outbuf, 1, out_size, f);
268    }
269
270    /* get the delayed frames */
271    for(; out_size; i++) {
272        fflush(stdout);
273
274        out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
275        printf("write frame %3d (size=%5d)\n", i, out_size);
276        fwrite(outbuf, 1, out_size, f);
277    }
278
279    /* add sequence end code to have a real mpeg file */
280    outbuf[0] = 0x00;
281    outbuf[1] = 0x00;
282    outbuf[2] = 0x01;
283    outbuf[3] = 0xb7;
284    fwrite(outbuf, 1, 4, f);
285    fclose(f);
286    free(picture_buf);
287    free(outbuf);
288
289    avcodec_close(c);
290    av_free(c);
291    av_free(picture);
292    printf("\n");
293}
294
295/*
296 * Video decoding example
297 */
298
299void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename)
300{
301    FILE *f;
302    int i;
303
304    f=fopen(filename,"w");
305    fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
306    for(i=0;i<ysize;i++)
307        fwrite(buf + i * wrap,1,xsize,f);
308    fclose(f);
309}
310
311void video_decode_example(const char *outfilename, const char *filename)
312{
313    AVCodec *codec;
314    AVCodecContext *c= NULL;
315    int frame, size, got_picture, len;
316    FILE *f;
317    AVFrame *picture;
318    uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
319    char buf[1024];
320
321    /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
322    memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
323
324    printf("Video decoding\n");
325
326    /* find the mpeg1 video decoder */
327    codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
328    if (!codec) {
329        fprintf(stderr, "codec not found\n");
330        exit(1);
331    }
332
333    c= avcodec_alloc_context();
334    picture= avcodec_alloc_frame();
335
336    if(codec->capabilities&CODEC_CAP_TRUNCATED)
337        c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
338
339    /* For some codecs, such as msmpeg4 and mpeg4, width and height
340       MUST be initialized there because this information is not
341       available in the bitstream. */
342
343    /* open it */
344    if (avcodec_open(c, codec) < 0) {
345        fprintf(stderr, "could not open codec\n");
346        exit(1);
347    }
348
349    /* the codec gives us the frame size, in samples */
350
351    f = fopen(filename, "rb");
352    if (!f) {
353        fprintf(stderr, "could not open %s\n", filename);
354        exit(1);
355    }
356
357    frame = 0;
358    for(;;) {
359        size = fread(inbuf, 1, INBUF_SIZE, f);
360        if (size == 0)
361            break;
362
363        /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
364           and this is the only method to use them because you cannot
365           know the compressed data size before analysing it.
366
367           BUT some other codecs (msmpeg4, mpeg4) are inherently frame
368           based, so you must call them with all the data for one
369           frame exactly. You must also initialize 'width' and
370           'height' before initializing them. */
371
372        /* NOTE2: some codecs allow the raw parameters (frame size,
373           sample rate) to be changed at any frame. We handle this, so
374           you should also take care of it */
375
376        /* here, we use a stream based decoder (mpeg1video), so we
377           feed decoder and see if it could decode a frame */
378        inbuf_ptr = inbuf;
379        while (size > 0) {
380            len = avcodec_decode_video(c, picture, &got_picture,
381                                       inbuf_ptr, size);
382            if (len < 0) {
383                fprintf(stderr, "Error while decoding frame %d\n", frame);
384                exit(1);
385            }
386            if (got_picture) {
387                printf("saving frame %3d\n", frame);
388                fflush(stdout);
389
390                /* the picture is allocated by the decoder. no need to
391                   free it */
392                snprintf(buf, sizeof(buf), outfilename, frame);
393                pgm_save(picture->data[0], picture->linesize[0],
394                         c->width, c->height, buf);
395                frame++;
396            }
397            size -= len;
398            inbuf_ptr += len;
399        }
400    }
401
402    /* some codecs, such as MPEG, transmit the I and P frame with a
403       latency of one frame. You must do the following to have a
404       chance to get the last frame of the video */
405    len = avcodec_decode_video(c, picture, &got_picture,
406                               NULL, 0);
407    if (got_picture) {
408        printf("saving last frame %3d\n", frame);
409        fflush(stdout);
410
411        /* the picture is allocated by the decoder. no need to
412           free it */
413        snprintf(buf, sizeof(buf), outfilename, frame);
414        pgm_save(picture->data[0], picture->linesize[0],
415                 c->width, c->height, buf);
416        frame++;
417    }
418
419    fclose(f);
420
421    avcodec_close(c);
422    av_free(c);
423    av_free(picture);
424    printf("\n");
425}
426
427int main(int argc, char **argv)
428{
429    const char *filename;
430
431    /* must be called before using avcodec lib */
432    avcodec_init();
433
434    /* register all the codecs */
435    avcodec_register_all();
436
437    if (argc <= 1) {
438        audio_encode_example("/tmp/test.mp2");
439        audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
440
441        video_encode_example("/tmp/test.mpg");
442        filename = "/tmp/test.mpg";
443    } else {
444        filename = argv[1];
445    }
446
447    //    audio_decode_example("/tmp/test.sw", filename);
448    video_decode_example("/tmp/test%d.pgm", filename);
449
450    return 0;
451}
452