szatmary / libcaption

Free open-source CEA608 / CEA708 closed-caption encoder/decoder
MIT License
151 stars 64 forks source link

Unable to render all 64 characters in a single frame. #44

Open embeddedguy1138 opened 6 years ago

embeddedguy1138 commented 6 years ago

I'm hoping you can help me with a bug I am working through.

From my understanding, CEA-608 should be able to render 64 characters per frame, two rows of 32 columns each. However, with libcaption I am only able to render up to 51 characters at a time. The characters that were cut off are placed into the next sei_message_t. Is this intentional or a bug?

I've been looking at sei_from_caption_frame() and sei_encode_eia608() for some insight into what might be going on.

  1. Every time an eia608_control_command is issued the cea708->user_data.cc_count is incremented. Won't this throw off the count if (31 == cea708->user_data.cc_count) when the number of characters is equal to 64?

  2. At my 51st character, cc_data = eia608_from_utf8_1(data, DEFAULT_CHANNEL) = 0. This forces the eia608_control_end_of_caption message to be issued (although I never see that in a hexdump of the sei message) and a new header gets issued with the remaining data. I haven't been able to figure out where this cc_data=0 is coming from yet.

I have noticed this behavior working out of both master and develop branches, though at present I am in the develop branch. I was hoping to have a patch for you instead of questions, but I am stumped at the moment.

Can you provide any information on this issue?

Thank you, Josh

szatmary commented 6 years ago

This is very much a bug. Thanks! I'll update here when I have an opportunity to resolve

embeddedguy1138 commented 6 years ago

I had some time this morning to look into this issue further, and was able to resolve one of my issues.

Issue 1 (w/Solution): It is possible for the cea708->user_data.cc_count == 31 at the same time as cc_data == 0. The will be a problem when sei_encode_eia608 is called recursively when the frame is finished because the eia608_control_end_of_caption control character will be inserted into the 'new' 708 header.

https://github.com/szatmary/libcaption/blob/e8b6261090eb3f2012427cc6b151c923f82453db/src/mpeg.c#L414-L435

Something like this should fix it:

// Check if the caption is finished first
uint16_t is_finished = cc_data & eia608_control_end_of_caption;  

// Prevent new 708 header when caption is finished
if (31 == cea708->user_data.cc_count && is_finished != eia608_control_end_of_caption) {
    sei_append_708(sei, cea708);
}

Please let me know if I can submit a pull request or if you would like to do it yourself.

Issue 2: The other issue is that then a 608 command word is executed (i.e. eia608_control_resume_caption_loading) the cc_count will get incremented. Each time this happens, the total range of possible cc_data (64 cells) is decreased. At most I can display 52 visible characters. I haven't been able to find out from the documentation if this is the expected behavior.

I have a workaround where cc_count will not get incremented on command words, which partially works. I have gotten all 64 visible characters to be displayed, but at the cost of breaking lots and lots of other things. I will update again when I make more progress.

If you have any advice I'd be happy to hear it!

Thanks, Josh