从大YUV文件中提取一些YUV帧

时间:2013-07-31 09:57:49

标签: image-processing video-capture video-processing yuv

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

3 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分: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

答案 2 :(得分:0)

<强>方法一:

如果您正在使用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