diff options
author | Hendrik Leppkes <h.leppkes@gmail.com> | 2016-11-28 17:22:18 +0300 |
---|---|---|
committer | Hendrik Leppkes <h.leppkes@gmail.com> | 2016-11-28 17:22:18 +0300 |
commit | 577f2367169d6c7d4bf4189fc16554e81c461705 (patch) | |
tree | 697f48895798f897635a0b2e5f3df6ae05d33784 /decoder | |
parent | 5ed89f9c263b3edaec2c62c27f1b49cc701cd6ef (diff) |
Apply stream-level extradata to outgoing video frames
Diffstat (limited to 'decoder')
-rw-r--r-- | decoder/LAVVideo/LAVVideo.cpp | 46 | ||||
-rw-r--r-- | decoder/LAVVideo/LAVVideo.h | 8 |
2 files changed, 54 insertions, 0 deletions
diff --git a/decoder/LAVVideo/LAVVideo.cpp b/decoder/LAVVideo/LAVVideo.cpp index 43a28c46..22e239ba 100644 --- a/decoder/LAVVideo/LAVVideo.cpp +++ b/decoder/LAVVideo/LAVVideo.cpp @@ -31,6 +31,7 @@ #include "resource.h" #include "IMediaSample3D.h" +#include "IMediaSideDataFFmpeg.h" #include <Shlwapi.h> @@ -64,6 +65,7 @@ CLAVVideo::CLAVVideo(LPUNKNOWN pUnk, HRESULT* phr) memset(&m_LAVPinInfo, 0, sizeof(m_LAVPinInfo)); memset(&m_FilterPrevFrame, 0, sizeof(m_FilterPrevFrame)); + memset(&m_SideData, 0, sizeof(m_SideData)); StaticInit(TRUE, nullptr); @@ -616,6 +618,31 @@ HRESULT CLAVVideo::CreateDecoder(const CMediaType *pmt) m_LAVPinInfoValid = FALSE; } + // Clear old sidedata + memset(&m_SideData, 0, sizeof(m_SideData)); + + // Read and store stream-level sidedata + IMediaSideData *pPinSideData = nullptr; + hr = FindPinIntefaceInGraph(m_pInput, __uuidof(IMediaSideData), (void **)&pPinSideData); + if (SUCCEEDED(hr)) { + MediaSideDataFFMpeg *pSideData = nullptr; + size_t size = 0; + hr = pPinSideData->GetSideData(IID_MediaSideDataFFMpeg, (const BYTE **)&pSideData, &size); + if (SUCCEEDED(hr) && size == sizeof(MediaSideDataFFMpeg)) { + for (int i = 0; i < pSideData->side_data_elems; i++) { + AVPacketSideData *sd = &pSideData->side_data[i]; + + // Display Mastering metadata, including color info + if (sd->type == AV_PKT_DATA_MASTERING_DISPLAY_METADATA && sd->size == sizeof(AVMasteringDisplayMetadata)) + { + m_SideData.Mastering = *(AVMasteringDisplayMetadata *)sd->data; + } + } + } + + SafeRelease(&pPinSideData); + } + m_dwDecodeFlags = 0; LPWSTR pszExtension = GetFileExtension(); @@ -1609,6 +1636,25 @@ HRESULT CLAVVideo::DeliverToRenderer(LAVFrame *pFrame) return S_FALSE; } + // Process stream-level sidedata and attach it to the frame if necessary + if (m_SideData.Mastering.has_colorspace) { + fillDXVAExtFormat(pFrame->ext_format, m_SideData.Mastering.color_range - 1, m_SideData.Mastering.color_primaries, m_SideData.Mastering.colorspace, m_SideData.Mastering.color_trc, m_SideData.Mastering.chroma_location); + } + if (m_SideData.Mastering.has_luminance || m_SideData.Mastering.has_primaries) { + bool bHasHDRData = false; + if (pFrame->side_data && pFrame->side_data_count) { + // Check if HDR data already exists + for (int i = 0; i < pFrame->side_data_count && bHasHDRData == false; i++) { + bHasHDRData = !!(pFrame->side_data[i].guidType == IID_MediaSideDataHDR); + } + } + + if (bHasHDRData == false) { + MediaSideDataHDR * hdr = (MediaSideDataHDR *)AddLAVFrameSideData(pFrame, IID_MediaSideDataHDR, sizeof(MediaSideDataHDR)); + processFFHDRData(hdr, &m_SideData.Mastering); + } + } + // Collect width/height int width = pFrame->width; int height = pFrame->height; diff --git a/decoder/LAVVideo/LAVVideo.h b/decoder/LAVVideo/LAVVideo.h index 9216bb55..03dd96c6 100644 --- a/decoder/LAVVideo/LAVVideo.h +++ b/decoder/LAVVideo/LAVVideo.h @@ -36,6 +36,10 @@ #include "BaseTrayIcon.h" #include "IMediaSideData.h" +extern "C" { +#include "libavutil/mastering_display_metadata.h" +}; + #define LAVC_VIDEO_REGISTRY_KEY L"Software\\LAV\\Video" #define LAVC_VIDEO_REGISTRY_KEY_FORMATS L"Software\\LAV\\Video\\Formats" #define LAVC_VIDEO_REGISTRY_KEY_OUTPUT L"Software\\LAV\\Video\\Output" @@ -262,6 +266,10 @@ private: BOOL m_LAVPinInfoValid = FALSE; LAVPinInfo m_LAVPinInfo; + struct { + AVMasteringDisplayMetadata Mastering; + } m_SideData; + CLAVVideoSubtitleInputPin *m_pSubtitleInput = nullptr; CLAVSubtitleConsumer *m_SubtitleConsumer = nullptr; |