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