examples/avcodec: split audio decoding into a separate example
[libav.git] / doc / examples / avcodec.c
CommitLineData
04d7f601
DB
1/*
2 * copyright (c) 2001 Fabrice Bellard
3 *
2912e87a 4 * This file is part of Libav.
b78e7197 5 *
2912e87a 6 * Libav is free software; you can redistribute it and/or
04d7f601
DB
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
b78e7197 9 * version 2.1 of the License, or (at your option) any later version.
04d7f601 10 *
2912e87a 11 * Libav is distributed in the hope that it will be useful,
04d7f601
DB
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
2912e87a 17 * License along with Libav; if not, write to the Free Software
04d7f601
DB
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
983e3246 21/**
ba87f080 22 * @file
d7537a6f 23 * libavcodec API use example.
de6d9b64 24 *
b339182e 25 * @example avcodec.c
41ed7ab4
VG
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.
de6d9b64 29 */
983e3246 30
de6d9b64
FB
31#include <stdlib.h>
32#include <stdio.h>
33#include <string.h>
9b2bb403 34
fe1b62fb
ZK
35#ifdef HAVE_AV_CONFIG_H
36#undef HAVE_AV_CONFIG_H
37#endif
38
1c38da85 39#include "libavcodec/avcodec.h"
a903f8f0 40#include "libavutil/channel_layout.h"
1d9c2dc8 41#include "libavutil/common.h"
661454aa 42#include "libavutil/imgutils.h"
14660b08 43#include "libavutil/mathematics.h"
0bafe049 44#include "libavutil/samplefmt.h"
de6d9b64
FB
45
46#define INBUF_SIZE 4096
de6d9b64
FB
47
48/*
115329f1 49 * Video encoding example
de6d9b64 50 */
504ffed1 51static void video_encode_example(const char *filename)
de6d9b64
FB
52{
53 AVCodec *codec;
e8b62df6 54 AVCodecContext *c= NULL;
661454aa 55 int i, ret, x, y, got_output;
de6d9b64 56 FILE *f;
492cd3a9 57 AVFrame *picture;
661454aa
AK
58 AVPacket pkt;
59 uint8_t endcode[] = { 0, 0, 1, 0xb7 };
de6d9b64
FB
60
61 printf("Video encoding\n");
62
41ed7ab4 63 /* find the mpeg1video encoder */
36ef5369 64 codec = avcodec_find_encoder(AV_CODEC_ID_MPEG1VIDEO);
de6d9b64
FB
65 if (!codec) {
66 fprintf(stderr, "codec not found\n");
67 exit(1);
68 }
69
71a861cf 70 c = avcodec_alloc_context3(codec);
5b9c3b45 71 picture = av_frame_alloc();
115329f1 72
de6d9b64
FB
73 /* put sample parameters */
74 c->bit_rate = 400000;
75 /* resolution must be a multiple of two */
115329f1 76 c->width = 352;
de6d9b64
FB
77 c->height = 288;
78 /* frames per second */
c0df9d75 79 c->time_base= (AVRational){1,25};
de6d9b64 80 c->gop_size = 10; /* emit one intra frame every ten frames */
17d71fb9 81 c->max_b_frames=1;
716d413c 82 c->pix_fmt = AV_PIX_FMT_YUV420P;
de6d9b64
FB
83
84 /* open it */
aac63cef 85 if (avcodec_open2(c, codec, NULL) < 0) {
de6d9b64
FB
86 fprintf(stderr, "could not open codec\n");
87 exit(1);
88 }
115329f1 89
1c0e205f 90 f = fopen(filename, "wb");
de6d9b64
FB
91 if (!f) {
92 fprintf(stderr, "could not open %s\n", filename);
93 exit(1);
94 }
115329f1 95
661454aa
AK
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;
de6d9b64
FB
105
106 /* encode 1 second of video */
107 for(i=0;i<25;i++) {
661454aa
AK
108 av_init_packet(&pkt);
109 pkt.data = NULL; // packet data will be allocated by the encoder
110 pkt.size = 0;
111
de6d9b64
FB
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++) {
6c16199b 117 picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
de6d9b64
FB
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++) {
6c16199b
MN
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;
de6d9b64
FB
126 }
127 }
128
661454aa
AK
129 picture->pts = i;
130
de6d9b64 131 /* encode the image */
661454aa
AK
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);
ce70f28a 141 av_packet_unref(&pkt);
661454aa 142 }
17d71fb9
MN
143 }
144
145 /* get the delayed frames */
661454aa 146 for (got_output = 1; got_output; i++) {
17d71fb9 147 fflush(stdout);
115329f1 148
661454aa
AK
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);
ce70f28a 158 av_packet_unref(&pkt);
661454aa 159 }
de6d9b64
FB
160 }
161
41ed7ab4 162 /* add sequence end code to have a real MPEG file */
661454aa 163 fwrite(endcode, 1, sizeof(endcode), f);
de6d9b64 164 fclose(f);
de6d9b64 165
9833a406 166 avcodec_free_context(&c);
661454aa 167 av_freep(&picture->data[0]);
eb891b31 168 av_frame_free(&picture);
de6d9b64
FB
169 printf("\n");
170}
171
172/*
115329f1 173 * Video decoding example
de6d9b64
FB
174 */
175
504ffed1
DB
176static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
177 char *filename)
de6d9b64
FB
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
504ffed1 189static void video_decode_example(const char *outfilename, const char *filename)
de6d9b64
FB
190{
191 AVCodec *codec;
e8b62df6 192 AVCodecContext *c= NULL;
4f313925 193 int frame, got_picture, len;
de6d9b64 194 FILE *f;
492cd3a9 195 AVFrame *picture;
059a9348 196 uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
de6d9b64 197 char buf[1024];
4f313925
TB
198 AVPacket avpkt;
199
200 av_init_packet(&avpkt);
de6d9b64 201
41ed7ab4 202 /* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */
059a9348 203 memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
6a686d58 204
de6d9b64
FB
205 printf("Video decoding\n");
206
41ed7ab4 207 /* find the MPEG-1 video decoder */
36ef5369 208 codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
de6d9b64
FB
209 if (!codec) {
210 fprintf(stderr, "codec not found\n");
211 exit(1);
212 }
213
71a861cf 214 c = avcodec_alloc_context3(codec);
5b9c3b45 215 picture = av_frame_alloc();
de6d9b64 216
def97856 217 if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
7c6eb0a1 218 c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames
f78ebb51 219
755bfeab
DB
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. */
de6d9b64
FB
223
224 /* open it */
aac63cef 225 if (avcodec_open2(c, codec, NULL) < 0) {
de6d9b64
FB
226 fprintf(stderr, "could not open codec\n");
227 exit(1);
228 }
115329f1 229
de6d9b64
FB
230 /* the codec gives us the frame size, in samples */
231
1c0e205f 232 f = fopen(filename, "rb");
de6d9b64
FB
233 if (!f) {
234 fprintf(stderr, "could not open %s\n", filename);
235 exit(1);
236 }
115329f1 237
de6d9b64
FB
238 frame = 0;
239 for(;;) {
4f313925
TB
240 avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
241 if (avpkt.size == 0)
de6d9b64
FB
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
115329f1 246 know the compressed data size before analysing it.
de6d9b64 247
58f26ba9
FB
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
de6d9b64
FB
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 */
4f313925
TB
259 avpkt.data = inbuf;
260 while (avpkt.size > 0) {
261 len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
de6d9b64
FB
262 if (len < 0) {
263 fprintf(stderr, "Error while decoding frame %d\n", frame);
264 exit(1);
265 }
266 if (got_picture) {
17d71fb9 267 printf("saving frame %3d\n", frame);
de6d9b64
FB
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);
115329f1 273 pgm_save(picture->data[0], picture->linesize[0],
de6d9b64
FB
274 c->width, c->height, buf);
275 frame++;
276 }
4f313925
TB
277 avpkt.size -= len;
278 avpkt.data += len;
de6d9b64
FB
279 }
280 }
281
41ed7ab4 282 /* Some codecs, such as MPEG, transmit the I- and P-frame with a
de6d9b64 283 latency of one frame. You must do the following to have a
41ed7ab4 284 chance to get the last frame of the video. */
4f313925
TB
285 avpkt.data = NULL;
286 avpkt.size = 0;
287 len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
de6d9b64 288 if (got_picture) {
17d71fb9 289 printf("saving last frame %3d\n", frame);
de6d9b64 290 fflush(stdout);
115329f1 291
de6d9b64
FB
292 /* the picture is allocated by the decoder. no need to
293 free it */
294 snprintf(buf, sizeof(buf), outfilename, frame);
115329f1 295 pgm_save(picture->data[0], picture->linesize[0],
de6d9b64
FB
296 c->width, c->height, buf);
297 frame++;
298 }
115329f1 299
de6d9b64
FB
300 fclose(f);
301
9833a406 302 avcodec_free_context(&c);
eb891b31 303 av_frame_free(&picture);
de6d9b64
FB
304 printf("\n");
305}
306
de6d9b64
FB
307int main(int argc, char **argv)
308{
309 const char *filename;
310
c9823f05 311 /* register all the codecs */
de6d9b64 312 avcodec_register_all();
fe1b62fb 313
de6d9b64 314 if (argc <= 1) {
de6d9b64
FB
315 video_encode_example("/tmp/test.mpg");
316 filename = "/tmp/test.mpg";
317 } else {
318 filename = argv[1];
319 }
320
de6d9b64
FB
321 video_decode_example("/tmp/test%d.pgm", filename);
322
323 return 0;
324}