ffmpeg encode/decode example
来源:互联网 发布:易语言播放音乐源码 编辑:程序博客网 时间:2024/05/18 09:29
00001 /*00002 * Copyright (c) 2001 Fabrice Bellard00003 *00004 * Permission is hereby granted, free of charge, to any person obtaining a copy00005 * of this software and associated documentation files (the "Software"), to deal00006 * in the Software without restriction, including without limitation the rights00007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell00008 * copies of the Software, and to permit persons to whom the Software is00009 * furnished to do so, subject to the following conditions:00010 *00011 * The above copyright notice and this permission notice shall be included in00012 * all copies or substantial portions of the Software.00013 *00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR00015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL00017 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER00018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,00019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN00020 * THE SOFTWARE.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 409600044 #define AUDIO_INBUF_SIZE 2048000045 #define AUDIO_REFILL_THRESH 409600046 00047 /* check that a given sample format is supported by the encoder */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 /* just pick the highest supported samplerate */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 /* select layout with the highest channel count */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 * Audio encoding example00102 */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 /* find the MP2 encoder */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 /* put sample parameters */00131 c->bit_rate = 64000;00132 00133 /* check that the encoder supports s16 pcm input */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 /* select other audio parameters supported by the encoder */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 /* open it */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 /* frame containing input raw audio */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 /* the codec gives us the frame size, in samples,00170 * we calculate the size of the samples buffer in bytes */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 /* setup the data pointers in the AVFrame */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 /* encode a single tone sound */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; // packet data will be allocated by the encoder00193 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 /* encode the samples */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 /* get the delayed frames */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 * Audio decoding.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 /* find the mpeg audio decoder */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 /* open it */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 /* decode until eof */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 } else00295 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 /* if a frame has been decoded, output it */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 /* Refill the input buffer, to avoid trying to decode00315 * incomplete frames. Instead of this, one could also use00316 * a parser, or use a proper container format through00317 * libavformat. */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 * Video encoding example00337 */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 /* find the mpeg1 video encoder */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 /* put sample parameters */00364 c->bit_rate = 400000;00365 /* resolution must be a multiple of two */00366 c->width = 352;00367 c->height = 288;00368 /* frames per second */00369 c->time_base= (AVRational){1,25};00370 c->gop_size = 10; /* emit one intra frame every ten frames */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 /* open it */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 /* the image can be allocated by any means and av_image_alloc() is00399 * just the most convenient way if av_malloc() is to be used */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 /* encode 1 second of video */00408 for(i=0;i<25;i++) {00409 av_init_packet(&pkt);00410 pkt.data = NULL; // packet data will be allocated by the encoder00411 pkt.size = 0;00412 00413 fflush(stdout);00414 /* prepare a dummy image */00415 /* Y */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 /* Cb and Cr */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 /* encode the image */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 /* get the delayed frames */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 /* add sequence end code to have a real mpeg file */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 * Video decoding example00476 */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 /* the picture is allocated by the decoder, no need to free it */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 /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */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 /* find the mpeg1 video decoder */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; /* we do not send complete frames */00551 00552 /* For some codecs, such as msmpeg4 and mpeg4, width and height00553 MUST be initialized there because this information is not00554 available in the bitstream. */00555 00556 /* open it */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 /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)00581 and this is the only method to use them because you cannot00582 know the compressed data size before analysing it.00583 00584 BUT some other codecs (msmpeg4, mpeg4) are inherently frame00585 based, so you must call them with all the data for one00586 frame exactly. You must also initialize 'width' and00587 'height' before initializing them. */00588 00589 /* NOTE2: some codecs allow the raw parameters (frame size,00590 sample rate) to be changed at any frame. We handle this, so00591 you should also take care of it */00592 00593 /* here, we use a stream based decoder (mpeg1video), so we00594 feed decoder and see if it could decode a frame */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 /* some codecs, such as MPEG, transmit the I and P frame with a00602 latency of one frame. You must do the following to have a00603 chance to get the last frame of the video */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 /* register all the codecs */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 }
阅读全文
0 0
- ffmpeg encode/decode example
- encode decode
- encode decode
- HTML encode & Decode
- js encode decode
- Javascript url decode, encode
- decode和encode
- ASP Encode/Decode Functions
- Extjs encode decode
- python decode encode
- oracle url encode decode
- URLEncoder.encode和decode
- encode decode学习心得
- Extjs encode decode
- Python中的decode/encode
- H264 encode and decode
- js encode decode
- decode、encode、unicode解码
- 时间复杂度和空间复杂度_增强版
- oracle数据库之约束
- 模拟器安装应用失败(INSTALL_FAILED_NO_MATCHING_ABIS)
- 解决Tomcat不能访问首页的问题,eclipse中tomcat能正常启动
- UnityShader——屏幕空间的能量罩(模拟守望先锋温斯顿的能量罩)
- ffmpeg encode/decode example
- HDU6134(莫比乌斯反演)
- nginx+obs搭建流媒体,实现直播
- 21、多项式插值,最小二乘法和牛顿迭代法
- Android进程间通信(二)- Messenger
- java was started but returned code=13
- 用爬虫来爬取廖老师的python教程的url
- django第一步
- opencv--画矩形框与图片截取