git.s-ol.nu obs-bmusb / b1d68dd
color space and range parameters s-ol 5 months ago
1 changed file(s) with 90 addition(s) and 43 deletion(s). Raw diff Collapse all Expand all
55 #include <bmusb/fake_capture.h>
66 #include <iostream>
77
8 #undef BMUSB_AUDIO
8 #define COLOR_SPACE "color_space"
9 #define COLOR_RANGE "color_range"
10
11 #define TEXT_COLOR_SPACE obs_module_text("ColorSpace")
12 #define TEXT_COLOR_SPACE_DEFAULT obs_module_text("ColorSpace.Default")
13 #define TEXT_COLOR_RANGE obs_module_text("ColorRange")
14 #define TEXT_COLOR_RANGE_DEFAULT obs_module_text("ColorRange.Default")
15 #define TEXT_COLOR_RANGE_PARTIAL obs_module_text("ColorRange.Partial")
16 #define TEXT_COLOR_RANGE_FULL obs_module_text("ColorRange.Full")
917
1018 namespace b = bmusb;
1119
1321 obs_source_t *source;
1422 b::CaptureInterface *capture;
1523 bool initialized;
24
25 video_colorspace space = VIDEO_CS_DEFAULT;
26 video_range_type range = VIDEO_RANGE_DEFAULT;
1627 };
1728
18 static const char *bmusb_getname(void *unused)
29 static const char *bmusb_get_name(void *unused)
1930 {
2031 UNUSED_PARAMETER(unused);
2132 return "Blackmagic USB3 source (bmusb)";
2233 }
2334
24 static void bmusb_destroy(void *data)
25 {
26 struct bmusb_inst *rt = (bmusb_inst *) data;
27
28 if (rt) {
29 std::cout << "DESTROY\n";
30 if (rt->initialized) {
31 delete rt->capture;
32 b::BMUSBCapture::stop_bm_thread();
33 }
34
35 bfree(rt);
36 }
37 }
38
39
4035 static void *bmusb_create(obs_data_t *settings, obs_source_t *source)
4136 {
4237 struct bmusb_inst *rt = (bmusb_inst *) bzalloc(sizeof(struct bmusb_inst));
43 rt->source = source;
4438
45 rt->capture = new b::BMUSBCapture(0); // @TODO select card
39 *rt = {
40 .source = source,
41 .capture = new b::BMUSBCapture(0), // @TODO select card
42 };
43
4644 rt->capture->set_pixel_format(b::PixelFormat_8BitYCbCr);
4745 rt->capture->set_frame_callback(
4846 [rt](uint16_t timecode,
5351
5452 if (!video_format.has_signal) {
5553 std::cerr << "scanning" << std::endl;
56 video_frame.owner->release_frame(video_frame);
57 audio_frame.owner->release_frame(audio_frame);
58 return;
59 }
60
61 if (video_format.interlaced) {
62 std::cerr << "oh no, video is interlaced" << std::endl;
63 video_frame.owner->release_frame(video_frame);
64 audio_frame.owner->release_frame(audio_frame);
65 return;
66 }
67
68 if (video_frame.interleaved) {
69 std::cerr << "oh no, video is interleaved" << std::endl;
7054 video_frame.owner->release_frame(video_frame);
7155 audio_frame.owner->release_frame(audio_frame);
7256 return;
8670 frame.linesize[0] = video_format.stride;
8771 frame.data[0] = video_frame.data + video_offset;
8872 frame.timestamp = cur_time;
89 frame.full_range = 1;
9073 frame.flip = 0;
91 video_format_get_parameters(VIDEO_CS_DEFAULT, VIDEO_RANGE_FULL,
74 frame.full_range = rt->range == VIDEO_RANGE_FULL;
75 video_format_get_parameters(rt->space, rt->range,
9276 frame.color_matrix, frame.color_range_min, frame.color_range_max);
9377
9478
11397 default: audio.speakers = SPEAKERS_UNKNOWN; break;
11498 }
11599 obs_source_output_audio(rt->source, &audio);
100 #else
101 UNUSED_PARAMETER(audio_offset);
102 UNUSED_PARAMETER(audio_format);
116103 #endif
117104 audio_frame.owner->release_frame(audio_frame);
105
106 UNUSED_PARAMETER(timecode);
118107 }
119108 );
120109 rt->capture->configure_card();
128117 return rt;
129118 }
130119
120 static void bmusb_destroy(void *data)
121 {
122 struct bmusb_inst *rt = (bmusb_inst *) data;
123 if (rt) {
124 if (rt->initialized) {
125 delete rt->capture;
126 b::BMUSBCapture::stop_bm_thread();
127 }
128
129 bfree(rt);
130 }
131 }
132
133 static void bmusb_update(void *data, obs_data_t *settings)
134 {
135 struct bmusb_inst *rt = (bmusb_inst *) data;
136
137 rt->space = (video_colorspace)obs_data_get_int(settings, COLOR_SPACE);
138 rt->range = (video_range_type)obs_data_get_int(settings, COLOR_RANGE);
139 }
140
141 static void bmusb_get_defaults(obs_data_t *settings)
142 {
143 obs_data_set_default_int(settings, COLOR_SPACE, VIDEO_CS_DEFAULT);
144 obs_data_set_default_int(settings, COLOR_RANGE, VIDEO_RANGE_DEFAULT);
145 }
146
147 static obs_properties_t *bmusb_get_properties(void *data)
148 {
149 obs_properties_t *props = obs_properties_create();
150
151 obs_property_t *list = obs_properties_add_list(props, COLOR_SPACE, TEXT_COLOR_SPACE,
152 OBS_COMBO_TYPE_LIST,
153 OBS_COMBO_FORMAT_INT);
154 obs_property_list_add_int(list, TEXT_COLOR_SPACE_DEFAULT,
155 VIDEO_CS_DEFAULT);
156 obs_property_list_add_int(list, "BT.601", VIDEO_CS_601);
157 obs_property_list_add_int(list, "BT.709", VIDEO_CS_709);
158
159 list = obs_properties_add_list(props, COLOR_RANGE, TEXT_COLOR_RANGE,
160 OBS_COMBO_TYPE_LIST,
161 OBS_COMBO_FORMAT_INT);
162 obs_property_list_add_int(list, TEXT_COLOR_RANGE_DEFAULT,
163 VIDEO_RANGE_DEFAULT);
164 obs_property_list_add_int(list, TEXT_COLOR_RANGE_PARTIAL,
165 VIDEO_RANGE_PARTIAL);
166 obs_property_list_add_int(list, TEXT_COLOR_RANGE_FULL,
167 VIDEO_RANGE_FULL);
168
169 UNUSED_PARAMETER(data);
170 return props;
171 }
172
173
131174 struct obs_source_info bmusb_source_info = {
132 .id = "bmusb",
133 .type = OBS_SOURCE_TYPE_INPUT,
175 .id = "bmusb",
176 .type = OBS_SOURCE_TYPE_INPUT,
134177 #ifdef BMUSB_AUDIO
135 .output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO,
178 .output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO,
136179 #else
137 .output_flags = OBS_SOURCE_ASYNC_VIDEO,
180 .output_flags = OBS_SOURCE_ASYNC_VIDEO,
138181 #endif
139 .get_name = bmusb_getname,
140 .create = bmusb_create,
141 .destroy = bmusb_destroy,
182 .get_name = bmusb_get_name,
183 .create = bmusb_create,
184 .destroy = bmusb_destroy,
185 .get_defaults = bmusb_get_defaults,
186 .get_properties = bmusb_get_properties,
187 .update = bmusb_update,
142188 };
143189
144190 OBS_DECLARE_MODULE()
191 OBS_MODULE_USE_DEFAULT_LOCALE("decklink", "en-US")
145192
146193 extern "C" bool obs_module_load(void)
147194 {