SmartVision 2.1の予約データ管理を担う, RsvData.dllのCOMインターフェイスについて詳説する. 扱うのは結果リストと予約リストであり, 表には出ないがADAMS-EPG受信も処理している.
作成法: まず, 適当なC++ソースファイル(例えばcreate_header.cppとする)に次のように書く.
#import "C:\Program Files\NEC\SmartVision\RsvData.dll" \ named_guids no_namespace raw_interfaces_only no_smart_pointersこのソースファイルを, 必要なインクルードファイルを読み込むようにしてコンパイルする.
C>cl create_header.cpp /I "C:\Program Files\Microsoft Platform SDK\Include\crt"すると, rsvdata.tlhというファイルが生成される. それをRsvData.hにリネームし, ATLを使わないように「#include <comdef.h>」をコメントアウトする.
なお, 製品版のVC++で実用プログラムを作成する場合, RsvData.hは不要で, ソースに次のように書けば十分.
#import "C:\Program Files\NEC\SmartVision\RsvData.dll"
録画・視聴するときの入力を表す. 実際に確認できたものは以下の通り:
MEDIA_TRST_ANALOG = 0; // TV MEDIA_CATV = 3; // CATV MEDIA_VIDEO = 4; // 外部入力
視聴・録画するときの種類・品質を表す. 実際に確認したものは以下の通り:
RSV_VIEW = 0; // 視聴 RSV_REC_HIGH = 1; // 高画質 RSV_REC_NORMAL = 2; // 標準画質 RSV_REC_USER = 4; // ユーザー設定 RSV_REC_LONG = 7; // 長時間 RSV_ADAMS_EPG = 256; // ADAMS-EPG受信
視聴・録画の繰り返しを表す.
REPEAT_ONCE = 0; // 一回のみ REPEAT_DAY = 1; // 毎日 REPEAT_WEEK = 2; // 毎週(曜日指定)
使用目的は不明だが, 恐らくobsolete. 意味のありそうなデータはあまり返ってこない.
__int64 id1; __int64 id2; short sCode; long lScr; long lExt; BSTR szKCode;
情報が欠けているので, obsoleteと思われる.
結果リスト・予約リストの内容を示す.
DATE dRsvStart; // 予約開始時刻. 1899年12月30日0時を基点とした日数のdouble型数値. DATE dRsvEnd; // 予約終了時刻. 1899年12月30日0時を基点とした日数のdouble型数値. enum tagRSV_MEDIA sMedia; // 録画・視聴するときの入力. char sChan; // TVでチャンネル番号. CATVでチャンネル番号-12. 外部入力で1. char sPriority; // 2→ADAMS-EPG受信, 3→おまかせ録画, 4→通常予約. enum tagRSV_TYPE RsvType; // 視聴・録画するときの種類・品質. enum tagRSV_REP RsvRep; // 視聴・録画の繰り返し. long lVoiceMode; // 不明. 0しか返ってこない. BSTR szGenre; // ジャンル名と思われるが, NULLしか返ってこない. struct tagRSV_AEPG * pAdamsEpg; // 返ってくるのがNULLか非NULLかはまちまち. BSTR szTitle; // 番組名. ADAMS-EPGのときはL"ADAMS-EPG受信". BSTR szContent; // 詳細情報. おまかせ録画以外ではNULLしか返ってこない. long lRecResult; // 予約結果. [*1]
[*1] 恐らく,
lRecResultが0〜12のときはGetRecResultMessage()でエラー内容を調べ,
lRecResultが13〜のときはtagRSV_STATのエラーを示すものと思われる.
確認できたのは以下の通り:
-1→予約
0→「成功しました」←GetRecResultMessage()より
4→「予約実行ができませんでした」←GetRecResultMessage()より
15→「失敗 予約をキャンセルしました。」←tagRSV_STATと一致.
一部を除き予約結果を表す. 実際に確認できたものは以下の通り:
STAT_YET = 0; // 予約
STAT_SUCCESS = 1; // 「成功」
STAT_FAIL_PWROFF = 2; // 「失敗 予約を開始することができませんでした。」
STAT_SUCCESS_USER_STOPPPED = 14; // 「成功 ユーザーが停止ボタンを押しました。」
STAT_FAIL_CANCEL = 15; // 「失敗 予約をキャンセルしました。」
STAT_ERR = 256; // --
STAT_ERR_OVERLAP = 257; // ↓
STAT_ERR_CAREOVERLAPTIME = 258; //
STAT_ERR_STARTTIME = 259; // ここはGetAddFailedMessage()でエラーメッセージを取得できる.
STAT_ERR_RSVTIME = 260; //
STAT_ERR_EPGOVERLAPTIME = 261; // ↑
STAT_ERR_BSOVERLAPTIME = 262; // --
STAT_ACT = 4096; // 「失敗 予期せぬ原因で予約に失敗しました。」
予約録画実行中にもこの値が返る.
STAT_DELETE = 61440; // (同じ時間帯に別の予約をしたため)この予約(ADAMS-EPG)は実行しない.
SmartVisionの制限を示すと思われる. 以下は全て推測. 括弧内は実際に得た数値.
long lMaxReservation; // 予約の最大数(128). long lBeforeRecStart; // 録画開始前に必要な秒数(180(=3分?)). long lMaxRecordingTime; // 連続録画可能秒数(86400(=24時間?))
結果リスト・予約リストの内容を示す.
unsigned long dwId; // ID[*1]
unsigned long dwPrevId; // 旧ID[*2]
unsigned long dwRsvApType; // 不明. 必ず0が返る.
DATE dRsvStart; // 予約開始時刻. 1899年12月30日0時を基点とした日数のdouble型数値.
DATE dRsvEnd; // 予約終了時刻. 1899年12月30日0時を基点とした日数のdouble型数値.
unsigned short wMedia; // 100h→外部入力, 1001h→TV, 1002h→CATV.
unsigned short wChan; // 外部入力で1, TVでチャンネル番号, CATVでチャンネル番号-12.
unsigned char byPriority; // 2→ADAMS-EPG受信, 3→おまかせ録画, 4→通常予約. (優先順位であろう).
unsigned long dwRsvType; // 0→視聴, 1→高画質, 2→標準画質, 4→長時間, 10h→ユーザー設定. [*3]
unsigned long dwRsvMode; // 1→視聴, 2→録画, 20012h→ADAMS-EPG受信.
unsigned long dwRsvRep; // 一回のみのとき0, 毎日のとき7Fh, 毎週のとき各ビットが曜日を表す.
// 1→日, 2→月, 4→火, 8→水, 10h→木, 20h→金, 40h→土.
unsigned long dwVoiceMode; // 不明. 必ず0が返る.
unsigned long dwAdamsEpg; // 不明. 大抵0で稀に1が返るが, 意味不明.
unsigned char byAccessFlag; // 不明. 必ず0が返る.
BSTR szTitle; // 番組名.
BSTR szContent; // 詳細情報. NULLでないのはおまかせ録画のときのみ.
unsigned long dwRecResult; // 予約結果. 65536を引くと, 列挙体のtagRSV_STATに対応すると思われる.
BSTR szUserName; // 予約ユーザー名.
unsigned long dwBitrate; // ビットレート. [*4]
unsigned char bySecret; // 0→通常, 1→シークレット予約.
unsigned char byGUIFlag; // 0→録画・ADAMS-EPG受信, 1→視聴.
[*1] 結果リスト・予約リストの項目ごとに振られる一意なID. SmartVisionをインストールした時刻から予約を設定した時刻までの時間を, 6日を1に換算してfloat型数値で表したものと思われるが, 細かい計算までは不明. 結果リストでは予約時のIDがそのまま使われる.
[*2] 予約情報は予約終了直後に自動的に更新され, 特に毎日・毎週予約の場合, 次回の予約を表す項目が自動的に生成される. そのとき, 古い項目のIDが新しい項目の旧IDの所にコピーされる.
[*3] ADAMS-EPG受信はここでは視聴扱い.
[*4] この値は, ファイルサイズ(MB)を録画時間(分)で割った値を整数に丸めたものと思われるが, 正確な計算式は不明. なお, 予約リストや視聴の結果リストの場合は0.
HRESULT Init(BSTR szRecApli); [in] szRecApli: COMを呼び出すクライアント名であろう.
Init()は最初に呼び出し, 初期化を行うものと推測される. szRecApliはSmartVision標準ではL"RecTime"である. 予約を設定すると, RsvData.bakにはszRecApliの内容が保存される.
HRESULT Term();
Term()はRelease()の直前に呼び出し, データの更新イベントを発生させ, 処理の後始末を行うものと推測される.
HRESULT AddRsv(struct tagRSVDATA RsvData, long * lRsvData, enum tagRSV_STAT * pResult); [in] RsvData: 追加する予約項目. [out] lRsvData: 重複している項目に対応するハンドル. [out] pResult: 予約できたかどうかの結果. 予約できたら0. エラーはGetAddFailedMessage()で変換.
設定情報が不足しておりobsoleteと思われるので, AddRsv2()を使用すべき.
HRESULT EnumRsv(short * pcMax, long * * plRsvData) [out] pcMax: RsvData.dllが保有する結果リストと予約リストの項目の総数. [out] plRsvData: 結果リストと予約リストの各項目に対応するハンドルの配列.
結果リスト・予約リストの各項目には対応するハンドルがある. EnumRsv()はそのハンドル一覧を返す. 各項目を操作するときはそのハンドルを利用する.
HRESULT GetRsv(long lRsvData, struct tagRSVDATA * pRsvData); [in] lRsvData: 結果リスト・予約リストの読み出したい項目に対応するハンドル. [out] pRsvData: 項目のデータ.
取得情報が不足しておりobsoleteと思われるので, GetRsv2()を使用すべき.
HRESULT DelRsv(long lRsvData); [in] lRsvData: 結果リスト・予約リストの削除する項目に対応するハンドル.
ログを見ると, DelRsv()はADAMS-EPG受信の予約削除に使用し, DelRsv2()は一般の予約削除に使用している様子. 何か理由があるのかは不明.
ADAMS-EPG受信を削除すると, 自動的に予約が更新され, 翌日のADAMS-EPG受信が追加される.
ADAMS-EPG受信以外の通常の予約を削除すると, 自動的に予約が更新され, 通常の予約をするために削除されたADAMS-EPG受信が復活する.
HRESULT GetStatus (struct tagEPGAP_STATUS * pStatus ); [out] pStatus: SmartVisionの各制限のデータ.
SmartVisionの制限を取得すると思われる.
HRESULT GetRecResultMessage(long lRecResult, BSTR * pErrMsg); [in] lRecResult: GetRsv()で取得した予約結果 [out] pErrMsg: 予約結果を説明するメッセージ
GetRsv2()や列挙体のtagRSV_STATと無関係なので, obsoleteと思われる.
lRecResultの範囲が0から12までのとき, 意味のあるメッセージが得られる.
HRESULT GetAddFailedMessage(long lAddFailed, BSTR * pErrMsg); [in] lAddFailed: AddRsv()・AddRsv2()・UpdateRsv()で取得した予約追加結果. [out] pErrMsg: 追加結果のエラーメッセージ.
tagRSV_STATの256〜262のときに対応している.
HRESULT CheckOverlapRsvData(DATE dateStart, DATE dateEnd, unsigned short * pResult); [in] dateStart: 予約開始時刻. [in] dateEnd: 予約終了時刻. [out] pResult: 重複調査結果. 1→重複なし, 0→重複あり.
この関数は使うべきではない.
現在のSmartVisionは連続的に録画できる. 例えば, 21:00-22:00と22:00-23:00というように, 別チャンネルでも間をおかずに続けて録画できる. しかし, CheckOverlapRsvData()は少なくとも3分の余裕がない限り, 重複ありと判定してしまう.
HRESULT GetRsv2(long lRsvData, struct tagRSVDATA2 * pRsvData2); [in] lRsvData: 結果リスト・予約リストの読み出したい項目に対応するハンドル. [out] pRsvData2: 項目のデータ.
HRESULT AddRsv2(struct tagRSVDATA2 RsvData2, long * lRsvData, enum tagRSV_STAT * pResult); [in] RsvData2: 追加する予約項目. [out] lRsvData: 重複している項目に対応するハンドル. [out] pResult: 予約できたかどうかの結果. 予約できたら0. エラーはGetAddFailedMessage()で変換.
予約追加に成功した場合, lRsvDataは不定, pResultには0が返る.
重複する予約がある場合, pResultには0でない値が返り, lRsvDataには重複する既存の予約項目のハンドルが返る.
既存の予約がADAMS-EPG受信であっても, 重複する場合はエラーとなって予約は追加できない. そのときは, ADAMS-EPG受信を削除してから予約を追加することになる.
HRESULT UpdateRsv(long * lRsvData, struct tagRSVDATA2 RsvData2, enum tagRSV_STAT * pResult, long * lOverlap); [in] lRsvData: 更新したい予約項目のハンドル. [in] RsvData2: 新しい予約項目. [out] pResult: 予約できたかどうかの結果. 予約できたら0. エラーはGetAddFailedMessage()で変換. [out] lOverlap: 重複する予約がないなら0. そうでないときは, 重複している既存の予約のハンドル.
lRsvDataに値は返って来ていないと思われるが, ポインタで渡しているので, 何かを受け取ることがあるのかもしれない.
HRESULT GetRsvAll(long * plRsvData, struct tagRSVDATA2 * pRsvData2 ); [out] plRsvData: ハンドル. データが終わると0. [out] pRsvData2: 予約・結果リストの項目のデータ
ハンドルと対応する項目のデータを一組ずつ出力する. 繰り返し呼び出すことで順にデータを読み出すことができ, plRsvDataが0になると全てのデータを読み出したことを表す.
HRESULT DelRsv2(short * psNum, long * * plRsvData );
調査したが仕様不明.
HRESULT CheckOverlapView(DATE dateStart, DATE dateEnd, unsigned short * pResult); [in] dateStart: 予約開始時間 [in] dateEnd: 予約終了時間 [out] pResult: 視聴予約との重複調査結果. 1→重複なし, 0→重複あり.
この関数は使うべきではない.
CheckOverlapRsvData()と同様, 既存の視聴予約と3分未満の近さのとき, 重複ありと判定してしまう.