This repository has been archived by the owner on Apr 17, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVideoUtils.cpp
86 lines (76 loc) · 2.47 KB
/
VideoUtils.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include "VideoUtils.hpp"
#ifndef __APPLE__
#include <Vfw.h>
#include <vector>
#include <windows.h>
#pragma comment(lib, "Vfw32.lib")
using namespace VideoUtils;
PAVIFILE pfile;
PAVISTREAM stream;
AVIFILEINFOA info;
long current_frame = 0;
long max_frames = 0;
std::vector<Image> cache{};
void VideoUtils::get_video_info() {
AVIFileInfo(pfile, &info, sizeof(AVIFILEINFO));
}
long VideoUtils::num_frames() { return AVIStreamLength(stream); }
void VideoUtils::open_video(const char *video_path) {
cache.clear();
AVIFileInit();
current_frame = 0;
max_frames = 0;
AVIFileOpen(&pfile, video_path, OF_READ, NULL);
HRESULT hr = AVIStreamOpenFromFile(&stream, video_path, streamtypeVIDEO, 0,
OF_READ, NULL);
get_video_info();
max_frames = num_frames();
debugger("frame: %d", max_frames);
cache.resize(max_frames);
}
Image VideoUtils::get_frame(int frame_index) {
current_frame = frame_index;
// if (cache[frame_index].contain_content())
// return cache[frame_index];
BITMAPINFOHEADER bih;
ZeroMemory(&bih, sizeof(BITMAPINFOHEADER));
bih.biBitCount = 24;
bih.biClrImportant = 0;
bih.biClrUsed = 0;
bih.biCompression = BI_RGB;
bih.biPlanes = 1;
bih.biSize = 40;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biSizeImage = (((bih.biWidth * 3) + 3) & 0xFFFC) * bih.biHeight;
PGETFRAME pframe = AVIStreamGetFrameOpen(stream, NULL);
BYTE *pDIB = (BYTE *)AVIStreamGetFrame(pframe, current_frame);
if (pDIB == NULL) {
debugger("reading failed");
Image tmp;
// return an empty image
return tmp;
}
// reading is fine
RtlMoveMemory(&bih.biSize, pDIB, sizeof(BITMAPINFOHEADER));
BYTE *Bits = new BYTE[bih.biSizeImage];
RtlMoveMemory(Bits, pDIB + sizeof(BITMAPINFOHEADER), bih.biSizeImage);
AVIStreamGetFrameClose(pframe); // rmb to close the frame decoder, otherwise
// it can cause decoder failure
Image tmp;
tmp.set(Bits, bih.biWidth, bih.biHeight);
// cache[frame_index] = tmp;
return tmp;
}
Image VideoUtils::next_frame() {
current_frame = (current_frame + 1) % (max_frames);
debugger("current: %d", current_frame);
return get_frame(current_frame);
}
#else
void VideoUtils::get_video_info() {}
long VideoUtils::num_frames() {}
void VideoUtils::open_video(const char *video_path) {}
Image VideoUtils::get_frame(int frame_index) {}
Image VideoUtils::next_frame() {}
#endif