【问题标题】:How do I parse KLV data?如何解析 KLV 数据?
【发布时间】:2019-06-24 11:31:50
【问题描述】:

如何解析 KLV 数据? 下面有一些代码。我想使用 klv 元数据制作地图。但是怎么做呢?

我知道经纬度在klv的第13和14键中。但是我怎么能用它们来制作地图呢。

ILMMpgDmx *CMainFrame::GetMPEG2DemuxInterface()
{
    IUnknown *pSplitter;
    HRESULT hr = m_player->GetSubObject(ltmmPlay_Object_Splitter, &pSplitter);
    if (SUCCEEDED(hr))
    {
        ILMMpgDmx *pMpgDmx;
        hr = pSplitter->QueryInterface(IID_ILMMpgDmx, (void **)&pMpgDmx);
        if (SUCCEEDED(hr))
        {
            pSplitter->Release();
            return pMpgDmx;
        }
        pSplitter->Release();
    }
    return NULL;
}

void CMainFrame::EnableMPEG2DemuxCallback()
{
    HRESULT hr;
    ILMMpgDmx *pMpgDmx = GetMPEG2DemuxInterface();
    if (pMpgDmx)
    {
        // make sure the demux is not using the callback I am about to destroy
        pMpgDmx->put_CallbackObj(NULL);

        DeleteCallbackClass();

        m_pCallback = new CMPEG2DemuxCallback(pMpgDmx);

        // Force the callback to be called in the main thread. C++ applications in general can handle data in another thread, but our app is using MFC
        // Our callback will display data in a window and MFC doesn't work well when you use windows from threads other than the main thread
        // So, for simplicity, we will ask the demux to send the data to the main thread
        hr = pMpgDmx->put_CallInSameThread(VARIANT_TRUE);
        hr = pMpgDmx->put_CallbackObj(m_pCallback);

        pMpgDmx->Release();
    }
}


被调用的 DataAvailable() 函数如下所示:


HRESULT STDMETHODCALLTYPE CMPEG2DemuxCallback::DataAvailable
( 
    /* [in] */ VARIANT *pData,
    /* [in] */ long lDataSize,
    /* [in] */ FileTypeConstants fileType,
    /* [in] */ long streamPID,
    /* [in] */ long streamType,
    /* [in] */ PTSTypeConstants PTSType,
    /* [in] */ double PTS,
    /* [in] */ long flags
)
{
    // skip small (most likely invalid) data chunks
    if(lDataSize <= 1)
        return S_OK;

    //refresh control
    { 
        static const DWORD MIN_REFRESH_TIME = 1000 ;//1 second
        static DWORD dwLastTime = 0 ;//allow first data to be displayed

        DWORD dwCurTime = GetTickCount ( ) ;

        if ( dwCurTime - dwLastTime < MIN_REFRESH_TIME )
        {         
            return S_OK ;
        }
        else
        {
            dwLastTime = dwCurTime ;
        }
    }

    CPrivateDataView* pDataView = CPrivateDataViewManager::GetPrivateDataListView ( ) ;

    if(!pDataView)
        return S_OK;//skip

    pDataView->SetRedraw ( FALSE ) ;
    pDataView->GetListCtrl ( ).DeleteAllItems ( ) ;

    {
        HRESULT hr;

        if(flags & DataFlag_IsKLV)
        {
            ILMKlvParser* pParser;

            hr = m_pMpgDmx->GetKlvParser(streamPID, &pParser);
            if(FAILED(hr))
                return hr;

            hr = EnumKlvKeys(pParser, pDataView, NULL, pData, lDataSize, flags);
            if(FAILED(hr)) 
            { 
                pParser->Release() ;

                return hr;
            }

            pParser->Release();
        }
        else if(flags & DataFlag_IsAscii)
        {
            CString str;

            hr = DumpVariantAsAscii(str, pData, lDataSize);
            if(FAILED(hr))
                return hr;

            pDataView->AddValue (str) ;
        }
        else if(flags & DataFlag_IsBinary)
        {
            CString str;

            hr = DumpVariantAsBinary(str, pData, lDataSize);
            if(FAILED(hr))
                return hr;

            pDataView->AddValue (str) ;
        }
        else
        {
            ASSERT ( FALSE ) ;      
            return E_UNEXPECTED;
        }
    }

    pDataView->SetRedraw ( TRUE ) ;
    pDataView->RedrawWindow ( ) ;

    return S_OK ;
}

这些都是我找到的代码。我还发现了这个 klv 库。我需要一条建议的途径。

https://github.com/Hunter522/libklv

【问题讨论】:

  • 你找到解决KLV的方法了吗?
  • 不,现在我正在尝试解决如何从流式视频中获取元数据。我想我应该使用 directshow pin/filters。

标签: c++ metadata mpeg2-ts


【解决方案1】:

我终于找到了如何从 MPEG2 TS 中解析 KLV。 我做了以下 1.使用知道解析元数据KLV的PID的MPEg2-demux directshow过滤器。 2.我建立了我自己的directshow过滤器(基于转储过滤器)这个过滤器接受接收KLV的整个PID,而不是从这里使用libklv https://github.com/Hunter522/libklv 我添加到过滤器中,这给了我键、长度和值。

但这里有诀窍: KLV 元数据可以是协议的一部分,所以在我的情况下,协议是 MISB 601.8 这里:https://upload.wikimedia.org/wikipedia/commons/1/19/MISB_Standard_0601.pdf

每个标签都有自己的公式、单位和名称 有 70 多个标签。 这意味着如果标签有 2 个字节,请转到 MISB 中的标签索引,公式就在那里。

【讨论】:

  • 你能和我分享你的代码吗?因为我尝试了好几个月。这是我的学校项目
  • 我不知道如何获取流中的元数据进行解析。首先,我应该从流中获取数据。但我无法做到这一点。你也可以分享你的联系方式吗?
  • hededesedede (at) gmail.com
  • 我还创建了一个用于在 VS 中显示的表单。谢谢
猜你喜欢
  • 1970-01-01
  • 2022-12-01
  • 2012-12-17
  • 2017-12-15
  • 2021-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多