相关博客列表 :

FFMPEG内存操作(一) avio_reading.c 回调读取数据到内存解析

FFMPEG内存操作(二)从内存中读取数及数据格式的转换

FFmpeg内存操作(三)内存转码器

本文代码来自于自雷霄骅的《最简单的基于FFmpeg的内存读写的例子:内存转码器》

    1. /**
    2. * This software convert video bitstream (Such as MPEG2) to H.264
    3. * bitstream. It read video bitstream from memory (not from a file),
    4. * convert it to H.264 bitstream, and finally output to another memory.
    5. * It's the simplest example to use FFmpeg to read (or write) from
    6. * memory.
    7. *
    8. */
    9. #include <stdio.h>
    10. #define __STDC_CONSTANT_MACROS
    11. #include "avcodec.h"
    12. #include "avformat.h"
    13. #include "avutil.h"
    14. #include "opt.h"
    15. #include "pixdesc.h"
    16. #include "mathematics.h"
    17. FILEFILE *fp_open;
    18. FILEFILE *fp_write;
    19. //Read File
    20. int read_buffer(voidvoid *opaque, uint8_t *buf, int buf_size){
    21. int true_size;
    22. if(!feof(fp_open)){
    23. true_size=fread(buf,1,buf_size,fp_open);
    24. printf("read_buffer buf_size = %d\n",buf_size);
    25. return true_size;
    26. }else{
    27. return -1;
    28. }
    29. }
    30. //Write File
    31. int write_buffer(voidvoid *opaque, uint8_t *buf, int buf_size){
    32. int true_size;
    33. if(!feof(fp_write)){
    34. true_size=fwrite(buf,1,buf_size,fp_write);
    35. printf("write_buffer buf_size = %d\n",buf_size);
    36. return true_size;
    37. }else{
    38. return -1;
    39. }
    40. }
    41. int flush_encoder(AVFormatContext *fmt_ctx,unsigned int stream_index)
    42. {
    43. int ret;
    44. int got_frame;
    45. AVPacket enc_pkt;
    46. if (!(fmt_ctx->streams[stream_index]->codec->codec->capabilities &
    47. CODEC_CAP_DELAY))
    48. return 0;
    49. while (1) {
    50. av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index);
    51. //ret = encode_write_frame(NULL, stream_index, &got_frame);
    52. enc_pkt.data = NULL;
    53. enc_pkt.size = 0;
    54. av_init_packet(&enc_pkt);
    55. ret = avcodec_encode_video2 (fmt_ctx->streams[stream_index]->codec, &enc_pkt,
    56. NULL, &got_frame);
    57. av_frame_free(NULL);
    58. if (ret < 0)
    59. break;
    60. if (!got_frame)
    61. {ret=0;break;}
    62. /* prepare packet for muxing */
    63. enc_pkt.stream_index = stream_index;
    64. enc_pkt.dts = av_rescale_q_rnd(enc_pkt.dts,
    65. fmt_ctx->streams[stream_index]->codec->time_base,
    66. fmt_ctx->streams[stream_index]->time_base,
    67. //(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    68. (AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    69. enc_pkt.pts = av_rescale_q_rnd(enc_pkt.pts,
    70. fmt_ctx->streams[stream_index]->codec->time_base,
    71. fmt_ctx->streams[stream_index]->time_base,
    72. (AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    73. //(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    74. enc_pkt.duration = av_rescale_q(enc_pkt.duration,
    75. fmt_ctx->streams[stream_index]->codec->time_base,
    76. fmt_ctx->streams[stream_index]->time_base);
    77. av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n");
    78. /* mux encoded frame */
    79. ret = av_write_frame(fmt_ctx, &enc_pkt);
    80. if (ret < 0)
    81. break;
    82. }
    83. return ret;
    84. }
    85. int main(int argc, char* argv[])
    86. {
    87. int ret;
    88. AVFormatContext* ifmt_ctx=NULL;
    89. AVFormatContext* ofmt_ctx=NULL;
    90. AVIOContext *avio_in=NULL;
    91. AVIOContext *avio_out=NULL;
    92. unsigned char* inbuffer=NULL;
    93. unsigned char* outbuffer=NULL;
    94. AVFrame *frame = NULL;
    95. AVPacket packet;
    96. AVPacket enc_pkt;
    97. AVStream *out_stream;
    98. AVStream *in_stream;
    99. AVCodecContext *dec_ctx;
    100. AVCodecContext *enc_ctx;
    101. AVCodec *encoder;
    102. AVStream *stream;
    103. AVCodecContext *codec_ctx;
    104. enum AVMediaType type;
    105. unsigned int stream_index;
    106. unsigned int i=0;
    107. int got_frame;
    108. int enc_got_frame;
    109. fp_open = fopen("cuc60anniversary_start.ts", "rb"); //视频源文件
    110. fp_write=fopen("cuc60anniversary_start.h264","wb+"); //输出文件
    111. av_register_all();
    112. ifmt_ctx=avformat_alloc_context();                                 /* Allocate an AVFormatContext. */
    113. avformat_alloc_output_context2(&ofmt_ctx, NULL, "h264", NULL);     /*  Allocate an AVFormatContext for an output format. */
    114. inbuffer=(unsigned char*)av_malloc(32768);
    115. outbuffer=(unsigned char*)av_malloc(32768);
    116. /*open input file*/
    117. avio_in =avio_alloc_context(inbuffer, 32768,0,NULL,read_buffer,NULL,NULL);
    118. if(avio_in==NULL)
    119. goto end;
    120. /*open output file*/
    121. avio_out =avio_alloc_context(outbuffer, 32768,1,NULL,NULL,write_buffer,NULL);
    122. if(avio_out==NULL)
    123. goto end;
    124. ifmt_ctx->pb=avio_in;                                           /* I/O context.    input output context */
    125. ifmt_ctx->flags=AVFMT_FLAG_CUSTOM_IO;                           /* The caller has supplied a custom AVIOContext, don't avio_close() it */
    126. if ((ret = avformat_open_input(&ifmt_ctx, "whatever", NULL, NULL)) < 0) {
    127. av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
    128. return ret;
    129. }
    130. if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {     /*  Read packets of a media file to get stream information */
    131. av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
    132. return ret;
    133. }
    134. for (i = 0; i < ifmt_ctx->nb_streams; i++) {
    135. stream = ifmt_ctx->streams[i];
    136. codec_ctx = stream->codec;
    137. /* Reencode video & audio and remux subtitles etc. 重新编码视频和音频和翻译字幕等  */
    138. if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO){
    139. /* Open decoder */
    140. /* Initialize the AVCodecContext to use the given AVCodec */
    141. ret = avcodec_open2(codec_ctx,  avcodec_find_decoder(codec_ctx->codec_id), NULL);
    142. if (ret < 0) {
    143. av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i);
    144. return ret;
    145. }
    146. }
    147. }
    148. //av_dump_format(ifmt_ctx, 0, "whatever", 0);
    149. //avio_out->write_packet=write_packet;
    150. ofmt_ctx->pb=avio_out;
    151. ofmt_ctx->flags=AVFMT_FLAG_CUSTOM_IO;
    152. for (i = 0; i < 1; i++) {
    153. out_stream = avformat_new_stream(ofmt_ctx, NULL);    /*  Add a new stream to a media file. */
    154. if (!out_stream) {
    155. av_log(NULL, AV_LOG_ERROR, "Failed allocating output stream\n");
    156. return AVERROR_UNKNOWN;
    157. }
    158. in_stream = ifmt_ctx->streams[i];
    159. dec_ctx = in_stream->codec;
    160. enc_ctx = out_stream->codec;
    161. if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
    162. {
    163. encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
    164. enc_ctx->height = dec_ctx->height;
    165. enc_ctx->width = dec_ctx->width;
    166. enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio;
    167. enc_ctx->pix_fmt = encoder->pix_fmts[0];
    168. enc_ctx->time_base = dec_ctx->time_base;
    169. //enc_ctx->time_base.num = 1;
    170. //enc_ctx->time_base.den = 25;
    171. //H264的必备选项,没有就会错
    172. enc_ctx->me_range=16;
    173. enc_ctx->max_qdiff = 4;
    174. enc_ctx->qmin = 10;
    175. enc_ctx->qmax = 51;
    176. enc_ctx->qcompress = 0.6;
    177. enc_ctx->refs=3;
    178. enc_ctx->bit_rate = 500000;
    179. ret = avcodec_open2(enc_ctx, encoder, NULL);
    180. if (ret < 0) {
    181. av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i);
    182. return ret;
    183. }
    184. }
    185. else if (dec_ctx->codec_type == AVMEDIA_TYPE_UNKNOWN) {
    186. av_log(NULL, AV_LOG_FATAL, "Elementary stream #%d is of unknown type, cannot proceed\n", i);
    187. return AVERROR_INVALIDDATA;
    188. } else {
    189. /* if this stream must be remuxed */
    190. /* Copy the settings of the source AVCodecContext into the destination  AVCodecContext */
    191. ret = avcodec_copy_context(ofmt_ctx->streams[i]->codec,   ifmt_ctx->streams[i]->codec);
    192. if (ret < 0) {
    193. av_log(NULL, AV_LOG_ERROR, "Copying stream context failed\n");
    194. return ret;
    195. }
    196. }
    197. if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
    198. enc_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
    199. }
    200. //av_dump_format(ofmt_ctx, 0, "whatever", 1);
    201. /* init muxer, write output file header */
    202. ret = avformat_write_header(ofmt_ctx, NULL);
    203. if (ret < 0) {
    204. av_log(NULL, AV_LOG_ERROR, "Error occurred when opening output file\n");
    205. return ret;
    206. }
    207. i=0;
    208. /* read all packets */
    209. while (1) {
    210. i++;
    211. if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0)   /* Return the next frame of a stream */
    212. break;
    213. stream_index = packet.stream_index;
    214. if(stream_index!=0)
    215. continue;
    216. type = ifmt_ctx->streams[packet.stream_index]->codec->codec_type;
    217. av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n", stream_index);
    218. av_log(NULL, AV_LOG_DEBUG, "Going to reencode the frame\n");
    219. frame = av_frame_alloc();
    220. if (!frame) {
    221. ret = AVERROR(ENOMEM);
    222. break;
    223. }
    224. packet.dts = av_rescale_q_rnd(packet.dts,               /* 解压缩时间戳 */
    225. ifmt_ctx->streams[stream_index]->time_base,
    226. ifmt_ctx->streams[stream_index]->codec->time_base,
    227. //(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    228. (AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    229. packet.pts = av_rescale_q_rnd(packet.pts,              /* 显示时间戳 */
    230. ifmt_ctx->streams[stream_index]->time_base,
    231. ifmt_ctx->streams[stream_index]->codec->time_base,
    232. //(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    233. (AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    234. /* Decode the video frame of size avpkt->size from avpkt->data into picture 解码输入文件 */
    235. ret = avcodec_decode_video2(ifmt_ctx->streams[stream_index]->codec, frame, &got_frame, &packet);
    236. printf("Decode 1 Packet\tsize:%d\tpts:%lld\n",packet.size,packet.pts);
    237. if (ret < 0) {
    238. av_frame_free(&frame);
    239. av_log(NULL, AV_LOG_ERROR, "Decoding failed\n");
    240. break;
    241. }
    242. if (got_frame) {
    243. frame->pts = av_frame_get_best_effort_timestamp(frame);
    244. frame->pict_type=AV_PICTURE_TYPE_NONE;
    245. /* Initialize optional fields of a packet with default values */
    246. enc_pkt.data = NULL;
    247. enc_pkt.size = 0;
    248. av_init_packet(&enc_pkt);
    249. /* Takes input raw video data from frame and writes the next output packet, if available, to avpkt */
    250. ret = avcodec_encode_video2 (ofmt_ctx->streams[stream_index]->codec, &enc_pkt, frame, &enc_got_frame);
    251. printf("Encode 1 Packet\tsize:%d\tpts:%lld\n",enc_pkt.size,enc_pkt.pts);
    252. av_frame_free(&frame);
    253. if (ret < 0)
    254. goto end;
    255. if (!enc_got_frame)
    256. continue;
    257. /* prepare packet for muxing */
    258. enc_pkt.stream_index = stream_index;
    259. enc_pkt.dts = av_rescale_q_rnd(enc_pkt.dts,
    260. ofmt_ctx->streams[stream_index]->codec->time_base,
    261. ofmt_ctx->streams[stream_index]->time_base,
    262. //(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    263. (AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    264. enc_pkt.pts = av_rescale_q_rnd(enc_pkt.pts,
    265. ofmt_ctx->streams[stream_index]->codec->time_base,
    266. ofmt_ctx->streams[stream_index]->time_base,
    267. //(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    268. (AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    269. enc_pkt.duration = av_rescale_q(enc_pkt.duration,
    270. ofmt_ctx->streams[stream_index]->codec->time_base,
    271. ofmt_ctx->streams[stream_index]->time_base);
    272. av_log(NULL, AV_LOG_INFO, "Muxing frame %d\n",i);
    273. /* mux encoded frame */
    274. /* Write a packet to an output media file */
    275. av_write_frame(ofmt_ctx,&enc_pkt);
    276. if (ret < 0)
    277. goto end;
    278. } else {
    279. av_frame_free(&frame);
    280. }
    281. av_free_packet(&packet);
    282. }
    283. /* flush encoders */
    284. for (i = 0; i < 1; i++) {
    285. /* flush encoder */
    286. ret = flush_encoder(ofmt_ctx,i);
    287. if (ret < 0) {
    288. av_log(NULL, AV_LOG_ERROR, "Flushing encoder failed\n");
    289. goto end;
    290. }
    291. }
    292. av_write_trailer(ofmt_ctx);
    293. end:
    294. av_freep(avio_in);
    295. av_freep(avio_out);
    296. av_free(inbuffer);
    297. av_free(outbuffer);
    298. av_free_packet(&packet);
    299. av_frame_free(&frame);
    300. avformat_close_input(&ifmt_ctx);
    301. avformat_free_context(ofmt_ctx);
    302. fclose(fp_open);
    303. if (ret < 0)
    304. av_log(NULL, AV_LOG_ERROR, "Error occurred\n");
    305. return (ret? 1:0);
    306. }
  1. from:http://blog.csdn.net/li_wen01/article/details/64905959

FFmpeg内存操作(三)内存转码器的更多相关文章

  1. 共享内存操作类(C#源码)

    原文 http://blog.csdn.net/yefanqiu/article/details/1717458 VC++的共享内存操作代码实现起来相对比较容易,但是用C#语言来实现,就有一定难度,由 ...

  2. Linux内存初始化(三) 内存布局

    一.前言 同样的,本文是内存初始化文章的一份补充文档,希望能够通过这样的一份文档,细致的展示在初始化阶段,Linux 4.4.6内核如何从device tree中提取信息,完成内存布局的任务.具体的c ...

  3. 【嵌入式开发】裸机引导操作系统和ARM 内存操作 ( DRAM SRAM 类型 简介 | Logical Bank | 内存地址空间介绍 | 内存芯片连接方式 | 内存初始化 | 汇编代码示例 )

    [嵌入式开发]ARM 内存操作 ( DRAM SRAM 类型 简介 | Logical Bank | 内存地址空间介绍 | 内存芯片连接方式 | 内存初始化 | 汇编代码示例 )     一. 内存 ...

  4. 最简单的基于FFmpeg的内存读写的例子:内存转码器

    ===================================================== 最简单的基于FFmpeg的内存读写的例子系列文章列表: 最简单的基于FFmpeg的内存读写的 ...

  5. FFMPEG内存操作(一) avio_reading.c 回调读取数据到内存解析

    相关博客列表 : FFMPEG内存操作(一) avio_reading.c 回调读取数据到内存解析 FFMPEG内存操作(二)从内存中读取数及数据格式的转换 FFmpeg内存操作(三)内存转码器 在F ...

  6. FFMPEG内存操作(二)从内存中读取数及数据格式的转换

    相关博客列表: FFMPEG内存操作(一) avio_reading.c 回调读取数据到内存解析 FFMPEG内存操作(二)从内存中读取数及数据格式的转换 FFmpeg内存操作(三)内存转码器 在雷神 ...

  7. Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器

    Android For JNI(二)--C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器 当我们把Hello World写完之后,我们就可以迈入C的大门了,今天就来讲讲基本的一些数据类型 ...

  8. ffmpeg转码器移植VC的工程:ffmpeg for MFC

    本文介绍一个自己做的FFMPEG移植到VC下的开源工程:ffmpeg for MFC.本工程将ffmpeg工程中的ffmpeg转码器(ffmpeg.c)移植到了VC环境下.并且使用MFC做了一套简单的 ...

  9. ffmpeg转码器移植VC的project:ffmpeg for MFC

    本文介绍一个自己做的FFMPEG移植到VC下的开源project:ffmpeg for MFC.本project将ffmpegproject中的ffmpeg转码器(ffmpeg.c)移植到了VC环境下 ...

随机推荐

  1. (转)深入理解Java内存模型之系列篇

    原文地址: http://blog.csdn.net/ccit0519/article/details/11241403 深入理解Java内存模型(一)——基础 并发编程模型的分类 在并发编程中,我们 ...

  2. 九度OJ 1192:回文字符串 (基础题)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3807 解决:1778 题目描述: 给出一个长度不超过1000的字符串,判断它是不是回文(顺读,逆读均相同)的. 输入: 输入包括一行字符串 ...

  3. AFN errorCode对应的状态码

    转 http://blog.csdn.NET/wangyanchang21/article/details/50932191 在很多时候都会遇到错误, 还会带有一些 Error Code , 比如在各 ...

  4. 【网络与系统安全】20179209 wireshark和nmap实验

    TCP三次握手包 在进行实验前,先梳理一遍TCP三次握手的过程,这个图是我本科学网络时画过不少于十遍的图,我觉得非常有纪念意义. 稍作解释,第一次握手,客户端发起请求连接,发送一个标志位为SYN的ip ...

  5. git本地分支管理

    查看分支:git branch创建分支:git branch dev重命名分支:git branch -m dev dev1删除分支:git branch -d dev切换分支:git checkou ...

  6. Bootstrap学习5--bootstrap中的模态框(modal,弹出层)

    bootstrap中的模态框(modal),不同于Tooltips,模态框以弹出对话框的形式出现,具有最小和最实用的功能集. 务必将模态框的 HTML 代码放在文档的最高层级内(也就是说,尽量作为 b ...

  7. Excel控制IE

    ---恢复内容开始--- 1.初始化and连接http网页 Set ie = CreateObject("InternetExplorer.Application") ie.Vis ...

  8. C#调用大漠插件

    大漠插件是一个很不错的东西,在按键精灵和易语言里面用得很多,可以后台找图找字,写游戏自动脚本用得特别多.前面写一个微信的自动脚本,查了一些资料,易语言不太熟悉,按键精灵功能上可能不好实现,就找了些资料 ...

  9. Linux服务器上的tomcat中部署web项目

    首先了解一下下面几个概念,讲得不太准确:1.JVMJVM是class以及jar(实际上就是很多个class压缩在一起)的运行环境,特征就是java和javaw命令,通过这两个命令,你可以执行class ...

  10. 导出数据到表格PHP

    导出数据到表格 public function excel(){ $filename = '导出表格'; $header = ['编号','名称']; $index = ['id','name']; ...