[vlc-devel] [PATCH] access: decklink: Support rgb input modes
Julian Scheel
julian at jusst.de
Mon Oct 16 12:45:54 CEST 2017
Check if the card reports yuv or rgb input and set the codec format
accordingly.
Signed-off-by: Julian Scheel <julian at jusst.de>
---
modules/access/decklink.cpp | 68 ++++++++++++++++++++++++++++++++++-----------
1 file changed, 52 insertions(+), 16 deletions(-)
diff --git a/modules/access/decklink.cpp b/modules/access/decklink.cpp
index 4c5f826fbd..04f0b469f4 100644
--- a/modules/access/decklink.cpp
+++ b/modules/access/decklink.cpp
@@ -140,6 +140,7 @@ struct demux_sys_t
bool autodetect;
es_out_id_t *video_es;
+ es_format_t video_fmt;
es_out_id_t *audio_es;
es_out_id_t *cc_es;
@@ -172,7 +173,8 @@ static const char *GetFieldDominance(BMDFieldDominance dom, uint32_t *flags)
}
}
-static es_format_t GetModeSettings(demux_t *demux, IDeckLinkDisplayMode *m)
+static es_format_t GetModeSettings(demux_t *demux, IDeckLinkDisplayMode *m,
+ BMDDetectedVideoInputFormatFlags fmt_flags)
{
demux_sys_t *sys = demux->p_sys;
uint32_t flags = 0;
@@ -185,7 +187,18 @@ static es_format_t GetModeSettings(demux_t *demux, IDeckLinkDisplayMode *m)
}
es_format_t video_fmt;
- vlc_fourcc_t chroma = sys->tenbits ? VLC_CODEC_I422_10L : VLC_CODEC_UYVY;
+ vlc_fourcc_t chroma = 0;
+ switch (fmt_flags) {
+ case bmdDetectedVideoInputYCbCr422:
+ chroma = sys->tenbits ? VLC_CODEC_I422_10L : VLC_CODEC_UYVY;
+ break;
+ case bmdDetectedVideoInputRGB444:
+ chroma = VLC_CODEC_ARGB;
+ break;
+ default:
+ msg_Err(demux, "Unsupported input format");
+ break;
+ }
es_format_Init(&video_fmt, VIDEO_ES, chroma);
video_fmt.video.i_chroma = chroma;
@@ -232,7 +245,7 @@ public:
return new_ref;
}
- virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode, BMDDetectedVideoInputFormatFlags)
+ virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode, BMDDetectedVideoInputFormatFlags flags)
{
demux_sys_t *sys = demux_->p_sys;
@@ -249,11 +262,23 @@ public:
return S_OK;
}
+ BMDPixelFormat fmt = 0;
+ switch (flags) {
+ case bmdDetectedVideoInputYCbCr422:
+ fmt = sys->tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV;
+ break;
+ case bmdDetectedVideoInputRGB444:
+ fmt = bmdFormat8BitARGB;
+ break;
+ default:
+ msg_Err(demux_, "Unsupported input format");
+ return S_OK;
+ }
+
es_out_Del(demux_->out, sys->video_es);
- es_format_t video_fmt = GetModeSettings(demux_, mode);
- sys->video_es = es_out_Add(demux_->out, &video_fmt);
+ sys->video_fmt = GetModeSettings(demux_, mode, flags);
+ sys->video_es = es_out_Add(demux_->out, &sys->video_fmt);
- BMDPixelFormat fmt = sys->tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV;
sys->input->PauseStreams();
sys->input->EnableVideoInput( mode->GetDisplayMode(), fmt, bmdVideoInputEnableFormatDetection );
sys->input->FlushStreams();
@@ -275,7 +300,8 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame
if (videoFrame) {
if (videoFrame->GetFlags() & bmdFrameHasNoInputSource) {
- msg_Warn(demux_, "No input signal detected");
+ msg_Warn(demux_, "No input signal detected (%dx%d)",
+ videoFrame->GetWidth(), videoFrame->GetHeight());
return S_OK;
}
@@ -283,7 +309,16 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame
const int height = videoFrame->GetHeight();
const int stride = videoFrame->GetRowBytes();
- int bpp = sys->tenbits ? 4 : 2;
+ int bpp = 0;
+ switch (sys->video_fmt.i_codec) {
+ case VLC_CODEC_I422_10L:
+ case VLC_CODEC_ARGB:
+ bpp = 4;
+ break;
+ case VLC_CODEC_UYVY:
+ bpp = 2;
+ break;
+ };
block_t *video_frame = block_Alloc(width * height * bpp);
if (!video_frame)
return S_OK;
@@ -296,7 +331,7 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame
video_frame->i_flags = BLOCK_FLAG_TYPE_I | sys->dominance_flags;
video_frame->i_pts = video_frame->i_dts = VLC_TS_0 + stream_time;
- if (sys->tenbits) {
+ if (sys->video_fmt.i_codec == VLC_CODEC_I422_10L) {
v210_convert((uint16_t*)video_frame->p_buffer, frame_bytes, width, height);
IDeckLinkVideoFrameAncillary *vanc;
if (videoFrame->GetAncillaryData(&vanc) == S_OK) {
@@ -329,12 +364,14 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame
}
vanc->Release();
}
- } else {
+ } else if (sys->video_fmt.i_codec == VLC_CODEC_UYVY) {
for (int y = 0; y < height; ++y) {
const uint8_t *src = (const uint8_t *)frame_bytes + stride * y;
uint8_t *dst = video_frame->p_buffer + width * 2 * y;
memcpy(dst, src, width * 2);
}
+ } else {
+ memcpy(video_frame->p_buffer, frame_bytes, width * height * bpp);
}
vlc_mutex_lock(&sys->pts_lock);
@@ -558,8 +595,7 @@ static int Open(vlc_object_t *p_this)
free(mode);
}
- es_format_t video_fmt;
- video_fmt.video.i_width = 0;
+ sys->video_fmt.video.i_width = 0;
for (IDeckLinkDisplayMode *m;; m->Release()) {
if ((mode_it->Next(&m) != S_OK) || !m)
@@ -584,14 +620,14 @@ static int Open(vlc_object_t *p_this)
double(time_scale) / frame_duration, field);
if (u.id == id) {
- video_fmt = GetModeSettings(demux, m);
+ sys->video_fmt = GetModeSettings(demux, m, bmdDetectedVideoInputYCbCr422);
msg_Dbg(demux, "Using that mode");
}
}
mode_it->Release();
- if (video_fmt.video.i_width == 0) {
+ if (sys->video_fmt.video.i_width == 0) {
msg_Err(demux, "Unknown video mode `%4.4s\' specified.", (char*)&u.id);
goto finish;
}
@@ -635,8 +671,8 @@ static int Open(vlc_object_t *p_this)
}
msg_Dbg(demux, "added new video es %4.4s %dx%d",
- (char*)&video_fmt.i_codec, video_fmt.video.i_width, video_fmt.video.i_height);
- sys->video_es = es_out_Add(demux->out, &video_fmt);
+ (char*)&sys->video_fmt.i_codec, sys->video_fmt.video.i_width, sys->video_fmt.video.i_height);
+ sys->video_es = es_out_Add(demux->out, &sys->video_fmt);
es_format_t audio_fmt;
es_format_Init(&audio_fmt, AUDIO_ES, VLC_CODEC_S16N);
--
2.14.2
More information about the vlc-devel
mailing list