examples/avcodec: split audio decoding into a separate example
[libav.git] / doc / examples / avcodec.c
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 * libavcodec API use example.
24 *
25 * @example avcodec.c
26 * Note that this library only handles codecs (MPEG, MPEG-4, etc...),
27 * not file formats (AVI, VOB, etc...). See library 'libavformat' for the
28 * format handling.
29 */
30
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/channel_layout.h"
41 #include "libavutil/common.h"
42 #include "libavutil/imgutils.h"
43 #include "libavutil/mathematics.h"
44 #include "libavutil/samplefmt.h"
45
46 #define INBUF_SIZE 4096
47
48 /*
49 * Video encoding example
50 */
51 static void video_encode_example(const char *filename)
52 {
53 AVCodec *codec;
54 AVCodecContext *c= NULL;
55 int i, ret, x, y, got_output;
56 FILE *f;
57 AVFrame *picture;
58 AVPacket pkt;
59 uint8_t endcode[] = { 0, 0, 1, 0xb7 };
60
61 printf("Video encoding\n");
62
63 /* find the mpeg1video encoder */
64 codec = avcodec_find_encoder(AV_CODEC_ID_MPEG1VIDEO);
65 if (!codec) {
66 fprintf(stderr, "codec not found\n");
67 exit(1);
68 }
69
70 c = avcodec_alloc_context3(codec);
71 picture = av_frame_alloc();
72
73 /* put sample parameters */
74 c->bit_rate = 400000;
75 /* resolution must be a multiple of two */
76 c->width = 352;
77 c->height = 288;
78 /* frames per second */
79 c->time_base= (AVRational){1,25};
80 c->gop_size = 10; /* emit one intra frame every ten frames */
81 c->max_b_frames=1;
82 c->pix_fmt = AV_PIX_FMT_YUV420P;
83
84 /* open it */
85 if (avcodec_open2(c, codec, NULL) < 0) {
86 fprintf(stderr, "could not open codec\n");
87 exit(1);
88 }
89
90 f = fopen(filename, "wb");
91 if (!f) {
92 fprintf(stderr, "could not open %s\n", filename);
93 exit(1);
94 }
95
96 ret = av_image_alloc(picture->data, picture->linesize, c->width, c->height,
97 c->pix_fmt, 32);
98 if (ret < 0) {
99 fprintf(stderr, "could not alloc raw picture buffer\n");
100 exit(1);
101 }
102 picture->format = c->pix_fmt;
103 picture->width = c->width;
104 picture->height = c->height;
105
106 /* encode 1 second of video */
107 for(i=0;i<25;i++) {
108 av_init_packet(&pkt);
109 pkt.data = NULL; // packet data will be allocated by the encoder
110 pkt.size = 0;
111
112 fflush(stdout);
113 /* prepare a dummy image */
114 /* Y */
115 for(y=0;y<c->height;y++) {
116 for(x=0;x<c->width;x++) {
117 picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
118 }
119 }
120
121 /* Cb and Cr */
122 for(y=0;y<c->height/2;y++) {
123 for(x=0;x<c->width/2;x++) {
124 picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
125 picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
126 }
127 }
128
129 picture->pts = i;
130
131 /* encode the image */
132 ret = avcodec_encode_video2(c, &pkt, picture, &got_output);
133 if (ret < 0) {
134 fprintf(stderr, "error encoding frame\n");
135 exit(1);
136 }
137
138 if (got_output) {
139 printf("encoding frame %3d (size=%5d)\n", i, pkt.size);
140 fwrite(pkt.data, 1, pkt.size, f);
141 av_packet_unref(&pkt);
142 }
143 }
144
145 /* get the delayed frames */
146 for (got_output = 1; got_output; i++) {
147 fflush(stdout);
148
149 ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
150 if (ret < 0) {
151 fprintf(stderr, "error encoding frame\n");
152 exit(1);
153 }
154
155 if (got_output) {
156 printf("encoding frame %3d (size=%5d)\n", i, pkt.size);
157 fwrite(pkt.data, 1, pkt.size, f);
158 av_packet_unref(&pkt);
159 }
160 }
161
162 /* add sequence end code to have a real MPEG file */
163 fwrite(endcode, 1, sizeof(endcode), f);
164 fclose(f);
165
166 avcodec_free_context(&c);
167 av_freep(&picture->data[0]);
168 av_frame_free(&picture);
169 printf("\n");
170 }
171
172 /*
173 * Video decoding example
174 */
175
176 static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
177 char *filename)
178 {
179 FILE *f;
180 int i;
181
182 f=fopen(filename,"w");
183 fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
184 for(i=0;i<ysize;i++)
185 fwrite(buf + i * wrap,1,xsize,f);
186 fclose(f);
187 }
188
189 static void video_decode_example(const char *outfilename, const char *filename)
190 {
191 AVCodec *codec;
192 AVCodecContext *c= NULL;
193 int frame, got_picture, len;
194 FILE *f;
195 AVFrame *picture;
196 uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
197 char buf[1024];
198 AVPacket avpkt;
199
200 av_init_packet(&avpkt);
201
202 /* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */
203 memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
204
205 printf("Video decoding\n");
206
207 /* find the MPEG-1 video decoder */
208 codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
209 if (!codec) {
210 fprintf(stderr, "codec not found\n");
211 exit(1);
212 }
213
214 c = avcodec_alloc_context3(codec);
215 picture = av_frame_alloc();
216
217 if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
218 c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames
219
220 /* For some codecs, such as msmpeg4 and mpeg4, width and height
221 MUST be initialized there because this information is not
222 available in the bitstream. */
223
224 /* open it */
225 if (avcodec_open2(c, codec, NULL) < 0) {
226 fprintf(stderr, "could not open codec\n");
227 exit(1);
228 }
229
230 /* the codec gives us the frame size, in samples */
231
232 f = fopen(filename, "rb");
233 if (!f) {
234 fprintf(stderr, "could not open %s\n", filename);
235 exit(1);
236 }
237
238 frame = 0;
239 for(;;) {
240 avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
241 if (avpkt.size == 0)
242 break;
243
244 /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
245 and this is the only method to use them because you cannot
246 know the compressed data size before analysing it.
247
248 BUT some other codecs (msmpeg4, mpeg4) are inherently frame
249 based, so you must call them with all the data for one
250 frame exactly. You must also initialize 'width' and
251 'height' before initializing them. */
252
253 /* NOTE2: some codecs allow the raw parameters (frame size,
254 sample rate) to be changed at any frame. We handle this, so
255 you should also take care of it */
256
257 /* here, we use a stream based decoder (mpeg1video), so we
258 feed decoder and see if it could decode a frame */
259 avpkt.data = inbuf;
260 while (avpkt.size > 0) {
261 len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
262 if (len < 0) {
263 fprintf(stderr, "Error while decoding frame %d\n", frame);
264 exit(1);
265 }
266 if (got_picture) {
267 printf("saving frame %3d\n", frame);
268 fflush(stdout);
269
270 /* the picture is allocated by the decoder. no need to
271 free it */
272 snprintf(buf, sizeof(buf), outfilename, frame);
273 pgm_save(picture->data[0], picture->linesize[0],
274 c->width, c->height, buf);
275 frame++;
276 }
277 avpkt.size -= len;
278 avpkt.data += len;
279 }
280 }
281
282 /* Some codecs, such as MPEG, transmit the I- and P-frame with a
283 latency of one frame. You must do the following to have a
284 chance to get the last frame of the video. */
285 avpkt.data = NULL;
286 avpkt.size = 0;
287 len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
288 if (got_picture) {
289 printf("saving last frame %3d\n", frame);
290 fflush(stdout);
291
292 /* the picture is allocated by the decoder. no need to
293 free it */
294 snprintf(buf, sizeof(buf), outfilename, frame);
295 pgm_save(picture->data[0], picture->linesize[0],
296 c->width, c->height, buf);
297 frame++;
298 }
299
300 fclose(f);
301
302 avcodec_free_context(&c);
303 av_frame_free(&picture);
304 printf("\n");
305 }
306
307 int main(int argc, char **argv)
308 {
309 const char *filename;
310
311 /* register all the codecs */
312 avcodec_register_all();
313
314 if (argc <= 1) {
315 video_encode_example("/tmp/test.mpg");
316 filename = "/tmp/test.mpg";
317 } else {
318 filename = argv[1];
319 }
320
321 video_decode_example("/tmp/test%d.pgm", filename);
322
323 return 0;
324 }