DRCSというのは Dynamic Redefinable Character Set の略で、ユーザが任意に定義できる外字です。日本の地デジ放送の字幕は ISO-2022-JP をベースにした8単位文字符号というエンコード形式が使われており、 ISO-2022-JP で定義されている文字の他に ARIB 外字というよくラテ欄で使われてるような記号を定義した文字が使えます。それでも文字が足りない場合は、ビットマップによる文字イメージと臨時の文字コードを送出し、表示側で文字の代わりにそのビットマップを表示するということが行われます。これが地デジの字幕における DRCS です。話者が画面外にいることを示す絵文字や、スピーカーや携帯電話越しの発話であることを示すスピーカーや携帯電話の絵文字、はたまた「つちよし」([土/口])とか「凜」の字は ISO-2022-JP にも ARIB 外字にも定義されていないので DRCS として表示されます。
余談ですが、「妖狐×僕SS」の主人公白鬼院凜々蝶の「凜」の字は、最初の数話は右下が「禾」でなく「示」になっている「凛」の字が表示されていましたが、途中から「凜」をイメージした DRCS に置き換えられました。
DRCS の定義
DRCS の定義は ARIB-STD-B24 第一編第2部付録規定D にあります。
Drcs_data_structure(){
NumberOfCode 8 uimsbf
For (i=0;i<numberOfCode;I++){
CharacterCode 16 uimsbf
NumberOfFont 8 uimsbf
for (j=0;j<numberOfFont;j++){
fontId 4 uimsbf
mode 4 bslbf
if (mode == ‘0000’|| mode==’0001’){
depth 8 uimsbf
width 8 uimsbf
height 8 uimsbf
for (k=0;k<N;k++){
patternData 8 uimsbf
}
else {
regionX 8 uimsbf
regionY 8 uimsbf
geometricData_length 16 uimsbf
for (k=0;k<N;k++){
geometricData 8 uimsbf
}
}
}
}
}
forが大文字はじまりだったり小文字だったり if の閉じカッコがなかったりしますがそのまま引用しました。ここで mode
は伝送モードを表し、0 か 1 の場合は「圧縮なし」を表し if 節の通り patternData
にビットマップデータがそのまま入ります。
DRCS データ構造は、1つ以上の文字を定義でき、さらにそれぞれの文字について1つ以上のフォントを定義できるようになっています。また文字イメージの幅、高さ、色深度も指定可能になっています。実際は、フォントは1、色深度は2、幅は16、高さは18で固定されているようです。
DRCSデータ実例
具体的な DRCS_data_structure
のバイナリを以下に示します:
01 41 21 01 00 00 10 12 00 00 0E 08 13 0C 31 9C
31 98 03 18 06 10 0C 10 18 30 10 20 10 20 00 00
00 00 20 40 70 E0 20 40 00 00 00 00
これを、先に引用したデータ構造に当てはめると以下のようになります:
バイナリ | フィールド | 補足 |
---|---|---|
01 | number_of_code | |
41 21 | character_code | DRCS1-0x21 |
01 | number_of_font | |
00 | font_id, mode | |
00 | depth | 2階層 |
10 | width | 幅16ドット = 2バイト |
12 | height | 高さ18ドット |
00 00 ... 00 00 | pattern_data |
pattern_data
は 1行2バイト×18行のデータです。2進数にしてみるとどういうイメージなのかわかりやすくなります。
2バイトごとに改行 | 2進数 | 0をスペースに置き換え |
---|---|---|
00 00 0E 08 13 0C 31 9C 31 98 03 18 06 10 0C 10 18 30 10 20 10 20 00 00 00 00 20 40 70 E0 20 40 00 00 00 00 |
0000000000000000 0000111000001000 0001001100001100 0011000110011100 0011000110011000 0000001100011000 0000011000010000 0000110000010000 0001100000110000 0001000000100000 0001000000100000 0000000000000000 0000000000000000 0010000001000000 0111000011100000 0010000001000000 0000000000000000 0000000000000000 |
111 1 1 11 11 11 11 111 11 11 11 11 11 11 1 11 1 11 11 1 1 1 1 1 1 111 111 1 1 |
というとで、この DRCS 構造で定義されていたのは "⁈" (疑問符感嘆符, ?!) でした。
この DRCS は CharacterCode
が 0x4121 で、上位バイトが 0x41 なので 1 バイト DRCS です。下位バイトは 0x21 で、字幕本文の中ではこのコードで参照されます。
次に現れた字幕本文バイナリの中身が以下だとすると:
0C 87 8A BF B4 A4 CE C0 BC 20 A4 AA CA CC A4 EC 21
これを8単位符号としてパースして以下の文字列を得られます
8単位符号 | 文字列 |
---|---|
0C | CS(画面消去) |
87 | WHF(前景色: 白) |
8A | NSZ(文字サイズ: 標準) |
BF B4 | 心 |
A4 CE | の |
C0 BC | 声 |
20 | (半角空白) |
A4 AA | お |
CA CC | 別 |
A4 EC | れ |
21 | ⁈ |
DRCS の文字コードはあくまで臨時のものなので、 0x21 がいつも "⁈" であるとは限りません。DRCS_data_structure
が出現するごとに上書きされることになります。
文字マッピング
ところで、
00 00 0E 08 13 0C 31 9C 31 98 03 18 06 10 0C 10 18 30
10 20 10 20 00 00 00 00 20 40 70 E0 20 40 00 00 00 00
というバイト列が "⁈" の字に相当しているということは今回目視で判断しました。将来画像認識とかでうまくマッピングできるようになるかもしれませんが、今回は PatternData
と実際の文字のマッピングをどこかで定義しておく必要があります。とりあえず md5 でハッシュを取って TSV 形式で保存しておけば良いかなと思います。そして、PatternData のビットマップイメージを PIL などの画像処理ライブラリを使ってハッシュをファイル名にして保存しておき、適宜マッピングファイルにハッシュと相当する文字を追加していくことになるでしょう。
4360dd96063ce1a9660cc8437e8238e3 ?!
これで、 DRCS_data_structure が出たら PatternData の hash を計算し、それが既知のものなら CharacterCode に代替文字列を紐付け、字幕本文に CharacterCode が出てきたら代替文字列を表示するようにすれば DRCS を普通の文字として扱えます。未知のものなら、何らかのマーカー文字列を出力して、あとでマッピングを追加したときに置換するのがよいでしょう。
ここらへんの ariblib での実装は drcs.py や caption.py から参照できます。