[FFmpeg-trac] #6021(avcodec:new): tx3g / mov_text subtitles are not encoded correctly in some specific cases
FFmpeg
trac at avcodec.org
Thu Dec 15 05:56:33 EET 2016
#6021: tx3g / mov_text subtitles are not encoded correctly in some specific cases
-------------------------------------+-------------------------------------
Reporter: erikbs | Owner:
Type: defect | Status: new
Priority: normal | Component: avcodec
Version: git-master | Resolution:
Keywords: utf8 | Blocked By:
mov_text ttxt tx3g subtitles mp4 | Reproduced by developer: 0
Blocking: |
Analyzed by developer: 0 |
-------------------------------------+-------------------------------------
Comment (by erikbs):
Okay, so I took a closer look at the [https://gpac.wp.mines-
telecom.fr/mp4box/ttxt-format-documentation/ TTXT format documenation],
and it clearly states that text lengths are counted in characters (not
bytes). (Note that this document only touches the XML form. In binary
form, the length of the different blocks (text, style etc.) appear to be
counted in bytes.)
I also played around with the code, and think I have found a solution:
1. In the MovTextContext struct, introduce a new member variable for the
text position as characters (without replacing the existing text_pos,
which is measured in bytes and needed for storing the length of the
blocks)
2. Increase the new variable by counting UTF8 characters instead of bytes
(according to the format documentation, only UTF8 is supported anyway). A
simple for+if will do (loop through all bytes and only count those where
the two most significant bits are not 10)
3. Replace all instances of text_pos with the new variable in code
regarding style.
My modified code produces files that play correctly in QuickTime and
contain subtitle streams equivalent to what MP4Box produces (MP4Box also
sets height/width, ffmpeg does not, but this does not seem to matter). I
have tested it on subtitles with nested styles too. My modifications may
not be the prettiest, but the code works as far as I can see. I have not
touched movtextdec.c, so when extracting TTXT subtitles from an MP4,
ffmpeg generates SRT files with misplaced style tags.
For movtextenc.c I have created a patch. Any help with submitting it is
highly appreciated. Me + git = disaster, and I do not even know if it is
in the correct format (I used {{{diff -u file1 file2}}}):
{{{
--- movtextenc.c 2016-02-26 21:15:02.000000000 +0000
+++ movtextenc.c 2016-12-15 02:29:03.000000000 +0000
@@ -70,6 +70,7 @@
uint8_t style_fontsize;
uint32_t style_color;
uint16_t text_pos;
+ uint16_t text_pos_char;
} MovTextContext;
typedef struct {
@@ -216,10 +217,10 @@
}
s->style_attributes_temp->style_flag = 0;
- s->style_attributes_temp->style_start =
AV_RB16(&s->text_pos);
+ s->style_attributes_temp->style_start =
AV_RB16(&s->text_pos_char);
} else {
if (s->style_attributes_temp->style_flag) { //break the style
record here and start a new one
- s->style_attributes_temp->style_end =
AV_RB16(&s->text_pos);
+ s->style_attributes_temp->style_end =
AV_RB16(&s->text_pos_char);
av_dynarray_add(&s->style_attributes, &s->count,
s->style_attributes_temp);
s->style_attributes_temp =
av_malloc(sizeof(*s->style_attributes_temp));
if (!s->style_attributes_temp) {
@@ -230,10 +231,10 @@
}
s->style_attributes_temp->style_flag =
s->style_attributes[s->count - 1]->style_flag;
- s->style_attributes_temp->style_start =
AV_RB16(&s->text_pos);
+ s->style_attributes_temp->style_start =
AV_RB16(&s->text_pos_char);
} else {
s->style_attributes_temp->style_flag = 0;
- s->style_attributes_temp->style_start =
AV_RB16(&s->text_pos);
+ s->style_attributes_temp->style_start =
AV_RB16(&s->text_pos_char);
}
}
switch (style){
@@ -248,7 +249,7 @@
break;
}
} else {
- s->style_attributes_temp->style_end = AV_RB16(&s->text_pos);
+ s->style_attributes_temp->style_end = AV_RB16(&s->text_pos_char);
av_dynarray_add(&s->style_attributes, &s->count,
s->style_attributes_temp);
s->style_attributes_temp =
av_malloc(sizeof(*s->style_attributes_temp));
@@ -273,7 +274,7 @@
break;
}
if (s->style_attributes_temp->style_flag) { //start of new style
record
- s->style_attributes_temp->style_start =
AV_RB16(&s->text_pos);
+ s->style_attributes_temp->style_start =
AV_RB16(&s->text_pos_char);
}
}
s->box_flags |= STYL_BOX;
@@ -284,11 +285,11 @@
MovTextContext *s = priv;
if (color_id == 2) { //secondary color changes
if (s->box_flags & HLIT_BOX) { //close tag
- s->hlit.end = AV_RB16(&s->text_pos);
+ s->hlit.end = AV_RB16(&s->text_pos_char);
} else {
s->box_flags |= HCLR_BOX;
s->box_flags |= HLIT_BOX;
- s->hlit.start = AV_RB16(&s->text_pos);
+ s->hlit.start = AV_RB16(&s->text_pos_char);
s->hclr.color = color | (0xFF << 24); //set alpha value to
FF
}
}
@@ -302,7 +303,10 @@
{
MovTextContext *s = priv;
av_bprint_append_data(&s->buffer, text, len);
- s->text_pos += len;
+ s->text_pos += len; // length of text in bytes
+ for (int i = 0; i < len; i++) // length of text in characters
+ if ((text[i] & 0xC0) != 0x80)
+ s->text_pos_char ++;
}
static void mov_text_new_line_cb(void *priv, int forced)
@@ -310,6 +314,7 @@
MovTextContext *s = priv;
av_bprint_append_data(&s->buffer, "\n", 1);
s->text_pos += 1;
+ s->text_pos_char += 1;
}
static const ASSCodesCallbacks mov_text_callbacks = {
@@ -328,6 +333,7 @@
size_t j;
s->text_pos = 0;
+ s->text_pos_char = 0;
s->count = 0;
s->box_flags = 0;
s->style_entries = 0;
}}}
--
Ticket URL: <https://trac.ffmpeg.org/ticket/6021#comment:2>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list