Commit 260dc965 authored by Rafaël Carré's avatar Rafaël Carré

decklink: simplify Open

parent cd017574
...@@ -314,16 +314,33 @@ static int GetVideoConn(demux_t *demux) ...@@ -314,16 +314,33 @@ static int GetVideoConn(demux_t *demux)
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static const char *GetFieldDominance(BMDFieldDominance dom, uint32_t *flags)
{
switch(dom)
{
case bmdProgressiveFrame:
return "";
case bmdProgressiveSegmentedFrame:
return ", segmented";
case bmdLowerFieldFirst:
*flags = BLOCK_FLAG_BOTTOM_FIELD_FIRST;
return ", interlaced [BFF]";
case bmdUpperFieldFirst:
*flags = BLOCK_FLAG_TOP_FIELD_FIRST;
return ", interlaced [TFF]";
case bmdUnknownFieldDominance:
default:
return ", unknown field dominance";
}
}
static int Open(vlc_object_t *p_this) static int Open(vlc_object_t *p_this)
{ {
demux_t *demux = (demux_t*)p_this; demux_t *demux = (demux_t*)p_this;
demux_sys_t *sys; demux_sys_t *sys;
int ret = VLC_EGENERIC; int ret = VLC_EGENERIC;
char *display_mode = NULL;
bool b_found_mode;
int card_index; int card_index;
int width, height, fps_num, fps_den; int width = 0, height, fps_num, fps_den;
int rate; int rate;
unsigned aspect_num, aspect_den; unsigned aspect_num, aspect_den;
...@@ -343,8 +360,6 @@ static int Open(vlc_object_t *p_this) ...@@ -343,8 +360,6 @@ static int Open(vlc_object_t *p_this)
vlc_mutex_init(&sys->pts_lock); vlc_mutex_init(&sys->pts_lock);
IDeckLinkDisplayModeIterator *display_iterator = NULL;
IDeckLinkIterator *decklink_iterator = CreateDeckLinkIteratorInstance(); IDeckLinkIterator *decklink_iterator = CreateDeckLinkIteratorInstance();
if (!decklink_iterator) { if (!decklink_iterator) {
msg_Err(demux, "DeckLink drivers not found."); msg_Err(demux, "DeckLink drivers not found.");
...@@ -367,10 +382,8 @@ static int Open(vlc_object_t *p_this) ...@@ -367,10 +382,8 @@ static int Open(vlc_object_t *p_this)
} }
const char *model_name; const char *model_name;
if (sys->card->GetModelName(&model_name) != S_OK) { if (sys->card->GetModelName(&model_name) != S_OK)
msg_Err(demux, "Could not get model name"); model_name = "unknown";
goto finish;
}
msg_Dbg(demux, "Opened DeckLink PCI card %d (%s)", card_index, model_name); msg_Dbg(demux, "Opened DeckLink PCI card %d (%s)", card_index, model_name);
...@@ -388,103 +401,69 @@ static int Open(vlc_object_t *p_this) ...@@ -388,103 +401,69 @@ static int Open(vlc_object_t *p_this)
if (GetVideoConn(demux) || GetAudioConn(demux)) if (GetVideoConn(demux) || GetAudioConn(demux))
goto finish; goto finish;
/* Get the list of display modes. */ char *mode;
if (sys->input->GetDisplayModeIterator(&display_iterator) != S_OK) { mode = var_CreateGetNonEmptyString(demux, "decklink-mode");
msg_Err(demux, "Failed to enumerate display modes"); if (!mode || strlen(mode) < 3 || strlen(mode) > 4) {
msg_Err(demux, "Invalid mode: `%s\'", mode ? mode : "");
goto finish; goto finish;
} }
display_mode = var_CreateGetNonEmptyString(demux, "decklink-mode"); /* Get the list of display modes. */
if (!display_mode || strlen(display_mode) > 4) { IDeckLinkDisplayModeIterator *mode_it;
msg_Err(demux, "Missing or invalid --decklink-mode string"); if (sys->input->GetDisplayModeIterator(&mode_it) != S_OK) {
msg_Err(demux, "Failed to enumerate display modes");
free(mode);
goto finish; goto finish;
} }
/* union {
* Pad the --decklink-mode string to four characters, so the user can specify e.g. "pal" BMDDisplayMode id;
* without having to add the trailing space. char str[4];
*/ } u;
char sz_display_mode_padded[5]; memcpy(u.str, mode, 4);
strcpy(sz_display_mode_padded, " "); if (u.str[3] == '\0')
for (unsigned i = 0; i < strlen(display_mode); ++i) u.str[3] = ' '; /* 'pal'\0 -> 'pal ' */
sz_display_mode_padded[i] = display_mode[i]; free(mode);
BMDDisplayMode wanted_mode_id; for (IDeckLinkDisplayMode *m;; m->Release()) {
memcpy(&wanted_mode_id, &sz_display_mode_padded, sizeof(wanted_mode_id)); if ((mode_it->Next(&m) != S_OK) || !m)
b_found_mode = false;
for (;;) {
IDeckLinkDisplayMode *display_mode;
if ((display_iterator->Next(&display_mode) != S_OK) || !display_mode)
break; break;
char sz_mode_id_text[5] = {0};
BMDDisplayMode mode_id = ntohl(display_mode->GetDisplayMode());
memcpy(sz_mode_id_text, &mode_id, sizeof(mode_id));
const char *mode_name; const char *mode_name;
if (display_mode->GetName(&mode_name) != S_OK) {
msg_Err(demux, "Failed to get display mode name");
display_mode->Release();
goto finish;
}
BMDTimeValue frame_duration, time_scale; BMDTimeValue frame_duration, time_scale;
if (display_mode->GetFrameRate(&frame_duration, &time_scale) != S_OK) { uint32_t flags = 0;
msg_Err(demux, "Failed to get frame rate"); const char *field = GetFieldDominance(m->GetFieldDominance(), &flags);
display_mode->Release(); BMDDisplayMode id = ntohl(m->GetDisplayMode());
goto finish;
if (m->GetName(&mode_name) != S_OK)
mode_name = "unknown";
if (m->GetFrameRate(&frame_duration, &time_scale) != S_OK) {
time_scale = 0;
frame_duration = 1;
} }
const char *field_dominance; msg_Dbg(demux, "Found mode '%4.4s': %s (%dx%d, %.3f fps%s)",
uint32_t dominance_flags = 0; (char*)&id, mode_name,
switch(display_mode->GetFieldDominance()) (int)m->GetWidth(), (int)m->GetHeight(),
{ double(time_scale) / frame_duration, field);
case bmdProgressiveFrame:
field_dominance = "";
break;
case bmdProgressiveSegmentedFrame:
field_dominance = ", segmented";
break;
case bmdLowerFieldFirst:
field_dominance = ", interlaced [BFF]";
dominance_flags = BLOCK_FLAG_BOTTOM_FIELD_FIRST;
break;
case bmdUpperFieldFirst:
field_dominance = ", interlaced [TFF]";
dominance_flags = BLOCK_FLAG_TOP_FIELD_FIRST;
break;
case bmdUnknownFieldDominance:
default:
field_dominance = ", unknown field dominance";
break;
}
msg_Dbg(demux, "Found mode '%s': %s (%dx%d, %.3f fps%s)", if (u.id == id) {
sz_mode_id_text, mode_name, width = m->GetWidth();
(int)display_mode->GetWidth(), (int)display_mode->GetHeight(), height = m->GetHeight();
double(time_scale) / frame_duration, field_dominance);
if (wanted_mode_id == mode_id) {
b_found_mode = true;
width = display_mode->GetWidth();
height = display_mode->GetHeight();
fps_num = time_scale; fps_num = time_scale;
fps_den = frame_duration; fps_den = frame_duration;
sys->dominance_flags = dominance_flags; sys->dominance_flags = flags;
} }
display_mode->Release();
} }
if (!b_found_mode) { mode_it->Release();
msg_Err(demux, "Unknown video mode specified. "
"Run VLC with -vv to get a list of supported modes."); if (width == 0) {
msg_Err(demux, "Unknown video mode `%4.4s\' specified.", (char*)&u.id);
goto finish; goto finish;
} }
if (sys->input->EnableVideoInput(htonl(wanted_mode_id), bmdFormat8BitYUV, 0) != S_OK) { if (sys->input->EnableVideoInput(htonl(u.id), bmdFormat8BitYUV, 0) != S_OK) {
msg_Err(demux, "Failed to enable video input"); msg_Err(demux, "Failed to enable video input");
goto finish; goto finish;
} }
...@@ -547,11 +526,6 @@ finish: ...@@ -547,11 +526,6 @@ finish:
if (decklink_iterator) if (decklink_iterator)
decklink_iterator->Release(); decklink_iterator->Release();
free(display_mode);
if (display_iterator)
display_iterator->Release();
if (ret != VLC_SUCCESS) if (ret != VLC_SUCCESS)
Close(p_this); Close(p_this);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment