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

We are looking for some solution that will insert VANC data (OP47 teletext or 608) into SDI, ideally using BMD Decklink cards and insertion should be on thy fly. Automation will send via REST API the text that should be displayed (inserted) to VANC.

Or we are opened to any solution that you already use in your project to embedd CC to your broadcast (even not SDI)

Thanks
Tony

This has been disussed multiple times in the forum. You can use the little magnifying glass icon to search for „close caption“ and find the other treads.

Thanks for hint Didi :slight_smile: Unfortunately I have not found solution in the forum, I am looking for even pro solution which maybe some of CasparCG users already found. We have succesfully implemented integration with Playbox Subtitler, but it is still quite expensive solution for most clients.

CC is, like Teletext, something, that is inserted in TV lines in the area outside of the visible display. AFAIK Decklink cards do not support this. So you need to use something, that uses a card, that can inserts data outside of the display area. As Caspar only supports Decklink and Bluefish, you may be out of luck.

As far as I’m aware, this is something that has been asked for a few times, but noone has contributed or funded an implementation, so no progress has been made.
There is a github issue discussing this Playback/record of 608/708 CC and VANC · Issue #92 · CasparCG/server · GitHub

I am pretty sure that decklinks can do it, the specs do say:

SDI Metadata Support
RP 188/SMPTE 12M-2 and closed captioning.

but I haven’t tried it so can’t say for certain. I did do RP188 in the NRK 2.1, but that is much simpler and hasn’t made its way upstream

Almost all modern BMD cards supports VANC insertion (these TV lines outside visible display). Even their SDK is pretty well documented, but spec of 608/708 is really huge and we are not able to implement it by our own, so I was looking even for some affordable business solution and as far as I found was from Playbox (about 10k € per channel) where we can utilize BMD Duo cards and loopback output from CasparCG SDI OUT to SDI IN (insert VANC based of SRT files) and OUT again to distribution.

I will be glad if someone, who have faced this problem in some project, can guide me to more affordable solution.

Thanks guys.

Thanks for clarification. We are able to fund an implementation to Caspar, so if someone is interested, please leave me a message. Thank you.

Any progress on this? I think we need some devs to come up with an estimate of what this project will cost to implement and maintain. There seems to be enough of us that want it to happen and are willing to contribute.

I am willing to start a fundraiser to coordinate development and testing for this, but I need to determine what order of magnitude of funding we need. I have mainly worked on the old client at this point, so have too much setup and familiarization to do to make such an estimate myself.

Maybe you can talk to @Julusian or @hummelstrand of Superfly.tv directly.

In order to come up with an estimate for how much work this would require, we would first need to have a specification of what needs to be built. There are several captioning standards, and lots of other requirements that may or may not be relevant, so someone needs to write a technical requirement specification. This specification could be created in a collaboration between interested parties in the community, but I’m afraid we don’t really have any free resources that we could offer in creating such a specification.

Once such a specification exists, SuperFly.tv is definitely interested in participating in a technical discussion on how to implement a solid captioning components, and based on this bid on developing it for the community.

Jonas Hummelstrand

CEO
SuperFly.tv

1 Like

Is there a thread that comprehensively explains the current state of frame rate conversion and workflow for CasparCG? I know interlaced formats used to be supported natively, but modern versions of the engine process in progressive and convert back to interlaced for the output. Captions data is extremely frame rate sensitive so even 5994 vs 60 can corrupt data.

I am working on writing a development specification for this, but I want to make sure I write it in a way that is compatible with the current server versions. I would guess that the 60 to 5994 conversion is primarily relevant to file based sources so could happen in FFmpeg producer.

I don’t think that there is a thread, that explains that. But from my limited understanding as non C++ developer, the interlace/progressive question is not relevant. As I think these ancillary data (teletext, CC etc.) is added at the last stage, before the signal leaves the card, when it already has been converted to interlace, if needed. By the way it’s not clear (to me) if any of the supported cards (bluefish and decklink) support adding such data to the SDi. Maybe we need to support another card type to make it work.

Is there a thread that comprehensively explains the current state of frame rate conversion and workflow for CasparCG?

I don’t know of one, but the basic flow is that we rely on ffmpeg to do any framerate conversions for us. I don’t know what that would mean here for captions.
We don’t always deinterlace the input, I think we do by default, but it can be turned off.

Captions data is extremely frame rate sensitive so even 5994 vs 60 can corrupt data.

The ‘easy’ answer to this might be to say captions will only be supported if the framerates match exactly between the source and output.
I’m curious, if this conversion will corrupt data, does corruption happen if frames get repeated on the sdi output?

The main thing I am wondering is where should these captions come from? Is the ideal situation for them to be automatically extracted from a stream in a playing clip? If so, is there a particular format/encoding that would be required. Perhaps you could provide a sample clip so I can quickly see how this might look?

Because CasparCG is based around there being multiple clips playing on a channel, I would propose a solution similar to what I did for timecode in a NRK fork, where the captions will be taken from a layer specified either in the config file, or changed via AMCP. This keeps the implementation simple, and makes it clear and predictable.

For decklink output, there is some prior work in this area from ronag/nxtedition Comparing CasparCG:master...nxtedition:scte104 · CasparCG/server · GitHub, that could be useful as a basis for this. In that they made it so that the captions would be inserted by an AMCP client making calls to the consumer, presumably some other tool would then be the source of those captions and not the clip file being played.
That branch is based on I think 2.2, and has dropped support for windows, so is only really useful as a reference, it is unlikely to be useful to run without work to upstream it.

2 Likes

I have personally managed playout servers in the past that ran decklink duo 2 mini and decklink 8k pro cards with functional CEA-608 captions so decklink certainly is possible. The cards output CEA-708 also, but for some reason the Cinegy playout software didn’t implement 708 correctly so they weren’t always usable for 708. I don’t think this is a decklink issue though because it was a problem with the AJA cards also.

608 and 708 captions are encoded in chunks that get transmitted with each frame of video in VANC or in user data for mpegts streams. Any frame rate conversion that repeats or drops frames will cause repeated or truncated characters or phrases. As far as I can tell the captions will need at least a partial decode/re-encode for any frame rate change. I believe there may be padding characters or sequences that can be inserted when duplicating frames but the captions track does need to stay in sync with audio. As a result it is pretty standard in the industry to require content conform to a specific frame rate and often a single file format. I think a single frame rate would be acceptable, but it would be nice to have both MP4 with user space captions according to SCTE-128 for mp4 and SMPTE436M captions in mxf files.

I can see it being appropriate to do all frame rate conversion encode/decode of captions on the FFmpeg side of things. There is some work still required to create the required functionality there though. It is more efficient on the computer side to do conversion on ingest/conform than on playout.

I will have to upgrade my CasparCG to the latest version and do some testing on 1080i5994 to see if I can avoid the deinterlace step. That resolution is still standard for many media libraries and would be good to support natively even though I would much rather do playout in 1080p2997 or above.

Setting a single layer as the default source for captions and allowing acmp commands is definitely the way to go.

The sources of captions that are most relevant are:

SDI VANC Data

User data captions following SCTE128 in MP4

User data captions in mpegts files

436M Captions Stream from MXF files

Recieving captions from acmp or other network source would be nice but needs to be made compatible with EEG, Evertz, Televue or other captions generation tools so that their captions generation services can be used. This function though is not required unless the place has millions in revenue so is not really relevant to the needs of most who would be funding the project.

2 Likes

Hi all,
Just wanted to follow up and share our working solution for inserting closed captions into SDI broadcast workflows.

We’ve developed a custom inserter application that operates downstream from CasparCG. It captures the SDI output signal from CasparCG, injects OP47 packets containing WST Teletext data (following ITU-R BT.1364 and ETS 300 706 standards), and sends the modified signal back to SDI output via DeckLink SDI cards. This ensures that caption insertion is fully decoupled from the playout system and graphics layer.

The captions themselves are controlled via a REST API, which allows for flexible integration with automation systems. We use our own automation tool that reads SRT files independently and manages the timing and display of the captions.

For systems that require burn-in subtitles (e.g. confidence monitors or preview feeds), we also use a CasparCG HTML template that receives the same SRT-based data, ensuring both closed captions and burn-ins stay in sync.

Of course, this solution assumes that your downstream multiplexer or encoder supports OP47 metadata. We’ve tested this successfully with both Cisco and WISI Chameleon devices.

Currently, the project is not open source, but I’m happy to answer specific questions or discuss technical aspects if anyone’s interested.

That said, it would of course be ideal if CasparCG itself supported VANC data insertion directly—perhaps via an API or scripting interface—so we wouldn’t need a passthrough application at all, and the OP47 data could be embedded directly into the SDI output. Not sure if this is something the CasparCG development team would consider for the roadmap, but it would certainly open up a lot of possibilities.

This was posted in the slack a few weeks ago:

So maybe something for this will appear at some point this year. Even if its not exactly what you need, once the flow of inserting ancillary packets is implemented, adding other types will likely be very easy.

2 Likes

Thanks, this sounds really promising!

We’d definitely welcome a more general-purpose solution that enables access to VANC packet insertion in the DeckLink consumer—without being tied to a specific payload format. That way, users could define and push any type of ancillary data they need, whether it’s SCTE-35, SCTE-104, OP47 Teletext, or something custom.

Having a flexible API or interface for this would open the door to a range of use cases across different broadcast environments.

I’d be happy to contribute or provide input where I can—though my focus is mostly in .NET-based development, so any integration points on that side would be especially interesting for me.

Looking forward to seeing how this evolves!

Awesome! General handling of ancillary data is a good place to start. A call to insert ancillary data could help for scte 104, but for CC it would need to be a call to select anc or CC input source. I would be happy to provide some support if it would expedite passing captions from a file format to decklink output. I care about cea-608 and CEA-708 input data.

I have found a developer to work on 608 and 708 captions in CasparCG, please dm me or contact Radiant Light Broadcasting (rlb.org) if you would like to help fund captions for CasparCG. We are working on file to file first, then will add decklink to decklink. Any help would be appreciated as more funding is needed.