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/opt.h>
00035 #include <libavcodec/avcodec.h>
00036 #include <libavutil/audioconvert.h>
00037 #include <libavutil/common.h>
00038 #include <libavutil/imgutils.h>
00039 #include <libavutil/mathematics.h>
00040 #include <libavutil/samplefmt.h>
00041
00042 #define INBUF_SIZE 4096
00043 #define AUDIO_INBUF_SIZE 20480
00044 #define AUDIO_REFILL_THRESH 4096
00045
00046
00047 static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
00048 {
00049 const enum AVSampleFormat *p = codec->sample_fmts;
00050
00051 while (*p != AV_SAMPLE_FMT_NONE) {
00052 if (*p == sample_fmt)
00053 return 1;
00054 p++;
00055 }
00056 return 0;
00057 }
00058
00059
00060 static int select_sample_rate(AVCodec *codec)
00061 {
00062 const int *p;
00063 int best_samplerate = 0;
00064
00065 if (!codec->supported_samplerates)
00066 return 44100;
00067
00068 p = codec->supported_samplerates;
00069 while (*p) {
00070 best_samplerate = FFMAX(*p, best_samplerate);
00071 p++;
00072 }
00073 return best_samplerate;
00074 }
00075
00076
00077 static int select_channel_layout(AVCodec *codec)
00078 {
00079 const uint64_t *p;
00080 uint64_t best_ch_layout = 0;
00081 int best_nb_channells = 0;
00082
00083 if (!codec->channel_layouts)
00084 return AV_CH_LAYOUT_STEREO;
00085
00086 p = codec->channel_layouts;
00087 while (*p) {
00088 int nb_channels = av_get_channel_layout_nb_channels(*p);
00089
00090 if (nb_channels > best_nb_channells) {
00091 best_ch_layout = *p;
00092 best_nb_channells = nb_channels;
00093 }
00094 p++;
00095 }
00096 return best_ch_layout;
00097 }
00098
00099
00100
00101
00102 static void audio_encode_example(const char *filename)
00103 {
00104 AVCodec *codec;
00105 AVCodecContext *c= NULL;
00106 AVFrame *frame;
00107 AVPacket pkt;
00108 int i, j, k, ret, got_output;
00109 int buffer_size;
00110 FILE *f;
00111 uint16_t *samples;
00112 float t, tincr;
00113
00114 printf("Encode audio file %s\n", filename);
00115
00116
00117 codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
00118 if (!codec) {
00119 fprintf(stderr, "Codec not found\n");
00120 exit(1);
00121 }
00122
00123 c = avcodec_alloc_context3(codec);
00124
00125
00126 c->bit_rate = 64000;
00127
00128
00129 c->sample_fmt = AV_SAMPLE_FMT_S16;
00130 if (!check_sample_fmt(codec, c->sample_fmt)) {
00131 fprintf(stderr, "Encoder does not support sample format %s",
00132 av_get_sample_fmt_name(c->sample_fmt));
00133 exit(1);
00134 }
00135
00136
00137 c->sample_rate = select_sample_rate(codec);
00138 c->channel_layout = select_channel_layout(codec);
00139 c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
00140
00141
00142 if (avcodec_open2(c, codec, NULL) < 0) {
00143 fprintf(stderr, "Could not open codec\n");
00144 exit(1);
00145 }
00146
00147 f = fopen(filename, "wb");
00148 if (!f) {
00149 fprintf(stderr, "Could not open %s\n", filename);
00150 exit(1);
00151 }
00152
00153
00154 frame = avcodec_alloc_frame();
00155 if (!frame) {
00156 fprintf(stderr, "Could not allocate audio frame\n");
00157 exit(1);
00158 }
00159
00160 frame->nb_samples = c->frame_size;
00161 frame->format = c->sample_fmt;
00162 frame->channel_layout = c->channel_layout;
00163
00164
00165
00166 buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
00167 c->sample_fmt, 0);
00168 samples = av_malloc(buffer_size);
00169 if (!samples) {
00170 fprintf(stderr, "Could not allocate %d bytes for samples buffer\n",
00171 buffer_size);
00172 exit(1);
00173 }
00174
00175 ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
00176 (const uint8_t*)samples, buffer_size, 0);
00177 if (ret < 0) {
00178 fprintf(stderr, "Could not setup audio frame\n");
00179 exit(1);
00180 }
00181
00182
00183 t = 0;
00184 tincr = 2 * M_PI * 440.0 / c->sample_rate;
00185 for(i=0;i<200;i++) {
00186 av_init_packet(&pkt);
00187 pkt.data = NULL;
00188 pkt.size = 0;
00189
00190 for (j = 0; j < c->frame_size; j++) {
00191 samples[2*j] = (int)(sin(t) * 10000);
00192
00193 for (k = 1; k < c->channels; k++)
00194 samples[2*j + k] = samples[2*j];
00195 t += tincr;
00196 }
00197
00198 ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
00199 if (ret < 0) {
00200 fprintf(stderr, "Error encoding audio frame\n");
00201 exit(1);
00202 }
00203 if (got_output) {
00204 fwrite(pkt.data, 1, pkt.size, f);
00205 av_free_packet(&pkt);
00206 }
00207 }
00208
00209
00210 for (got_output = 1; got_output; i++) {
00211 ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output);
00212 if (ret < 0) {
00213 fprintf(stderr, "Error encoding frame\n");
00214 exit(1);
00215 }
00216
00217 if (got_output) {
00218 fwrite(pkt.data, 1, pkt.size, f);
00219 av_free_packet(&pkt);
00220 }
00221 }
00222 fclose(f);
00223
00224 av_freep(&samples);
00225 avcodec_free_frame(&frame);
00226 avcodec_close(c);
00227 av_free(c);
00228 }
00229
00230
00231
00232
00233 static void audio_decode_example(const char *outfilename, const char *filename)
00234 {
00235 AVCodec *codec;
00236 AVCodecContext *c= NULL;
00237 int len;
00238 FILE *f, *outfile;
00239 uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
00240 AVPacket avpkt;
00241 AVFrame *decoded_frame = NULL;
00242
00243 av_init_packet(&avpkt);
00244
00245 printf("Decode audio file %s to %s\n", filename, outfilename);
00246
00247
00248 codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
00249 if (!codec) {
00250 fprintf(stderr, "Codec not found\n");
00251 exit(1);
00252 }
00253
00254 c = avcodec_alloc_context3(codec);
00255
00256
00257 if (avcodec_open2(c, codec, NULL) < 0) {
00258 fprintf(stderr, "Could not open codec\n");
00259 exit(1);
00260 }
00261
00262 f = fopen(filename, "rb");
00263 if (!f) {
00264 fprintf(stderr, "Could not open %s\n", filename);
00265 exit(1);
00266 }
00267 outfile = fopen(outfilename, "wb");
00268 if (!outfile) {
00269 av_free(c);
00270 exit(1);
00271 }
00272
00273
00274 avpkt.data = inbuf;
00275 avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
00276
00277 while (avpkt.size > 0) {
00278 int got_frame = 0;
00279
00280 if (!decoded_frame) {
00281 if (!(decoded_frame = avcodec_alloc_frame())) {
00282 fprintf(stderr, "Could not allocate audio frame\n");
00283 exit(1);
00284 }
00285 } else
00286 avcodec_get_frame_defaults(decoded_frame);
00287
00288 len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
00289 if (len < 0) {
00290 fprintf(stderr, "Error while decoding\n");
00291 exit(1);
00292 }
00293 if (got_frame) {
00294
00295 int data_size = av_samples_get_buffer_size(NULL, c->channels,
00296 decoded_frame->nb_samples,
00297 c->sample_fmt, 1);
00298 fwrite(decoded_frame->data[0], 1, data_size, outfile);
00299 }
00300 avpkt.size -= len;
00301 avpkt.data += len;
00302 avpkt.dts =
00303 avpkt.pts = AV_NOPTS_VALUE;
00304 if (avpkt.size < AUDIO_REFILL_THRESH) {
00305
00306
00307
00308
00309 memmove(inbuf, avpkt.data, avpkt.size);
00310 avpkt.data = inbuf;
00311 len = fread(avpkt.data + avpkt.size, 1,
00312 AUDIO_INBUF_SIZE - avpkt.size, f);
00313 if (len > 0)
00314 avpkt.size += len;
00315 }
00316 }
00317
00318 fclose(outfile);
00319 fclose(f);
00320
00321 avcodec_close(c);
00322 av_free(c);
00323 avcodec_free_frame(&decoded_frame);
00324 }
00325
00326
00327
00328
00329 static void video_encode_example(const char *filename, int codec_id)
00330 {
00331 AVCodec *codec;
00332 AVCodecContext *c= NULL;
00333 int i, ret, x, y, got_output;
00334 FILE *f;
00335 AVFrame *frame;
00336 AVPacket pkt;
00337 uint8_t endcode[] = { 0, 0, 1, 0xb7 };
00338
00339 printf("Encode video file %s\n", filename);
00340
00341
00342 codec = avcodec_find_encoder(codec_id);
00343 if (!codec) {
00344 fprintf(stderr, "Codec not found\n");
00345 exit(1);
00346 }
00347
00348 c = avcodec_alloc_context3(codec);
00349
00350
00351 c->bit_rate = 400000;
00352
00353 c->width = 352;
00354 c->height = 288;
00355
00356 c->time_base= (AVRational){1,25};
00357 c->gop_size = 10;
00358 c->max_b_frames=1;
00359 c->pix_fmt = PIX_FMT_YUV420P;
00360
00361 if(codec_id == AV_CODEC_ID_H264)
00362 av_opt_set(c->priv_data, "preset", "slow", 0);
00363
00364
00365 if (avcodec_open2(c, codec, NULL) < 0) {
00366 fprintf(stderr, "Could not open codec\n");
00367 exit(1);
00368 }
00369
00370 f = fopen(filename, "wb");
00371 if (!f) {
00372 fprintf(stderr, "Could not open %s\n", filename);
00373 exit(1);
00374 }
00375
00376 frame = avcodec_alloc_frame();
00377 if (!frame) {
00378 fprintf(stderr, "Could not allocate video frame\n");
00379 exit(1);
00380 }
00381 frame->format = c->pix_fmt;
00382 frame->width = c->width;
00383 frame->height = c->height;
00384
00385
00386
00387 ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
00388 c->pix_fmt, 32);
00389 if (ret < 0) {
00390 fprintf(stderr, "Could not allocate raw picture buffer\n");
00391 exit(1);
00392 }
00393
00394
00395 for(i=0;i<25;i++) {
00396 av_init_packet(&pkt);
00397 pkt.data = NULL;
00398 pkt.size = 0;
00399
00400 fflush(stdout);
00401
00402
00403 for(y=0;y<c->height;y++) {
00404 for(x=0;x<c->width;x++) {
00405 frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
00406 }
00407 }
00408
00409
00410 for(y=0;y<c->height/2;y++) {
00411 for(x=0;x<c->width/2;x++) {
00412 frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
00413 frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
00414 }
00415 }
00416
00417 frame->pts = i;
00418
00419
00420 ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
00421 if (ret < 0) {
00422 fprintf(stderr, "Error encoding frame\n");
00423 exit(1);
00424 }
00425
00426 if (got_output) {
00427 printf("Write frame %3d (size=%5d)\n", i, pkt.size);
00428 fwrite(pkt.data, 1, pkt.size, f);
00429 av_free_packet(&pkt);
00430 }
00431 }
00432
00433
00434 for (got_output = 1; got_output; i++) {
00435 fflush(stdout);
00436
00437 ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
00438 if (ret < 0) {
00439 fprintf(stderr, "Error encoding frame\n");
00440 exit(1);
00441 }
00442
00443 if (got_output) {
00444 printf("Write frame %3d (size=%5d)\n", i, pkt.size);
00445 fwrite(pkt.data, 1, pkt.size, f);
00446 av_free_packet(&pkt);
00447 }
00448 }
00449
00450
00451 fwrite(endcode, 1, sizeof(endcode), f);
00452 fclose(f);
00453
00454 avcodec_close(c);
00455 av_free(c);
00456 av_freep(&frame->data[0]);
00457 avcodec_free_frame(&frame);
00458 printf("\n");
00459 }
00460
00461
00462
00463
00464
00465 static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
00466 char *filename)
00467 {
00468 FILE *f;
00469 int i;
00470
00471 f=fopen(filename,"w");
00472 fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
00473 for(i=0;i<ysize;i++)
00474 fwrite(buf + i * wrap,1,xsize,f);
00475 fclose(f);
00476 }
00477
00478 static void video_decode_example(const char *outfilename, const char *filename)
00479 {
00480 AVCodec *codec;
00481 AVCodecContext *c= NULL;
00482 int frame, got_picture, len;
00483 FILE *f;
00484 AVFrame *picture;
00485 uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
00486 char buf[1024];
00487 AVPacket avpkt;
00488
00489 av_init_packet(&avpkt);
00490
00491
00492 memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
00493
00494 printf("Decode video file %s to %s\n", filename, outfilename);
00495
00496
00497 codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
00498 if (!codec) {
00499 fprintf(stderr, "Codec not found\n");
00500 exit(1);
00501 }
00502
00503 c = avcodec_alloc_context3(codec);
00504 if(codec->capabilities&CODEC_CAP_TRUNCATED)
00505 c->flags|= CODEC_FLAG_TRUNCATED;
00506
00507
00508
00509
00510
00511
00512 if (avcodec_open2(c, codec, NULL) < 0) {
00513 fprintf(stderr, "Could not open codec\n");
00514 exit(1);
00515 }
00516
00517
00518
00519 f = fopen(filename, "rb");
00520 if (!f) {
00521 fprintf(stderr, "Could not open %s\n", filename);
00522 exit(1);
00523 }
00524
00525 picture = avcodec_alloc_frame();
00526 if (!picture) {
00527 fprintf(stderr, "Could not allocate video frame\n");
00528 exit(1);
00529 }
00530
00531 frame = 0;
00532 for(;;) {
00533 avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
00534 if (avpkt.size == 0)
00535 break;
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 avpkt.data = inbuf;
00553 while (avpkt.size > 0) {
00554 len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
00555 if (len < 0) {
00556 fprintf(stderr, "Error while decoding frame %d\n", frame);
00557 exit(1);
00558 }
00559 if (got_picture) {
00560 printf("Saving frame %3d\n", frame);
00561 fflush(stdout);
00562
00563
00564
00565 snprintf(buf, sizeof(buf), outfilename, frame);
00566 pgm_save(picture->data[0], picture->linesize[0],
00567 c->width, c->height, buf);
00568 frame++;
00569 }
00570 avpkt.size -= len;
00571 avpkt.data += len;
00572 }
00573 }
00574
00575
00576
00577
00578 avpkt.data = NULL;
00579 avpkt.size = 0;
00580 len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
00581 if (got_picture) {
00582 printf("Saving last frame %3d\n", frame);
00583 fflush(stdout);
00584
00585
00586
00587 snprintf(buf, sizeof(buf), outfilename, frame);
00588 pgm_save(picture->data[0], picture->linesize[0],
00589 c->width, c->height, buf);
00590 frame++;
00591 }
00592
00593 fclose(f);
00594
00595 avcodec_close(c);
00596 av_free(c);
00597 avcodec_free_frame(&picture);
00598 printf("\n");
00599 }
00600
00601 int main(int argc, char **argv)
00602 {
00603 const char *output_type;
00604
00605
00606 avcodec_register_all();
00607
00608 if (argc < 2) {
00609 printf("usage: %s output_type\n"
00610 "API example program to decode/encode a media stream with libavcodec.\n"
00611 "This program generates a synthetic stream and encodes it to a file\n"
00612 "named test.h264, test.mp2 or test.mpg depending on output_type.\n"
00613 "The encoded stream is then decoded and written to a raw data output\n."
00614 "output_type must be choosen between 'h264', 'mp2', 'mpg'\n",
00615 argv[0]);
00616 return 1;
00617 }
00618 output_type = argv[1];
00619
00620 if (!strcmp(output_type, "h264")) {
00621 video_encode_example("test.h264", AV_CODEC_ID_H264);
00622 } else if (!strcmp(output_type, "mp2")) {
00623 audio_encode_example("test.mp2");
00624 audio_decode_example("test.sw", "test.mp2");
00625 } else if (!strcmp(output_type, "mpg")) {
00626 video_encode_example("test.mpg", AV_CODEC_ID_MPEG1VIDEO);
00627 video_decode_example("test%02d.pgm", "test.mpg");
00628 } else {
00629 fprintf(stderr, "Invalid output type '%s', choose between 'h264', 'mp2', or 'mpg'\n",
00630 output_type);
00631 return 1;
00632 }
00633
00634 return 0;
00635 }