0

我正在寻找 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]
4

3 回答 3

2

如果你有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
于 2013-08-22T20:01:20.967 回答
2

这是用 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;
}
于 2013-07-31T15:18:30.757 回答
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
于 2018-04-12T18:25:15.733 回答