Ticket #6240: 6240-v1.patch

File 6240-v1.patch, 7.8 KB (added by danielk, 16 years ago)

work in progress..

  • libs/libmythtv/xine_demux_sputext.cpp

     
    3232#include "config.h"
    3333#endif
    3434
     35#include <ctype.h>
    3536#include <stdlib.h>
    3637#include <stdio.h>
    3738#include <unistd.h>
     
    9798  off_t nread = 0;
    9899  char *s;
    99100  int linelen;
    100  
    101   if ((len - demuxstr->buflen) > 512) {
    102     if((nread = fread(
    103             &demuxstr->buf[demuxstr->buflen], 1,
    104             len - demuxstr->buflen, demuxstr->file_ptr)) < 0) {
     101
     102  // Since our RemoteFile code sleeps 200ms whenever we get back less data
     103  // than requested, but this code just keeps trying to read until it gets
     104  // an error back, we check for empty reads so that we can stop reading
     105  // when there is no more data to read
     106  if (demuxstr->emptyReads == 0 && (len - demuxstr->buflen) > 512) {
     107    nread = demuxstr->rbuffer->Read(
     108        &demuxstr->buf[demuxstr->buflen], len - demuxstr->buflen);
     109    if (nread < 0) {
    105110      printf("read failed.\n");
    106111      return NULL;
    107112    }
    108113  }
    109  
     114 
     115  if (!nread)
     116    demuxstr->emptyReads++;
     117
    110118  demuxstr->buflen += nread;
    111119  demuxstr->buf[demuxstr->buflen] = '\0';
    112120
     
    10991107  };
    11001108
    11011109  /* Rewind (sub_autodetect() needs to read input from the beginning) */
    1102   if(fseek(demuxstr->file_ptr, 0, SEEK_SET) == -1) {
     1110  if(demuxstr->rbuffer->Seek(0, SEEK_SET) == -1) {
    11031111    printf("seek failed.\n");
    11041112    return NULL;
    11051113  }
    11061114  demuxstr->buflen = 0;
     1115  demuxstr->emptyReads = 0;
    11071116
    11081117  demuxstr->format=sub_autodetect (demuxstr);
    11091118  if (demuxstr->format==FORMAT_UNKNOWN) {
     
    11131122  /*printf("Detected subtitle file format: %d\n", demuxstr->format);*/
    11141123   
    11151124  /* Rewind */
    1116   if(fseek(demuxstr->file_ptr, 0, SEEK_SET) == -1) {
     1125  if(demuxstr->rbuffer->Seek(0, SEEK_SET) == -1) {
    11171126    printf("seek failed.\n");
    11181127    return NULL;
    11191128  }
    11201129  demuxstr->buflen = 0;
     1130  demuxstr->emptyReads = 0;
    11211131
    11221132  demuxstr->num=0;n_max=32;
    11231133  first = (subtitle_t *) malloc(n_max*sizeof(subtitle_t));
  • libs/libmythtv/playercontext.cpp

     
    477477        _nvp->SetNoAudio();
    478478    else
    479479    {
    480 // FIXME: This causes startup to take *forever*
    481 //        _nvp->LoadExternalSubtitles(buffer->GetFilename());
     480        QString subfn = ComputeExternalSubtitleFileName(buffer->GetFilename());
     481        if (!subfn.isEmpty())
     482            _nvp->LoadExternalSubtitles(subfn);
    482483    }
    483484
    484485    if ((embedwinid > 0) && embedbounds)
     
    550551    return StartDecoderThread(maxWait);
    551552}
    552553
     554#include <QDir>
     555#include "storagegroup.h"
     556QString PlayerContext::ComputeExternalSubtitleFileName(
     557    const QString &videoFile) const
     558{
     559    if (videoFile.isEmpty())
     560        return QString::null;
     561
     562    QString fileName = videoFile;
     563    QString dirName  = ".";
     564
     565    int dirPos = videoFile.lastIndexOf(QChar('/'));
     566    if (dirPos > 0)
     567    {
     568        fileName = videoFile.mid(dirPos + 1);
     569        dirName = videoFile.left(dirPos);
     570    }
     571
     572    QString baseName = fileName;
     573    int suffixPos = fileName.lastIndexOf(QChar('.'));
     574    if (suffixPos > 0)
     575        baseName = fileName.left(suffixPos);
     576
     577    // Try to find files with the same base name, but ending with
     578    // '.srt', '.sub', or '.txt'
     579    QStringList ext;
     580    ext += ".srt";
     581    ext += ".sub";
     582    ext += ".txt";
     583
     584    if (dirName.startsWith("myth://"))
     585    {
     586        QString sgroup = "";
     587        if (dirName.indexOf('@') > -1)
     588            sgroup = dirName.mid(7, dirName.indexOf('@', 7) - 7);
     589
     590        StorageGroup sg(sgroup);
     591        QStringList::const_iterator it = ext.begin();
     592        for (; it != ext.end(); ++it)
     593        {
     594            if (sg.FileExists(baseName + *it))
     595                return dirName + "/" + baseName + *it;
     596        }
     597
     598        return QString::null;
     599    }
     600
     601    QStringList el;
     602    {
     603        // The dir listing does not work if the filename has the
     604        // following chars "[]()" so we convert them to the wildcard '?'
     605        const QString findBaseName = baseName
     606            .replace("[", "?")
     607            .replace("]", "?")
     608            .replace("(", "?")
     609            .replace(")", "?");
     610
     611        QStringList::const_iterator eit = ext.begin();
     612        for (; eit != ext.end(); eit++)
     613            el += findBaseName + *eit;
     614    }
     615
     616    // Some Qt versions do not accept paths in the search string of
     617    // entryList() so we have to set the dir first
     618    QDir dir;
     619    dir.setPath(dirName);
     620
     621    const QStringList candidates = dir.entryList(el);
     622
     623    QStringList::const_iterator cit = candidates.begin();
     624    QStringList::const_iterator eit = ext.begin();
     625    for (; (cit != candidates.end()) && (eit != ext.end()); ++cit, ++eit)
     626    {
     627        QFileInfo fi(dirName + "/" + *cit);
     628        if (fi.exists() && (fi.size() > 0))
     629            return dirName + "/" + baseName + *eit;
     630    }
     631
     632    return QString::null;
     633}
     634
    553635/** \fn PlayerContext::StartDecoderThread(int)
    554636 *  \brief Starts player, must be called after StartRecorder().
    555637 *  \param maxWait How long to wait for NuppelVideoPlayer to start playing.
  • libs/libmythtv/xine_demux_sputext.h

     
    11#ifndef XINE_DEMUX_SPUTEXT_H
    22#define XINE_DEMUX_SPUTEXT_H
    33
    4 #ifdef __cplusplus
    5 extern "C" {
    6 #endif
     4#include "RingBuffer.h"
    75
    8 #include <ctype.h>
    9 #include <stdio.h>
    10 
    116#define SUB_BUFSIZE   1024
    127#define SUB_MAX_TEXT  5
    138#define MAX_TIMEOUT 4
     
    2621
    2722typedef struct {
    2823
    29   FILE*              file_ptr;
     24  RingBuffer*        rbuffer;
    3025
    3126  int                status;
    3227
    3328  char               buf[SUB_BUFSIZE];
    3429  off_t              buflen;
     30  off_t              emptyReads;
    3531
    3632  float              mpsub_position; 
    3733
     
    4844
    4945subtitle_t *sub_read_file (demux_sputext_t*);
    5046
    51 #ifdef __cplusplus
    52 }
    5347#endif
    54 
    55 #endif
  • libs/libmythtv/playercontext.h

     
    134134    bool IsValidLiveTV(void) const
    135135        { return nvp && tvchain && recorder && buffer; }
    136136
     137  private:
     138    QString ComputeExternalSubtitleFileName(const QString &videoFile) const;
     139
    137140  public:
    138141    QString             recUsage;
    139142    NuppelVideoPlayer  *nvp;
  • libs/libmythtv/textsubtitleparser.cpp

     
    1111#include <qtextcodec.h>
    1212
    1313#include "mythcontext.h"
     14#include "RingBuffer.h"
    1415
    1516using std::lower_bound;
    1617
     
    110111bool TextSubtitleParser::LoadSubtitles(QString fileName, TextSubtitles &target)
    111112{
    112113    demux_sputext_t sub_data;
    113     sub_data.file_ptr = fopen(fileName.toLocal8Bit().constData(), "r");
     114    sub_data.rbuffer = new RingBuffer(fileName, 0, false);
    114115   
    115     if (!sub_data.file_ptr)
     116    if (!sub_data.rbuffer)
    116117        return false;
    117118   
    118119    subtitle_t *loaded_subs = sub_read_file(&sub_data);
    119120    if (!loaded_subs)
    120121    {
    121         fclose(sub_data.file_ptr);
     122                delete sub_data.rbuffer;
    122123        return false;
    123124    }
    124125
     
    131132    if (!textCodec)
    132133        textCodec = QTextCodec::codecForName("utf-8");
    133134    if (!textCodec)
     135        {
     136        delete sub_data.rbuffer;
    134137        return false;
     138    }
    135139
    136140    QTextDecoder *dec = textCodec->makeDecoder();
    137141
     
    162166    // textCodec object is managed by Qt, do not delete...
    163167
    164168    free(loaded_subs);
    165     fclose(sub_data.file_ptr);
    166169
     170    delete sub_data.rbuffer;
    167171    return true;
    168172}