vlc | branch: master | Rafaël Carré <fun...@videolan.org> | Wed Dec 12 18:17:25 2012 +0100| [898bd72bf713a599dd041afe37220fcc9591685d] | committer: Rafaël Carré
decklink: add v210 capabilities (--decklink-tenbits) This is off by default due to being more CPU/memory intensive. Closed Captions can only be read in 10 bits mode. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=898bd72bf713a599dd041afe37220fcc9591685d --- modules/access/decklink.cpp | 86 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 10 deletions(-) diff --git a/modules/access/decklink.cpp b/modules/access/decklink.cpp index 4dcbe8c..0c812a1 100644 --- a/modules/access/decklink.cpp +++ b/modules/access/decklink.cpp @@ -2,6 +2,8 @@ * decklink.cpp: BlackMagic DeckLink SDI input module ***************************************************************************** * Copyright (C) 2010 Steinar H. Gunderson + * Copyright (C) 2009 Michael Niedermayer <michae...@gmx.at> + * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com> * * Authors: Steinar H. Gunderson <steinar+...@gunderson.no> * @@ -113,6 +115,7 @@ vlc_module_begin () change_string_list(ppsz_videoconns, ppsz_videoconns_text) add_string("decklink-aspect-ratio", NULL, ASPECT_RATIO_TEXT, ASPECT_RATIO_LONGTEXT, true) + add_bool("decklink-tenbits", true, N_("10 bits"), N_("10 bits"), true) add_shortcut("decklink") set_capability("access_demux", 10) @@ -141,6 +144,8 @@ struct demux_sys_t uint32_t dominance_flags; int channels; + + bool tenbits; }; class DeckLinkCaptureDelegate : public IDeckLinkInputCallback @@ -179,6 +184,16 @@ private: demux_t *demux_; }; +static uint32_t av_le2ne32(uint32_t val) +{ + union { + uint32_t v; + uint8_t b[4]; + } u; + u.v = val; + return (u.b[0] << 0) | (u.b[1] << 8) | (u.b[2] << 16) | (u.b[3] << 24); +} + HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame* videoFrame, IDeckLinkAudioInputPacket* audioFrame) { demux_sys_t *sys = demux_->p_sys; @@ -192,18 +207,65 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame const int width = videoFrame->GetWidth(); const int height = videoFrame->GetHeight(); const int stride = videoFrame->GetRowBytes(); - const int bpp = 2; - block_t *video_frame = block_New(demux_, width * height * bpp); + block_t *video_frame = block_New(demux_, width * height * 4); if (!video_frame) return S_OK; - void *frame_bytes; - videoFrame->GetBytes(&frame_bytes); - 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 * bpp * y; - memcpy(dst, src, width * bpp); + uint8_t *frame_bytes; + videoFrame->GetBytes((void**)&frame_bytes); + + if (sys->tenbits) { + /* TODO: VANC */ + + //width &= ~1; + int stride = ((width + 47) / 48) * 48 * 8 / 3; + + uint16_t *y = (uint16_t*)(&video_frame->p_buffer[0]); + uint16_t *u = (uint16_t*)(&video_frame->p_buffer[width * height * 2]); + uint16_t *v = (uint16_t*)(&video_frame->p_buffer[width * height * 3]); + +#define READ_PIXELS(a, b, c) \ + do { \ + val = av_le2ne32(*src++); \ + *a++ = val & 0x3FF; \ + *b++ = (val >> 10) & 0x3FF; \ + *c++ = (val >> 20) & 0x3FF; \ + } while (0) + + for (int h = 0; h < height; h++) { + const uint32_t *src = (const uint32_t*)frame_bytes; + uint32_t val = 0; + int w; + for (w = 0; w < width - 5; w += 6) { + READ_PIXELS(u, y, v); + READ_PIXELS(y, u, y); + READ_PIXELS(v, y, u); + READ_PIXELS(y, v, y); + } + if (w < width - 1) { + READ_PIXELS(u, y, v); + + val = av_le2ne32(*src++); + *y++ = val & 0x3FF; + } + if (w < width - 3) { + *u++ = (val >> 10) & 0x3FF; + *y++ = (val >> 20) & 0x3FF; + + val = av_le2ne32(*src++); + *v++ = val & 0x3FF; + *y++ = (val >> 10) & 0x3FF; + } + + frame_bytes += stride; + } + } else { + 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); + } } BMDTimeValue stream_time, frame_duration; @@ -360,6 +422,8 @@ static int Open(vlc_object_t *p_this) vlc_mutex_init(&sys->pts_lock); + sys->tenbits = var_InheritBool(p_this, "decklink-tenbits"); + IDeckLinkIterator *decklink_iterator = CreateDeckLinkIteratorInstance(); if (!decklink_iterator) { msg_Err(demux, "DeckLink drivers not found."); @@ -463,7 +527,8 @@ static int Open(vlc_object_t *p_this) goto finish; } - if (sys->input->EnableVideoInput(htonl(u.id), bmdFormat8BitYUV, 0) != S_OK) { + BMDPixelFormat fmt; fmt = sys->tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV; + if (sys->input->EnableVideoInput(htonl(u.id), fmt, 0) != S_OK) { msg_Err(demux, "Failed to enable video input"); goto finish; } @@ -489,7 +554,8 @@ static int Open(vlc_object_t *p_this) /* Declare elementary streams */ es_format_t video_fmt; - es_format_Init(&video_fmt, VIDEO_ES, VLC_CODEC_UYVY); + vlc_fourcc_t chroma; chroma = sys->tenbits ? VLC_CODEC_I422_10L : VLC_CODEC_UYVY; + es_format_Init(&video_fmt, VIDEO_ES, chroma); video_fmt.video.i_width = width; video_fmt.video.i_height = height; video_fmt.video.i_sar_num = 1; _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org http://mailman.videolan.org/listinfo/vlc-commits