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

📄 tsubreadermplayer.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    if (!fd.fgets (line, this->LINE_LEN))
     return previous=store(current);

    next = line;//,i=1;
    while ((next =sub_readtext (next,current))!=NULL)
     ;

    if (current.at(0)[0]=='\0' && current.at(1)[0]=='\0') {
        // void subtitle -> end of previous marked and exit
        previous = NULL;
        return NULL;
        }

    return previous=store(current);
}

template<class tchar> Tsubtitle* TsubtitleParserSubrip09<tchar>::parse(Tstream &fd,int flags) {
    tchar line[this->LINE_LEN+1];
    int a1,a2,a3;
    const tchar * next=NULL;
    int i;

    while (1) {
    // try to locate next subtitle
        if (!fd.fgets (line, this->LINE_LEN))
                return NULL;
        if (!(tchar_traits<tchar>::sscanf() (line, _L("[%d:%d:%d]"),&a1,&a2,&a3) < 3))
                break;
    }
    TsubtitleTextBase<tchar> current(this->format);
    current.start = this->hmsToTime(a1,a2,a3);
    if (previous != NULL)
        previous->stop = current.start-1;

    if (!fd.fgets (line, this->LINE_LEN))
        return NULL;

    next = line;i=0;

    //(*current)[0]=""; // just to be sure that string is clear

    while ((next =sub_readtext (next, current))!=NULL)
     i++;

    if (current.size()==0 || (current.at(0)[0]=='\0') && (i==0)) {
        // void subtitle -> end of previous marked and exit
        previous = NULL;
        return NULL;
        }

    return previous=store(current);
}

template<class tchar> Tsubtitle* TsubtitleParserMPL2<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,end=0;

    do {
	if (!fd.fgets (line, this->LINE_LEN)) return NULL;
    } while ((tchar_traits<tchar>::sscanf() (line,
		      _L("[%ld][%ld]%[^\r\n]"),
		      &start, &end, line2) < 3));
    TsubtitleTextBase<tchar> current(this->format);
    current.start = this->frameToTime(start);
    current.stop = this->frameToTime(end);
    p=line2;
    next=p;
    while ((next =sub_readtext (next, current))!=NULL)
     ;
    return store(current);
}

template<class tchar> TsubtitleParserBase* TsubtitleParserBase::getParser0(int format,double fps,const TsubtitlesSettings *cfg,const Tconfig *ffcfg,Tsubreader *subreader,bool isEmbedded)
{
 switch (format&Tsubreader::SUB_FORMATMASK)
  {
   case Tsubreader::SUB_MICRODVD  :return new TsubtitleParserMicrodvd<tchar>(format,fps,cfg,ffcfg,subreader);
   case Tsubreader::SUB_SUBRIP    :return new TsubtitleParserSubrip<tchar>(format,fps,cfg,ffcfg,subreader);
   case Tsubreader::SUB_SUBVIEWER :return new TsubtitleParserSubviewer<tchar>(format,fps,cfg,ffcfg,subreader);
   case Tsubreader::SUB_SAMI      :return new TsubtitleParserSami<tchar>(format,fps,cfg,ffcfg,subreader);
   case Tsubreader::SUB_VPLAYER   :return new TsubtitleParserVplayer<tchar>(format,fps,cfg,ffcfg,subreader);
   case Tsubreader::SUB_RT        :return new TsubtitleParserRt<tchar>(format,fps,cfg,ffcfg,subreader);
   case Tsubreader::SUB_SSA       :return new TsubtitleParserSSA<tchar>(format,fps,cfg,ffcfg,subreader,isEmbedded);
   case Tsubreader::SUB_DUNNOWHAT :return new TsubtitleParserDunnowhat<tchar>(format,fps,cfg,ffcfg,subreader);
   case Tsubreader::SUB_MPSUB     :return new TsubtitleParserMPsub<tchar>(format,fps,cfg,ffcfg,subreader);
   case Tsubreader::SUB_AQTITLE   :return new TsubtitleParserAqt<tchar>(format,fps,cfg,ffcfg,subreader);
   case Tsubreader::SUB_SUBVIEWER2:return new TsubtitleParserSubviewer2<tchar>(format,fps,cfg,ffcfg,subreader);
   case Tsubreader::SUB_SUBRIP09  :return new TsubtitleParserSubrip09<tchar>(format,fps,cfg,ffcfg,subreader);
   case Tsubreader::SUB_MPL2      :return new TsubtitleParserMPL2<tchar>(format,fps,cfg,ffcfg,subreader);
   default:return NULL;
  }
}
TsubtitleParserBase* TsubtitleParserBase::getParser(int format,double fps,const TsubtitlesSettings *cfg,const Tconfig *ffcfg,Tsubreader *subreader,bool utf8,bool isEmbedded)
{
 if (ffcfg->unicodeOS && (utf8 || Tsubreader::getSubEnc(format)&Tstream::ENC_UNICODE))
  return getParser0<wchar_t>(format,fps,cfg,ffcfg,subreader,isEmbedded);
 else
  return getParser0<char>(format,fps,cfg,ffcfg,subreader,isEmbedded);
}

//======================================= TsubreaderMplayer =======================================
TsubreaderMplayer::TsubreaderMplayer(Tstream &fd,int sub_format,double fps,const TsubtitlesSettings *cfg,const Tconfig *ffcfg,bool isEmbedded)
{
 TsubtitleParserBase *parser=TsubtitleParserBase::getParser(sub_format,fps,cfg,ffcfg,this,false,isEmbedded);
 if (!parser) return;

 fd.rewind();

 while (parser->parse(fd))
  ;
 delete parser;

 processDuration(cfg);

 if (cfg->timeoverlap && !empty())
  {
   for (iterator s=begin();s!=end()-1;s++)
    if ((*s)->stop<(*s)->start)
     (*s)->stop=(*(s+1))->start-1;
   processOverlap(sub_format);
  }
}

void Tsubreader::processOverlap(int sub_format)
{
 int sub_format1=sub_format&Tsubreader::SUB_FORMATMASK;
 if (!(sub_format1==Tsubreader::SUB_MICRODVD
    || sub_format1==Tsubreader::SUB_SUBRIP
    || sub_format1==Tsubreader::SUB_SAMI
    || sub_format1==Tsubreader::SUB_VPLAYER
    || sub_format1==Tsubreader::SUB_RT
    || sub_format1==Tsubreader::SUB_SSA
    || sub_format1==Tsubreader::SUB_DUNNOWHAT
    || sub_format1==Tsubreader::SUB_MPSUB
    || sub_format1==Tsubreader::SUB_AQTITLE
    || sub_format1==Tsubreader::SUB_SUBVIEWER2
    || sub_format1==Tsubreader::SUB_SUBRIP09
    || sub_format1==Tsubreader::SUB_MPL2))
  return;
 static const int SUB_MAX_TEXT=INT_MAX/2;
 int sub_orig = size();
 int n_first = size();
 int sub_num =0;
 std::vector<Tsubtitle*> newsubs;
 for (int sub_first = 0; sub_first < n_first; ++sub_first)
  {
   REFERENCE_TIME global_start = at(sub_first)->start,global_end = at(sub_first)->stop, local_start, local_end;
   int lines_to_add = at(sub_first)->numlines(), sub_to_add = 0;
   int **placeholder = NULL, higher_line = 0, counter, start_block_sub = sub_num;
   char real_block = 1;

   // here we find the number of subtitles inside the 'block'
   // and its span interval. this works well only with sorted
   // subtitles
   while ((sub_first + sub_to_add + 1 < n_first) && (at(sub_first + sub_to_add + 1)->start < global_end))
    {
     ++sub_to_add;
     lines_to_add += at(sub_first + sub_to_add)->numlines();
     if (at(sub_first + sub_to_add)->start < global_start)
      global_start = at(sub_first + sub_to_add)->start;
     if (at(sub_first + sub_to_add)->stop > global_end)
      global_end = at(sub_first + sub_to_add)->stop;
    }

   // we need a structure to keep trace of the screen lines
   // used by the subs, a 'placeholder'
   counter = 2 * sub_to_add + 1;  // the maximum number of subs derived rom a block of sub_to_add+1 subs
   placeholder = (int **) malloc(sizeof(int *) * counter);
   for (int i = 0; i < counter; ++i)
    {
     placeholder[i] = (int *) malloc(sizeof(int) * lines_to_add);
     for (int j = 0; j < lines_to_add; ++j)
      placeholder[i][j] = -1;
    }

   counter = 0;
   local_end = global_start - 1;
   do
    {
     // here we find the beginning and the end of a new subtitle in the block
     local_start = local_end + 1;
     local_end   = global_end;
     for (int j = 0; j <= sub_to_add; ++j)
      if ((at(sub_first + j)->start - 1 > local_start) && (at(sub_first + j)->start - 1 < local_end))
       local_end = at(sub_first + j)->start - 1;
      else if ((at(sub_first + j)->stop > local_start) && (at(sub_first + j)->stop< local_end))
       local_end = at(sub_first + j)->stop;

     // here we allocate the screen lines to subs we must
     // display in current local_start-local_end interval.
     // if the subs were yet presents in the previous interval
     // they keep the same lines, otherwise they get unused lines
     for (int j = 0; j <= sub_to_add; ++j)
      {
       if ((at(sub_first + j)->start <= local_end) && (at(sub_first + j)->stop > local_start))
        {
         unsigned long sub_lines=at(sub_first + j)->numlines(), fragment_length = lines_to_add + 1,tmp=0;
         char boolean = 0;
         int fragment_position = -1;

         // if this is not the first new sub of the block
         // we find if this sub was present in the previous
         // new sub
         if (counter)
          for (int i = 0; i < lines_to_add; ++i)
           if (placeholder[counter - 1][i] == sub_first + j)
            {
             placeholder[counter][i] = sub_first + j;
             boolean = 1;
            }
         if (boolean)
          continue;
         // we are looking for the shortest among all groups of
         // sequential blank lines whose length is greater than or
         // equal to sub_lines. we store in fragment_position the
         // position of the shortest group, in fragment_length its
         // length, and in tmp the length of the group currently
         // examined
         int i;
         for (i = 0; i < lines_to_add; ++i)
          {
           if (placeholder[counter][i] == -1)
            ++tmp; // placeholder[counter][i] is part of the current group of blank lines
           else
            {
             if (tmp == sub_lines)
              {
               // current group's size fits exactly the one we
               // need, so we stop looking
               fragment_position = i - tmp;
               tmp = 0;
               break;
              }
             if ((tmp) && (tmp > sub_lines) && (tmp < fragment_length))
              {
               // current group is the best we found till here,
               // but is still bigger than the one we are looking
               // for, so we keep on looking
               fragment_length = tmp;
               fragment_position = i - tmp;
               tmp = 0;
              }
             else
              tmp = 0; // current group doesn't fit at all, so we forget it
            }
          }
         if (tmp)
          if ((tmp >= sub_lines) && (tmp < fragment_length))  // last screen line is blank, a group ends with it
           fragment_position = i - tmp;
         if (fragment_position == -1)
          {
           // it was not possible to find free screen line(s) for a subtitle,
           // usually this means a bug in the code; however we do not overlap
           //mp_msg(MSGT_SUBREADER, MSGL_WARN, "SUB: we could not find a suitable position for an overlapping subtitle\n");
           higher_line = SUB_MAX_TEXT + 1;
           break;
          }
         else
          for (tmp = 0; tmp < sub_lines; ++tmp)
           placeholder[counter][fragment_position + tmp] = sub_first + j;
        }
      }
     for (int j = higher_line + 1; j < lines_to_add; ++j)
      if (placeholder[counter][j] != -1)
       higher_line = j;
      else
       break;

     // we read the placeholder structure and create the new subs.
     Tsubtitle *second=at(0)->create();
     second->start = local_start;
     second->stop  = local_end;
     for (int i = 0, j = 0; j < lines_to_add ; ++j)
      if (placeholder[counter][j] != -1)
       {
        at(placeholder[counter][j])->copyProps(second);
        int lines = at(placeholder[counter][j])->numlines();
        for (int ls = 0; ls < lines; ++ls)
         //second[sub_num].text[i++] = strdup(first[placeholder[counter][j]].text[ls]);
         //second->push_back((*(TsubtitleTextBase<char>*)at(placeholder[counter][j]))[ls]);
         at(placeholder[counter][j])->copyLine(second,ls);
        j+=lines-1;
       }
      else
       second->addEmpty();
     newsubs.push_back(second);
     ++sub_num;
     ++counter;
    } while (local_end < global_end);
   counter = 2 * sub_to_add + 1;
   for (int i = 0; i < counter; ++i)
    free(placeholder[i]);
   free(placeholder);
   sub_first += sub_to_add;
  }
 clear();
 for (std::vector<Tsubtitle*>::const_iterator s=newsubs.begin();s!=newsubs.end();s++)
  push_back(*s);
 IsProcessOverlapDone=true;
}

⌨️ 快捷键说明

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