⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tsubreadermplayer.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*
 * Subtitle reader with format autodetection
 *
 * Written by laaz
 * Some code cleanup & realloc() by A'rpi/ESP-team
 * dunnowhat sub format by szabi
 */

#include "stdafx.h"
#include "TsubreaderMplayer.h"
#include "TsubtitlesSettings.h"
#include "Tstream.h"
#include "Tconfig.h"
#include "ffdebug.h"

//========================================= TsubtitleParser =========================================
template<class tchar> TsubtitleParser<tchar>::TsubtitleParser(int Iformat,double Ifps,const TsubtitlesSettings *Icfg,const Tconfig *Iffcfg,Tsubreader *Isubreader):
 TsubtitleParserBase(Iformat,Ifps),
 cfg(Icfg),
 ffcfg(Iffcfg),
 textfix(Icfg,Iffcfg),
 subreader(Isubreader),
 textformat(Iffcfg->getHtmlColors())
{
}

template<class tchar> int TsubtitleParser<tchar>::eol(tchar p) {
    return (p=='\r' || p=='\n' || p=='\0');
}

/* Remove leading and trailing space */
template<class tchar> void TsubtitleParser<tchar>::trail_space(tchar *s) {
        int i = 0;
        while (tchar_traits<tchar>::isspace((typename tchar_traits<tchar>::uchar_t)s[i])) ++i;
        if (i) strcpy(s, s + i);
        i = (int)strlen(s) - 1;
        while (i > 0 && tchar_traits<tchar>::isspace((typename tchar_traits<tchar>::uchar_t)s[i])) s[i--] = '\0';
}

template<class tchar> Tsubtitle* TsubtitleParser<tchar>::store(TsubtitleTextBase<tchar> &sub)
{
 sub.format(textformat);
 sub.fix(textfix);
 subreader->push_back(new TsubtitleTextBase<tchar>(sub));
 return subreader->back();
}

template<class tchar> Tsubtitle* TsubtitleParserSami<tchar>::parse(Tstream &fd,int flags) {
    tchar text[this->LINE_LEN+1], *p=NULL,*q;
    int state;


    /* read the first line */
    if (!s)
     if ((s = fd.fgets(line, this->LINE_LEN))==NULL) return NULL;

    TsubtitleTextBase<tchar> current(this->format);
    current.start = current.stop = 0;
    state = 0;

    do {
        switch (state) {

        case 0: /* find "START=" or "Slacktime:" */
            slacktime_s = stristr (s, _L("Slacktime:"));
	    if (slacktime_s)
                sub_slacktime = strtol (slacktime_s+10, NULL, 0) / 10;

            s = (tchar*)stristr (s, _L("Start="));
            if (s) {
                int sec1000=strtol (s + 6, &s, 0);
                current.start = this->hmsToTime(0,0,sec1000/1000,(sec1000%1000)/10);
                /* eat '>' */
                for (; *s != '>' && *s != '\0'; s++);
                s++;
                state = 1; continue;
            }
            break;

	case 1: /* find (optionnal) "<P", skip other TAGs */
	    for  (; *s == ' ' || *s == '\t'; s++); /* strip blanks, if any */
	    if (*s == '\0') break;
	    if (*s != '<') { state = 3; p = text; continue; } /* not a TAG */
	    s++;
	    if (*s == 'P' || *s == 'p') { s++; state = 2; continue; } /* found '<P' */
	    for (; *s != '>' && *s != '\0'; s++); /* skip remains of non-<P> TAG */
	    if (s == '\0')
	      break;
	    s++;
            continue;

        case 2: /* find ">" */
            if ((s = strchr (s, '>'))!=NULL) { s++; state = 3; p = text; continue; }
            break;

        case 3: /* get all text until '<' appears */
            if (*s == '\0') break;
            else if (!_strnicmp (s, _L("<br>"), 4)) {
                *p = '\0'; p = text; trail_space (text);
                if (text[0] != '\0')
                    current.add(text);
                s += 4;
            }
	    else if ((*s == '{') && !sub_no_text_pp) { state = 5; ++s; continue; }
            else if (*s == '<') { state = 4; }
            else if (!_strnicmp (s, _L("&nbsp;"), 6)) { *p++ = ' '; s += 6; }
            else if (*s == '\t') { *p++ = ' '; s++; }
            else if (*s == '\r' || *s == '\n') { s++; }
            else *p++ = *s++;

            /* skip duplicated space */
            if (p > text + 2) if (*(p-1) == ' ' && *(p-2) == ' ') p--;

            continue;

	case 4: /* get current->end or skip <TAG> */
	    q = (tchar*)stristr (s, _L("Start="));
            if (q) {
                int sec1000=strtol (q + 6, &q, 0);
                current.stop = this->hmsToTime(0,0, sec1000/1000,(sec1000%1000)/10-1);
                *p = '\0'; trail_space (text);
                if (text[0] != '\0')
                    current.add(text);
                if (current.size() > 0) { state = 99; break; }
                state = 0; continue;
            }
            s = strchr (s, '>');
            if (s) { s++; state = 3; continue; }
            break;
       case 5: /* get rid of {...} text, but read the alignment code */
	    if ((*s == '\\') && (*(s + 1) == 'a') && !sub_no_text_pp) {
               if (stristr(s, _L("\\a1")) != NULL) {
                   //current->alignment = SUB_ALIGNMENT_BOTTOMLEFT;
                   s = s + 3;
               }
               if (stristr(s, _L("\\a2")) != NULL) {
                   //current->alignment = SUB_ALIGNMENT_BOTTOMCENTER;
                   s = s + 3;
               } else if (stristr(s, _L("\\a3")) != NULL) {
                   //current->alignment = SUB_ALIGNMENT_BOTTOMRIGHT;
                   s = s + 3;
               } else if ((stristr(s, _L("\\a4")) != NULL) || (stristr(s, _L("\\a5")) != NULL) || (stristr(s, _L("\\a8")) != NULL)) {
                   //current->alignment = SUB_ALIGNMENT_TOPLEFT;
                   s = s + 3;
               } else if (stristr(s, _L("\\a6")) != NULL) {
                   //current->alignment = SUB_ALIGNMENT_TOPCENTER;
                   s = s + 3;
               } else if (stristr(s, _L("\\a7")) != NULL) {
                   //current->alignment = SUB_ALIGNMENT_TOPRIGHT;
                   s = s + 3;
               } else if (stristr(s, _L("\\a9")) != NULL) {
                   //current->alignment = SUB_ALIGNMENT_MIDDLELEFT;
                   s = s + 3;
               } else if (stristr(s, _L("\\a10")) != NULL) {
                   //current->alignment = SUB_ALIGNMENT_MIDDLECENTER;
                   s = s + 4;
               } else if (stristr(s, _L("\\a11")) != NULL) {
                   //current->alignment = SUB_ALIGNMENT_MIDDLERIGHT;
                   s = s + 4;
               }
	    }
	    if (*s == '}') state = 3;
	    ++s;
	    continue;
        }

        /* read next line */
        if (state != 99 && (s = fd.fgets (line, this->LINE_LEN))==NULL) {
            if (current.start > 0) {
                break; // if it is the last subtitle
            } else {
                return NULL;
            }
        }

    } while (state != 99);

    // For the last subtitle
    if (current.stop <= 0) {
        current.stop = current.start + this->hmsToTime(0,0,sub_slacktime/1000,(sub_slacktime%1000)/10);
        *p = '\0'; trail_space (text);
        if (text[0] != '\0')
            current.add(text);
    }
    return store(current);
}


template<class tchar> const tchar* TsubtitleParser<tchar>::sub_readtext(const tchar *source, TsubtitleTextBase<tchar> &sub) {
    int len=0;
    const tchar *p=source;

//    printf("src=%p  dest=%p  \n",source,dest);

    while ( !eol(*p) && *p!= '|' ) {
        p++,len++;
    }

    sub.add(source,len);
    while (*p=='\r' || *p=='\n' || *p=='|') p++;

    if (*p) return p;  // not-last text field
    else return NULL;  // last text field
}

template<class tchar> Tsubtitle* TsubtitleParserMicrodvd<tchar>::parse(Tstream &fd,int flags) {
    tchar line[this->LINE_LEN+1];
    tchar line2[this->LINE_LEN+1];
    const tchar *p, *next;

    int start=0,stop=0;
    bool skip;
    do {
      do {
          if (!fd.fgets (line, this->LINE_LEN)) return NULL;
      } while ((tchar_traits<tchar>::sscanf() (line,
                        _L("{%ld}{}%[^\r\n]"),
                        &start, line2) < 2) &&
               (tchar_traits<tchar>::sscanf() (line,
                        _L("{%ld}{%ld}%[^\r\n]"),
                        &start, &stop, line2) < 3));
      skip=false;
      if (start==1 && stop==1)
       {
        tchar *e;double newfps;
        if ((newfps=strtod(line2,&e))>0 && !*e)
         {
          this->fps=newfps;
          skip=true;
         }
       }
    } while (skip);

    TsubtitleTextBase<tchar> current(this->format);
    current.start=this->frameToTime(start);
    current.stop =this->frameToTime(stop );

    p=line2;

    next=p;
    while ((next =sub_readtext (next, current))!=NULL)
     ;
    return store(current);
}

template<class tchar> Tsubtitle* TsubtitleParserSubrip<tchar>::parse(Tstream &fd,int flags) {
    tchar line[this->LINE_LEN+1];
    int a1,a2,a3,a4,b1,b2,b3,b4;
    tchar *p=NULL, *q=NULL;
    int len;
    TsubtitleTextBase<tchar> current(this->format);
    while (1) {
        if (!fd.fgets (line, this->LINE_LEN)) return NULL;
        if (flags&this->PARSETIME)
         {
          if (tchar_traits<tchar>::sscanf() (line, _L("%d:%d:%d.%d,%d:%d:%d.%d"),&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4) < 8) continue;
          current.start = this->hmsToTime(a1,a2,a3,a4);
          current.stop  = this->hmsToTime(b1,b2,b3,b4);
          if (!fd.fgets (line, this->LINE_LEN)) return NULL;
         }

        p=q=line;
        for (;;) {
            for (q=p,len=0; *p && *p!='\r' && *p!='\n' && *p!='|' && strncmp(p,_L("[br]"),4); p++,len++);
            current.add(q,len);
            if (!*p || *p=='\r' || *p=='\n') break;
            if (*p=='|') p++;
            else while (*p++!=']');
        }
        break;
    }

    return store(current);
}

template<class tchar> Tsubtitle* TsubtitleParserSubviewer<tchar>::parse(Tstream &fd,int flags) {
    tchar line[this->LINE_LEN+1];
    int a1,a2,a3,a4,b1,b2,b3,b4;
    tchar *p=NULL;
    int len;
    TsubtitleTextBase<tchar> current(this->format);
    TsubtitleParser<tchar>::textformat.resetProps();
    while (!current.size()) {
        if (flags&this->PARSETIME)
         {
          if (!fd.fgets (line, this->LINE_LEN)) return NULL;
          int li;
	  if ((len=tchar_traits<tchar>::sscanf() (line, _L("%d:%d:%d%[,.:]%d --> %d:%d:%d%[,.:]%d"),&a1,&a2,&a3,&li,&a4,&b1,&b2,&b3,&li,&b4)) < 10)
           continue;
          current.start = this->hmsToTime(a1,a2,a3,a4/10);
          current.stop  = this->hmsToTime(b1,b2,b3,b4/10);
         }
        for (;;) {
            if (!fd.fgets (line, this->LINE_LEN)) goto end;//break;
            len=0;
            for (p=line; *p!='\n' && *p!='\r' && *p; p++,len++);
            if (len) {
                int j=0,skip=0;
		tchar *curptr0,*curptr=curptr0=(tchar*)_alloca((len+1)*sizeof(tchar));
                for(; j<len; j++) {
		    /* let's filter html tags ::atmos */
                    /*
		    if(line[j]=='>') {
			skip=0;
			continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -