api-example.c
Go to the documentation of this file.
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 
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 
35 #ifdef HAVE_AV_CONFIG_H
36 #undef HAVE_AV_CONFIG_H
37 #endif
38 
39 #include "libavcodec/avcodec.h"
40 #include "libavutil/mathematics.h"
41 #include "libavutil/samplefmt.h"
42 
43 #define INBUF_SIZE 4096
44 #define AUDIO_INBUF_SIZE 20480
45 #define AUDIO_REFILL_THRESH 4096
46 
47 /*
48  * Audio encoding example
49  */
50 static void audio_encode_example(const char *filename)
51 {
52  AVCodec *codec;
53  AVCodecContext *c= NULL;
54  int frame_size, i, j, out_size, outbuf_size;
55  FILE *f;
56  short *samples;
57  float t, tincr;
58  uint8_t *outbuf;
59 
60  printf("Audio encoding\n");
61 
62  /* find the MP2 encoder */
64  if (!codec) {
65  fprintf(stderr, "codec not found\n");
66  exit(1);
67  }
68 
69  c = avcodec_alloc_context3(codec);
70 
71  /* put sample parameters */
72  c->bit_rate = 64000;
73  c->sample_rate = 44100;
74  c->channels = 2;
75 
76  /* open it */
77  if (avcodec_open(c, codec) < 0) {
78  fprintf(stderr, "could not open codec\n");
79  exit(1);
80  }
81 
82  /* the codec gives us the frame size, in samples */
83  frame_size = c->frame_size;
84  samples = malloc(frame_size * 2 * c->channels);
85  outbuf_size = 10000;
86  outbuf = malloc(outbuf_size);
87 
88  f = fopen(filename, "wb");
89  if (!f) {
90  fprintf(stderr, "could not open %s\n", filename);
91  exit(1);
92  }
93 
94  /* encode a single tone sound */
95  t = 0;
96  tincr = 2 * M_PI * 440.0 / c->sample_rate;
97  for(i=0;i<200;i++) {
98  for(j=0;j<frame_size;j++) {
99  samples[2*j] = (int)(sin(t) * 10000);
100  samples[2*j+1] = samples[2*j];
101  t += tincr;
102  }
103  /* encode the samples */
104  out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
105  fwrite(outbuf, 1, out_size, f);
106  }
107  fclose(f);
108  free(outbuf);
109  free(samples);
110 
111  avcodec_close(c);
112  av_free(c);
113 }
114 
115 /*
116  * Audio decoding.
117  */
118 static void audio_decode_example(const char *outfilename, const char *filename)
119 {
120  AVCodec *codec;
121  AVCodecContext *c= NULL;
122  int len;
123  FILE *f, *outfile;
125  AVPacket avpkt;
126  AVFrame *decoded_frame = NULL;
127 
128  av_init_packet(&avpkt);
129 
130  printf("Audio decoding\n");
131 
132  /* find the mpeg audio decoder */
134  if (!codec) {
135  fprintf(stderr, "codec not found\n");
136  exit(1);
137  }
138 
139  c = avcodec_alloc_context3(codec);
140 
141  /* open it */
142  if (avcodec_open(c, codec) < 0) {
143  fprintf(stderr, "could not open codec\n");
144  exit(1);
145  }
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  int got_frame = 0;
164 
165  if (!decoded_frame) {
166  if (!(decoded_frame = avcodec_alloc_frame())) {
167  fprintf(stderr, "out of memory\n");
168  exit(1);
169  }
170  } else
171  avcodec_get_frame_defaults(decoded_frame);
172 
173  len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
174  if (len < 0) {
175  fprintf(stderr, "Error while decoding\n");
176  exit(1);
177  }
178  if (got_frame) {
179  /* if a frame has been decoded, output it */
180  int data_size = av_samples_get_buffer_size(NULL, c->channels,
181  decoded_frame->nb_samples,
182  c->sample_fmt, 1);
183  fwrite(decoded_frame->data[0], 1, data_size, outfile);
184  }
185  avpkt.size -= len;
186  avpkt.data += len;
187  if (avpkt.size < AUDIO_REFILL_THRESH) {
188  /* Refill the input buffer, to avoid trying to decode
189  * incomplete frames. Instead of this, one could also use
190  * a parser, or use a proper container format through
191  * libavformat. */
192  memmove(inbuf, avpkt.data, avpkt.size);
193  avpkt.data = inbuf;
194  len = fread(avpkt.data + avpkt.size, 1,
195  AUDIO_INBUF_SIZE - avpkt.size, f);
196  if (len > 0)
197  avpkt.size += len;
198  }
199  }
200 
201  fclose(outfile);
202  fclose(f);
203 
204  avcodec_close(c);
205  av_free(c);
206  av_free(decoded_frame);
207 }
208 
209 /*
210  * Video encoding example
211  */
212 static void video_encode_example(const char *filename)
213 {
214  AVCodec *codec;
215  AVCodecContext *c= NULL;
216  int i, out_size, size, x, y, outbuf_size;
217  FILE *f;
218  AVFrame *picture;
219  uint8_t *outbuf, *picture_buf;
220 
221  printf("Video encoding\n");
222 
223  /* find the mpeg1 video encoder */
225  if (!codec) {
226  fprintf(stderr, "codec not found\n");
227  exit(1);
228  }
229 
230  c = avcodec_alloc_context3(codec);
231  picture= avcodec_alloc_frame();
232 
233  /* put sample parameters */
234  c->bit_rate = 400000;
235  /* resolution must be a multiple of two */
236  c->width = 352;
237  c->height = 288;
238  /* frames per second */
239  c->time_base= (AVRational){1,25};
240  c->gop_size = 10; /* emit one intra frame every ten frames */
241  c->max_b_frames=1;
243 
244  /* open it */
245  if (avcodec_open(c, codec) < 0) {
246  fprintf(stderr, "could not open codec\n");
247  exit(1);
248  }
249 
250  f = fopen(filename, "wb");
251  if (!f) {
252  fprintf(stderr, "could not open %s\n", filename);
253  exit(1);
254  }
255 
256  /* alloc image and output buffer */
257  outbuf_size = 100000;
258  outbuf = malloc(outbuf_size);
259  size = c->width * c->height;
260  picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
261 
262  picture->data[0] = picture_buf;
263  picture->data[1] = picture->data[0] + size;
264  picture->data[2] = picture->data[1] + size / 4;
265  picture->linesize[0] = c->width;
266  picture->linesize[1] = c->width / 2;
267  picture->linesize[2] = c->width / 2;
268 
269  /* encode 1 second of video */
270  for(i=0;i<25;i++) {
271  fflush(stdout);
272  /* prepare a dummy image */
273  /* Y */
274  for(y=0;y<c->height;y++) {
275  for(x=0;x<c->width;x++) {
276  picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
277  }
278  }
279 
280  /* Cb and Cr */
281  for(y=0;y<c->height/2;y++) {
282  for(x=0;x<c->width/2;x++) {
283  picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
284  picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
285  }
286  }
287 
288  /* encode the image */
289  out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
290  printf("encoding frame %3d (size=%5d)\n", i, out_size);
291  fwrite(outbuf, 1, out_size, f);
292  }
293 
294  /* get the delayed frames */
295  for(; out_size; i++) {
296  fflush(stdout);
297 
298  out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
299  printf("write frame %3d (size=%5d)\n", i, out_size);
300  fwrite(outbuf, 1, out_size, f);
301  }
302 
303  /* add sequence end code to have a real mpeg file */
304  outbuf[0] = 0x00;
305  outbuf[1] = 0x00;
306  outbuf[2] = 0x01;
307  outbuf[3] = 0xb7;
308  fwrite(outbuf, 1, 4, f);
309  fclose(f);
310  free(picture_buf);
311  free(outbuf);
312 
313  avcodec_close(c);
314  av_free(c);
315  av_free(picture);
316  printf("\n");
317 }
318 
319 /*
320  * Video decoding example
321  */
322 
323 static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
324  char *filename)
325 {
326  FILE *f;
327  int i;
328 
329  f=fopen(filename,"w");
330  fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
331  for(i=0;i<ysize;i++)
332  fwrite(buf + i * wrap,1,xsize,f);
333  fclose(f);
334 }
335 
336 static void video_decode_example(const char *outfilename, const char *filename)
337 {
338  AVCodec *codec;
339  AVCodecContext *c= NULL;
340  int frame, got_picture, len;
341  FILE *f;
342  AVFrame *picture;
343  uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
344  char buf[1024];
345  AVPacket avpkt;
346 
347  av_init_packet(&avpkt);
348 
349  /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
350  memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
351 
352  printf("Video decoding\n");
353 
354  /* find the mpeg1 video decoder */
356  if (!codec) {
357  fprintf(stderr, "codec not found\n");
358  exit(1);
359  }
360 
361  c = avcodec_alloc_context3(codec);
362  picture= avcodec_alloc_frame();
363 
365  c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
366 
367  /* For some codecs, such as msmpeg4 and mpeg4, width and height
368  MUST be initialized there because this information is not
369  available in the bitstream. */
370 
371  /* open it */
372  if (avcodec_open(c, codec) < 0) {
373  fprintf(stderr, "could not open codec\n");
374  exit(1);
375  }
376 
377  /* the codec gives us the frame size, in samples */
378 
379  f = fopen(filename, "rb");
380  if (!f) {
381  fprintf(stderr, "could not open %s\n", filename);
382  exit(1);
383  }
384 
385  frame = 0;
386  for(;;) {
387  avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
388  if (avpkt.size == 0)
389  break;
390 
391  /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
392  and this is the only method to use them because you cannot
393  know the compressed data size before analysing it.
394 
395  BUT some other codecs (msmpeg4, mpeg4) are inherently frame
396  based, so you must call them with all the data for one
397  frame exactly. You must also initialize 'width' and
398  'height' before initializing them. */
399 
400  /* NOTE2: some codecs allow the raw parameters (frame size,
401  sample rate) to be changed at any frame. We handle this, so
402  you should also take care of it */
403 
404  /* here, we use a stream based decoder (mpeg1video), so we
405  feed decoder and see if it could decode a frame */
406  avpkt.data = inbuf;
407  while (avpkt.size > 0) {
408  len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
409  if (len < 0) {
410  fprintf(stderr, "Error while decoding frame %d\n", frame);
411  exit(1);
412  }
413  if (got_picture) {
414  printf("saving frame %3d\n", frame);
415  fflush(stdout);
416 
417  /* the picture is allocated by the decoder. no need to
418  free it */
419  snprintf(buf, sizeof(buf), outfilename, frame);
420  pgm_save(picture->data[0], picture->linesize[0],
421  c->width, c->height, buf);
422  frame++;
423  }
424  avpkt.size -= len;
425  avpkt.data += len;
426  }
427  }
428 
429  /* some codecs, such as MPEG, transmit the I and P frame with a
430  latency of one frame. You must do the following to have a
431  chance to get the last frame of the video */
432  avpkt.data = NULL;
433  avpkt.size = 0;
434  len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
435  if (got_picture) {
436  printf("saving last frame %3d\n", frame);
437  fflush(stdout);
438 
439  /* the picture is allocated by the decoder. no need to
440  free it */
441  snprintf(buf, sizeof(buf), outfilename, frame);
442  pgm_save(picture->data[0], picture->linesize[0],
443  c->width, c->height, buf);
444  frame++;
445  }
446 
447  fclose(f);
448 
449  avcodec_close(c);
450  av_free(c);
451  av_free(picture);
452  printf("\n");
453 }
454 
455 int main(int argc, char **argv)
456 {
457  const char *filename;
458 
459  /* must be called before using avcodec lib */
460  avcodec_init();
461 
462  /* register all the codecs */
464 
465  if (argc <= 1) {
466  audio_encode_example("/tmp/test.mp2");
467  audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
468 
469  video_encode_example("/tmp/test.mpg");
470  filename = "/tmp/test.mpg";
471  } else {
472  filename = argv[1];
473  }
474 
475  // audio_decode_example("/tmp/test.sw", filename);
476  video_decode_example("/tmp/test%d.pgm", filename);
477 
478  return 0;
479 }