string pathname = search_for_file(filename);
if (filename.empty()) {
fprintf(stderr, "%s not found, sleeping one second and trying again...\n", filename.c_str());
+ send_disconnected_frame();
producer_thread_should_quit.sleep_for(seconds(1));
continue;
}
if (!play_video(pathname)) {
// Error.
fprintf(stderr, "Error when playing %s, sleeping one second and trying again...\n", pathname.c_str());
+ send_disconnected_frame();
producer_thread_should_quit.sleep_for(seconds(1));
continue;
}
}
}
+void FFmpegCapture::send_disconnected_frame()
+{
+ // Send an empty frame to signal that we have no signal anymore.
+ FrameAllocator::Frame video_frame = video_frame_allocator->alloc_frame();
+ if (video_frame.data) {
+ VideoFormat video_format;
+ video_format.width = width;
+ video_format.height = height;
+ video_format.stride = width * 4;
+ video_format.frame_rate_nom = 60;
+ video_format.frame_rate_den = 1;
+ video_format.is_connected = false;
+
+ video_frame.len = width * height * 4;
+ memset(video_frame.data, 0, video_frame.len);
+
+ frame_callback(timecode++,
+ video_frame, /*video_offset=*/0, video_format,
+ FrameAllocator::Frame(), /*audio_offset=*/0, AudioFormat());
+ }
+}
+
bool FFmpegCapture::play_video(const string &pathname)
{
// Note: Call before open, not after; otherwise, there's a race.
void configure_card() override;
void start_bm_capture() override;
void stop_dequeue_thread() override;
-
- // TODO: Specify error status through this.
- bool get_disconnected() const override { return false; }
+ bool get_disconnected() const override { return false; } // We never unplug.
std::map<uint32_t, bmusb::VideoMode> get_available_video_modes() const;
void set_video_mode(uint32_t video_mode_id) override {} // Ignore.
private:
void producer_thread_func();
+ void send_disconnected_frame();
bool play_video(const std::string &pathname);
void internal_rewind();