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 }