]> git.sesse.net Git - ffmpeg/blob - libavcodec/apiexample.c
Fix lossless jpeg encoder to comply to spec and store full redundant
[ffmpeg] / libavcodec / apiexample.c
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 */
437     avcodec_register_all();
438
439     if (argc <= 1) {
440         audio_encode_example("/tmp/test.mp2");
441         audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
442
443         video_encode_example("/tmp/test.mpg");
444         filename = "/tmp/test.mpg";
445     } else {
446         filename = argv[1];
447     }
448
449     //    audio_decode_example("/tmp/test.sw", filename);
450     video_decode_example("/tmp/test%d.pgm", filename);
451
452     return 0;
453 }