ffmpeg关于io的输入输出操作
来源:互联网 发布:安卓数据恢复软件 编辑:程序博客网 时间:2024/06/02 16:42
ffmpeg关于io的输入输出操作
ffmpeg 无论转码是本地文件输入输出,例如将mp4文件 转成 flv文件,或者从rtmp流接入到rtsp流,这时候我们在输入输出端拿不到数据流,只能拿到输入输出的地址,这时候ffmpeg的 io就出场了,道理是把输入输出流写入到缓存中,在做处理。应用场景例如:从http 拿到的数据流,从摄像头拿到的数据流,这些都能作为io输入,将mux后的数据write到io用于存成文件,或者librtmp打包出去,这些都用于io输出。具体操作如下:
1:ffmpeg的IO输入
Io_Buf_Info buf_info;//这里必须用av_malloc申请,用calloc申请会崩溃buf_info.BufLen = DEMUX_MAX_IO_BUF_SIZE;buf_info.Buf = (char * )av_malloc(buf_info.BufLen);m_list_format_io_buf[rtmpaddress_id] = (buf_info);AVIOContext * pb = NULL;AVInputFormat *piFmt = NULL;AVFormatContext * m_pFmt = NULL;//step1:申请一个AVIOContext,传入回调函数//填写当前要读的rtmpaddress_id 回调里面才能知道去读哪一个地址的流param->use_rtmpaddress_id = rtmpaddress_id;pb = avio_alloc_context((unsigned char *)buf_info.Buf, buf_info.BufLen,0, param,param->read_packet_cb, NULL,param->seek_cb);if (!pb) {printf("ERROR : avio alloc failed!\n");return -1;}//step2:探测流格式if (av_probe_input_buffer2(pb, &piFmt, "", NULL,0,0) < 0) {printf("ERROR : probe failed!\n");return -1;} else {printf("SUCCESS :probe success!\n");printf("format: %s[%s]\n", piFmt->name, piFmt->long_name);}m_pFmt = avformat_alloc_context();m_pFmt->pb = pb; //step3:这一步很关键//step4:打开流if (avformat_open_input(&m_pFmt, "", piFmt, NULL) < 0){printf("ERROR : avformat open failed.\n");return -1;} else {printf("SUCCESS : open stream success!\n");}av_dump_format(m_pFmt, 0, "", 0);这样就和本地文件一样用av_read_frame读取数据read_packet_cb中放入数据。
2:ffmpeg的IO输出
<pre name="code" class="cpp">Module_StreamInfo * module_streaminfo = in_video->second;AVFormatContext * formatcontext = avformat_alloc_context();AVIOContext * pb = NULL;AVStream * ovideo_st = NULL; Io_Buf_Info io_buf_info_video;io_cb_write_pram * cb_pram_video = NULL;cb_pram_video = (io_cb_write_pram *)malloc(sizeof(io_cb_write_pram )* 1);cb_pram_video->thisclass = this;cb_pram_video->pram = module_streaminfo;m_list_cb_write_pram[module_streaminfo->stream_id] = (cb_pram_video);//step1 申请一个AVFormatContext if (m_mux_info.mux_format == MuxFormat_Flv){avformat_alloc_output_context2(&formatcontext, NULL,"flv",NULL); }else if (m_mux_info.mux_format == MuxFormat_Mpegts){avformat_alloc_output_context2(&formatcontext, NULL,"mpegts",NULL); }else if (m_mux_info.mux_format == MuxFormat_Mp4){avformat_alloc_output_context2(&formatcontext, NULL,"mp4",NULL); }else{avformat_alloc_output_context2(&formatcontext, NULL,"flv",NULL); }if (!formatcontext) { return -1;} //step2申请一个AVIOContext//这里分配大小一定要是4096的整数倍,足够一帧大小否则中断io_buf_info_video.BufLen = (module_streaminfo->VideoInfo.Width * module_streaminfo->VideoInfo.Height * 3 /20 + 100) /4096 * 4096;io_buf_info_video.Buf =(char *)calloc(module_streaminfo->BufLen,sizeof(char));m_list_format_io_buf[in_video->first] = (io_buf_info_video);pb = avio_alloc_context((unsigned char *)m_list_format_io_buf[in_video->first].Buf,m_list_format_io_buf[in_video->first].BufLen,1,cb_pram_video, NULL, cb_write_data, NULL);if (!pb) {printf("error : avio alloc failed!\n");return -1;}//step3:这一步很关键,将输出的buf和AVFormatContext关联formatcontext->pb = pb; //The caller has supplied a custom AVIOContext, don't avio_close() it.//AVFMT_FLAG_FLUSH_PACKETS这个值相当重要,他决定每次写av_interleaved_write_frame,是否立刻返回formatcontext->flags = AVFMT_FLAG_CUSTOM_IO | AVFMT_FLAG_FLUSH_PACKETS; //step4 添加流信息ovideo_st = add_out_stream2(formatcontext,AVMEDIA_TYPE_VIDEO,module_streaminfo);if (ovideo_st == NULL){return -1;}//这里要填写1否则中断av_dump_format(formatcontext, 0, "", 1);ret = avformat_write_header(formatcontext, NULL); if (ret != 0) { printf("Call avformat_write_header function failed.\n"); return -1; }avio_flush(pb);这样在cb_write_data回调中就有要的数据了。
如有错误请指正:
交流请加QQ群:62054820
QQ:379969650.
0 0
- ffmpeg关于io的输入输出操作
- ffmpeg的IO操作
- ffmpeg的IO操作
- ffmpeg的IO操作
- ffmpeg的IO操作
- ffmpeg的IO操作
- 关于单片机IO口输入输出的理解!
- 关于Java基础输入输出IO的问题
- Java输入输出(IO)操作
- C++关于文件输入输出的简单操作
- labview下关于文件输入输出io口的操作
- c++重载io输入输出操作符的一个简单例子
- 黑马程序员训练营-----IO 输入输出流操作的规律
- 92、java的IO操作-标准输入输出流
- 文件的输入输出 IO
- IO流的输入输出
- Java的IO输入输出
- python的IO输入输出
- spark-shell 统计hbase数据条目数
- 列表搜索条件美化
- windows bat无限循环的实现
- socket.io 网络聊天室
- web项目如何获取容器
- ffmpeg关于io的输入输出操作
- HP Laserjet1010网络打印机安装 win7 64bit
- Android:视图绘制(五) ------Paint进阶之PathEffect
- Eclipse 配置黑色主题
- 172. Factorial Trailing Zeroes
- java发送http的get、post请求
- 全局引用和本地引用
- Android进阶——RecycleView的使用之自定义聊天界面(三)
- Java面试题大全