-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcapture.cpp
79 lines (67 loc) · 1.87 KB
/
capture.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
#include "capture.hpp"
Capture::Capture(std::string filename, std::string format, int width, int height)
:context(nullptr)
,filename(filename)
,format(format)
,width(width)
,height(height)
,stream(0)
{
avdevice_register_all();
av_register_all();
}
Capture::~Capture() {
if (context != nullptr) {
avformat_free_context(context);
}
}
int Capture::init() {
auto input = av_find_input_format(format.c_str());
if (!input) {
return 1;
}
std::string size = std::to_string(width) + "x" + std::to_string(height);
AVDictionary *opts = nullptr;
av_dict_set(&opts, "video_size", size.c_str(), 0);
int err = avformat_open_input(&context, filename.c_str(), input, &opts);
av_dict_free(&opts);
if (err != 0) {
return 2;
}
stream = this->searchStream(AVMEDIA_TYPE_VIDEO, AV_PIX_FMT_UYVY422);
if (stream < 0) {
return 3;
}
if (context->streams[stream]->codecpar->width != width ||
context->streams[stream]->codecpar->height != height ) {
return 4;
}
av_dump_format(context, 0, filename.c_str(), 0);
return 0;
}
int Capture::searchStream(int type, int format) {
for(unsigned int i=0; i<context->nb_streams; i++) {
if(context->streams[i]->codecpar->codec_type==type &&
context->streams[i]->codecpar->format==format) {
return i;
}
}
return -1;
}
bool Capture::done() {
return false; // let's stream forever and ever and ever...
}
int Capture::decode(std::function<void (uint8_t*)> callback) {
AVPacket packet;
int err = av_read_frame(context, &packet);
if (err) {
return err;
}
// check if current frame is from the stream we are processing
if (packet.stream_index != stream) {
return 1;
}
callback(packet.data);
av_packet_unref(&packet);
return 0;
}