#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <cstddef>
#include <DeckLinkAPI.h>
#include <DeckLinkAPIModes.h>
#include "bmusb/bmusb.h"
+#define FRAME_SIZE (8 << 20) // 8 MB.
+
using namespace std;
using namespace std::placeholders;
exit(1);
}
- if (input->EnableAudioInput(48000, bmdAudioSampleType16bitInteger, 2) != S_OK) {
+ if (input->EnableAudioInput(48000, bmdAudioSampleType32bitInteger, 2) != S_OK) {
fprintf(stderr, "Failed to enable audio input for card %d\n", card_index);
exit(1);
}
if (current_audio_frame.data != nullptr) {
const uint8_t *frame_bytes;
audio_frame->GetBytes((void **)&frame_bytes);
+ current_audio_frame.len = sizeof(int32_t) * 2 * num_samples;
- memcpy(current_audio_frame.data, frame_bytes, sizeof(int32_t) * 2 * num_samples);
+ memcpy(current_audio_frame.data, frame_bytes, current_audio_frame.len);
audio_format.bits_per_sample = 32;
audio_format.num_channels = 2;
return S_OK;
}
+void DeckLinkCapture::configure_card()
+{
+ if (video_frame_allocator == nullptr) {
+ set_video_frame_allocator(new MallocFrameAllocator(FRAME_SIZE, NUM_QUEUED_VIDEO_FRAMES)); // FIXME: leak.
+ }
+ if (audio_frame_allocator == nullptr) {
+ set_audio_frame_allocator(new MallocFrameAllocator(65536, NUM_QUEUED_AUDIO_FRAMES)); // FIXME: leak.
+ }
+}
+
void DeckLinkCapture::start_bm_capture()
{
if (input->StartStreams() != S_OK) {
void convert_fixed24_to_fp32(float *dst, size_t out_channels, const uint8_t *src, size_t in_channels, size_t num_samples)
{
+ assert(in_channels >= out_channels);
for (size_t i = 0; i < num_samples; ++i) {
for (size_t j = 0; j < out_channels; ++j) {
uint32_t s1 = *src++;
}
}
+void convert_fixed32_to_fp32(float *dst, size_t out_channels, const uint8_t *src, size_t in_channels, size_t num_samples)
+{
+ assert(in_channels >= out_channels);
+ for (size_t i = 0; i < num_samples; ++i) {
+ for (size_t j = 0; j < out_channels; ++j) {
+ // Note: Assumes little-endian.
+ int32_t s = *(int32_t *)src;
+ dst[i * out_channels + j] = s * (1.0f / 4294967296.0f);
+ src += 4;
+ }
+ src += 4 * (in_channels - out_channels);
+ }
+}
+
void insert_new_frame(RefCountedFrame frame, unsigned field_num, bool interlaced, unsigned card_index, InputState *input_state)
{
if (interlaced) {
int64_t frame_length = int64_t(TIMEBASE * video_format.frame_rate_den) / video_format.frame_rate_nom;
- size_t num_samples = (audio_frame.len >= audio_offset) ? (audio_frame.len - audio_offset) / 8 / 3 : 0;
+ size_t num_samples = (audio_frame.len >= audio_offset) ? (audio_frame.len - audio_offset) / audio_format.num_channels / (audio_format.bits_per_sample / 8) : 0;
if (num_samples > OUTPUT_FREQUENCY / 10) {
printf("Card %d: Dropping frame with implausible audio length (len=%d, offset=%d) [timecode=0x%04x video_len=%d video_offset=%d video_format=%x)\n",
card_index, int(audio_frame.len), int(audio_offset),
case 24:
convert_fixed24_to_fp32(&audio[0], 2, audio_frame.data + audio_offset, audio_format.num_channels, num_samples);
break;
+ case 32:
+ convert_fixed32_to_fp32(&audio[0], 2, audio_frame.data + audio_offset, audio_format.num_channels, num_samples);
+ break;
default:
fprintf(stderr, "Cannot handle audio with %u bits per sample\n", audio_format.bits_per_sample);
assert(false);