【问题标题】:What is the correct way to tune (and scan for) an ATSC Channel?调谐(和扫描)ATSC 频道的正确方法是什么?
【发布时间】:2014-02-06 14:56:33
【问题描述】:

我试图了解大多数应用程序如何执行 ATSC 调整。假设我已经有一个通过

获得的 ATSC 调谐请求
ITuneRequest *pITuneRequest = NULL;
pATSCTuningSpace->CreateTuneRequest(&pTuneRequest)`

似乎有三种流行的方法:

1) 构建所有major.minor 频道的列表并将它们映射到物理频道,然后在请求major.minor 时调到该物理频道。该地图是通过如下代码构建的:

for i = 2 to 69
    tune_to_physical_channel(i)
    if (tuner_has_lock())
         add_to_known_list(i, major_of(i), minor_of(i));
next

UI 仅向用户显示主要频道列表。

我在这里看到的问题是我似乎得到了重复的映射;有时我调物理频道 30 并看到 43.1,而其他时候我调它却看到 43.2!为什么会发生这种情况?

2) 直接调到major.minor。允许直接输入主要和次要频道,并且根本不使用物理频道。我已经尝试过使用几个本地频道:8.1、8.2、43.1、43.2、43.3、49.1、49.2。

8.1 和 8.2 如果构建调优请求并设置如下参数,则可以完美调优:

IATSCChannelTuneRequest* pIATSCChannelTuneRequest = NULL;
IATSCLocator *pIATSCLocator = NULL;
hr = pITuneRequest->QueryInterface( IID_IATSCChannelTuneRequest, 
            (void**)&pIATSCChannelTuneRequest); 
pIATSCChannelTuneRequest->put_Channel(lMajorChannel);
pIATSCChannelTuneRequest->put_MinorChannel(lMinorChannel);
::CoCreateInstance( CLSID_ATSCLocator, 0, CLSCTX_INPROC, IID_IATSCLocator,       
            (void**)&pIATSCLocator);
pIATSCLocator->put_CarrierFrequency(-1);
pIATSCLocator->put_SymbolRate(-1);
pIATSCLocator->put_PhysicalChannel(-1);
pIATSCChannelTuneRequest->put_Locator(pIATSCLocator);

其他频道从不调谐。为什么?其他应用程序(例如 WinTV)可以正确调整所有内容。

3) 通过扫描给定地理区域的已知频率列表来构建主要频道列表。一些应用程序使用基于位置的已知频率such as this onethis onethis one 为自己播种。请注意,所有这些都是美国特有的。

我还没有真正尝试过,但我的计划是提供一个列表,并构建一个major.minor -> 频率的映射,类似于#1:

foreach (frequency f in frequency_array)
    tune_to_frequency (f)
    if (tuner_has_lock())
         add_to_known_list(f, major_of(f), minor_of(f));
next

所以问题又是:应用程序如何实现对 ATSC 频道的扫描/调谐?

【问题讨论】:

  • 您的已知列表是如何建立的?如果物理通道是数组的索引,则不可能进行双重映射,并且复制只会简单地替换第一个映射。这至少有助于1)。我假设映射只完成一次?还是你反复映射?后者也可以解释为什么映射会产生不一致的结果。
  • >双重映射是不可能的——这就是我的问题的重点。在方法 1 中,我有时会看到对物理频道 30 的调谐请求导致调谐到 43.1,有时会看到调谐请求将我调谐到 43.2。这种行为似乎没有模式,我预计物理 - > major.minor 映射的关系是 1:1。我对方法 1 的行为提出的最后一件事是……为什么会发生这种情况?我不想替换第一个映射,因为你永远不知道这两个次要频道中的哪一个会被实际调谐。
  • 关系不一定是1:1。实际上,除非我理解系统错误,否则映射只是专业到物理,而未成年人只是在同一通道上提供的几个数据流。这意味着节目(major.minor)比频道(物理)多得多。
  • 这是我想到的一种情况。我想把它写下来,但这个问题已经几乎成为一个TL; DR。扫描频道的正确方法是否可能是:for (i=2 to 69) { tune_physical(i); currentmajor = get_major_of(i); for (j = 1 to max_minor) { tune_major_minor(currentmajor, j); } }
  • 它应该可以在不调用tune_physical(i) 的情况下工作,因为物理映射1:1 到major(顺便说一下,你的get_major_of(i) 就是这个映射)。因此,除非您想捕获我不知道的奇怪异常,否则tune_major_minor(currentmajor, j) 应该就足够了。

标签: visual-c++ directshow


【解决方案1】:

简而言之,我们的解决方案是不支持扫描,采用方法二:直接调到 Major.Minor。在我原来的帖子中,我注意到这仅适用于我所在地区的 8.1 和 8.2。

事实证明,设置ChannelMinorChannel 是不够的。我需要cross-reference each major channel 并在调整时设置PhysicalChannel (RFChannel)。因此,为了调整,我们为所有请求设置了ChannelMinorChannelPhysicalChannel

我在TuneRequest 中将所有其他属性(包括CarrierFrequency)设置为-1。

此外,我还发现了另外两个用于查找的资源:

http://transition.fcc.gov/mb/engineering/dtvmaps/
http://www.tvfool.com

附带说明,出于我们的应用目的,要求用户使用天线web.org 查找物理 (RF) 频道是合理的。如果用户手头没有这些信息,我不确定您如何仍然使用我们的方法。

【讨论】:

    猜你喜欢
    • 2019-11-09
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    • 1970-01-01
    • 2011-11-19
    相关资源
    最近更新 更多