return false;
}
+// There are seemingly no direct indicators of sample rate; you just get
+// one frame's worth and have to guess from that.
+int guess_sample_rate(const VideoFormat &video_format, size_t len, int default_rate)
+{
+ size_t num_samples = len / 3 / 8;
+ size_t num_samples_per_second = num_samples * video_format.frame_rate_nom / video_format.frame_rate_den;
+
+ // See if we match or are very close to any of the mandatory HDMI sample rates.
+ const int candidate_sample_rates[] = { 32000, 44100, 48000 };
+ for (int rate : candidate_sample_rates) {
+ if (abs(int(num_samples_per_second) - rate) < 50) {
+ return rate;
+ }
+ }
+
+ fprintf(stderr, "%ld samples at %d/%d fps (%ld Hz) matches no known sample rate, keeping capture at %d Hz\n",
+ num_samples, video_format.frame_rate_nom, video_format.frame_rate_den, num_samples_per_second, default_rate);
+ return default_rate;
+}
+
} // namespace
FrameAllocator::~FrameAllocator() {}
if (has_dequeue_callbacks) {
dequeue_init_callback();
}
+ size_t last_sample_rate = 48000;
while (!dequeue_thread_should_quit) {
unique_lock<mutex> lock(queue_lock);
queues_not_empty.wait(lock, [this]{ return dequeue_thread_should_quit || (!pending_video_frames.empty() && !pending_audio_frames.empty()); });
AudioFormat audio_format;
audio_format.bits_per_sample = 24;
audio_format.num_channels = 8;
+ audio_format.sample_rate = last_sample_rate;
if (uint16_less_than_with_wraparound(video_timecode, audio_timecode)) {
printf("Video block 0x%04x without corresponding audio block, dropping.\n",
video_timecode);
VideoFormat video_format;
audio_format.id = audio_frame.format;
if (decode_video_format(video_frame.format, &video_format)) {
+ if (audio_frame.frame.len != 0) {
+ audio_format.sample_rate = guess_sample_rate(video_format, audio_frame.frame.len, last_sample_rate);
+ last_sample_rate = audio_format.sample_rate;
+ }
frame_callback(video_timecode,
video_frame.frame, HEADER_SIZE, video_format,
audio_frame.frame, AUDIO_HEADER_SIZE, audio_format);
} else {
+ video_frame_allocator->release_frame(video_frame.frame);
+ audio_format.sample_rate = last_sample_rate;
frame_callback(video_timecode,
FrameAllocator::Frame(), 0, video_format,
audio_frame.frame, AUDIO_HEADER_SIZE, audio_format);