obs-studio/plugins/decklink/decklink-device-instance.hpp
jp9000 2f8d28f7fa decklink: Keep deckLinkConfiguration while in use
Apparently this annoying, stupid variable was leaking before the ComPtr
was added, which ironically was necessary to ensure devices worked.
After that ComPtr commit some devices stopped capturing properly.
Basically, it implies that this pointer needs to stick around while the
device is in use.

(Jim note: This was one of the most painful things I've ever had to
debug)
2022-09-02 17:09:12 -07:00

115 lines
3.3 KiB
C++

#pragma once
#define LOG(level, message, ...) \
blog(level, "%s: " message, "decklink", ##__VA_ARGS__)
#include <obs-module.h>
#include <media-io/video-scaler.h>
#include "decklink-device.hpp"
#include "OBSVideoFrame.h"
class AudioRepacker;
class DecklinkBase;
class DeckLinkDeviceInstance : public IDeckLinkInputCallback {
protected:
ComPtr<IDeckLinkConfiguration> deckLinkConfiguration;
struct obs_source_frame2 currentFrame;
struct obs_source_audio currentPacket;
struct obs_source_cea_708 currentCaptions;
DecklinkBase *decklink = nullptr;
DeckLinkDevice *device = nullptr;
DeckLinkDeviceMode *mode = nullptr;
BMDVideoConnection videoConnection;
BMDAudioConnection audioConnection;
BMDDisplayMode displayMode = bmdModeNTSC;
BMDPixelFormat pixelFormat = bmdFormat8BitYUV;
video_colorspace colorSpace = VIDEO_CS_DEFAULT;
video_colorspace activeColorSpace = VIDEO_CS_DEFAULT;
video_range_type colorRange = VIDEO_RANGE_DEFAULT;
ComPtr<IDeckLinkInput> input;
ComPtr<IDeckLinkOutput> output;
volatile long refCount = 1;
int64_t audioOffset = 0;
uint64_t nextAudioTS = 0;
uint64_t lastVideoTS = 0;
AudioRepacker *audioRepacker = nullptr;
speaker_layout channelFormat = SPEAKERS_STEREO;
bool swap;
bool allow10Bit;
OBSVideoFrame *convertFrame = nullptr;
ComPtr<IDeckLinkMutableVideoFrame> decklinkOutputFrame;
void FinalizeStream();
void SetupVideoFormat(DeckLinkDeviceMode *mode_);
void HandleAudioPacket(IDeckLinkAudioInputPacket *audioPacket,
const uint64_t timestamp);
void HandleVideoFrame(IDeckLinkVideoInputFrame *videoFrame,
const uint64_t timestamp);
public:
DeckLinkDeviceInstance(DecklinkBase *decklink, DeckLinkDevice *device);
virtual ~DeckLinkDeviceInstance();
inline DeckLinkDevice *GetDevice() const { return device; }
inline long long GetActiveModeId() const
{
return mode ? mode->GetId() : 0;
}
inline BMDPixelFormat GetActivePixelFormat() const
{
return pixelFormat;
}
inline video_colorspace GetActiveColorSpace() const
{
return colorSpace;
}
inline video_range_type GetActiveColorRange() const
{
return colorRange;
}
inline speaker_layout GetActiveChannelFormat() const
{
return channelFormat;
}
inline bool GetActiveSwapState() const { return swap; }
inline BMDVideoConnection GetVideoConnection() const
{
return videoConnection;
}
inline BMDAudioConnection GetAudioConnection() const
{
return audioConnection;
}
inline DeckLinkDeviceMode *GetMode() const { return mode; }
bool StartCapture(DeckLinkDeviceMode *mode, bool allow10Bit,
BMDVideoConnection bmdVideoConnection,
BMDAudioConnection bmdAudioConnection);
bool StopCapture(void);
bool StartOutput(DeckLinkDeviceMode *mode_);
bool StopOutput(void);
HRESULT STDMETHODCALLTYPE
VideoInputFrameArrived(IDeckLinkVideoInputFrame *videoFrame,
IDeckLinkAudioInputPacket *audioPacket);
HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(
BMDVideoInputFormatChangedEvents events,
IDeckLinkDisplayMode *newMode,
BMDDetectedVideoInputFormatFlags detectedSignalFlags);
ULONG STDMETHODCALLTYPE AddRef(void);
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv);
ULONG STDMETHODCALLTYPE Release(void);
void DisplayVideoFrame(video_data *frame);
void WriteAudio(audio_data *frames);
void HandleCaptionPacket(IDeckLinkAncillaryPacket *packet,
const uint64_t timestamp);
};