diff --git a/mythtv/libs/libmythtv/captions/textsubtitleparser.cpp b/mythtv/libs/libmythtv/captions/textsubtitleparser.cpp index e41ac7189ef..f323194f4b1 100644 --- a/mythtv/libs/libmythtv/captions/textsubtitleparser.cpp +++ b/mythtv/libs/libmythtv/captions/textsubtitleparser.cpp @@ -390,17 +390,15 @@ void TextSubtitleParser::LoadSubtitles(const QString &fileName, newsub.m_end *= 10; } - for (int line = 0; line < sub->lines; ++line) + for (size_t line = 0; line < sub->text.size(); ++line) { - const char *subLine = sub->text[line]; + const char *subLine = sub->text[line].c_str(); QString str; if (textCodec) str = dec->toUnicode(subLine, strlen(subLine)); else str = QString(subLine); newsub.m_textLines.push_back(str); - - free(sub->text[line]); } target.AddSubtitle(newsub); } diff --git a/mythtv/libs/libmythtv/captions/xine_demux_sputext.cpp b/mythtv/libs/libmythtv/captions/xine_demux_sputext.cpp index ce248561ac9..29516a82c83 100644 --- a/mythtv/libs/libmythtv/captions/xine_demux_sputext.cpp +++ b/mythtv/libs/libmythtv/captions/xine_demux_sputext.cpp @@ -127,7 +127,7 @@ static subtitle_t *sub_read_line_sami(demux_sputext_t *demuxstr, subtitle_t *cur char text[LINE_LEN + 1]; char *p = nullptr; - current->lines = current->start = 0; + current->start = 0; current->end = -1; int state = 0; @@ -161,7 +161,7 @@ static subtitle_t *sub_read_line_sami(demux_sputext_t *demuxstr, subtitle_t *cur else if (strncasecmp (s_s, "
", 4) == 0 || *s_s == '\n') { *p = '\0'; p = text; trail_space (text); if (text[0] != '\0') - current->text[current->lines++] = strdup (text); + current->text.push_back( strdup (text) ); if (*s_s == '\n') s_s++; else s_s += 4; } else if (*s_s == '<') { state = 4; } @@ -174,8 +174,8 @@ static subtitle_t *sub_read_line_sami(demux_sputext_t *demuxstr, subtitle_t *cur current->end = strtol (q + 6, &q, 0) / 10 - 1; *p = '\0'; trail_space (text); if (text[0] != '\0') - current->text[current->lines++] = strdup (text); - if (current->lines > 0) { state = 99; break; } + current->text.push_back( strdup (text) ); + if (current->text.size() > 0) { state = 99; break; } state = 0; continue; } s_s = strchr (s_s, '>'); @@ -247,17 +247,12 @@ static subtitle_t *sub_read_line_microdvd(demux_sputext_t *demuxstr, subtitle_t char *p=line2; char *next=p; - int i=0; - while ((next =sub_readtext (next, &(current->text[i])))) { + char *out { nullptr }; + while ((next = sub_readtext (next, &out))) { if (next==ERR) return (subtitle_t *)ERR; - i++; - if (i>=SUB_MAX_TEXT) { - printf ("Too many lines in a subtitle\n"); - current->lines=i; - return current; - } + current->text.push_back(out); } - current->lines= ++i; + current->text.push_back(out); return current; } @@ -282,20 +277,16 @@ static subtitle_t *sub_read_line_subviewer(demux_sputext_t *demuxstr, subtitle_t return nullptr; char *p=line; - for (current->lines=1; current->lines <= SUB_MAX_TEXT; current->lines++) { + while (true) { char *q=nullptr; int len = 0; for (q=p,len=0; *p && *p!='\r' && *p!='\n' && *p!='|' && (strncasecmp(p,"[br]",4) != 0); p++,len++); - current->text[current->lines-1]=(char *)malloc (len+1); - if (!current->text[current->lines-1]) return (subtitle_t *)ERR; - strncpy (current->text[current->lines-1], q, len); - current->text[current->lines-1][len]='\0'; + current->text.push_back(std::string(q, len)); if (!*p || *p=='\r' || *p=='\n') break; if (*p=='[') while (*p++!=']'); if (*p=='|') p++; } - if (current->lines > SUB_MAX_TEXT) current->lines = SUB_MAX_TEXT; break; } return current; @@ -314,19 +305,15 @@ static subtitle_t *sub_read_line_subrip(demux_sputext_t *demuxstr,subtitle_t *cu } while(i < 8); current->start = a1*360000+a2*6000+a3*100+a4/10; current->end = b1*360000+b2*6000+b3*100+b4/10; - i=0; int end_sub=0; do { char *p = nullptr; /* pointer to the curently read char */ char temp_line[SUB_BUFSIZE]; /* subtitle line that will be transfered to current->text[i] */ int temp_index = 0; /* ... and its index wich 'points' to the first EMPTY place -> last read char is at temp_index-1 if temp_index>0 */ temp_line[SUB_BUFSIZE-1]='\0'; /* just in case... */ - if(!read_line_from_input(demuxstr,line,LINE_LEN)) { - if(i) - break; /* if something was read, transmit it */ - return nullptr; /* if not, repport EOF */ - } - for(temp_index=0,p=line;*p!='\0' && !end_sub && temp_indextext.size() > 0) ? current : nullptr; + for(temp_index=0,p=line;*p!='\0' && !end_sub && temp_index1) { /* more than 1 char (including '\0') -> that is a valid one */ - current->text[i]=(char *)malloc(temp_index); - if(!current->text[i]) - return (subtitle_t *)ERR; - strncpy(current->text[i],temp_line,temp_index); /* temp_index<=SUB_BUFSIZE is always true here */ - i++; + current->text.push_back(std::string(temp_line,temp_index)); temp_index=0; } else end_sub=1; } } } - } while(i=SUB_MAX_TEXT) - printf("Too many lines in a subtitle\n"); - current->lines=i; + } while(end_sub == 0); return current; } @@ -398,7 +378,7 @@ static subtitle_t *sub_read_line_vplayer(demux_sputext_t *demuxstr,subtitle_t *c memset (current, 0, sizeof(subtitle_t)); - while (!current->text[0]) { + while (current->text.empty()) { if( demuxstr->next_line[0] == '\0' ) { /* if the buffer is empty.... */ if( !read_line_from_input(demuxstr, line, LINE_LEN) ) return nullptr; } else { @@ -429,18 +409,13 @@ static subtitle_t *sub_read_line_vplayer(demux_sputext_t *demuxstr,subtitle_t *c } char *next=p; - int i=0; - while( (next = sub_readtext( next, &(current->text[i]))) ) { + char *out { nullptr }; + while( (next = sub_readtext( next, &out )) ) { if (next==ERR) return (subtitle_t *)ERR; - i++; - if (i>=SUB_MAX_TEXT) { - printf("Too many lines in a subtitle\n"); - current->lines=i; - return current; - } + current->text.push_back(out); } - current->lines=++i; + current->text.push_back(out); } return current; } @@ -457,7 +432,7 @@ static subtitle_t *sub_read_line_rt(demux_sputext_t *demuxstr,subtitle_t *curren memset (current, 0, sizeof(subtitle_t)); - while (!current->text[0]) { + while (current->text.empty()) { if (!read_line_from_input(demuxstr, line, LINE_LEN)) return nullptr; /* * TODO: it seems that format of time is not easily determined, it may be 1:12, 1:12.0 or 0:1:12.0 @@ -478,18 +453,13 @@ static subtitle_t *sub_read_line_rt(demux_sputext_t *demuxstr,subtitle_t *curren current->end = b1*360000+b2*6000+b3*100+b4/10; /* TODO: I don't know what kind of convention is here for marking multiline subs, maybe
like in xml? */ char *next = strstr(line,"")+8; - int i=0; - while ((next =sub_readtext (next, &(current->text[i])))) { + char *out {nullptr}; + while ((next = sub_readtext (next, &out))) { if (next==ERR) return (subtitle_t *)ERR; - i++; - if (i>=SUB_MAX_TEXT) { - printf("Too many lines in a subtitle\n"); - current->lines=i; - return current; - } + current->text.push_back(out); } - current->lines=i+1; + current->text.push_back(out); } return current; } @@ -543,23 +513,15 @@ static subtitle_t *sub_read_line_ssa(demux_sputext_t *demuxstr,subtitle_t *curre /* eliminate the trailing comma */ if(*line2 == ',') line2++; - current->lines=0; - int num=0; current->start = 360000*hour1 + 6000*min1 + 100*sec1 + hunsec1; current->end = 360000*hour2 + 6000*min2 + 100*sec2 + hunsec2; while (((tmp=strstr(line2, "\\n")) != nullptr) || ((tmp=strstr(line2, "\\N")) != nullptr) ){ - current->text[num]=(char *)malloc(tmp-line2+1); - strncpy (current->text[num], line2, tmp-line2); - current->text[num][tmp-line2]='\0'; + current->text.push_back(std::string(line2, tmp-line2)); line2=tmp+2; - num++; - current->lines++; - if (current->lines >= SUB_MAX_TEXT) return current; } - current->text[num]=strdup(line2); - current->lines++; + current->text.push_back(line2); return current; } @@ -608,8 +570,7 @@ static subtitle_t *sub_read_line_pjs (demux_sputext_t *demuxstr, subtitle_t *cur for (s++, d=text; *s && *s!='"'; s++, d++) *d=*s; *d=0; - current->text[0] = strdup(text); - current->lines = 1; + current->text.push_back(text); return current; } @@ -618,7 +579,6 @@ static subtitle_t *sub_read_line_mpsub (demux_sputext_t *demuxstr, subtitle_t *c char line[LINE_LEN + 1]; float a = NAN; float b = NAN; - int num=0; do { if (!read_line_from_input(demuxstr, line, LINE_LEN)) @@ -630,15 +590,15 @@ static subtitle_t *sub_read_line_mpsub (demux_sputext_t *demuxstr, subtitle_t *c demuxstr->mpsub_position += (b*100.0F); current->end = (int) demuxstr->mpsub_position; - while (num < SUB_MAX_TEXT) { + while (true) { if (!read_line_from_input(demuxstr, line, LINE_LEN)) - return (num > 0) ? current : nullptr; + return (current->text.size() > 0) ? current : nullptr; char *p=line; while (isspace(*p)) p++; - if (eol(*p) && num > 0) + if (eol(*p) && current->text.size() > 0) return current; if (eol(*p)) @@ -648,11 +608,10 @@ static subtitle_t *sub_read_line_mpsub (demux_sputext_t *demuxstr, subtitle_t *c for (q=p; !eol(*q); q++); *q='\0'; if (strlen(p)) { - current->text[num]=strdup(p); + current->text.push_back(p); /* printf(">%s<\n",p); */ - current->lines = ++num; } else { - if (num) + if (current->text.size()) return current; return nullptr; } @@ -677,15 +636,16 @@ static subtitle_t *sub_read_line_aqt (demux_sputext_t *demuxstr, subtitle_t *cur if (!read_line_from_input(demuxstr, line, LINE_LEN)) return nullptr; - sub_readtext((char *) &line,¤t->text[0]); - current->lines = 1; + char *out {nullptr}; + sub_readtext((char *) &line,&out); + current->text.push_back(out); current->end = -1; if (!read_line_from_input(demuxstr, line, LINE_LEN)) return current;; - sub_readtext((char *) &line,¤t->text[1]); - current->lines = 2; + sub_readtext((char *) &line,&out); + current->text.push_back(out); if ((current->text[0][0]==0) && (current->text[1][0]==0)) { return nullptr; @@ -709,7 +669,7 @@ static subtitle_t *sub_read_line_jacobsub(demux_sputext_t *demuxstr, subtitle_t memset(line1, 0, LINE_LEN+1); memset(line2, 0, LINE_LEN+1); memset(directive, 0, LINE_LEN+1); - while (!current->text[0]) { + while (current->text.empty()) { if (!read_line_from_input(demuxstr, line1, LINE_LEN)) { return nullptr; } @@ -801,7 +761,6 @@ static subtitle_t *sub_read_line_jacobsub(demux_sputext_t *demuxstr, subtitle_t long) (((b1 * 3600 + b2 * 60 + b3) * s_jacoTimeRes + b4 + s_jacoShift) * 100.0 / s_jacoTimeRes); } - current->lines = 0; p = line2; while ((*p == ' ') || (*p == '\t')) { ++p; @@ -833,7 +792,7 @@ static subtitle_t *sub_read_line_jacobsub(demux_sputext_t *demuxstr, subtitle_t strcpy(line2, line1); p = line2; } - for (q = line1; (!eol(*p)) && (current->lines < SUB_MAX_TEXT); ++p) { + for (q = line1; (!eol(*p)); ++p) { switch (*p) { case '{': comment++; @@ -865,7 +824,7 @@ static subtitle_t *sub_read_line_jacobsub(demux_sputext_t *demuxstr, subtitle_t if (*(p + 1) == 'n') { *q = '\0'; q = line1; - current->text[current->lines++] = strdup(line1); + current->text.push_back(line1); ++p; break; } @@ -908,12 +867,8 @@ static subtitle_t *sub_read_line_jacobsub(demux_sputext_t *demuxstr, subtitle_t } } *q = '\0'; - if (current->lines < SUB_MAX_TEXT) - current->text[current->lines] = strdup(line1); - else - printf ("Too many lines in a subtitle\n"); + current->text.push_back(line1); } - current->lines++; return current; } @@ -921,30 +876,25 @@ static subtitle_t *sub_read_line_subviewer2(demux_sputext_t *demuxstr, subtitle_ char line[LINE_LEN+1]; int a1=0,a2=0,a3=0,a4=0; // NOLINT(readability-isolate-declaration) char *p=nullptr; - int i = 0; - while (!current->text[0]) { + while (current->text.empty()) { if (!read_line_from_input(demuxstr, line, LINE_LEN)) return nullptr; if (line[0]!='{') continue; if (sscanf (line, "{T %d:%d:%d:%d",&a1,&a2,&a3,&a4) < 4) continue; current->start = a1*360000+a2*6000+a3*100+a4/10; - for (i=0; itext[i]=(char *)malloc (len+1); - if (!current->text[i]) return (subtitle_t *)ERR; - strncpy (current->text[i], line, len); current->text[i][len]='\0'; - ++i; + current->text.push_back(std::string(line, len)); } else { break; } } - current->lines=i; } return current; } @@ -967,17 +917,12 @@ static subtitle_t *sub_read_line_subrip09 (demux_sputext_t *demuxstr, subtitle_t current->end = -1; char *next=line; - int i=0; - while ((next = sub_readtext (next, &(current->text[i])))) { + char *out {nullptr}; + while ((next = sub_readtext (next, &out))) { if (next==ERR) return (subtitle_t *)ERR; - i++; - if (i>=SUB_MAX_TEXT) { - printf("Too many lines in a subtitle\n"); - current->lines=i; - return current; - } + current->text.push_back(out); } - current->lines= ++i; + current->text.push_back(out); return current; } @@ -1001,17 +946,12 @@ static subtitle_t *sub_read_line_mpl2(demux_sputext_t *demuxstr, subtitle_t *cur char *p=line2; char *next=p; - int i=0; - while ((next = sub_readtext (next, &(current->text[i])))) { + char *out {nullptr}; + while ((next = sub_readtext (next, &out))) { if (next == ERR) {return (subtitle_t *)ERR;} - i++; - if (i >= SUB_MAX_TEXT) { - printf("Too many lines in a subtitle\n"); - current->lines = i; - return current; - } + current->text.push_back(out); } - current->lines= ++i; + current->text.push_back(out); return current; } diff --git a/mythtv/libs/libmythtv/captions/xine_demux_sputext.h b/mythtv/libs/libmythtv/captions/xine_demux_sputext.h index e0fde65fa17..4a18bea4869 100644 --- a/mythtv/libs/libmythtv/captions/xine_demux_sputext.h +++ b/mythtv/libs/libmythtv/captions/xine_demux_sputext.h @@ -1,10 +1,11 @@ #ifndef XINE_DEMUX_SPUTEXT_H #define XINE_DEMUX_SPUTEXT_H +#include + #include "io/mythmediabuffer.h" #define SUB_BUFSIZE 1024 -#define SUB_MAX_TEXT 5 #define MAX_TIMEOUT 4 #define DEBUG_XINE_DEMUX_SPUTEXT 0 @@ -27,12 +28,10 @@ struct subtitle_t { - int lines; ///< Count of text lines in this subtitle set. - long start; ///< Starting time in msec or starting frame long end; ///< Ending time in msec or starting frame - char *text[SUB_MAX_TEXT]; ///< The subtitle text lines. + std::vector text; ///< The subtitle text lines. }; struct demux_sputext_t { diff --git a/mythtv/libs/libmythtv/test/test_xine_demux/test_xine_demux.cpp b/mythtv/libs/libmythtv/test/test_xine_demux/test_xine_demux.cpp index 374f6d13567..b30e9e9f010 100644 --- a/mythtv/libs/libmythtv/test/test_xine_demux/test_xine_demux.cpp +++ b/mythtv/libs/libmythtv/test/test_xine_demux/test_xine_demux.cpp @@ -43,10 +43,10 @@ void TextXineDemux::test_captions_microdvd(void) QCOMPARE(sub_data.format, FORMAT_MICRODVD); QVERIFY(loaded_subs != nullptr); QCOMPARE(sub_data.num, 17); - QCOMPARE(sub_data.subtitles[0].lines, 1); - QCOMPARE(sub_data.subtitles[14].lines, 2); - QCOMPARE(sub_data.subtitles[15].lines, 2); - QCOMPARE(sub_data.subtitles[16].lines, 1); + QCOMPARE(sub_data.subtitles[0].text.size(), static_cast(1)); + QCOMPARE(sub_data.subtitles[14].text.size(), static_cast(2)); + QCOMPARE(sub_data.subtitles[15].text.size(), static_cast(2)); + QCOMPARE(sub_data.subtitles[16].text.size(), static_cast(1)); } void TextXineDemux::test_captions_srt(void) @@ -66,9 +66,9 @@ void TextXineDemux::test_captions_srt(void) QCOMPARE(sub_data.format, FORMAT_SUBRIP); QVERIFY(loaded_subs != nullptr); QCOMPARE(sub_data.num, 4); - QCOMPARE(sub_data.subtitles[3].lines, 3); - QVERIFY(!QString(sub_data.subtitles[3].text[1]).contains("{\\i1}")); - QVERIFY(!QString(sub_data.subtitles[3].text[1]).contains("")); + QCOMPARE(sub_data.subtitles[3].text.size(), static_cast(3)); + QVERIFY(!QString::fromStdString(sub_data.subtitles[3].text[1]).contains("{\\i1}")); + QVERIFY(!QString::fromStdString(sub_data.subtitles[3].text[1]).contains("")); } void TextXineDemux::test_captions_subviewer_data(void) @@ -100,10 +100,10 @@ void TextXineDemux::test_captions_subviewer(void) QCOMPARE(sub_data.format, format); QVERIFY(loaded_subs != nullptr); QCOMPARE(sub_data.num, 4); - QCOMPARE(sub_data.subtitles[1].lines, 2); - QCOMPARE(sub_data.subtitles[2].lines, 3); - QCOMPARE(sub_data.subtitles[3].lines, 1); - QVERIFY(QString(sub_data.subtitles[2].text[0]).contains("String3")); + QCOMPARE(sub_data.subtitles[1].text.size(), static_cast(2)); + QCOMPARE(sub_data.subtitles[2].text.size(), static_cast(3)); + QCOMPARE(sub_data.subtitles[3].text.size(), static_cast(1)); + QVERIFY(QString::fromStdString(sub_data.subtitles[2].text[0]).contains("String3")); } void TextXineDemux::test_captions_smi(void) @@ -125,8 +125,8 @@ void TextXineDemux::test_captions_smi(void) QCOMPARE(sub_data.format, FORMAT_SAMI); QVERIFY(loaded_subs != nullptr); QCOMPARE(sub_data.num, 4); - QCOMPARE(sub_data.subtitles[3].lines, 3); - QVERIFY(!QString(sub_data.subtitles[3].text[1]).contains("")); + QCOMPARE(sub_data.subtitles[3].text.size(), static_cast(3)); + QVERIFY(!QString::fromStdString(sub_data.subtitles[3].text[1]).contains("")); } void TextXineDemux::test_captions_vplayer(void) @@ -146,7 +146,7 @@ void TextXineDemux::test_captions_vplayer(void) QCOMPARE(sub_data.format, FORMAT_VPLAYER); QVERIFY(loaded_subs != nullptr); QCOMPARE(sub_data.num, 5); - QCOMPARE(sub_data.subtitles[3].lines, 1); + QCOMPARE(sub_data.subtitles[3].text.size(), static_cast(1)); } void TextXineDemux::test_captions_rt(void) @@ -239,8 +239,8 @@ void TextXineDemux::test_captions_mpsub(void) QCOMPARE(sub_data.format, FORMAT_MPSUB); QVERIFY(loaded_subs != nullptr); QCOMPARE(sub_data.num, 3); - QCOMPARE(sub_data.subtitles[0].lines, 1); - QCOMPARE(sub_data.subtitles[1].lines, 2); + QCOMPARE(sub_data.subtitles[0].text.size(), static_cast(1)); + QCOMPARE(sub_data.subtitles[1].text.size(), static_cast(2)); } void TextXineDemux::test_captions_aqtitle(void) @@ -260,9 +260,9 @@ void TextXineDemux::test_captions_aqtitle(void) QCOMPARE(sub_data.format, FORMAT_AQTITLE); QVERIFY(loaded_subs != nullptr); QCOMPARE(sub_data.num, 6); - QCOMPARE(sub_data.subtitles[0].lines, 2); - QCOMPARE(sub_data.subtitles[4].lines, 2); - QCOMPARE(sub_data.subtitles[5].lines, 1); + QCOMPARE(sub_data.subtitles[0].text.size(), static_cast(2)); + QCOMPARE(sub_data.subtitles[4].text.size(), static_cast(2)); + QCOMPARE(sub_data.subtitles[5].text.size(), static_cast(1)); } void TextXineDemux::test_captions_jaco(void) @@ -284,11 +284,11 @@ void TextXineDemux::test_captions_jaco(void) QCOMPARE(sub_data.num, 37); // Lines containing the "RLB" directive are skipped, altering the // line numbers compared to the original file. - QCOMPARE(sub_data.subtitles[0].lines, 3); - QCOMPARE(sub_data.subtitles[4].lines, 1); - QVERIFY(QString(sub_data.subtitles[4].text[0]).startsWith("(And")); - QCOMPARE(sub_data.subtitles[5].lines, 3); - QCOMPARE(sub_data.subtitles[6].lines, 2); + QCOMPARE(sub_data.subtitles[0].text.size(), static_cast(3)); + QCOMPARE(sub_data.subtitles[4].text.size(), static_cast(1)); + QVERIFY(QString::fromStdString(sub_data.subtitles[4].text[0]).startsWith("(And")); + QCOMPARE(sub_data.subtitles[5].text.size(), static_cast(3)); + QCOMPARE(sub_data.subtitles[6].text.size(), static_cast(2)); } void TextXineDemux::test_captions_subrip09(void) @@ -308,9 +308,9 @@ void TextXineDemux::test_captions_subrip09(void) QCOMPARE(sub_data.format, FORMAT_SUBRIP09); QVERIFY(loaded_subs != nullptr); QCOMPARE(sub_data.num, 4); - QCOMPARE(sub_data.subtitles[2].lines, 3); - QCOMPARE(sub_data.subtitles[3].lines, 2); - QVERIFY(QString(sub_data.subtitles[3].text[1]).contains("fleece")); + QCOMPARE(sub_data.subtitles[2].text.size(), static_cast(3)); + QCOMPARE(sub_data.subtitles[3].text.size(), static_cast(2)); + QVERIFY(QString::fromStdString(sub_data.subtitles[3].text[1]).contains("fleece")); } void TextXineDemux::test_captions_mpl2(void) // MPL @@ -330,10 +330,10 @@ void TextXineDemux::test_captions_mpl2(void) // MPL QCOMPARE(sub_data.format, FORMAT_MPL2); QVERIFY(loaded_subs != nullptr); QCOMPARE(sub_data.num, 6); - QCOMPARE(sub_data.subtitles[0].lines, 1); - QCOMPARE(sub_data.subtitles[1].lines, 2); - QCOMPARE(sub_data.subtitles[2].lines, 1); - QCOMPARE(sub_data.subtitles[5].lines, 2); + QCOMPARE(sub_data.subtitles[0].text.size(), static_cast(1)); + QCOMPARE(sub_data.subtitles[1].text.size(), static_cast(2)); + QCOMPARE(sub_data.subtitles[2].text.size(), static_cast(1)); + QCOMPARE(sub_data.subtitles[5].text.size(), static_cast(2)); } void TextXineDemux::cleanupTestCase()