00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00032 #include <math.h>
00033
00034 #include <libavutil/imgutils.h>
00035 #include <libavutil/opt.h>
00036 #include <libavcodec/avcodec.h>
00037 #include <libavutil/mathematics.h>
00038 #include <libavutil/samplefmt.h>
00039
00040 #define INBUF_SIZE 4096
00041 #define AUDIO_INBUF_SIZE 20480
00042 #define AUDIO_REFILL_THRESH 4096
00043
00044
00045
00046
00047 static void audio_encode_example(const char *filename)
00048 {
00049 AVCodec *codec;
00050 AVCodecContext *c= NULL;
00051 int frame_size, i, j, out_size, outbuf_size;
00052 FILE *f;
00053 short *samples;
00054 float t, tincr;
00055 uint8_t *outbuf;
00056
00057 printf("Encode audio file %s\n", filename);
00058
00059
00060 codec = avcodec_find_encoder(CODEC_ID_MP2);
00061 if (!codec) {
00062 fprintf(stderr, "codec not found\n");
00063 exit(1);
00064 }
00065
00066 c = avcodec_alloc_context3(codec);
00067
00068
00069 c->bit_rate = 64000;
00070 c->sample_rate = 44100;
00071 c->channels = 2;
00072 c->sample_fmt = AV_SAMPLE_FMT_S16;
00073
00074
00075 if (avcodec_open2(c, codec, NULL) < 0) {
00076 fprintf(stderr, "could not open codec\n");
00077 exit(1);
00078 }
00079
00080
00081 frame_size = c->frame_size;
00082 samples = malloc(frame_size * 2 * c->channels);
00083 outbuf_size = 10000;
00084 outbuf = malloc(outbuf_size);
00085
00086 f = fopen(filename, "wb");
00087 if (!f) {
00088 fprintf(stderr, "could not open %s\n", filename);
00089 exit(1);
00090 }
00091
00092
00093 t = 0;
00094 tincr = 2 * M_PI * 440.0 / c->sample_rate;
00095 for(i=0;i<200;i++) {
00096 for(j=0;j<frame_size;j++) {
00097 samples[2*j] = (int)(sin(t) * 10000);
00098 samples[2*j+1] = samples[2*j];
00099 t += tincr;
00100 }
00101
00102 out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
00103 fwrite(outbuf, 1, out_size, f);
00104 }
00105 fclose(f);
00106 free(outbuf);
00107 free(samples);
00108
00109 avcodec_close(c);
00110 av_free(c);
00111 }
00112
00113
00114
00115
00116 static void audio_decode_example(const char *outfilename, const char *filename)
00117 {
00118 AVCodec *codec;
00119 AVCodecContext *c= NULL;
00120 int len;
00121 FILE *f, *outfile;
00122 uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
00123 AVPacket avpkt;
00124 AVFrame *decoded_frame = NULL;
00125
00126 av_init_packet(&avpkt);
00127
00128 printf("Decode audio file %s\n", filename);
00129
00130
00131 codec = avcodec_find_decoder(CODEC_ID_MP2);
00132 if (!codec) {
00133 fprintf(stderr, "codec not found\n");
00134 exit(1);
00135 }
00136
00137 c = avcodec_alloc_context3(codec);
00138
00139
00140 if (avcodec_open2(c, codec, NULL) < 0) {
00141 fprintf(stderr, "could not open codec\n");
00142 exit(1);
00143 }
00144
00145 f = fopen(filename, "rb");
00146 if (!f) {
00147 fprintf(stderr, "could not open %s\n", filename);
00148 exit(1);
00149 }
00150 outfile = fopen(outfilename, "wb");
00151 if (!outfile) {
00152 av_free(c);
00153 exit(1);
00154 }
00155
00156
00157 avpkt.data = inbuf;
00158 avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
00159
00160 while (avpkt.size > 0) {
00161 int got_frame = 0;
00162
00163 if (!decoded_frame) {
00164 if (!(decoded_frame = avcodec_alloc_frame())) {
00165 fprintf(stderr, "out of memory\n");
00166 exit(1);
00167 }
00168 } else
00169 avcodec_get_frame_defaults(decoded_frame);
00170
00171 len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
00172 if (len < 0) {
00173 fprintf(stderr, "Error while decoding\n");
00174 exit(1);
00175 }
00176 if (got_frame) {
00177
00178 int data_size = av_samples_get_buffer_size(NULL, c->channels,
00179 decoded_frame->nb_samples,
00180 c->sample_fmt, 1);
00181 fwrite(decoded_frame->data[0], 1, data_size, outfile);
00182 }
00183 avpkt.size -= len;
00184 avpkt.data += len;
00185 avpkt.dts =
00186 avpkt.pts = AV_NOPTS_VALUE;
00187 if (avpkt.size < AUDIO_REFILL_THRESH) {
00188
00189
00190
00191
00192 memmove(inbuf, avpkt.data, avpkt.size);
00193 avpkt.data = inbuf;
00194 len = fread(avpkt.data + avpkt.size, 1,
00195 AUDIO_INBUF_SIZE - avpkt.size, f);
00196 if (len > 0)
00197 avpkt.size += len;
00198 }
00199 }
00200
00201 fclose(outfile);
00202 fclose(f);
00203
00204 avcodec_close(c);
00205 av_free(c);
00206 av_free(decoded_frame);
00207 }
00208
00209
00210
00211
00212 static void video_encode_example(const char *filename, int codec_id)
00213 {
00214 AVCodec *codec;
00215 AVCodecContext *c= NULL;
00216 int i, out_size, x, y, outbuf_size;
00217 FILE *f;
00218 AVFrame *picture;
00219 uint8_t *outbuf;
00220 int had_output=0;
00221
00222 printf("Encode video file %s\n", filename);
00223
00224
00225 codec = avcodec_find_encoder(codec_id);
00226 if (!codec) {
00227 fprintf(stderr, "codec not found\n");
00228 exit(1);
00229 }
00230
00231 c = avcodec_alloc_context3(codec);
00232 picture= avcodec_alloc_frame();
00233
00234
00235 c->bit_rate = 400000;
00236
00237 c->width = 352;
00238 c->height = 288;
00239
00240 c->time_base= (AVRational){1,25};
00241 c->gop_size = 10;
00242 c->max_b_frames=1;
00243 c->pix_fmt = PIX_FMT_YUV420P;
00244
00245 if(codec_id == CODEC_ID_H264)
00246 av_opt_set(c->priv_data, "preset", "slow", 0);
00247
00248
00249 if (avcodec_open2(c, codec, NULL) < 0) {
00250 fprintf(stderr, "could not open codec\n");
00251 exit(1);
00252 }
00253
00254 f = fopen(filename, "wb");
00255 if (!f) {
00256 fprintf(stderr, "could not open %s\n", filename);
00257 exit(1);
00258 }
00259
00260
00261 outbuf_size = 100000 + 12*c->width*c->height;
00262 outbuf = malloc(outbuf_size);
00263
00264
00265
00266 av_image_alloc(picture->data, picture->linesize,
00267 c->width, c->height, c->pix_fmt, 1);
00268
00269
00270 for(i=0;i<25;i++) {
00271 fflush(stdout);
00272
00273
00274 for(y=0;y<c->height;y++) {
00275 for(x=0;x<c->width;x++) {
00276 picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
00277 }
00278 }
00279
00280
00281 for(y=0;y<c->height/2;y++) {
00282 for(x=0;x<c->width/2;x++) {
00283 picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
00284 picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
00285 }
00286 }
00287
00288
00289 out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
00290 had_output |= out_size;
00291 printf("encoding frame %3d (size=%5d)\n", i, out_size);
00292 fwrite(outbuf, 1, out_size, f);
00293 }
00294
00295
00296 for(; out_size || !had_output; i++) {
00297 fflush(stdout);
00298
00299 out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
00300 had_output |= out_size;
00301 printf("write frame %3d (size=%5d)\n", i, out_size);
00302 fwrite(outbuf, 1, out_size, f);
00303 }
00304
00305
00306 outbuf[0] = 0x00;
00307 outbuf[1] = 0x00;
00308 outbuf[2] = 0x01;
00309 outbuf[3] = 0xb7;
00310 fwrite(outbuf, 1, 4, f);
00311 fclose(f);
00312 free(outbuf);
00313
00314 avcodec_close(c);
00315 av_free(c);
00316 av_free(picture->data[0]);
00317 av_free(picture);
00318 printf("\n");
00319 }
00320
00321
00322
00323
00324
00325 static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
00326 char *filename)
00327 {
00328 FILE *f;
00329 int i;
00330
00331 f=fopen(filename,"w");
00332 fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
00333 for(i=0;i<ysize;i++)
00334 fwrite(buf + i * wrap,1,xsize,f);
00335 fclose(f);
00336 }
00337
00338 static void video_decode_example(const char *outfilename, const char *filename)
00339 {
00340 AVCodec *codec;
00341 AVCodecContext *c= NULL;
00342 int frame, got_picture, len;
00343 FILE *f;
00344 AVFrame *picture;
00345 uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
00346 char buf[1024];
00347 AVPacket avpkt;
00348
00349 av_init_packet(&avpkt);
00350
00351
00352 memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
00353
00354 printf("Decode video file %s\n", filename);
00355
00356
00357 codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
00358 if (!codec) {
00359 fprintf(stderr, "codec not found\n");
00360 exit(1);
00361 }
00362
00363 c = avcodec_alloc_context3(codec);
00364 picture= avcodec_alloc_frame();
00365
00366 if(codec->capabilities&CODEC_CAP_TRUNCATED)
00367 c->flags|= CODEC_FLAG_TRUNCATED;
00368
00369
00370
00371
00372
00373
00374 if (avcodec_open2(c, codec, NULL) < 0) {
00375 fprintf(stderr, "could not open codec\n");
00376 exit(1);
00377 }
00378
00379
00380
00381 f = fopen(filename, "rb");
00382 if (!f) {
00383 fprintf(stderr, "could not open %s\n", filename);
00384 exit(1);
00385 }
00386
00387 frame = 0;
00388 for(;;) {
00389 avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
00390 if (avpkt.size == 0)
00391 break;
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 avpkt.data = inbuf;
00409 while (avpkt.size > 0) {
00410 len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
00411 if (len < 0) {
00412 fprintf(stderr, "Error while decoding frame %d\n", frame);
00413 exit(1);
00414 }
00415 if (got_picture) {
00416 printf("saving frame %3d\n", frame);
00417 fflush(stdout);
00418
00419
00420
00421 snprintf(buf, sizeof(buf), outfilename, frame);
00422 pgm_save(picture->data[0], picture->linesize[0],
00423 c->width, c->height, buf);
00424 frame++;
00425 }
00426 avpkt.size -= len;
00427 avpkt.data += len;
00428 }
00429 }
00430
00431
00432
00433
00434 avpkt.data = NULL;
00435 avpkt.size = 0;
00436 len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
00437 if (got_picture) {
00438 printf("saving last frame %3d\n", frame);
00439 fflush(stdout);
00440
00441
00442
00443 snprintf(buf, sizeof(buf), outfilename, frame);
00444 pgm_save(picture->data[0], picture->linesize[0],
00445 c->width, c->height, buf);
00446 frame++;
00447 }
00448
00449 fclose(f);
00450
00451 avcodec_close(c);
00452 av_free(c);
00453 av_free(picture);
00454 printf("\n");
00455 }
00456
00457 int main(int argc, char **argv)
00458 {
00459 const char *filename;
00460
00461
00462 avcodec_register_all();
00463
00464 if (argc <= 1) {
00465 audio_encode_example("/tmp/test.mp2");
00466 audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
00467
00468 video_encode_example("/tmp/test.h264", CODEC_ID_H264);
00469 video_encode_example("/tmp/test.mpg", CODEC_ID_MPEG1VIDEO);
00470 filename = "/tmp/test.mpg";
00471 } else {
00472 filename = argv[1];
00473 }
00474
00475
00476 video_decode_example("/tmp/test%d.pgm", filename);
00477
00478 return 0;
00479 }