我正在寻找 WIN32 程序将部分 1920x1080px 4:2:0 .YUV 大文件(cca. 43GB)复制到较小的 .YUV 文件中。我用过的所有程序,即YUV播放器,当时只能复制/保存1帧。将 YUV 原始数据切割成更小的 YUV 视频(图像)的最简单/合适的方法是什么?类似于 ffmpeg 命令的东西:
ffmpeg -ss [start_seconds] -t [duration_seconds] -i [input_file] [outputfile]
我正在寻找 WIN32 程序将部分 1920x1080px 4:2:0 .YUV 大文件(cca. 43GB)复制到较小的 .YUV 文件中。我用过的所有程序,即YUV播放器,当时只能复制/保存1帧。将 YUV 原始数据切割成更小的 YUV 视频(图像)的最简单/合适的方法是什么?类似于 ffmpeg 命令的东西:
ffmpeg -ss [start_seconds] -t [duration_seconds] -i [input_file] [outputfile]
如果你有python可用,你可以使用这种方法将每个帧存储为一个单独的文件:
src_yuv = open(self.filename, 'rb')
for i in xrange(NUMBER_OF_FRAMES):
data = src_yuv.read(NUMBER_OF_BYTES)
fname = "frame" + "%d" % i + ".yuv"
dst_yuv = open(fname, 'wb')
dst_yuv.write(data)
sys.stdout.write('.')
sys.stdout.flush()
dst_yuv.close()
src_yuv.close()
只需将大写变量更改为有效数字,例如一帧 1080p 的 NUMBER_OF_BYTES 应该是1920*1080*3/2=3110400
或者,如果您安装 cygwin,您可以使用该dd
工具,例如获取 1080p 剪辑的第一帧:
dd bs=3110400 count=1 if=sample.yuv of=frame1.yuv
这是用 C++ 编写的代码的最小工作示例,如果有人会寻找一个简单的解决方案:
// include libraries
#include <fstream>
using namespace std;
#define P420 1.5
const int IMAGE_SIZE = 1920*1080; // ful HD image size in pixels
const double IMAGE_CONVERTION = P420;
int n_frames = 300; // set number of frames to copy
int skip_frames = 500; // set number of frames to skip from the begining of the input file
char in_string[] = "F:\\BigBucksBunny\\yuv\\BigBuckBunny_1920_1080_24fps.yuv";
char out_string[] = "out.yuv";
//////////////////////
// main
//////////////////////
int main(int argc, char** argv)
{
double image_size = IMAGE_SIZE * IMAGE_CONVERTION;
long file_size = 0;
// IO files
ofstream out_file(out_string, ios::out | ios::binary);
ifstream in_file(in_string, ios::in | ios::binary);
// error cheking, like check n_frames+skip_frames overflow
//
// TODO
// image buffer
char* image = new char[(int)image_size];
// skip frames
in_file.seekg(skip_frames*image_size);
// read/write image buffer one by one
for(int i = 0; i < n_frames; i++)
{
in_file.read(image, image_size);
out_file.write(image, image_size);
}
// close the files
out_file.close();
in_file.close();
printf("Copy finished ...");
return 0;
}
方法1:
如果您使用的是 gstreamer,并且您只想从大型 yuv 文件中获取前 X 个 yuv 帧,那么您可以使用以下方法
gst-launch-1.0 filesrc num-buffers=X location="Your_large.yuv" ! videoparse width=x height=y format="xy" ! filesink location="FirstXframes.yuv"
方法2:
计算1帧的大小,然后使用split
实用程序将大文件分成小文件。
利用
split -b size_in_bytes Large_file prefix