How do you insert Closed Captions in your TV broadcast solutions?

We have been testing this with a client in Australia back and forth during the winter and it works reliably for them now. I haven’t had time to backport the final fixes to the upstream main branch, but I can do that and create a PR within the coming weeks.

The TL;DR on how to use this: Send an APPLY command to the channel / consumer using a specific decklink device. In that command, you specify that you’re providing an OP47 payload and the WST packets that you want to embed (base64 encoded), separated by space. Something like this:

“APPLY 1-301 OP47 VVUnFRUCFRXQFdBeFSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg VVUn0McLC87pa+xhcyD3YXMgaOXy5YqKICAgICAgICAgICAgICAgICAgICAg VVUnFYwLC81ha+luZyBhbu/0aOXyIPLv9yD0aGH0IOlzIOzvbmfl8oqKICAg”

For a little more detail, have a look at this demo op47 client: casparcg-vanc-demo/op47-client.js at main · niklaspandersson/casparcg-vanc-demo · GitHub

regards
Niklas

1 Like

Hi, thank you. I was able to build the wintv-vanc branch of nxtedition’s CasparCG and use the demo client on it. However I’m not sure if the data is actually in the SDI output, as I was not successful with getting any VANC data back from (externally looped) SDI input using ffmpeg, or ffmpeg+ccextractor and I am not sure how to figure out if the data are actually not there or my testing is wrong. How do you go about testing the output signal?

Now that you mentioned that branch, I realize that the casparcg branch referenced in the demo repo doesn’t have the final fixes :man_facepalming:, I made that demo before things settled on the casparcg side. I’ve updated the README now, and the “correct” casparcg branch is this: GitHub - nxtedition/casparcg at fix/decklink-vanc-parity

But to answer your question. I also loop back the SDI signal as an input on the same machine, but I use klvanc-tools to analyze the vanc data of the SDI input. But again, you not seeing any data with your test setup could just as well be that that casparcg branch doesn’t work properly after all.

1 Like

I took the time to port the fixes over to upstream. Here is the PR with all fixes applied to the casparcg master branch

1 Like

Thank you for putting time and effort into this. Unfortunately it still doesn’t work for me (testing with original DeckLink 4K Extreme). And now using klvanc tools, the klvanc_capture doesn’t show anything from Caspar (using the fix/decklink-vanc-parity branch), but shows everything when sending from klvanc_transmitter. Caspar doesn’t show any related errors. On init shows [info] DeckLink 4K Extreme [1-1|1080i5000] DeckLink hardware supports VANC.The APPLY command executes successfully, trace log level doesn’t reveal anything more. Should I maybe try using different version of DeckLink DesktopVideo? I don’t really know what version I started with, but during testing, I updated to the newest - 15.3.1

Can you post the decklink related config and the APPLY command your using?

Also, what do you mean that klvanc_capture “doesn’t show anytning”? Do you mean that it doesn’t show any vanc data, or that it doesn’t detect an input signal at all?

I think the minimal Desktop Video version is 12.3 for the vanc api that caspar is using.

<decklink>
	<device>1</device>
	<embedded-audio>true</embedded-audio>
	<vanc>
		<op47-line>12</op47-line>
		<op47-line-2>575</op47-line-2>
		<op42-sd-line>21</op42-sd-line>
		<op47-dummy-header>VVUnFRXq6v0v6pteFSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg</op47-dummy-header>
		<scte104-line>13</scte104-line>
	</vanc>
</decklink>

also tried with closing <op47-dummy-header> with </dummy-header> like it is in example configuration in casparcg-vanc-demo repo (I knew that wouldn’t help, but wanted to try with exact same config)

tried also with op47-line-field2 instead of op47-line-2, as that is what the option is according to decklink/consumer/config.cpp, result not different

tried command from op-47-client.js (with edit to actual contained text)

APPLY 1-301 OP47 VVUnFRUCFRXQFdBeFSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg VVUn0McLC1Tlc/Qg9On0dexrdYqKICAgICAgICAgICAgICAgICAgICAgICAg VVUnFYwLC8TydWh5IPJhZOVrioogICAgICAgICAgICAgICAgICAgICAgICAg

also tried exact copy of command from previous comments

APPLY 1-301 OP47 VVUnFRUCFRXQFdBeFSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg VVUn0McLC87pa+xhcyD3YXMgaOXy5YqKICAgICAgICAgICAgICAgICAgICAg VVUnFYwLC81ha+luZyBhbu/0aOXyIPLv9yD0aGH0IOlzIOzvbmfl8oqKICAg

running klvanc_capture -M says SIGNAL LOCKED Hi50, but doesn’t show any data packets when executing APPLY commands in Caspar

Thanks for the sponsoring, much appreciated :folded_hands:

Are you sure you’re capturing the correct connector? I’ve never used the -M option, but I have to specify -i 1 for instance to select the connector that I’ve looped back the signal to. I also need to have one level of “verbosity” using -v

So, the complete command I run is ./klvanc_capture -i 1 -v. With that it captures without problem, I get output like this:

hdr->type   = 6
 ->adf      = 0x0000/0x03ff/0x03ff
 ->did/sdid = 0x43 / 0x02 [RDD8 Subtitling Distribution packet (SDP)] via SDI line 12
 ->h_offset = 0
 ->checksum = 0x017f (VALID)
 ->payloadLengthWords = 58
 ->payload  = 51 15 3a 02 95 00 00 00 00 55 55 27 15 15 ea ea fd 2f ea 9b 5e 15 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 74 8d 10 c5 
parse_SDP()
klvanc_dump_SDP()
Subtitle Description Packet struct
 pkt->identifier = 0x5115
 pkt->format_code = 0x2
 pkt->descriptors[i].line = 0x15
 pkt->descriptors[i].field = 0x1
 55 55 27 15 15 ea ea fd 2f ea 9b 5e 15 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
 pkt->descriptors[i].line = 0x0
 pkt->descriptors[i].field = 0x0
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 pkt->descriptors[i].line = 0x0
 pkt->descriptors[i].field = 0x0
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 pkt->descriptors[i].line = 0x0
 pkt->descriptors[i].field = 0x0
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 pkt->descriptors[i].line = 0x0
 pkt->descriptors[i].field = 0x0
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 pkt->sequence_counter = 0x8d10

The <op47-dummy-header></dummy-header> is a typo, you are of course correct in that it should be closed with </op47-dummy-header>

I noticed another issue with the example in casparcg-vanc-demo. To configure the line for field 2, the correct element is <op47-line-field2>, not <op47-line-2>. But that should not affect anything other than you not getting vanc packets on field2, you should still get them on field1.

I don’t need to specify input because there is only one working DeckLink in that computer, so when it defaults to -i0 it opens the only input.

The CasparCG outputs into the output of the same card, SDI from that goes to bmd VideoHub (also tried connecting directly) then from there it is going to one of our multiview inputs and also back to the same DeckLink card. When CasparCG is running I can see its output on the multiview, when I run the APPLY command I don’t see any packets with klvanc_capture, situation doesn’t change when running it with -v. Using the same device, running klvanc_transmitter -d0 -m Hi50 -M ../vanc-packets/klvanc_transmitter.cfgI can then see its output on the multiview and if I send any of the provided packets, I can immediately see them on the klvanc_capture.

I’m starting to think, since you mentioned that this VANC implementation’s minimum desktop video version is probably 12.3, the problem might be that the card in my test machine is just too old and maybe doesn’t support it. The card came out in late 2012 and desktop video 12.3 is from early 2022. (The reason I didn’t try it with a newer card yet is that I’d have to take it from a PC in production).

So it was indeed the old card that was the problem. Tried with current DeckLink SDI 4K and it started to work immediately. Now I only have to figure out how to properly encode Czech characters (ěščřžýáíé). Thank you again for everything!

And if anyone wants to view the signal with the op47 titles, you can do so with ffplay if you have ffmpeg configured with --enable-libzvbi and –enable-decklink - e.g. ffplay -f decklink -teletext_lines all -i “DeckLink SDI 4K”

2 Likes

If you need some help with that, let me know in PM, so we can arrange a call.

you can also see examples of how to encode locale specific characters in x26-encoder.js in the vanc-demo repo