FFMPEG实现的转码程序

本例子是由FFEMPG的doc/example例子transcode.c修改而来,可以根据需求任意转换音视频的编码。

原来的例子的作用更类似于remux,并没有实现转码的功能,只是实现了格式转换,比如ts转avi等。并不能实现音视频编码格式的转换,比如将h264转为mpeg2。

FFMPEG转码的实现有多种方式:

一种方式是:流解复用->视频+音频流->解码->YUV/PCM等->视音频编码->重新生成的音视频流->复用->流

另一种方式依赖AVFilter,这一部分在另外的几篇文章中解释怎么用。虽然AVFilter学习起来可能比较困难,但是在实际的编程应用中,依靠AVFilter做转码效率比第一种方式高,并且解码的CPU和时间消耗也少的多。所以,还是建议好好学习这部分的,毕竟我一直觉得FFMPEG的强项就是解码和转码。

本例子是视频mpeg2转h264,音频mpegaudio转g711。

[cpp] view plain copy

print?

  1. <span style="font-family:SimHei;font-size:18px;">/*
  2. * based on FFMPEG transcode.c
  3. * modified by tongli
  4. */
  5. #include <stdio.h>
  6. #include "snprintf.h"
  7. extern "C"
  8. {
  9. #include <libavcodec/avcodec.h>
  10. #include <libavformat/avformat.h>
  11. #include <libavfilter/avfiltergraph.h>
  12. #include <libavfilter/avcodec.h>
  13. #include <libavfilter/buffersink.h>
  14. #include <libavfilter/buffersrc.h>
  15. #include <libavutil/opt.h>
  16. #include <libavutil/pixdesc.h>
  17. }
  18. static AVFormatContext *ifmt_ctx;
  19. static AVFormatContext *ofmt_ctx;
  20. typedef struct FilteringContext {
  21. AVFilterContext *buffersink_ctx;
  22. AVFilterContext *buffersrc_ctx;
  23. AVFilterGraph *filter_graph;
  24. } FilteringContext;
  25. static FilteringContext *filter_ctx;
  26. static int open_input_file(const char *filename)
  27. {
  28. int ret;
  29. unsigned int i;
  30. ifmt_ctx = NULL;
  31. if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) {
  32. av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
  33. return ret;
  34. }
  35. if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
  36. av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
  37. return ret;
  38. }
  39. for (i = 0; i < ifmt_ctx->nb_streams; i++) {
  40. AVStream *stream;
  41. AVCodecContext *codec_ctx;
  42. stream = ifmt_ctx->streams[i];
  43. codec_ctx = stream->codec;
  44. /* Reencode video & audio and remux subtitles etc. */
  45. if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
  46. || codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
  47. /* Open decoder */
  48. ret = avcodec_open2(codec_ctx,
  49. avcodec_find_decoder(codec_ctx->codec_id), NULL);
  50. if (ret < 0) {
  51. av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i);
  52. return ret;
  53. }
  54. }
  55. }
  56. av_dump_format(ifmt_ctx, 0, filename, 0);
  57. return 0;
  58. }
  59. static int open_output_file(const char *filename)
  60. {
  61. AVStream *out_stream;
  62. AVStream *in_stream;
  63. AVCodecContext *dec_ctx, *enc_ctx;
  64. AVCodec *encoder;
  65. int ret;
  66. unsigned int i;
  67. ofmt_ctx = NULL;
  68. avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, filename);
  69. if (!ofmt_ctx) {
  70. av_log(NULL, AV_LOG_ERROR, "Could not create output context\n");
  71. return AVERROR_UNKNOWN;
  72. }
  73. for (i = 0; i < ifmt_ctx->nb_streams; i++) {
  74. out_stream = avformat_new_stream(ofmt_ctx, NULL);
  75. if (!out_stream) {
  76. av_log(NULL, AV_LOG_ERROR, "Failed allocating output stream\n");
  77. return AVERROR_UNKNOWN;
  78. }
  79. in_stream = ifmt_ctx->streams[i];
  80. dec_ctx = in_stream->codec;
  81. enc_ctx = out_stream->codec;
  82. if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
  83. {
  84. encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
  85. if (!encoder) {
  86. av_log(NULL, AV_LOG_FATAL, "Neccessary encoder not found\n");
  87. return AVERROR_INVALIDDATA;
  88. }
  89. enc_ctx->height = dec_ctx->height;
  90. enc_ctx->width = dec_ctx->width;
  91. enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio;
  92. enc_ctx->pix_fmt = encoder->pix_fmts[0];
  93. enc_ctx->time_base = dec_ctx->time_base;
  94. enc_ctx->me_range = 16;
  95. enc_ctx->max_qdiff = 4;
  96. enc_ctx->qmin = 10;
  97. enc_ctx->qmax = 51;
  98. enc_ctx->qcompress = 0.6;
  99. enc_ctx->refs = 3;
  100. enc_ctx->bit_rate = 500000;
  101. ret = avcodec_open2(enc_ctx, encoder, NULL);
  102. if (ret < 0) {
  103. av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i);
  104. return ret;
  105. }
  106. }
  107. else if (dec_ctx->codec_type == AVMEDIA_TYPE_UNKNOWN) {
  108. av_log(NULL, AV_LOG_FATAL, "Elementary stream #%d is of unknown type, cannot proceed\n", i);
  109. return AVERROR_INVALIDDATA;
  110. }
  111. else if (dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO)
  112. {
  113. encoder = avcodec_find_encoder(AV_CODEC_ID_PCM_ALAW);
  114. enc_ctx->sample_rate = dec_ctx->sample_rate;
  115. enc_ctx->channel_layout = dec_ctx->channel_layout;
  116. enc_ctx->channels = av_get_channel_layout_nb_channels(enc_ctx->channel_layout);
  117. enc_ctx->sample_fmt = encoder->sample_fmts[0];
  118. AVRational ar = { 1, enc_ctx->sample_rate };
  119. enc_ctx->time_base = ar;
  120. ret = avcodec_open2(enc_ctx, encoder, NULL);
  121. if (ret < 0) {
  122. av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i);
  123. return ret;
  124. }
  125. }
  126. else {
  127. ret = avcodec_copy_context(ofmt_ctx->streams[i]->codec,
  128. ifmt_ctx->streams[i]->codec);
  129. if (ret < 0) {
  130. av_log(NULL, AV_LOG_ERROR, "Copying stream context failed\n");
  131. return ret;
  132. }
  133. }
  134. if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
  135. enc_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
  136. }
  137. av_dump_format(ofmt_ctx, 0, filename, 1);
  138. if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) {
  139. ret = avio_open(&ofmt_ctx->pb, filename, AVIO_FLAG_WRITE);
  140. if (ret < 0) {
  141. av_log(NULL, AV_LOG_ERROR, "Could not open output file ‘%s‘", filename);
  142. return ret;
  143. }
  144. }
  145. /* init muxer, write output file header */
  146. ret = avformat_write_header(ofmt_ctx, NULL);
  147. if (ret < 0) {
  148. av_log(NULL, AV_LOG_ERROR, "Error occurred when opening output file\n");
  149. return ret;
  150. }
  151. return 0;
  152. }
  153. static int init_filter(FilteringContext* fctx, AVCodecContext *dec_ctx,
  154. AVCodecContext *enc_ctx, const char *filter_spec)
  155. {
  156. char args[512];
  157. int ret = 0;
  158. AVFilter *buffersrc = NULL;
  159. AVFilter *buffersink = NULL;
  160. AVFilterContext *buffersrc_ctx = NULL;
  161. AVFilterContext *buffersink_ctx = NULL;
  162. AVFilterInOut *outputs = avfilter_inout_alloc();
  163. AVFilterInOut *inputs = avfilter_inout_alloc();
  164. AVFilterGraph *filter_graph = avfilter_graph_alloc();
  165. if (!outputs || !inputs || !filter_graph) {
  166. ret = AVERROR(ENOMEM);
  167. goto end;
  168. }
  169. if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
  170. buffersrc = avfilter_get_by_name("buffer");
  171. buffersink = avfilter_get_by_name("buffersink");
  172. if (!buffersrc || !buffersink) {
  173. av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found\n");
  174. ret = AVERROR_UNKNOWN;
  175. goto end;
  176. }
  177. snprintf(args, sizeof(args),
  178. "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
  179. dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
  180. dec_ctx->time_base.num, dec_ctx->time_base.den,
  181. dec_ctx->sample_aspect_ratio.num,
  182. dec_ctx->sample_aspect_ratio.den);
  183. ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
  184. args, NULL, filter_graph);
  185. if (ret < 0) {
  186. av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
  187. goto end;
  188. }
  189. ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
  190. NULL, NULL, filter_graph);
  191. if (ret < 0) {
  192. av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
  193. goto end;
  194. }
  195. ret = av_opt_set_bin(buffersink_ctx, "pix_fmts",
  196. (uint8_t*)&enc_ctx->pix_fmt, sizeof(enc_ctx->pix_fmt),
  197. AV_OPT_SEARCH_CHILDREN);
  198. if (ret < 0) {
  199. av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
  200. goto end;
  201. }
  202. }
  203. else if (dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
  204. buffersrc = avfilter_get_by_name("abuffer");
  205. buffersink = avfilter_get_by_name("abuffersink");
  206. if (!buffersrc || !buffersink) {
  207. av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found\n");
  208. ret = AVERROR_UNKNOWN;
  209. goto end;
  210. }
  211. if (!dec_ctx->channel_layout)
  212. dec_ctx->channel_layout =
  213. av_get_default_channel_layout(dec_ctx->channels);
  214. snprintf(args, sizeof(args),
  215. "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
  216. dec_ctx->time_base.num, dec_ctx->time_base.den, dec_ctx->sample_rate,
  217. av_get_sample_fmt_name(dec_ctx->sample_fmt),
  218. dec_ctx->channel_layout);
  219. ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
  220. args, NULL, filter_graph);
  221. if (ret < 0) {
  222. av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
  223. goto end;
  224. }
  225. ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
  226. NULL, NULL, filter_graph);
  227. if (ret < 0) {
  228. av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n");
  229. goto end;
  230. }
  231. ret = av_opt_set_bin(buffersink_ctx, "sample_fmts",
  232. (uint8_t*)&enc_ctx->sample_fmt, sizeof(enc_ctx->sample_fmt),
  233. AV_OPT_SEARCH_CHILDREN);
  234. if (ret < 0) {
  235. av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n");
  236. goto end;
  237. }
  238. ret = av_opt_set_bin(buffersink_ctx, "channel_layouts",
  239. (uint8_t*)&enc_ctx->channel_layout,
  240. sizeof(enc_ctx->channel_layout), AV_OPT_SEARCH_CHILDREN);
  241. if (ret < 0) {
  242. av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
  243. goto end;
  244. }
  245. ret = av_opt_set_bin(buffersink_ctx, "sample_rates",
  246. (uint8_t*)&enc_ctx->sample_rate, sizeof(enc_ctx->sample_rate),
  247. AV_OPT_SEARCH_CHILDREN);
  248. if (ret < 0) {
  249. av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");
  250. goto end;
  251. }
  252. }
  253. else {
  254. ret = AVERROR_UNKNOWN;
  255. goto end;
  256. }
  257. /* Endpoints for the filter graph. */
  258. outputs->name = av_strdup("in");
  259. outputs->filter_ctx = buffersrc_ctx;
  260. outputs->pad_idx = 0;
  261. outputs->next = NULL;
  262. inputs->name = av_strdup("out");
  263. inputs->filter_ctx = buffersink_ctx;
  264. inputs->pad_idx = 0;
  265. inputs->next = NULL;
  266. if (!outputs->name || !inputs->name) {
  267. ret = AVERROR(ENOMEM);
  268. goto end;
  269. }
  270. if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_spec,
  271. &inputs, &outputs, NULL)) < 0)
  272. goto end;
  273. if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
  274. goto end;
  275. /* Fill FilteringContext */
  276. fctx->buffersrc_ctx = buffersrc_ctx;
  277. fctx->buffersink_ctx = buffersink_ctx;
  278. fctx->filter_graph = filter_graph;
  279. end:
  280. avfilter_inout_free(&inputs);
  281. avfilter_inout_free(&outputs);
  282. return ret;
  283. }
  284. static int init_filters(void)
  285. {
  286. const char *filter_spec;
  287. unsigned int i;
  288. int ret;
  289. filter_ctx = (FilteringContext*)av_malloc_array(ifmt_ctx->nb_streams, sizeof(*filter_ctx));
  290. if (!filter_ctx)
  291. return AVERROR(ENOMEM);
  292. for (i = 0; i < ifmt_ctx->nb_streams; i++) {
  293. filter_ctx[i].buffersrc_ctx = NULL;
  294. filter_ctx[i].buffersink_ctx = NULL;
  295. filter_ctx[i].filter_graph = NULL;
  296. if (!(ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO
  297. || ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO))
  298. continue;
  299. if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
  300. filter_spec = "null"; /* passthrough (dummy) filter for video */
  301. else
  302. filter_spec = "anull"; /* passthrough (dummy) filter for audio */
  303. ret = init_filter(&filter_ctx[i], ifmt_ctx->streams[i]->codec,
  304. ofmt_ctx->streams[i]->codec, filter_spec);
  305. if (ret)
  306. return ret;
  307. }
  308. return 0;
  309. }
  310. static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame) {
  311. int ret;
  312. int got_frame_local;
  313. AVPacket enc_pkt;
  314. int(*enc_func)(AVCodecContext *, AVPacket *, const AVFrame *, int *) =
  315. (ifmt_ctx->streams[stream_index]->codec->codec_type ==
  316. AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2;
  317. if (!got_frame)
  318. got_frame = &got_frame_local;
  319. av_log(NULL, AV_LOG_INFO, "Encoding frame\n");
  320. /* encode filtered frame */
  321. enc_pkt.data = NULL;
  322. enc_pkt.size = 0;
  323. av_init_packet(&enc_pkt);
  324. ret = enc_func(ofmt_ctx->streams[stream_index]->codec, &enc_pkt,
  325. filt_frame, got_frame);
  326. av_frame_free(&filt_frame);
  327. if (ret < 0)
  328. return ret;
  329. if (!(*got_frame))
  330. return 0;
  331. /* prepare packet for muxing */
  332. enc_pkt.stream_index = stream_index;
  333. av_packet_rescale_ts(&enc_pkt,
  334. ofmt_ctx->streams[stream_index]->codec->time_base,
  335. ofmt_ctx->streams[stream_index]->time_base);
  336. av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n");
  337. /* mux encoded frame */
  338. ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
  339. return ret;
  340. }
  341. static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index)
  342. {
  343. int ret;
  344. AVFrame *filt_frame;
  345. av_log(NULL, AV_LOG_INFO, "Pushing decoded frame to filters\n");
  346. /* push the decoded frame into the filtergraph */
  347. ret = av_buffersrc_add_frame_flags(filter_ctx[stream_index].buffersrc_ctx,
  348. frame, 0);
  349. if (ret < 0) {
  350. av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
  351. return ret;
  352. }
  353. /* pull filtered frames from the filtergraph */
  354. while (1) {
  355. filt_frame = av_frame_alloc();
  356. if (!filt_frame) {
  357. ret = AVERROR(ENOMEM);
  358. break;
  359. }
  360. av_log(NULL, AV_LOG_INFO, "Pulling filtered frame from filters\n");
  361. ret = av_buffersink_get_frame(filter_ctx[stream_index].buffersink_ctx,
  362. filt_frame);
  363. if (ret < 0) {
  364. /* if no more frames for output - returns AVERROR(EAGAIN)
  365. * if flushed and no more frames for output - returns AVERROR_EOF
  366. * rewrite retcode to 0 to show it as normal procedure completion
  367. */
  368. if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
  369. ret = 0;
  370. av_frame_free(&filt_frame);
  371. break;
  372. }
  373. filt_frame->pict_type = AV_PICTURE_TYPE_NONE;
  374. ret = encode_write_frame(filt_frame, stream_index, NULL);
  375. if (ret < 0)
  376. break;
  377. }
  378. return ret;
  379. }
  380. static int flush_encoder(unsigned int stream_index)
  381. {
  382. int ret;
  383. int got_frame;
  384. if (!(ofmt_ctx->streams[stream_index]->codec->codec->capabilities &
  385. CODEC_CAP_DELAY))
  386. return 0;
  387. while (1) {
  388. av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index);
  389. ret = encode_write_frame(NULL, stream_index, &got_frame);
  390. if (ret < 0)
  391. break;
  392. if (!got_frame)
  393. return 0;
  394. }
  395. return ret;
  396. }
  397. int main(int argc, char **argv)
  398. {
  399. int ret;
  400. AVPacket packet; //= { .data = NULL, .size = 0 };
  401. packet.data = NULL;
  402. packet.size = 0;
  403. AVFrame *frame = NULL;
  404. enum AVMediaType type;
  405. unsigned int stream_index;
  406. unsigned int i;
  407. int got_frame;
  408. int(*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket *);
  409. av_register_all();
  410. avfilter_register_all();
  411. if ((ret = open_input_file("test.ts")) < 0)
  412. goto end;
  413. if ((ret = open_output_file("test.avi")) < 0)
  414. goto end;
  415. if ((ret = init_filters()) < 0)
  416. goto end;
  417. /* read all packets */
  418. while (1) {
  419. if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0)
  420. break;
  421. stream_index = packet.stream_index;
  422. type = ifmt_ctx->streams[packet.stream_index]->codec->codec_type;
  423. av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n",
  424. stream_index);
  425. if (filter_ctx[stream_index].filter_graph) {
  426. av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the frame\n");
  427. frame = av_frame_alloc();
  428. if (!frame) {
  429. ret = AVERROR(ENOMEM);
  430. break;
  431. }
  432. av_packet_rescale_ts(&packet,
  433. ifmt_ctx->streams[stream_index]->time_base,
  434. ifmt_ctx->streams[stream_index]->codec->time_base);
  435. dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 :
  436. avcodec_decode_audio4;
  437. ret = dec_func(ifmt_ctx->streams[stream_index]->codec, frame,
  438. &got_frame, &packet);
  439. if (ret < 0) {
  440. av_frame_free(&frame);
  441. av_log(NULL, AV_LOG_ERROR, "Decoding failed\n");
  442. break;
  443. }
  444. if (got_frame) {
  445. frame->pts = av_frame_get_best_effort_timestamp(frame);
  446. ret = filter_encode_write_frame(frame, stream_index);
  447. av_frame_free(&frame);
  448. if (ret < 0)
  449. goto end;
  450. }
  451. else {
  452. av_frame_free(&frame);
  453. }
  454. }
  455. else {
  456. /* remux this frame without reencoding */
  457. av_packet_rescale_ts(&packet,
  458. ifmt_ctx->streams[stream_index]->time_base,
  459. ofmt_ctx->streams[stream_index]->time_base);
  460. ret = av_interleaved_write_frame(ofmt_ctx, &packet);
  461. if (ret < 0)
  462. goto end;
  463. }
  464. av_free_packet(&packet);
  465. }
  466. /* flush filters and encoders */
  467. for (i = 0; i < ifmt_ctx->nb_streams; i++) {
  468. /* flush filter */
  469. if (!filter_ctx[i].filter_graph)
  470. continue;
  471. ret = filter_encode_write_frame(NULL, i);
  472. if (ret < 0) {
  473. av_log(NULL, AV_LOG_ERROR, "Flushing filter failed\n");
  474. goto end;
  475. }
  476. /* flush encoder */
  477. ret = flush_encoder(i);
  478. if (ret < 0) {
  479. av_log(NULL, AV_LOG_ERROR, "Flushing encoder failed\n");
  480. goto end;
  481. }
  482. }
  483. av_write_trailer(ofmt_ctx);
  484. end:
  485. av_free_packet(&packet);
  486. av_frame_free(&frame);
  487. for (i = 0; i < ifmt_ctx->nb_streams; i++) {
  488. avcodec_close(ifmt_ctx->streams[i]->codec);
  489. if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && ofmt_ctx->streams[i]->codec)
  490. avcodec_close(ofmt_ctx->streams[i]->codec);
  491. if (filter_ctx && filter_ctx[i].filter_graph)
  492. avfilter_graph_free(&filter_ctx[i].filter_graph);
  493. }
  494. av_free(filter_ctx);
  495. avformat_close_input(&ifmt_ctx);
  496. if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
  497. avio_closep(&ofmt_ctx->pb);
  498. avformat_free_context(ofmt_ctx);
  499. if (ret < 0)
  500. av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n"); //av_err2str(ret));
  501. return ret ? 1 : 0;
  502. }
  503. </span>

源代码下载:

csdn工程:http://download.csdn.NET/detail/rootusers/8425619

from:http://blog.csdn.net/rootusers/article/details/43488827

时间: 2024-10-09 20:58:40

FFMPEG实现的转码程序的相关文章

最简单的基于FFMPEG的转码程序

本文介绍一个简单的基于FFmpeg的转码器.转码器在视音频编解码处理的程序中,属于一个比较复杂的东西.因为它结合了视频的解码和编码.一个视频播放器,一般只包含解码功能:一个视频编码工具,一般只包含编码功能:而一个视频转码器,则需要先对视频进行解码,然后再对视频进行编码,因而相当于解码器和编码器的结合.下图例举了一个视频的转码流程.输入视频的封装格式是FLV,视频编码标准是H.264,音频编码标准是AAC:输出视频的封装格式是AVI,视频编码标准是MPEG2,音频编码标准是MP3.从流程中可以看出

最简单的基于FFMPEG的转码程序 [转]

本文介绍一个简单的基于FFmpeg的转码器.它可以将一种视频格式(包括封转格式和编码格式)转换为另一种视频格式.转码器在视音频编解码处理的 程序中,属于一个比较复杂的东西.因为它结合了视频的解码和编码.一个视频播放器,一般只包含解码功能:一个视频编码工具,一般只包含编码功能:而一个视 频转码器,则需要先对视频进行解码,然后再对视频进行编码,因而相当于解码器和编码器的结合.下图例举了一个视频的转码流程.输入视频的封装格式是 FLV,视频编码标准是H.264,音频编码标准是AAC:输出视频的封装格式

FFmpeg简单转码程序--视频剪辑

学习了雷神的文章,慕斯人分享精神,感其英年而逝,不胜唏嘘.他有分享一个转码程序<最简单的基于FFMPEG的转码程序>其中使用了filter(参考了ffmpeg.c中的流程),他曾说想再编写一个不需要filter的版本,可惜未有机会.恰好工作中有相关ffmpeg处理内容,故狗尾续貂,撰写本文. 相关流程: 1.打开输入文件 2.打开输出文件 3.设置解码环境 4.设置输出流信息 5.设置编码环境 6.打开输入流循环读取,解码再编码写入 7.fflush解码和编码ctx 8.关闭文件 本文的代码,

汉字转码程序

研究了一下汉字编码,包括汉字的区位码.机内码,挺好玩的,也是比较实用的,一般我们在涂卡是区位码,比如“马”的区位码是3477,然后我们就涂上3477,然后读卡机就能根据区位码识别汉字:而机内码是机器内部的编码,平常我们可能用的比较少,“马”的机内码是49901,读者可以试一下:打开记事本,然后按住“Alt”键,不要松开,然后依次按49901,松开“Alt”,“马”字就打出来了!哈哈,神奇吧!其他汉字或字母包括符号都能通过这种方式输入.以后大家输入自己的姓名的时候,完全可以“秀”一把,哈哈,不调用

大麦户谷得住家创业好平台源码程序网站的安装功能说明

程序介绍:,适用范围:大麦户信誉平台源码,PHP淘宝信誉平台源码,仿大麦户程序,谷得大麦户源码程序,互刷信誉平台演示地址:www.xinxishequ.com运行环境:PHP.MYsql 其他说明:本程序是基于php架构开发,模板更简洁大方,源码易改.它不但比目前整个网络淘宝互刷源码的功能更加强大完善.本站亲自测试并修改优化了部分页面,php信誉源码中比较完整并集成多功能的店铺信誉网源码,新手也可以很容易修改使用.源码页面设计简洁,后台完整无错并且无任何功能限制.更多功能请自己下载摸索,这里就不

菠菜源码程序,菠菜系统程序,我们做什么?

bbs.svs9.com 菠菜源码程序,菠菜系统程序,菠菜网站源码,http://bbs.svs9.com/ 与客户沟通,从使用者的角度发现问题,找到解决方案.多年的项目服务经验,让设计和互联网技术完美结合,创造极具个性.有价值的用户体验产品. APP软件开发 基于iOS/Android应用开发掌控智能终端时代 高端定制网站 企业高端定制网站设计彰显品牌形象 移动WEB开发 定制手机网站/微网站制作布局移动互联网 界面品牌设计 以专业的视角为企业提供非常有创意和视觉冲击力的网站,致力于树立良好的

FFmpeg:视频转码、剪切、合并、播放速调整

原文:https://fzheng.me/2016/01/08/ffmpeg/ FFmpeg:视频转码.剪切.合并.播放速调整 2016-01-08 前阵子帮导师处理项目 ppt,因为插入视频的格式问题被搞得焦头烂额.Windows 内置解码器不够全,PowerPoint 原生支持的内嵌视频格式有限.更麻烦的是新版本的 PowerPoint 支持的格式(比如 MPEG4 编码的 .mp4)旧版本还不支持,而你对手头的 ppt 即将播放的场所用什么系统什么版本的软件又无能为力,所以最稳妥的方式是,

最简单的基于FFMPEG的转码程序分析 +ffmpga代码简析(转 +总结)

模块:  libavcodec    - 编码解码器         libavdevice   - 输入输出设备的支持         libavfilter   - 视音频滤镜支持         libavformat   - 视音频等格式的解析         libavutil     - 工具库         libpostproc   - 后期效果处理         libswscale    - 图像颜色.尺寸转换 1. ffmpga代码简析 1.1 av_log() av_

最简单的基于FFMPEG的转码程序 [转] —— 分析

模块:  libavcodec    - 编码解码器         libavdevice   - 输入输出设备的支持         libavfilter   - 视音频滤镜支持         libavformat   - 视音频等格式的解析         libavutil     - 工具库         libpostproc   - 后期效果处理         libswscale    - 图像颜色.尺寸转换 1. 主函数分析: int_tmain(int argc,