yading@10
|
1 /*
|
yading@10
|
2 * Copyright (c) 2001 Fabrice Bellard
|
yading@10
|
3 *
|
yading@10
|
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
|
yading@10
|
5 * of this software and associated documentation files (the "Software"), to deal
|
yading@10
|
6 * in the Software without restriction, including without limitation the rights
|
yading@10
|
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
yading@10
|
8 * copies of the Software, and to permit persons to whom the Software is
|
yading@10
|
9 * furnished to do so, subject to the following conditions:
|
yading@10
|
10 *
|
yading@10
|
11 * The above copyright notice and this permission notice shall be included in
|
yading@10
|
12 * all copies or substantial portions of the Software.
|
yading@10
|
13 *
|
yading@10
|
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
yading@10
|
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
yading@10
|
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
yading@10
|
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
yading@10
|
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
yading@10
|
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
yading@10
|
20 * THE SOFTWARE.
|
yading@10
|
21 */
|
yading@10
|
22
|
yading@10
|
23 /**
|
yading@10
|
24 * @file
|
yading@10
|
25 * libavcodec API use example.
|
yading@10
|
26 *
|
yading@10
|
27 * Note that libavcodec only handles codecs (mpeg, mpeg4, etc...),
|
yading@10
|
28 * not file formats (avi, vob, mp4, mov, mkv, mxf, flv, mpegts, mpegps, etc...). See library 'libavformat' for the
|
yading@10
|
29 * format handling
|
yading@10
|
30 * @example doc/examples/decoding_encoding.c
|
yading@10
|
31 */
|
yading@10
|
32
|
yading@10
|
33 #include <math.h>
|
yading@10
|
34
|
yading@10
|
35 #include <libavutil/opt.h>
|
yading@10
|
36 #include <libavcodec/avcodec.h>
|
yading@10
|
37 #include <libavutil/channel_layout.h>
|
yading@10
|
38 #include <libavutil/common.h>
|
yading@10
|
39 #include <libavutil/imgutils.h>
|
yading@10
|
40 #include <libavutil/mathematics.h>
|
yading@10
|
41 #include <libavutil/samplefmt.h>
|
yading@10
|
42
|
yading@10
|
43 #define INBUF_SIZE 4096
|
yading@10
|
44 #define AUDIO_INBUF_SIZE 20480
|
yading@10
|
45 #define AUDIO_REFILL_THRESH 4096
|
yading@10
|
46
|
yading@10
|
47 /* check that a given sample format is supported by the encoder */
|
yading@10
|
48 static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
|
yading@10
|
49 {
|
yading@10
|
50 const enum AVSampleFormat *p = codec->sample_fmts;
|
yading@10
|
51
|
yading@10
|
52 while (*p != AV_SAMPLE_FMT_NONE) {
|
yading@10
|
53 if (*p == sample_fmt)
|
yading@10
|
54 return 1;
|
yading@10
|
55 p++;
|
yading@10
|
56 }
|
yading@10
|
57 return 0;
|
yading@10
|
58 }
|
yading@10
|
59
|
yading@10
|
60 /* just pick the highest supported samplerate */
|
yading@10
|
61 static int select_sample_rate(AVCodec *codec)
|
yading@10
|
62 {
|
yading@10
|
63 const int *p;
|
yading@10
|
64 int best_samplerate = 0;
|
yading@10
|
65
|
yading@10
|
66 if (!codec->supported_samplerates)
|
yading@10
|
67 return 44100;
|
yading@10
|
68
|
yading@10
|
69 p = codec->supported_samplerates;
|
yading@10
|
70 while (*p) {
|
yading@10
|
71 best_samplerate = FFMAX(*p, best_samplerate);
|
yading@10
|
72 p++;
|
yading@10
|
73 }
|
yading@10
|
74 return best_samplerate;
|
yading@10
|
75 }
|
yading@10
|
76
|
yading@10
|
77 /* select layout with the highest channel count */
|
yading@10
|
78 static int select_channel_layout(AVCodec *codec)
|
yading@10
|
79 {
|
yading@10
|
80 const uint64_t *p;
|
yading@10
|
81 uint64_t best_ch_layout = 0;
|
yading@10
|
82 int best_nb_channels = 0;
|
yading@10
|
83
|
yading@10
|
84 if (!codec->channel_layouts)
|
yading@10
|
85 return AV_CH_LAYOUT_STEREO;
|
yading@10
|
86
|
yading@10
|
87 p = codec->channel_layouts;
|
yading@10
|
88 while (*p) {
|
yading@10
|
89 int nb_channels = av_get_channel_layout_nb_channels(*p);
|
yading@10
|
90
|
yading@10
|
91 if (nb_channels > best_nb_channels) {
|
yading@10
|
92 best_ch_layout = *p;
|
yading@10
|
93 best_nb_channels = nb_channels;
|
yading@10
|
94 }
|
yading@10
|
95 p++;
|
yading@10
|
96 }
|
yading@10
|
97 return best_ch_layout;
|
yading@10
|
98 }
|
yading@10
|
99
|
yading@10
|
100 /*
|
yading@10
|
101 * Audio encoding example
|
yading@10
|
102 */
|
yading@10
|
103 static void audio_encode_example(const char *filename)
|
yading@10
|
104 {
|
yading@10
|
105 AVCodec *codec;
|
yading@10
|
106 AVCodecContext *c= NULL;
|
yading@10
|
107 AVFrame *frame;
|
yading@10
|
108 AVPacket pkt;
|
yading@10
|
109 int i, j, k, ret, got_output;
|
yading@10
|
110 int buffer_size;
|
yading@10
|
111 FILE *f;
|
yading@10
|
112 uint16_t *samples;
|
yading@10
|
113 float t, tincr;
|
yading@10
|
114
|
yading@10
|
115 printf("Encode audio file %s\n", filename);
|
yading@10
|
116
|
yading@10
|
117 /* find the MP2 encoder */
|
yading@10
|
118 codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
|
yading@10
|
119 if (!codec) {
|
yading@10
|
120 fprintf(stderr, "Codec not found\n");
|
yading@10
|
121 exit(1);
|
yading@10
|
122 }
|
yading@10
|
123
|
yading@10
|
124 c = avcodec_alloc_context3(codec);
|
yading@10
|
125 if (!c) {
|
yading@10
|
126 fprintf(stderr, "Could not allocate audio codec context\n");
|
yading@10
|
127 exit(1);
|
yading@10
|
128 }
|
yading@10
|
129
|
yading@10
|
130 /* put sample parameters */
|
yading@10
|
131 c->bit_rate = 64000;
|
yading@10
|
132
|
yading@10
|
133 /* check that the encoder supports s16 pcm input */
|
yading@10
|
134 c->sample_fmt = AV_SAMPLE_FMT_S16;
|
yading@10
|
135 if (!check_sample_fmt(codec, c->sample_fmt)) {
|
yading@10
|
136 fprintf(stderr, "Encoder does not support sample format %s",
|
yading@10
|
137 av_get_sample_fmt_name(c->sample_fmt));
|
yading@10
|
138 exit(1);
|
yading@10
|
139 }
|
yading@10
|
140
|
yading@10
|
141 /* select other audio parameters supported by the encoder */
|
yading@10
|
142 c->sample_rate = select_sample_rate(codec);
|
yading@10
|
143 c->channel_layout = select_channel_layout(codec);
|
yading@10
|
144 c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
|
yading@10
|
145
|
yading@10
|
146 /* open it */
|
yading@10
|
147 if (avcodec_open2(c, codec, NULL) < 0) {
|
yading@10
|
148 fprintf(stderr, "Could not open codec\n");
|
yading@10
|
149 exit(1);
|
yading@10
|
150 }
|
yading@10
|
151
|
yading@10
|
152 f = fopen(filename, "wb");
|
yading@10
|
153 if (!f) {
|
yading@10
|
154 fprintf(stderr, "Could not open %s\n", filename);
|
yading@10
|
155 exit(1);
|
yading@10
|
156 }
|
yading@10
|
157
|
yading@10
|
158 /* frame containing input raw audio */
|
yading@10
|
159 frame = avcodec_alloc_frame();
|
yading@10
|
160 if (!frame) {
|
yading@10
|
161 fprintf(stderr, "Could not allocate audio frame\n");
|
yading@10
|
162 exit(1);
|
yading@10
|
163 }
|
yading@10
|
164
|
yading@10
|
165 frame->nb_samples = c->frame_size;
|
yading@10
|
166 frame->format = c->sample_fmt;
|
yading@10
|
167 frame->channel_layout = c->channel_layout;
|
yading@10
|
168
|
yading@10
|
169 /* the codec gives us the frame size, in samples,
|
yading@10
|
170 * we calculate the size of the samples buffer in bytes */
|
yading@10
|
171 buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
|
yading@10
|
172 c->sample_fmt, 0);
|
yading@10
|
173 samples = av_malloc(buffer_size);
|
yading@10
|
174 if (!samples) {
|
yading@10
|
175 fprintf(stderr, "Could not allocate %d bytes for samples buffer\n",
|
yading@10
|
176 buffer_size);
|
yading@10
|
177 exit(1);
|
yading@10
|
178 }
|
yading@10
|
179 /* setup the data pointers in the AVFrame */
|
yading@10
|
180 ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
|
yading@10
|
181 (const uint8_t*)samples, buffer_size, 0);
|
yading@10
|
182 if (ret < 0) {
|
yading@10
|
183 fprintf(stderr, "Could not setup audio frame\n");
|
yading@10
|
184 exit(1);
|
yading@10
|
185 }
|
yading@10
|
186
|
yading@10
|
187 /* encode a single tone sound */
|
yading@10
|
188 t = 0;
|
yading@10
|
189 tincr = 2 * M_PI * 440.0 / c->sample_rate;
|
yading@10
|
190 for(i=0;i<200;i++) {
|
yading@10
|
191 av_init_packet(&pkt);
|
yading@10
|
192 pkt.data = NULL; // packet data will be allocated by the encoder
|
yading@10
|
193 pkt.size = 0;
|
yading@10
|
194
|
yading@10
|
195 for (j = 0; j < c->frame_size; j++) {
|
yading@10
|
196 samples[2*j] = (int)(sin(t) * 10000);
|
yading@10
|
197
|
yading@10
|
198 for (k = 1; k < c->channels; k++)
|
yading@10
|
199 samples[2*j + k] = samples[2*j];
|
yading@10
|
200 t += tincr;
|
yading@10
|
201 }
|
yading@10
|
202 /* encode the samples */
|
yading@10
|
203 ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
|
yading@10
|
204 if (ret < 0) {
|
yading@10
|
205 fprintf(stderr, "Error encoding audio frame\n");
|
yading@10
|
206 exit(1);
|
yading@10
|
207 }
|
yading@10
|
208 if (got_output) {
|
yading@10
|
209 fwrite(pkt.data, 1, pkt.size, f);
|
yading@10
|
210 av_free_packet(&pkt);
|
yading@10
|
211 }
|
yading@10
|
212 }
|
yading@10
|
213
|
yading@10
|
214 /* get the delayed frames */
|
yading@10
|
215 for (got_output = 1; got_output; i++) {
|
yading@10
|
216 ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output);
|
yading@10
|
217 if (ret < 0) {
|
yading@10
|
218 fprintf(stderr, "Error encoding frame\n");
|
yading@10
|
219 exit(1);
|
yading@10
|
220 }
|
yading@10
|
221
|
yading@10
|
222 if (got_output) {
|
yading@10
|
223 fwrite(pkt.data, 1, pkt.size, f);
|
yading@10
|
224 av_free_packet(&pkt);
|
yading@10
|
225 }
|
yading@10
|
226 }
|
yading@10
|
227 fclose(f);
|
yading@10
|
228
|
yading@10
|
229 av_freep(&samples);
|
yading@10
|
230 avcodec_free_frame(&frame);
|
yading@10
|
231 avcodec_close(c);
|
yading@10
|
232 av_free(c);
|
yading@10
|
233 }
|
yading@10
|
234
|
yading@10
|
235 /*
|
yading@10
|
236 * Audio decoding.
|
yading@10
|
237 */
|
yading@10
|
238 static void audio_decode_example(const char *outfilename, const char *filename)
|
yading@10
|
239 {
|
yading@10
|
240 AVCodec *codec;
|
yading@10
|
241 AVCodecContext *c= NULL;
|
yading@10
|
242 int len;
|
yading@10
|
243 FILE *f, *outfile;
|
yading@10
|
244 uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
|
yading@10
|
245 AVPacket avpkt;
|
yading@10
|
246 AVFrame *decoded_frame = NULL;
|
yading@10
|
247
|
yading@10
|
248 av_init_packet(&avpkt);
|
yading@10
|
249
|
yading@10
|
250 printf("Decode audio file %s to %s\n", filename, outfilename);
|
yading@10
|
251
|
yading@10
|
252 /* find the mpeg audio decoder */
|
yading@10
|
253 codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
|
yading@10
|
254 if (!codec) {
|
yading@10
|
255 fprintf(stderr, "Codec not found\n");
|
yading@10
|
256 exit(1);
|
yading@10
|
257 }
|
yading@10
|
258
|
yading@10
|
259 c = avcodec_alloc_context3(codec);
|
yading@10
|
260 if (!c) {
|
yading@10
|
261 fprintf(stderr, "Could not allocate audio codec context\n");
|
yading@10
|
262 exit(1);
|
yading@10
|
263 }
|
yading@10
|
264
|
yading@10
|
265 /* open it */
|
yading@10
|
266 if (avcodec_open2(c, codec, NULL) < 0) {
|
yading@10
|
267 fprintf(stderr, "Could not open codec\n");
|
yading@10
|
268 exit(1);
|
yading@10
|
269 }
|
yading@10
|
270
|
yading@10
|
271 f = fopen(filename, "rb");
|
yading@10
|
272 if (!f) {
|
yading@10
|
273 fprintf(stderr, "Could not open %s\n", filename);
|
yading@10
|
274 exit(1);
|
yading@10
|
275 }
|
yading@10
|
276 outfile = fopen(outfilename, "wb");
|
yading@10
|
277 if (!outfile) {
|
yading@10
|
278 av_free(c);
|
yading@10
|
279 exit(1);
|
yading@10
|
280 }
|
yading@10
|
281
|
yading@10
|
282 /* decode until eof */
|
yading@10
|
283 avpkt.data = inbuf;
|
yading@10
|
284 avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
|
yading@10
|
285
|
yading@10
|
286 while (avpkt.size > 0) {
|
yading@10
|
287 int got_frame = 0;
|
yading@10
|
288
|
yading@10
|
289 if (!decoded_frame) {
|
yading@10
|
290 if (!(decoded_frame = avcodec_alloc_frame())) {
|
yading@10
|
291 fprintf(stderr, "Could not allocate audio frame\n");
|
yading@10
|
292 exit(1);
|
yading@10
|
293 }
|
yading@10
|
294 } else
|
yading@10
|
295 avcodec_get_frame_defaults(decoded_frame);
|
yading@10
|
296
|
yading@10
|
297 len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
|
yading@10
|
298 if (len < 0) {
|
yading@10
|
299 fprintf(stderr, "Error while decoding\n");
|
yading@10
|
300 exit(1);
|
yading@10
|
301 }
|
yading@10
|
302 if (got_frame) {
|
yading@10
|
303 /* if a frame has been decoded, output it */
|
yading@10
|
304 int data_size = av_samples_get_buffer_size(NULL, c->channels,
|
yading@10
|
305 decoded_frame->nb_samples,
|
yading@10
|
306 c->sample_fmt, 1);
|
yading@10
|
307 fwrite(decoded_frame->data[0], 1, data_size, outfile);
|
yading@10
|
308 }
|
yading@10
|
309 avpkt.size -= len;
|
yading@10
|
310 avpkt.data += len;
|
yading@10
|
311 avpkt.dts =
|
yading@10
|
312 avpkt.pts = AV_NOPTS_VALUE;
|
yading@10
|
313 if (avpkt.size < AUDIO_REFILL_THRESH) {
|
yading@10
|
314 /* Refill the input buffer, to avoid trying to decode
|
yading@10
|
315 * incomplete frames. Instead of this, one could also use
|
yading@10
|
316 * a parser, or use a proper container format through
|
yading@10
|
317 * libavformat. */
|
yading@10
|
318 memmove(inbuf, avpkt.data, avpkt.size);
|
yading@10
|
319 avpkt.data = inbuf;
|
yading@10
|
320 len = fread(avpkt.data + avpkt.size, 1,
|
yading@10
|
321 AUDIO_INBUF_SIZE - avpkt.size, f);
|
yading@10
|
322 if (len > 0)
|
yading@10
|
323 avpkt.size += len;
|
yading@10
|
324 }
|
yading@10
|
325 }
|
yading@10
|
326
|
yading@10
|
327 fclose(outfile);
|
yading@10
|
328 fclose(f);
|
yading@10
|
329
|
yading@10
|
330 avcodec_close(c);
|
yading@10
|
331 av_free(c);
|
yading@10
|
332 avcodec_free_frame(&decoded_frame);
|
yading@10
|
333 }
|
yading@10
|
334
|
yading@10
|
335 /*
|
yading@10
|
336 * Video encoding example
|
yading@10
|
337 */
|
yading@10
|
338 static void video_encode_example(const char *filename, int codec_id)
|
yading@10
|
339 {
|
yading@10
|
340 AVCodec *codec;
|
yading@10
|
341 AVCodecContext *c= NULL;
|
yading@10
|
342 int i, ret, x, y, got_output;
|
yading@10
|
343 FILE *f;
|
yading@10
|
344 AVFrame *frame;
|
yading@10
|
345 AVPacket pkt;
|
yading@10
|
346 uint8_t endcode[] = { 0, 0, 1, 0xb7 };
|
yading@10
|
347
|
yading@10
|
348 printf("Encode video file %s\n", filename);
|
yading@10
|
349
|
yading@10
|
350 /* find the mpeg1 video encoder */
|
yading@10
|
351 codec = avcodec_find_encoder(codec_id);
|
yading@10
|
352 if (!codec) {
|
yading@10
|
353 fprintf(stderr, "Codec not found\n");
|
yading@10
|
354 exit(1);
|
yading@10
|
355 }
|
yading@10
|
356
|
yading@10
|
357 c = avcodec_alloc_context3(codec);
|
yading@10
|
358 if (!c) {
|
yading@10
|
359 fprintf(stderr, "Could not allocate video codec context\n");
|
yading@10
|
360 exit(1);
|
yading@10
|
361 }
|
yading@10
|
362
|
yading@10
|
363 /* put sample parameters */
|
yading@10
|
364 c->bit_rate = 400000;
|
yading@10
|
365 /* resolution must be a multiple of two */
|
yading@10
|
366 c->width = 352;
|
yading@10
|
367 c->height = 288;
|
yading@10
|
368 /* frames per second */
|
yading@10
|
369 c->time_base= (AVRational){1,25};
|
yading@10
|
370 c->gop_size = 10; /* emit one intra frame every ten frames */
|
yading@10
|
371 c->max_b_frames=1;
|
yading@10
|
372 c->pix_fmt = AV_PIX_FMT_YUV420P;
|
yading@10
|
373
|
yading@10
|
374 if(codec_id == AV_CODEC_ID_H264)
|
yading@10
|
375 av_opt_set(c->priv_data, "preset", "slow", 0);
|
yading@10
|
376
|
yading@10
|
377 /* open it */
|
yading@10
|
378 if (avcodec_open2(c, codec, NULL) < 0) {
|
yading@10
|
379 fprintf(stderr, "Could not open codec\n");
|
yading@10
|
380 exit(1);
|
yading@10
|
381 }
|
yading@10
|
382
|
yading@10
|
383 f = fopen(filename, "wb");
|
yading@10
|
384 if (!f) {
|
yading@10
|
385 fprintf(stderr, "Could not open %s\n", filename);
|
yading@10
|
386 exit(1);
|
yading@10
|
387 }
|
yading@10
|
388
|
yading@10
|
389 frame = avcodec_alloc_frame();
|
yading@10
|
390 if (!frame) {
|
yading@10
|
391 fprintf(stderr, "Could not allocate video frame\n");
|
yading@10
|
392 exit(1);
|
yading@10
|
393 }
|
yading@10
|
394 frame->format = c->pix_fmt;
|
yading@10
|
395 frame->width = c->width;
|
yading@10
|
396 frame->height = c->height;
|
yading@10
|
397
|
yading@10
|
398 /* the image can be allocated by any means and av_image_alloc() is
|
yading@10
|
399 * just the most convenient way if av_malloc() is to be used */
|
yading@10
|
400 ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
|
yading@10
|
401 c->pix_fmt, 32);
|
yading@10
|
402 if (ret < 0) {
|
yading@10
|
403 fprintf(stderr, "Could not allocate raw picture buffer\n");
|
yading@10
|
404 exit(1);
|
yading@10
|
405 }
|
yading@10
|
406
|
yading@10
|
407 /* encode 1 second of video */
|
yading@10
|
408 for(i=0;i<25;i++) {
|
yading@10
|
409 av_init_packet(&pkt);
|
yading@10
|
410 pkt.data = NULL; // packet data will be allocated by the encoder
|
yading@10
|
411 pkt.size = 0;
|
yading@10
|
412
|
yading@10
|
413 fflush(stdout);
|
yading@10
|
414 /* prepare a dummy image */
|
yading@10
|
415 /* Y */
|
yading@10
|
416 for(y=0;y<c->height;y++) {
|
yading@10
|
417 for(x=0;x<c->width;x++) {
|
yading@10
|
418 frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
|
yading@10
|
419 }
|
yading@10
|
420 }
|
yading@10
|
421
|
yading@10
|
422 /* Cb and Cr */
|
yading@10
|
423 for(y=0;y<c->height/2;y++) {
|
yading@10
|
424 for(x=0;x<c->width/2;x++) {
|
yading@10
|
425 frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
|
yading@10
|
426 frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
|
yading@10
|
427 }
|
yading@10
|
428 }
|
yading@10
|
429
|
yading@10
|
430 frame->pts = i;
|
yading@10
|
431
|
yading@10
|
432 /* encode the image */
|
yading@10
|
433 ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
|
yading@10
|
434 if (ret < 0) {
|
yading@10
|
435 fprintf(stderr, "Error encoding frame\n");
|
yading@10
|
436 exit(1);
|
yading@10
|
437 }
|
yading@10
|
438
|
yading@10
|
439 if (got_output) {
|
yading@10
|
440 printf("Write frame %3d (size=%5d)\n", i, pkt.size);
|
yading@10
|
441 fwrite(pkt.data, 1, pkt.size, f);
|
yading@10
|
442 av_free_packet(&pkt);
|
yading@10
|
443 }
|
yading@10
|
444 }
|
yading@10
|
445
|
yading@10
|
446 /* get the delayed frames */
|
yading@10
|
447 for (got_output = 1; got_output; i++) {
|
yading@10
|
448 fflush(stdout);
|
yading@10
|
449
|
yading@10
|
450 ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
|
yading@10
|
451 if (ret < 0) {
|
yading@10
|
452 fprintf(stderr, "Error encoding frame\n");
|
yading@10
|
453 exit(1);
|
yading@10
|
454 }
|
yading@10
|
455
|
yading@10
|
456 if (got_output) {
|
yading@10
|
457 printf("Write frame %3d (size=%5d)\n", i, pkt.size);
|
yading@10
|
458 fwrite(pkt.data, 1, pkt.size, f);
|
yading@10
|
459 av_free_packet(&pkt);
|
yading@10
|
460 }
|
yading@10
|
461 }
|
yading@10
|
462
|
yading@10
|
463 /* add sequence end code to have a real mpeg file */
|
yading@10
|
464 fwrite(endcode, 1, sizeof(endcode), f);
|
yading@10
|
465 fclose(f);
|
yading@10
|
466
|
yading@10
|
467 avcodec_close(c);
|
yading@10
|
468 av_free(c);
|
yading@10
|
469 av_freep(&frame->data[0]);
|
yading@10
|
470 avcodec_free_frame(&frame);
|
yading@10
|
471 printf("\n");
|
yading@10
|
472 }
|
yading@10
|
473
|
yading@10
|
474 /*
|
yading@10
|
475 * Video decoding example
|
yading@10
|
476 */
|
yading@10
|
477
|
yading@10
|
478 static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
|
yading@10
|
479 char *filename)
|
yading@10
|
480 {
|
yading@10
|
481 FILE *f;
|
yading@10
|
482 int i;
|
yading@10
|
483
|
yading@10
|
484 f=fopen(filename,"w");
|
yading@10
|
485 fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
|
yading@10
|
486 for(i=0;i<ysize;i++)
|
yading@10
|
487 fwrite(buf + i * wrap,1,xsize,f);
|
yading@10
|
488 fclose(f);
|
yading@10
|
489 }
|
yading@10
|
490
|
yading@10
|
491 static int decode_write_frame(const char *outfilename, AVCodecContext *avctx,
|
yading@10
|
492 AVFrame *frame, int *frame_count, AVPacket *pkt, int last)
|
yading@10
|
493 {
|
yading@10
|
494 int len, got_frame;
|
yading@10
|
495 char buf[1024];
|
yading@10
|
496
|
yading@10
|
497 len = avcodec_decode_video2(avctx, frame, &got_frame, pkt);
|
yading@10
|
498 if (len < 0) {
|
yading@10
|
499 fprintf(stderr, "Error while decoding frame %d\n", *frame_count);
|
yading@10
|
500 return len;
|
yading@10
|
501 }
|
yading@10
|
502 if (got_frame) {
|
yading@10
|
503 printf("Saving %sframe %3d\n", last ? "last " : "", *frame_count);
|
yading@10
|
504 fflush(stdout);
|
yading@10
|
505
|
yading@10
|
506 /* the picture is allocated by the decoder, no need to free it */
|
yading@10
|
507 snprintf(buf, sizeof(buf), outfilename, *frame_count);
|
yading@10
|
508 pgm_save(frame->data[0], frame->linesize[0],
|
yading@10
|
509 avctx->width, avctx->height, buf);
|
yading@10
|
510 (*frame_count)++;
|
yading@10
|
511 }
|
yading@10
|
512 if (pkt->data) {
|
yading@10
|
513 pkt->size -= len;
|
yading@10
|
514 pkt->data += len;
|
yading@10
|
515 }
|
yading@10
|
516 return 0;
|
yading@10
|
517 }
|
yading@10
|
518
|
yading@10
|
519 static void video_decode_example(const char *outfilename, const char *filename)
|
yading@10
|
520 {
|
yading@10
|
521 AVCodec *codec;
|
yading@10
|
522 AVCodecContext *c= NULL;
|
yading@10
|
523 int frame_count;
|
yading@10
|
524 FILE *f;
|
yading@10
|
525 AVFrame *frame;
|
yading@10
|
526 uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
|
yading@10
|
527 AVPacket avpkt;
|
yading@10
|
528
|
yading@10
|
529 av_init_packet(&avpkt);
|
yading@10
|
530
|
yading@10
|
531 /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
|
yading@10
|
532 memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
yading@10
|
533
|
yading@10
|
534 printf("Decode video file %s to %s\n", filename, outfilename);
|
yading@10
|
535
|
yading@10
|
536 /* find the mpeg1 video decoder */
|
yading@10
|
537 codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
|
yading@10
|
538 if (!codec) {
|
yading@10
|
539 fprintf(stderr, "Codec not found\n");
|
yading@10
|
540 exit(1);
|
yading@10
|
541 }
|
yading@10
|
542
|
yading@10
|
543 c = avcodec_alloc_context3(codec);
|
yading@10
|
544 if (!c) {
|
yading@10
|
545 fprintf(stderr, "Could not allocate video codec context\n");
|
yading@10
|
546 exit(1);
|
yading@10
|
547 }
|
yading@10
|
548
|
yading@10
|
549 if(codec->capabilities&CODEC_CAP_TRUNCATED)
|
yading@10
|
550 c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
|
yading@10
|
551
|
yading@10
|
552 /* For some codecs, such as msmpeg4 and mpeg4, width and height
|
yading@10
|
553 MUST be initialized there because this information is not
|
yading@10
|
554 available in the bitstream. */
|
yading@10
|
555
|
yading@10
|
556 /* open it */
|
yading@10
|
557 if (avcodec_open2(c, codec, NULL) < 0) {
|
yading@10
|
558 fprintf(stderr, "Could not open codec\n");
|
yading@10
|
559 exit(1);
|
yading@10
|
560 }
|
yading@10
|
561
|
yading@10
|
562 f = fopen(filename, "rb");
|
yading@10
|
563 if (!f) {
|
yading@10
|
564 fprintf(stderr, "Could not open %s\n", filename);
|
yading@10
|
565 exit(1);
|
yading@10
|
566 }
|
yading@10
|
567
|
yading@10
|
568 frame = avcodec_alloc_frame();
|
yading@10
|
569 if (!frame) {
|
yading@10
|
570 fprintf(stderr, "Could not allocate video frame\n");
|
yading@10
|
571 exit(1);
|
yading@10
|
572 }
|
yading@10
|
573
|
yading@10
|
574 frame_count = 0;
|
yading@10
|
575 for(;;) {
|
yading@10
|
576 avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
|
yading@10
|
577 if (avpkt.size == 0)
|
yading@10
|
578 break;
|
yading@10
|
579
|
yading@10
|
580 /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
|
yading@10
|
581 and this is the only method to use them because you cannot
|
yading@10
|
582 know the compressed data size before analysing it.
|
yading@10
|
583
|
yading@10
|
584 BUT some other codecs (msmpeg4, mpeg4) are inherently frame
|
yading@10
|
585 based, so you must call them with all the data for one
|
yading@10
|
586 frame exactly. You must also initialize 'width' and
|
yading@10
|
587 'height' before initializing them. */
|
yading@10
|
588
|
yading@10
|
589 /* NOTE2: some codecs allow the raw parameters (frame size,
|
yading@10
|
590 sample rate) to be changed at any frame. We handle this, so
|
yading@10
|
591 you should also take care of it */
|
yading@10
|
592
|
yading@10
|
593 /* here, we use a stream based decoder (mpeg1video), so we
|
yading@10
|
594 feed decoder and see if it could decode a frame */
|
yading@10
|
595 avpkt.data = inbuf;
|
yading@10
|
596 while (avpkt.size > 0)
|
yading@10
|
597 if (decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 0) < 0)
|
yading@10
|
598 exit(1);
|
yading@10
|
599 }
|
yading@10
|
600
|
yading@10
|
601 /* some codecs, such as MPEG, transmit the I and P frame with a
|
yading@10
|
602 latency of one frame. You must do the following to have a
|
yading@10
|
603 chance to get the last frame of the video */
|
yading@10
|
604 avpkt.data = NULL;
|
yading@10
|
605 avpkt.size = 0;
|
yading@10
|
606 decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 1);
|
yading@10
|
607
|
yading@10
|
608 fclose(f);
|
yading@10
|
609
|
yading@10
|
610 avcodec_close(c);
|
yading@10
|
611 av_free(c);
|
yading@10
|
612 avcodec_free_frame(&frame);
|
yading@10
|
613 printf("\n");
|
yading@10
|
614 }
|
yading@10
|
615
|
yading@10
|
616 int main(int argc, char **argv)
|
yading@10
|
617 {
|
yading@10
|
618 const char *output_type;
|
yading@10
|
619
|
yading@10
|
620 /* register all the codecs */
|
yading@10
|
621 avcodec_register_all();
|
yading@10
|
622
|
yading@10
|
623 if (argc < 2) {
|
yading@10
|
624 printf("usage: %s output_type\n"
|
yading@10
|
625 "API example program to decode/encode a media stream with libavcodec.\n"
|
yading@10
|
626 "This program generates a synthetic stream and encodes it to a file\n"
|
yading@10
|
627 "named test.h264, test.mp2 or test.mpg depending on output_type.\n"
|
yading@10
|
628 "The encoded stream is then decoded and written to a raw data output.\n"
|
yading@10
|
629 "output_type must be choosen between 'h264', 'mp2', 'mpg'.\n",
|
yading@10
|
630 argv[0]);
|
yading@10
|
631 return 1;
|
yading@10
|
632 }
|
yading@10
|
633 output_type = argv[1];
|
yading@10
|
634
|
yading@10
|
635 if (!strcmp(output_type, "h264")) {
|
yading@10
|
636 video_encode_example("test.h264", AV_CODEC_ID_H264);
|
yading@10
|
637 } else if (!strcmp(output_type, "mp2")) {
|
yading@10
|
638 audio_encode_example("test.mp2");
|
yading@10
|
639 audio_decode_example("test.sw", "test.mp2");
|
yading@10
|
640 } else if (!strcmp(output_type, "mpg")) {
|
yading@10
|
641 video_encode_example("test.mpg", AV_CODEC_ID_MPEG1VIDEO);
|
yading@10
|
642 video_decode_example("test%02d.pgm", "test.mpg");
|
yading@10
|
643 } else {
|
yading@10
|
644 fprintf(stderr, "Invalid output type '%s', choose between 'h264', 'mp2', or 'mpg'\n",
|
yading@10
|
645 output_type);
|
yading@10
|
646 return 1;
|
yading@10
|
647 }
|
yading@10
|
648
|
yading@10
|
649 return 0;
|
yading@10
|
650 }
|