ffmpeg mp4解码管道输出的问题
时间:2022-07-26
本文章向大家介绍ffmpeg mp4解码管道输出的问题,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
测试代码:
HANDLE hReadPipe, hWritePipe;
SECURITY_ATTRIBUTES sa;
int testFfmpegPipe() // 测试ffmpeg管道io
{
char cmdString[200]{ "ffmpeg -i D:\vc\images\small.mp4 -f image2pipe -pix_fmt bgr24 -vcodec rawvideo -" };
// 创建管道
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL; //使用系统默认的安全描述符
sa.bInheritHandle = TRUE; //一定要为TRUE,不然句柄不能被继承。
CreatePipe(&hReadPipe, &hWritePipe, &sa, 0); //创建pipe内核对象,设置好hReadPipe,hWritePipe.
// 创建dos子进程
STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWritePipe; //设定其标准错误输出为hWritePipe
si.hStdOutput = hWritePipe; //设定其标准输出为hWritePipe
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if (!CreateProcess(NULL, cmdString
, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) {
//MessageBox("Error on CreateProcess()");
return 1;
}
CloseHandle(hWritePipe);
Mat rgba = Mat::zeros(cv::Size(560,320), CV_8UC3);
const uint32_t framebytes = 560 * 320 * 3 * 1.1;
char buffer[framebytes] = { 0 };
DWORD bytesRead;
uint32_t a = 0;
while (true) {
if (ReadFile(hReadPipe, buffer, framebytes, &bytesRead, NULL) == NULL)//从hReadPipe中读出数据.
break;
if (bytesRead<5000) {
cout << buffer << endl;
}
cout << bytesRead << endl;
}
return 0;
}
视频是 560*320,166帧
上面主进程读取的字节数如下:共,2834行,与理想的166帧166行相差甚远,每帧560*320*3=537600也和下面的不一样。
44
1686
67
701
17
93
34
391
32768
32768
32768
32768
32768
32768
32768
32768
32768
32768
32768
32768
32768
32768
32768
32768
13312
...
32768
32768
32768
32768
13312
100
104
开头和结果这些小字节的都是解码的什么鬼哦
打印出来才发现,是ffmpeg的各种提示信息。。。。
ffmpeg version 4.3.1-full_build-www.gyan.dev
Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 10.2.0 (Rev1, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-lzma --enable-libsnappy --enable-zlib --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libzvbi --enable-librav1e --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libwavpack --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
libavutil 56. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
把头尾的这些小字节去掉,总数刚好对的上,看来这个buffer是固定了32768=2^15不够一帧,要自己循环处理。
上面16个32768 + 13312 刚好等于一帧大小。
好了,需要ffmpeg屏蔽中间提示信息,加上这个就好了:
-loglevel quiet
加上帧大小,循环读出,满足一帧容量后输出,最终代码如下:
HANDLE hReadPipe, hWritePipe;
SECURITY_ATTRIBUTES sa;
int testFfmpegPipe() // 测试ffmpeg管道io
{
char cmdString[200]{ "ffmpeg -loglevel quiet -i D:\vc\images\small.mp4 -f image2pipe -pix_fmt bgr24 -vcodec rawvideo -" };
// 创建管道
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL; //使用系统默认的安全描述符
sa.bInheritHandle = TRUE; //一定要为TRUE,不然句柄不能被继承。
CreatePipe(&hReadPipe, &hWritePipe, &sa, 0); //创建pipe内核对象,设置好hReadPipe,hWritePipe.
// 创建dos子进程
STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWritePipe; //设定其标准错误输出为hWritePipe
si.hStdOutput = hWritePipe; //设定其标准输出为hWritePipe
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if (!CreateProcess(NULL, cmdString
, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) {
//MessageBox("Error on CreateProcess()");
return 1;
}
CloseHandle(hWritePipe);
Mat rgba = Mat::zeros(cv::Size(560,320), CV_8UC3);
const uint32_t framebytes = 560 * 320 * 3;
char buffer[framebytes] = { 0 };
uint32_t readCount = 0;
DWORD bytesRead;
while (true) {
if (ReadFile(hReadPipe, buffer, framebytes, &bytesRead, NULL) == NULL) { //从hReadPipe中读出数据.
break;
}
memcpy(rgba.data + readCount, buffer, bytesRead);
readCount += bytesRead;
if (readCount == framebytes) { // 拿到完整一帧了
cout << "frame finished." << endl;
readCount = 0;
waitKey(100);
imshow("frame", rgba);
//imwrite("D:\vc\images\xx.bmp", rgba);
}
}
return 0;
}
- 关于Java你不知道的10件事
- 03-移动端开发教程-CSS3新特性(下)
- 大数据面试题整理
- 02-移动端开发教程-CSS3新特性(中)
- 强悍!Java 9 中的9个新特性
- 神经网络反向传播梯度计算数学原理
- Spring Boot 1.5.10 发布:修复重要安全漏洞!!!
- 从零开始写项目第三篇【在线聊天和个人收藏夹】
- TiDB 源码阅读系列文章(六)Select 语句概览
- 从零开始写项目第四篇【搭建Linux环境】
- salesforce零基础学习(八十六)Ajax Toolkit (VF页面中使用及javascript action使用)
- salesforce零基础学习(八十五)streaming api 简单使用(接近实时获取你需要跟踪的数据的更新消息状态)
- 深入nDPI
- 44个Java代码性能优化总结
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- QPainter的fillRect函数-QGradient-Preset渐变颜色预设值
- 深度学习|Tensorflow2.0进阶
- Mumble——简介及搭建
- 网站开启HSTS增强安全性
- 形式化分析工具(六):HLPSL Tutorial(Example 4,other)
- Typecho回复可见功能
- 微信小程序开发实战(13):图像组件(image)
- Typecho文章代码高亮功能
- “数据分析师”面试最怕被问到的SQL优化问题(下)
- 普通小程序的订阅消息不再限制时间
- Telnet 配置实验
- 网站加速那些事
- Python逻辑运算
- 获取小程序码并接受buffer流保存为图片的方法
- 在Python中使用OpenCV绘画和素描