annotate apiexample.c @ 233:3f5b72726118 libavcodec

- More work on preliminary bit rate control, just to be able to get an average variance for picture's MBs so we can adjust qscale on the MB layer.
author pulento
date Sun, 10 Feb 2002 06:10:50 +0000
parents 79be2c581c01
children 44a1dab0205c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
1 /* avcodec API use example.
986e461dc072 Initial revision
glantau
parents:
diff changeset
2 *
986e461dc072 Initial revision
glantau
parents:
diff changeset
3 * Note that this library only handles codecs (mpeg, mpeg4, etc...),
986e461dc072 Initial revision
glantau
parents:
diff changeset
4 * not file formats (avi, vob, etc...). See library 'libav' for the
986e461dc072 Initial revision
glantau
parents:
diff changeset
5 * format handling
986e461dc072 Initial revision
glantau
parents:
diff changeset
6 */
986e461dc072 Initial revision
glantau
parents:
diff changeset
7 #include <stdlib.h>
986e461dc072 Initial revision
glantau
parents:
diff changeset
8 #include <stdio.h>
986e461dc072 Initial revision
glantau
parents:
diff changeset
9 #include <string.h>
986e461dc072 Initial revision
glantau
parents:
diff changeset
10 #include <math.h>
986e461dc072 Initial revision
glantau
parents:
diff changeset
11
986e461dc072 Initial revision
glantau
parents:
diff changeset
12 #include "avcodec.h"
986e461dc072 Initial revision
glantau
parents:
diff changeset
13
986e461dc072 Initial revision
glantau
parents:
diff changeset
14 #define INBUF_SIZE 4096
986e461dc072 Initial revision
glantau
parents:
diff changeset
15
986e461dc072 Initial revision
glantau
parents:
diff changeset
16 /*
986e461dc072 Initial revision
glantau
parents:
diff changeset
17 * Audio encoding example
986e461dc072 Initial revision
glantau
parents:
diff changeset
18 */
986e461dc072 Initial revision
glantau
parents:
diff changeset
19 void audio_encode_example(const char *filename)
986e461dc072 Initial revision
glantau
parents:
diff changeset
20 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
21 AVCodec *codec;
986e461dc072 Initial revision
glantau
parents:
diff changeset
22 AVCodecContext codec_context, *c = &codec_context;
986e461dc072 Initial revision
glantau
parents:
diff changeset
23 int frame_size, i, j, out_size, outbuf_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
24 FILE *f;
986e461dc072 Initial revision
glantau
parents:
diff changeset
25 short *samples;
986e461dc072 Initial revision
glantau
parents:
diff changeset
26 float t, tincr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
27 UINT8 *outbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
28
986e461dc072 Initial revision
glantau
parents:
diff changeset
29 printf("Audio encoding\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
30
986e461dc072 Initial revision
glantau
parents:
diff changeset
31 /* find the MP2 encoder */
986e461dc072 Initial revision
glantau
parents:
diff changeset
32 codec = avcodec_find_encoder(CODEC_ID_MP2);
986e461dc072 Initial revision
glantau
parents:
diff changeset
33 if (!codec) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
34 fprintf(stderr, "codec not found\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
35 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
36 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
37
986e461dc072 Initial revision
glantau
parents:
diff changeset
38 /* put default values */
986e461dc072 Initial revision
glantau
parents:
diff changeset
39 memset(c, 0, sizeof(*c));
986e461dc072 Initial revision
glantau
parents:
diff changeset
40
986e461dc072 Initial revision
glantau
parents:
diff changeset
41 /* put sample parameters */
986e461dc072 Initial revision
glantau
parents:
diff changeset
42 c->bit_rate = 64000;
986e461dc072 Initial revision
glantau
parents:
diff changeset
43 c->sample_rate = 44100;
986e461dc072 Initial revision
glantau
parents:
diff changeset
44 c->channels = 2;
986e461dc072 Initial revision
glantau
parents:
diff changeset
45
986e461dc072 Initial revision
glantau
parents:
diff changeset
46 /* open it */
986e461dc072 Initial revision
glantau
parents:
diff changeset
47 if (avcodec_open(c, codec) < 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
48 fprintf(stderr, "could not open codec\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
49 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
50 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
51
986e461dc072 Initial revision
glantau
parents:
diff changeset
52 /* the codec gives us the frame size, in samples */
986e461dc072 Initial revision
glantau
parents:
diff changeset
53 frame_size = c->frame_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
54 samples = malloc(frame_size * 2 * c->channels);
986e461dc072 Initial revision
glantau
parents:
diff changeset
55 outbuf_size = 10000;
986e461dc072 Initial revision
glantau
parents:
diff changeset
56 outbuf = malloc(outbuf_size);
986e461dc072 Initial revision
glantau
parents:
diff changeset
57
986e461dc072 Initial revision
glantau
parents:
diff changeset
58 f = fopen(filename, "w");
986e461dc072 Initial revision
glantau
parents:
diff changeset
59 if (!f) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
60 fprintf(stderr, "could not open %s\n", filename);
986e461dc072 Initial revision
glantau
parents:
diff changeset
61 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
62 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
63
986e461dc072 Initial revision
glantau
parents:
diff changeset
64 /* encode a single tone sound */
986e461dc072 Initial revision
glantau
parents:
diff changeset
65 t = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
66 tincr = 2 * M_PI * 440.0 / c->sample_rate;
986e461dc072 Initial revision
glantau
parents:
diff changeset
67 for(i=0;i<200;i++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
68 for(j=0;j<frame_size;j++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
69 samples[2*j] = (int)(sin(t) * 10000);
986e461dc072 Initial revision
glantau
parents:
diff changeset
70 samples[2*j+1] = samples[2*j];
986e461dc072 Initial revision
glantau
parents:
diff changeset
71 t += tincr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
72 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
73 /* encode the samples */
986e461dc072 Initial revision
glantau
parents:
diff changeset
74 out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
986e461dc072 Initial revision
glantau
parents:
diff changeset
75 fwrite(outbuf, 1, out_size, f);
986e461dc072 Initial revision
glantau
parents:
diff changeset
76 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
77 fclose(f);
986e461dc072 Initial revision
glantau
parents:
diff changeset
78 free(outbuf);
986e461dc072 Initial revision
glantau
parents:
diff changeset
79 free(samples);
986e461dc072 Initial revision
glantau
parents:
diff changeset
80
986e461dc072 Initial revision
glantau
parents:
diff changeset
81 avcodec_close(c);
986e461dc072 Initial revision
glantau
parents:
diff changeset
82 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
83
986e461dc072 Initial revision
glantau
parents:
diff changeset
84 /*
986e461dc072 Initial revision
glantau
parents:
diff changeset
85 * Audio decoding.
986e461dc072 Initial revision
glantau
parents:
diff changeset
86 */
986e461dc072 Initial revision
glantau
parents:
diff changeset
87 void audio_decode_example(const char *outfilename, const char *filename)
986e461dc072 Initial revision
glantau
parents:
diff changeset
88 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
89 AVCodec *codec;
986e461dc072 Initial revision
glantau
parents:
diff changeset
90 AVCodecContext codec_context, *c = &codec_context;
986e461dc072 Initial revision
glantau
parents:
diff changeset
91 int out_size, size, len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
92 FILE *f, *outfile;
986e461dc072 Initial revision
glantau
parents:
diff changeset
93 UINT8 *outbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
94 UINT8 inbuf[INBUF_SIZE], *inbuf_ptr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
95
986e461dc072 Initial revision
glantau
parents:
diff changeset
96 printf("Audio decoding\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
97
986e461dc072 Initial revision
glantau
parents:
diff changeset
98 /* find the mpeg audio decoder */
986e461dc072 Initial revision
glantau
parents:
diff changeset
99 codec = avcodec_find_decoder(CODEC_ID_MP2);
986e461dc072 Initial revision
glantau
parents:
diff changeset
100 if (!codec) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
101 fprintf(stderr, "codec not found\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
102 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
103 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
104
986e461dc072 Initial revision
glantau
parents:
diff changeset
105 /* put default values */
986e461dc072 Initial revision
glantau
parents:
diff changeset
106 memset(c, 0, sizeof(*c));
986e461dc072 Initial revision
glantau
parents:
diff changeset
107
986e461dc072 Initial revision
glantau
parents:
diff changeset
108 /* open it */
986e461dc072 Initial revision
glantau
parents:
diff changeset
109 if (avcodec_open(c, codec) < 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
110 fprintf(stderr, "could not open codec\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
111 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
112 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
113
986e461dc072 Initial revision
glantau
parents:
diff changeset
114 outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
986e461dc072 Initial revision
glantau
parents:
diff changeset
115
986e461dc072 Initial revision
glantau
parents:
diff changeset
116 f = fopen(filename, "r");
986e461dc072 Initial revision
glantau
parents:
diff changeset
117 if (!f) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
118 fprintf(stderr, "could not open %s\n", filename);
986e461dc072 Initial revision
glantau
parents:
diff changeset
119 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
120 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
121 outfile = fopen(outfilename, "w");
986e461dc072 Initial revision
glantau
parents:
diff changeset
122 if (!outfile) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
123 fprintf(stderr, "could not open %s\n", outfilename);
986e461dc072 Initial revision
glantau
parents:
diff changeset
124 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
125 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
126
986e461dc072 Initial revision
glantau
parents:
diff changeset
127 /* decode until eof */
986e461dc072 Initial revision
glantau
parents:
diff changeset
128 inbuf_ptr = inbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
129 for(;;) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
130 size = fread(inbuf, 1, INBUF_SIZE, f);
986e461dc072 Initial revision
glantau
parents:
diff changeset
131 if (size == 0)
986e461dc072 Initial revision
glantau
parents:
diff changeset
132 break;
986e461dc072 Initial revision
glantau
parents:
diff changeset
133
986e461dc072 Initial revision
glantau
parents:
diff changeset
134 inbuf_ptr = inbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
135 while (size > 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
136 len = avcodec_decode_audio(c, (short *)outbuf, &out_size,
986e461dc072 Initial revision
glantau
parents:
diff changeset
137 inbuf_ptr, size);
986e461dc072 Initial revision
glantau
parents:
diff changeset
138 if (len < 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
139 fprintf(stderr, "Error while decoding\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
140 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
141 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
142 if (out_size > 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
143 /* if a frame has been decoded, output it */
986e461dc072 Initial revision
glantau
parents:
diff changeset
144 fwrite(outbuf, 1, out_size, outfile);
986e461dc072 Initial revision
glantau
parents:
diff changeset
145 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
146 size -= len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
147 inbuf_ptr += len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
148 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
149 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
150
986e461dc072 Initial revision
glantau
parents:
diff changeset
151 fclose(outfile);
986e461dc072 Initial revision
glantau
parents:
diff changeset
152 fclose(f);
986e461dc072 Initial revision
glantau
parents:
diff changeset
153 free(outbuf);
986e461dc072 Initial revision
glantau
parents:
diff changeset
154
986e461dc072 Initial revision
glantau
parents:
diff changeset
155 avcodec_close(c);
986e461dc072 Initial revision
glantau
parents:
diff changeset
156 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
157
986e461dc072 Initial revision
glantau
parents:
diff changeset
158 /*
986e461dc072 Initial revision
glantau
parents:
diff changeset
159 * Video encoding example
986e461dc072 Initial revision
glantau
parents:
diff changeset
160 */
986e461dc072 Initial revision
glantau
parents:
diff changeset
161 void video_encode_example(const char *filename)
986e461dc072 Initial revision
glantau
parents:
diff changeset
162 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
163 AVCodec *codec;
986e461dc072 Initial revision
glantau
parents:
diff changeset
164 AVCodecContext codec_context, *c = &codec_context;
986e461dc072 Initial revision
glantau
parents:
diff changeset
165 int i, out_size, size, x, y, outbuf_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
166 FILE *f;
986e461dc072 Initial revision
glantau
parents:
diff changeset
167 AVPicture picture;
986e461dc072 Initial revision
glantau
parents:
diff changeset
168 UINT8 *outbuf, *picture_buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
169
986e461dc072 Initial revision
glantau
parents:
diff changeset
170 printf("Video encoding\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
171
986e461dc072 Initial revision
glantau
parents:
diff changeset
172 /* find the mpeg1 video encoder */
986e461dc072 Initial revision
glantau
parents:
diff changeset
173 codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
986e461dc072 Initial revision
glantau
parents:
diff changeset
174 if (!codec) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
175 fprintf(stderr, "codec not found\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
176 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
177 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
178
986e461dc072 Initial revision
glantau
parents:
diff changeset
179 /* put default values */
986e461dc072 Initial revision
glantau
parents:
diff changeset
180 memset(c, 0, sizeof(*c));
986e461dc072 Initial revision
glantau
parents:
diff changeset
181
986e461dc072 Initial revision
glantau
parents:
diff changeset
182 /* put sample parameters */
986e461dc072 Initial revision
glantau
parents:
diff changeset
183 c->bit_rate = 400000;
986e461dc072 Initial revision
glantau
parents:
diff changeset
184 /* resolution must be a multiple of two */
986e461dc072 Initial revision
glantau
parents:
diff changeset
185 c->width = 352;
986e461dc072 Initial revision
glantau
parents:
diff changeset
186 c->height = 288;
986e461dc072 Initial revision
glantau
parents:
diff changeset
187 /* frames per second */
986e461dc072 Initial revision
glantau
parents:
diff changeset
188 c->frame_rate = 25 * FRAME_RATE_BASE;
986e461dc072 Initial revision
glantau
parents:
diff changeset
189 c->gop_size = 10; /* emit one intra frame every ten frames */
986e461dc072 Initial revision
glantau
parents:
diff changeset
190
986e461dc072 Initial revision
glantau
parents:
diff changeset
191 /* open it */
986e461dc072 Initial revision
glantau
parents:
diff changeset
192 if (avcodec_open(c, codec) < 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
193 fprintf(stderr, "could not open codec\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
194 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
195 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
196
986e461dc072 Initial revision
glantau
parents:
diff changeset
197 /* the codec gives us the frame size, in samples */
986e461dc072 Initial revision
glantau
parents:
diff changeset
198
986e461dc072 Initial revision
glantau
parents:
diff changeset
199 f = fopen(filename, "w");
986e461dc072 Initial revision
glantau
parents:
diff changeset
200 if (!f) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
201 fprintf(stderr, "could not open %s\n", filename);
986e461dc072 Initial revision
glantau
parents:
diff changeset
202 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
203 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
204
986e461dc072 Initial revision
glantau
parents:
diff changeset
205 /* alloc image and output buffer */
986e461dc072 Initial revision
glantau
parents:
diff changeset
206 outbuf_size = 100000;
986e461dc072 Initial revision
glantau
parents:
diff changeset
207 outbuf = malloc(outbuf_size);
986e461dc072 Initial revision
glantau
parents:
diff changeset
208 size = c->width * c->height;
986e461dc072 Initial revision
glantau
parents:
diff changeset
209 picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
986e461dc072 Initial revision
glantau
parents:
diff changeset
210
986e461dc072 Initial revision
glantau
parents:
diff changeset
211 picture.data[0] = picture_buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
212 picture.data[1] = picture.data[0] + size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
213 picture.data[2] = picture.data[1] + size / 4;
986e461dc072 Initial revision
glantau
parents:
diff changeset
214 picture.linesize[0] = c->width;
986e461dc072 Initial revision
glantau
parents:
diff changeset
215 picture.linesize[1] = c->width / 2;
986e461dc072 Initial revision
glantau
parents:
diff changeset
216 picture.linesize[2] = c->width / 2;
986e461dc072 Initial revision
glantau
parents:
diff changeset
217
986e461dc072 Initial revision
glantau
parents:
diff changeset
218 /* encode 1 second of video */
986e461dc072 Initial revision
glantau
parents:
diff changeset
219 for(i=0;i<25;i++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
220 printf("encoding frame %3d\r", i);
986e461dc072 Initial revision
glantau
parents:
diff changeset
221 fflush(stdout);
986e461dc072 Initial revision
glantau
parents:
diff changeset
222 /* prepare a dummy image */
986e461dc072 Initial revision
glantau
parents:
diff changeset
223 /* Y */
986e461dc072 Initial revision
glantau
parents:
diff changeset
224 for(y=0;y<c->height;y++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
225 for(x=0;x<c->width;x++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
226 picture.data[0][y * picture.linesize[0] + x] = x + y + i * 3;
986e461dc072 Initial revision
glantau
parents:
diff changeset
227 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
228 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
229
986e461dc072 Initial revision
glantau
parents:
diff changeset
230 /* Cb and Cr */
986e461dc072 Initial revision
glantau
parents:
diff changeset
231 for(y=0;y<c->height/2;y++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
232 for(x=0;x<c->width/2;x++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
233 picture.data[1][y * picture.linesize[1] + x] = 128 + y + i * 2;
986e461dc072 Initial revision
glantau
parents:
diff changeset
234 picture.data[2][y * picture.linesize[2] + x] = 64 + x + i * 5;
986e461dc072 Initial revision
glantau
parents:
diff changeset
235 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
236 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
237
986e461dc072 Initial revision
glantau
parents:
diff changeset
238 /* encode the image */
986e461dc072 Initial revision
glantau
parents:
diff changeset
239 out_size = avcodec_encode_video(c, outbuf, outbuf_size, &picture);
986e461dc072 Initial revision
glantau
parents:
diff changeset
240 fwrite(outbuf, 1, out_size, f);
986e461dc072 Initial revision
glantau
parents:
diff changeset
241 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
242
986e461dc072 Initial revision
glantau
parents:
diff changeset
243 /* add sequence end code to have a real mpeg file */
986e461dc072 Initial revision
glantau
parents:
diff changeset
244 outbuf[0] = 0x00;
986e461dc072 Initial revision
glantau
parents:
diff changeset
245 outbuf[1] = 0x00;
986e461dc072 Initial revision
glantau
parents:
diff changeset
246 outbuf[2] = 0x01;
986e461dc072 Initial revision
glantau
parents:
diff changeset
247 outbuf[3] = 0xb7;
986e461dc072 Initial revision
glantau
parents:
diff changeset
248 fwrite(outbuf, 1, 4, f);
986e461dc072 Initial revision
glantau
parents:
diff changeset
249 fclose(f);
986e461dc072 Initial revision
glantau
parents:
diff changeset
250 free(picture_buf);
986e461dc072 Initial revision
glantau
parents:
diff changeset
251 free(outbuf);
986e461dc072 Initial revision
glantau
parents:
diff changeset
252
986e461dc072 Initial revision
glantau
parents:
diff changeset
253 avcodec_close(c);
986e461dc072 Initial revision
glantau
parents:
diff changeset
254 printf("\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
255 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
256
986e461dc072 Initial revision
glantau
parents:
diff changeset
257 /*
986e461dc072 Initial revision
glantau
parents:
diff changeset
258 * Video decoding example
986e461dc072 Initial revision
glantau
parents:
diff changeset
259 */
986e461dc072 Initial revision
glantau
parents:
diff changeset
260
986e461dc072 Initial revision
glantau
parents:
diff changeset
261 void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename)
986e461dc072 Initial revision
glantau
parents:
diff changeset
262 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
263 FILE *f;
986e461dc072 Initial revision
glantau
parents:
diff changeset
264 int i;
986e461dc072 Initial revision
glantau
parents:
diff changeset
265
986e461dc072 Initial revision
glantau
parents:
diff changeset
266 f=fopen(filename,"w");
986e461dc072 Initial revision
glantau
parents:
diff changeset
267 fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
986e461dc072 Initial revision
glantau
parents:
diff changeset
268 for(i=0;i<ysize;i++)
986e461dc072 Initial revision
glantau
parents:
diff changeset
269 fwrite(buf + i * wrap,1,xsize,f);
986e461dc072 Initial revision
glantau
parents:
diff changeset
270 fclose(f);
986e461dc072 Initial revision
glantau
parents:
diff changeset
271 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
272
986e461dc072 Initial revision
glantau
parents:
diff changeset
273 void video_decode_example(const char *outfilename, const char *filename)
986e461dc072 Initial revision
glantau
parents:
diff changeset
274 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
275 AVCodec *codec;
986e461dc072 Initial revision
glantau
parents:
diff changeset
276 AVCodecContext codec_context, *c = &codec_context;
986e461dc072 Initial revision
glantau
parents:
diff changeset
277 int frame, size, got_picture, len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
278 FILE *f;
986e461dc072 Initial revision
glantau
parents:
diff changeset
279 AVPicture picture;
986e461dc072 Initial revision
glantau
parents:
diff changeset
280 UINT8 inbuf[INBUF_SIZE], *inbuf_ptr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
281 char buf[1024];
986e461dc072 Initial revision
glantau
parents:
diff changeset
282
986e461dc072 Initial revision
glantau
parents:
diff changeset
283 printf("Video decoding\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
284
986e461dc072 Initial revision
glantau
parents:
diff changeset
285 /* find the mpeg1 video decoder */
986e461dc072 Initial revision
glantau
parents:
diff changeset
286 codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
986e461dc072 Initial revision
glantau
parents:
diff changeset
287 if (!codec) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
288 fprintf(stderr, "codec not found\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
289 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
290 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
291
986e461dc072 Initial revision
glantau
parents:
diff changeset
292 /* put default values */
986e461dc072 Initial revision
glantau
parents:
diff changeset
293 memset(c, 0, sizeof(*c));
986e461dc072 Initial revision
glantau
parents:
diff changeset
294
71
79be2c581c01 changed opendivx to mpeg4
glantau
parents: 0
diff changeset
295 /* for some codecs, such as msmpeg4 and mpeg4, width and height
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
296 MUST be initialized there because these info are not available
986e461dc072 Initial revision
glantau
parents:
diff changeset
297 in the bitstream */
986e461dc072 Initial revision
glantau
parents:
diff changeset
298
986e461dc072 Initial revision
glantau
parents:
diff changeset
299 /* open it */
986e461dc072 Initial revision
glantau
parents:
diff changeset
300 if (avcodec_open(c, codec) < 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
301 fprintf(stderr, "could not open codec\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
302 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
303 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
304
986e461dc072 Initial revision
glantau
parents:
diff changeset
305 /* the codec gives us the frame size, in samples */
986e461dc072 Initial revision
glantau
parents:
diff changeset
306
986e461dc072 Initial revision
glantau
parents:
diff changeset
307 f = fopen(filename, "r");
986e461dc072 Initial revision
glantau
parents:
diff changeset
308 if (!f) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
309 fprintf(stderr, "could not open %s\n", filename);
986e461dc072 Initial revision
glantau
parents:
diff changeset
310 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
311 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
312
986e461dc072 Initial revision
glantau
parents:
diff changeset
313 frame = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
314 for(;;) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
315 size = fread(inbuf, 1, INBUF_SIZE, f);
986e461dc072 Initial revision
glantau
parents:
diff changeset
316 if (size == 0)
986e461dc072 Initial revision
glantau
parents:
diff changeset
317 break;
986e461dc072 Initial revision
glantau
parents:
diff changeset
318
986e461dc072 Initial revision
glantau
parents:
diff changeset
319 /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
986e461dc072 Initial revision
glantau
parents:
diff changeset
320 and this is the only method to use them because you cannot
986e461dc072 Initial revision
glantau
parents:
diff changeset
321 know the compressed data size before analysing it.
986e461dc072 Initial revision
glantau
parents:
diff changeset
322
71
79be2c581c01 changed opendivx to mpeg4
glantau
parents: 0
diff changeset
323 BUT some other codecs (msmpeg4, mpeg4) are inherently frame
79be2c581c01 changed opendivx to mpeg4
glantau
parents: 0
diff changeset
324 based, so you must call them with all the data for one
79be2c581c01 changed opendivx to mpeg4
glantau
parents: 0
diff changeset
325 frame exactly. You must also initialize 'width' and
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
326 'height' before initializing them. */
986e461dc072 Initial revision
glantau
parents:
diff changeset
327
986e461dc072 Initial revision
glantau
parents:
diff changeset
328 /* NOTE2: some codecs allow the raw parameters (frame size,
986e461dc072 Initial revision
glantau
parents:
diff changeset
329 sample rate) to be changed at any frame. We handle this, so
986e461dc072 Initial revision
glantau
parents:
diff changeset
330 you should also take care of it */
986e461dc072 Initial revision
glantau
parents:
diff changeset
331
986e461dc072 Initial revision
glantau
parents:
diff changeset
332 /* here, we use a stream based decoder (mpeg1video), so we
986e461dc072 Initial revision
glantau
parents:
diff changeset
333 feed decoder and see if it could decode a frame */
986e461dc072 Initial revision
glantau
parents:
diff changeset
334 inbuf_ptr = inbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
335 while (size > 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
336 len = avcodec_decode_video(c, &picture, &got_picture,
986e461dc072 Initial revision
glantau
parents:
diff changeset
337 inbuf_ptr, size);
986e461dc072 Initial revision
glantau
parents:
diff changeset
338 if (len < 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
339 fprintf(stderr, "Error while decoding frame %d\n", frame);
986e461dc072 Initial revision
glantau
parents:
diff changeset
340 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
341 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
342 if (got_picture) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
343 printf("saving frame %3d\r", frame);
986e461dc072 Initial revision
glantau
parents:
diff changeset
344 fflush(stdout);
986e461dc072 Initial revision
glantau
parents:
diff changeset
345
986e461dc072 Initial revision
glantau
parents:
diff changeset
346 /* the picture is allocated by the decoder. no need to
986e461dc072 Initial revision
glantau
parents:
diff changeset
347 free it */
986e461dc072 Initial revision
glantau
parents:
diff changeset
348 snprintf(buf, sizeof(buf), outfilename, frame);
986e461dc072 Initial revision
glantau
parents:
diff changeset
349 pgm_save(picture.data[0], picture.linesize[0],
986e461dc072 Initial revision
glantau
parents:
diff changeset
350 c->width, c->height, buf);
986e461dc072 Initial revision
glantau
parents:
diff changeset
351 frame++;
986e461dc072 Initial revision
glantau
parents:
diff changeset
352 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
353 size -= len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
354 inbuf_ptr += len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
355 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
356 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
357
986e461dc072 Initial revision
glantau
parents:
diff changeset
358 /* some codecs, such as MPEG, transmit the I and P frame with a
986e461dc072 Initial revision
glantau
parents:
diff changeset
359 latency of one frame. You must do the following to have a
986e461dc072 Initial revision
glantau
parents:
diff changeset
360 chance to get the last frame of the video */
986e461dc072 Initial revision
glantau
parents:
diff changeset
361 len = avcodec_decode_video(c, &picture, &got_picture,
986e461dc072 Initial revision
glantau
parents:
diff changeset
362 NULL, 0);
986e461dc072 Initial revision
glantau
parents:
diff changeset
363 if (got_picture) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
364 printf("saving frame %3d\r", frame);
986e461dc072 Initial revision
glantau
parents:
diff changeset
365 fflush(stdout);
986e461dc072 Initial revision
glantau
parents:
diff changeset
366
986e461dc072 Initial revision
glantau
parents:
diff changeset
367 /* the picture is allocated by the decoder. no need to
986e461dc072 Initial revision
glantau
parents:
diff changeset
368 free it */
986e461dc072 Initial revision
glantau
parents:
diff changeset
369 snprintf(buf, sizeof(buf), outfilename, frame);
986e461dc072 Initial revision
glantau
parents:
diff changeset
370 pgm_save(picture.data[0], picture.linesize[0],
986e461dc072 Initial revision
glantau
parents:
diff changeset
371 c->width, c->height, buf);
986e461dc072 Initial revision
glantau
parents:
diff changeset
372 frame++;
986e461dc072 Initial revision
glantau
parents:
diff changeset
373 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
374
986e461dc072 Initial revision
glantau
parents:
diff changeset
375 fclose(f);
986e461dc072 Initial revision
glantau
parents:
diff changeset
376
986e461dc072 Initial revision
glantau
parents:
diff changeset
377 avcodec_close(c);
986e461dc072 Initial revision
glantau
parents:
diff changeset
378 printf("\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
379 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
380
986e461dc072 Initial revision
glantau
parents:
diff changeset
381
986e461dc072 Initial revision
glantau
parents:
diff changeset
382 int main(int argc, char **argv)
986e461dc072 Initial revision
glantau
parents:
diff changeset
383 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
384 const char *filename;
986e461dc072 Initial revision
glantau
parents:
diff changeset
385
986e461dc072 Initial revision
glantau
parents:
diff changeset
386 /* must be called before using avcodec lib */
986e461dc072 Initial revision
glantau
parents:
diff changeset
387 avcodec_init();
986e461dc072 Initial revision
glantau
parents:
diff changeset
388
986e461dc072 Initial revision
glantau
parents:
diff changeset
389 /* register all the codecs (you can also register only the codec
986e461dc072 Initial revision
glantau
parents:
diff changeset
390 you wish to have smaller code */
986e461dc072 Initial revision
glantau
parents:
diff changeset
391 avcodec_register_all();
986e461dc072 Initial revision
glantau
parents:
diff changeset
392
986e461dc072 Initial revision
glantau
parents:
diff changeset
393 if (argc <= 1) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
394 audio_encode_example("/tmp/test.mp2");
986e461dc072 Initial revision
glantau
parents:
diff changeset
395 audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
986e461dc072 Initial revision
glantau
parents:
diff changeset
396
986e461dc072 Initial revision
glantau
parents:
diff changeset
397 video_encode_example("/tmp/test.mpg");
986e461dc072 Initial revision
glantau
parents:
diff changeset
398 filename = "/tmp/test.mpg";
986e461dc072 Initial revision
glantau
parents:
diff changeset
399 } else {
986e461dc072 Initial revision
glantau
parents:
diff changeset
400 filename = argv[1];
986e461dc072 Initial revision
glantau
parents:
diff changeset
401 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
402
986e461dc072 Initial revision
glantau
parents:
diff changeset
403 // audio_decode_example("/tmp/test.sw", filename);
986e461dc072 Initial revision
glantau
parents:
diff changeset
404 video_decode_example("/tmp/test%d.pgm", filename);
986e461dc072 Initial revision
glantau
parents:
diff changeset
405
986e461dc072 Initial revision
glantau
parents:
diff changeset
406 return 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
407 }