progress
s-ol
4 years ago
0 | 0 | #include <stdlib.h> |
1 | 1 | #include <obs.h> |
2 | #include <util/platform.h> | |
2 | 3 | #include <obs-module.h> |
3 | 4 | #include <bmusb/bmusb.h> |
4 | ||
5 | #include <stdio.h> | |
5 | #include <iostream> | |
6 | 6 | |
7 | 7 | using bmusb::BMUSBCapture; |
8 | 8 | using bmusb::FrameAllocator; |
10 | 10 | using bmusb::AudioFormat; |
11 | 11 | |
12 | 12 | struct bmusb_inst { |
13 | obs_source_t *source; | |
14 | BMUSBCapture *capture; | |
15 | bool initialized; | |
13 | obs_source_t *source; | |
14 | BMUSBCapture *capture; | |
15 | bool initialized; | |
16 | 16 | }; |
17 | 17 | |
18 | 18 | static const char *bmusb_getname(void *unused) |
27 | 27 | |
28 | 28 | if (rt) { |
29 | 29 | if (rt->initialized) { |
30 | delete rt->capture; | |
30 | 31 | BMUSBCapture::stop_bm_thread(); |
31 | delete rt->capture; | |
32 | 32 | } |
33 | 33 | |
34 | 34 | bfree(rt); |
47 | 47 | FrameAllocator::Frame video_frame, size_t video_offset, VideoFormat video_format, |
48 | 48 | FrameAllocator::Frame audio_frame, size_t audio_offset, AudioFormat audio_format |
49 | 49 | ) { |
50 | printf("got fraem %d\n", timecode); | |
51 | UNUSED_PARAMETER(video_format); | |
52 | UNUSED_PARAMETER(audio_format); | |
53 | rt->capture->get_video_frame_allocator()->release_frame(video_frame); | |
54 | rt->capture->get_audio_frame_allocator()->release_frame(audio_frame); | |
50 | uint64_t cur_time = os_gettime_ns(); | |
51 | ||
52 | if (!video_format.has_signal) { | |
53 | std::cerr << "scanning" << std::endl; | |
54 | video_frame.owner->release_frame(video_frame); | |
55 | audio_frame.owner->release_frame(audio_frame); | |
56 | return; | |
57 | } | |
58 | ||
59 | uint8_t num_fields = video_format.interlaced ? 2 : 1; | |
60 | if (video_format.interlaced) { | |
61 | std::cerr << "oh no, video is interlaced" << std::endl; | |
62 | video_frame.owner->release_frame(video_frame); | |
63 | audio_frame.owner->release_frame(audio_frame); | |
64 | return; | |
65 | } | |
66 | ||
67 | if (video_frame.interleaved) { | |
68 | std::cerr << "oh no, video is interleaved" << std::endl; | |
69 | video_frame.owner->release_frame(video_frame); | |
70 | audio_frame.owner->release_frame(audio_frame); | |
71 | return; | |
72 | } | |
73 | struct obs_source_frame frame; | |
74 | frame.width = video_format.width; | |
75 | frame.height = video_format.height; | |
76 | frame.format = VIDEO_FORMAT_UYVY; | |
77 | frame.linesize[0] = frame.width * 2; | |
78 | frame.data[0] = video_frame.data + video_offset; | |
79 | frame.timestamp = cur_time; | |
80 | obs_source_output_video(rt->source, &frame); | |
81 | video_frame.owner->release_frame(video_frame); | |
82 | ||
83 | #ifdef BMUSB_AUDIO | |
84 | struct obs_source_audio audio; | |
85 | audio.samples_per_sec = audio_format.sample_rate; | |
86 | audio.frames = (audio_frame.len > audio_offset) ? (audio_frame.len - audio_offset) / audio_format.num_channels / (audio_format.bits_per_sample / 8) : 0; | |
87 | audio.format = AUDIO_FORMAT_32BIT; | |
88 | audio.data[0] = audio_frame.data + audio_offset; | |
89 | audio.timestamp = cur_time; | |
90 | switch (audio_format.num_channels) { | |
91 | case 1: audio.speakers = SPEAKERS_MONO; break; | |
92 | case 2: audio.speakers = SPEAKERS_STEREO; break; | |
93 | case 3: audio.speakers = SPEAKERS_2POINT1; break; | |
94 | case 4: audio.speakers = SPEAKERS_4POINT0; break; | |
95 | case 5: audio.speakers = SPEAKERS_4POINT1; break; | |
96 | case 6: audio.speakers = SPEAKERS_5POINT1; break; | |
97 | case 8: audio.speakers = SPEAKERS_7POINT1; break; | |
98 | default: audio.speakers = SPEAKERS_UNKNOWN; break; | |
99 | } | |
100 | obs_source_output_audio(rt->source, &audio); | |
101 | #endif | |
102 | audio_frame.owner->release_frame(audio_frame); | |
55 | 103 | } |
56 | 104 | ); |
57 | 105 | rt->capture->configure_card(); |
68 | 116 | struct obs_source_info bmusb_source_info = { |
69 | 117 | .id = "bmusb", |
70 | 118 | .type = OBS_SOURCE_TYPE_INPUT, |
119 | #ifdef BMUSB_AUDIO | |
120 | .output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO, | |
121 | #else | |
71 | 122 | .output_flags = OBS_SOURCE_ASYNC_VIDEO, |
123 | #endif | |
72 | 124 | .get_name = bmusb_getname, |
73 | 125 | .create = bmusb_create, |
74 | 126 | .destroy = bmusb_destroy, |