Ticket #9825: 9825-v1.patch

File 9825-v1.patch, 19.0 KB (added by danielk, 14 years ago)

Patch to address error reporting an child thread shutdown.

  • mythtv/libs/libmythtv/NuppelVideoRecorder.cpp

    diff --git a/mythtv/libs/libmythtv/NuppelVideoRecorder.cpp b/mythtv/libs/libmythtv/NuppelVideoRecorder.cpp
    index debd75b..17481c2 100644
    a b NuppelVideoRecorder::NuppelVideoRecorder(TVRec *rec, ChannelBase *channel) :  
    8787{
    8888    channelObj = channel;
    8989
    90     encoding = false;
    9190    fd = -1;
    9291    channelfd = -1;
    9392    lf = tf = 0;
    NuppelVideoRecorder::NuppelVideoRecorder(TVRec *rec, ChannelBase *channel) :  
    130129    text_buffer_count = 0;
    131130    text_buffer_size = 0;
    132131
    133     childrenLive = false;
    134     errored = false;
    135 
    136     recording = false;
    137 
    138132    writepaused = false;
    139133    audiopaused = false;
    140134    mainpaused = false;
    bool NuppelVideoRecorder::IsRecording(void)  
    491485    return recording;
    492486}
    493487
    494 bool NuppelVideoRecorder::IsErrored(void)
    495 {
    496     return errored;
    497 }
    498 
    499488long long NuppelVideoRecorder::GetFramesWritten(void)
    500489{
    501490    return framesWritten;
    void NuppelVideoRecorder::Initialize(void)  
    748737        livetv = false;
    749738        if (!ringBuffer->IsOpen())
    750739        {
    751             LOG(VB_GENERAL, LOG_ERR, LOC + "Could not open RingBuffer");
    752             errored = true;
     740            _error = "Could not open RingBuffer";
     741            LOG(VB_GENERAL, LOG_ERR, LOC + _error);
    753742            return;
    754743        }
    755744    }
    void NuppelVideoRecorder::ResizeVideoBuffers(void)  
    992981    }
    993982}
    994983
    995 void NuppelVideoRecorder::StopRecording(void)
    996 {
    997     encoding = false;
    998     V4LRecorder::StopRecording();
    999 }
    1000 
    1001984void NuppelVideoRecorder::StreamAllocate(void)
    1002985{
    1003986    strm = new signed char[width * height * 2 + 10];
    bool NuppelVideoRecorder::Open(void)  
    10171000        fd = open(vdevice.constData(), O_RDWR);
    10181001        if (retries++ > 5)
    10191002        {
    1020             LOG(VB_GENERAL, LOG_ERR, LOC +
    1021                 QString("Can't open video device: %1").arg(videodevice));
    1022             LOG(VB_GENERAL, LOG_ERR, LOC + "open video: " + ENO);
     1003            _error = QString("Can't open video device: %1").arg(videodevice);
     1004            LOG(VB_GENERAL, LOG_ERR, LOC + _error + ENO);
    10231005            KillChildren();
    1024             errored = true;
    10251006            return false;
    10261007        }
    10271008    }
    void NuppelVideoRecorder::run(void)  
    10721053    if (lzo_init() != LZO_E_OK)
    10731054    {
    10741055        LOG(VB_GENERAL, LOG_ERR, LOC + "lzo_init() failed, exiting");
    1075         errored = true;
     1056        _error = "lzo_init() failed, exiting";
     1057        LOG(VB_GENERAL, LOG_ERR, LOC + _error);
    10761058        return;
    10771059    }
    10781060
    10791061    if (!Open())
    10801062    {
    1081         errored = true;
     1063        _error = "Failed to open device";
     1064        LOG(VB_GENERAL, LOG_ERR, LOC + _error);
    10821065        return;
    10831066    }
    10841067
    void NuppelVideoRecorder::run(void)  
    10861069
    10871070    if (usingv4l2 && !SetFormatV4L2())
    10881071    {
    1089         errored = true;
     1072        _error = "Failed to set V4L2 format";
     1073        LOG(VB_GENERAL, LOG_ERR, LOC + _error);
    10901074        return;
    10911075    }
    10921076
    void NuppelVideoRecorder::run(void)  
    11121096
    11131097    if (CreateNuppelFile() != 0)
    11141098    {
    1115         LOG(VB_GENERAL, LOG_ERR, LOC + QString("Cannot open '%1' for writing")
    1116                 .arg(ringBuffer->GetFilename()));
    1117         errored = true;
     1099        _error = QString("Cannot open '%1' for writing")
     1100            .arg(ringBuffer->GetFilename());
     1101        LOG(VB_GENERAL, LOG_ERR, LOC + _error);
    11181102        return;
    11191103    }
    11201104
    1121     if (childrenLive)
     1105    if (IsHelperRequested())
    11221106    {
    11231107        LOG(VB_GENERAL, LOG_ERR, LOC + "Children are already alive");
    1124         errored = true;
     1108        _error = "Children are already alive";
    11251109        return;
    11261110    }
    11271111
    1128     if (!SpawnChildren())
    11291112    {
    1130         LOG(VB_GENERAL, LOG_ERR, LOC + "Couldn't spawn children");
    1131         errored = true;
    1132         return;
     1113        QMutexLocker locker(&pauseLock);
     1114        request_recording = true;
     1115        request_helper = true;
     1116        recording = true;
     1117        recordingWait.wakeAll();
    11331118    }
    11341119
     1120    write_thread = new NVRWriteThread(this);
     1121    write_thread->start();
     1122
     1123    audio_thread = new NVRAudioThread(this);
     1124    audio_thread->start();
     1125
     1126    if ((vbimode != VBIMode::None) && (OpenVBIDevice() >= 0))
     1127        vbi_thread = new VBIThread(this);
     1128
    11351129    // save the start time
    11361130    gettimeofday(&stm, &tzone);
    11371131
    void NuppelVideoRecorder::run(void)  
    11431137        inpixfmt = FMT_NONE;
    11441138        InitFilters();
    11451139        DoV4L2();
    1146         return;
    11471140    }
    11481141    else
    11491142        DoV4L1();
     1143
     1144    {
     1145        QMutexLocker locker(&pauseLock);
     1146        request_recording = false;
     1147        request_helper = false;
     1148        recording = false;
     1149        recordingWait.wakeAll();
     1150    }
    11501151}
    11511152
    11521153#ifdef USING_V4L1
    void NuppelVideoRecorder::DoV4L1(void)  
    11681169
    11691170    if (ioctl(fd, VIDIOCGCAP, &vc) < 0)
    11701171    {
    1171         LOG(VB_GENERAL, LOG_ERR, LOC + "VIDIOCGCAP: " + ENO);
     1172        QString tmp = "VIDIOCGCAP: " + ENO;
    11721173        KillChildren();
    1173         errored = true;
     1174        LOG(VB_GENERAL, LOG_ERR, tmp);
     1175        _error = tmp;
    11741176        return;
    11751177    }
    11761178
    void NuppelVideoRecorder::DoV4L1(void)  
    12101212    if ((vc.type & VID_TYPE_MJPEG_ENCODER) && hardware_encode)
    12111213    {
    12121214        DoMJPEG();
    1213         errored = true;
     1215        _error = "MJPEG requested but not available.";
     1216        LOG(VB_GENERAL, LOG_ERR, LOC + _error);
    12141217        return;
    12151218    }
    12161219
    void NuppelVideoRecorder::DoV4L1(void)  
    12191222
    12201223    if (ioctl(fd, VIDIOCGMBUF, &vm) < 0)
    12211224    {
    1222         LOG(VB_GENERAL, LOG_ERR, LOC + "VIDIOCGMBUF: " +ENO);
     1225        QString tmp = "VIDIOCGMBUF: " + ENO;
    12231226        KillChildren();
    1224         errored = true;
     1227        LOG(VB_GENERAL, LOG_ERR, LOC + tmp);
     1228        _error = tmp;
    12251229        return;
    12261230    }
    12271231
    12281232    if (vm.frames < 2)
    12291233    {
    1230         LOG(VB_GENERAL, LOG_ERR, LOC + "need a minimum of 2 capture buffers");
     1234        QString tmp = "need a minimum of 2 capture buffers";
    12311235        KillChildren();
    1232         errored = true;
     1236        LOG(VB_GENERAL, LOG_ERR, LOC + tmp);
     1237        _error = tmp;
    12331238        return;
    12341239    }
    12351240
    void NuppelVideoRecorder::DoV4L1(void)  
    12411246                                               fd, 0);
    12421247    if (buf <= 0)
    12431248    {
    1244         LOG(VB_GENERAL, LOG_ERR, LOC + "mmap: " + ENO);
     1249        QString tmp = "mmap: " + ENO;
    12451250        KillChildren();
    1246         errored = true;
     1251        LOG(VB_GENERAL, LOG_ERR, LOC + tmp);
     1252        _error = tmp;
    12471253        return;
    12481254    }
    12491255
    void NuppelVideoRecorder::DoV4L1(void)  
    12611267    if (ioctl(fd, VIDIOCMCAPTURE, &mm)<0)
    12621268        LOG(VB_GENERAL, LOG_ERR, LOC + "VIDIOCMCAPTUREi1: " + ENO);
    12631269
    1264     encoding = true;
    1265     recording = true;
    1266 
    12671270    int syncerrors = 0;
    12681271
    1269     while (encoding)
     1272    while (IsRecordingRequested() && !IsErrored())
    12701273    {
    12711274        {
    12721275            QMutexLocker locker(&pauseLock);
    void NuppelVideoRecorder::DoV4L1(void)  
    13381341
    13391342    FinishRecording();
    13401343
    1341     recording = false;
    13421344    close(fd);
    13431345}
    13441346#else // if !USING_V4L1
    void NuppelVideoRecorder::DoV4L2(void)  
    14871489        comp.flags |= GO7007_COMP_CLOSED_GOP;
    14881490        if (ioctl(fd, GO7007IOC_S_COMP_PARAMS, &comp) < 0)
    14891491        {
    1490             LOG(VB_GENERAL, LOG_ERR, LOC + "Unable to set compression params");
    1491             errored = true;
     1492            _error = "Unable to set compression params";
     1493            LOG(VB_GENERAL, LOG_ERR, LOC + _error);
    14921494            return;
    14931495        }
    14941496
    void NuppelVideoRecorder::DoV4L2(void)  
    15011503
    15021504        if (ioctl(fd, GO7007IOC_S_MPEG_PARAMS, &mpeg) < 0)
    15031505        {
    1504             LOG(VB_GENERAL, LOG_ERR, LOC + "Unable to set MPEG params");
    1505             errored = true;
     1506            _error = "Unable to set MPEG params";
     1507            LOG(VB_GENERAL, LOG_ERR, LOC + _error);
    15061508            return;
    15071509        }
    15081510
    void NuppelVideoRecorder::DoV4L2(void)  
    15151517
    15161518        if (ioctl(fd, GO7007IOC_S_BITRATE, &usebitrate) < 0)
    15171519        {
    1518             LOG(VB_GENERAL, LOG_ERR, LOC + "Unable to set bitrate");
    1519             errored = true;
     1520            _error = "Unable to set bitrate";
     1521            LOG(VB_GENERAL, LOG_ERR, LOC + _error);
    15201522            return;
    15211523        }
    15221524
    void NuppelVideoRecorder::DoV4L2(void)  
    15311533
    15321534    if (ioctl(fd, VIDIOC_REQBUFS, &vrbuf) < 0)
    15331535    {
    1534         LOG(VB_GENERAL, LOG_ERR, LOC +
    1535             "Not able to get any capture buffers, exiting");
    1536         errored = true;
     1536        _error = "Not able to get any capture buffers, exiting";
     1537        LOG(VB_GENERAL, LOG_ERR, LOC + _error);
    15371538        return;
    15381539    }
    15391540
    void NuppelVideoRecorder::DoV4L2(void)  
    15581559        {
    15591560            LOG(VB_GENERAL, LOG_ERR, LOC +
    15601561                QString("unable to query capture buffer %1").arg(i));
    1561             errored = true;
     1562            _error = "Unable to query capture buffer";
    15621563            return;
    15631564        }
    15641565
    void NuppelVideoRecorder::DoV4L2(void)  
    15691570        if (buffers[i] == MAP_FAILED)
    15701571        {
    15711572            LOG(VB_GENERAL, LOG_ERR, LOC + "mmap: " + ENO);
    1572             LOG(VB_GENERAL, LOG_ERR, LOC + QString("Memory map failed"));
    1573             errored = true;
     1573            LOG(VB_GENERAL, LOG_ERR, LOC + "Memory map failed");
     1574            _error = "Memory map failed";
    15741575            return;
    15751576        }
    15761577        bufferlen[i] = vbuf.length;
    void NuppelVideoRecorder::DoV4L2(void)  
    15921593    int frame = 0;
    15931594    bool forcekey = false;
    15941595
    1595     encoding = true;
    1596     recording = true;
    15971596    resetcapture = false;
    15981597
    15991598    // setup pixel format conversions for YUYV and UYVY
    void NuppelVideoRecorder::DoV4L2(void)  
    16101609        output_buffer = (uint8_t*)av_malloc(height * width * 3 / 2);
    16111610        if (!output_buffer)
    16121611        {
    1613             LOG(VB_GENERAL, LOG_ERR, LOC +
    1614                 "Cannot initialize image conversionbuffer");
    1615             errored = true;
     1612            _error = "Cannot initialize image conversion buffer";
     1613            LOG(VB_GENERAL, LOG_ERR, LOC + _error);
    16161614            return;
    16171615        }
    16181616
    void NuppelVideoRecorder::DoV4L2(void)  
    16211619                                           SWS_FAST_BILINEAR, NULL, NULL, NULL);
    16221620        if (!convert_ctx)
    16231621        {
    1624             LOG(VB_GENERAL, LOG_ERR, LOC +
    1625                 "Cannot initialize image conversion context");
    1626             errored = true;
     1622            _error = "Cannot initialize image conversion context";
     1623            LOG(VB_GENERAL, LOG_ERR, LOC + _error);
    16271624            return;
    16281625        }
    16291626
    16301627        avpicture_fill(&img_out, output_buffer, PIX_FMT_YUV420P, width, height);
    16311628    }
    16321629
    1633     while (encoding) {
     1630    while (IsRecordingRequested() && !IsErrored())
     1631    {
    16341632again:
    16351633        {
    16361634            QMutexLocker locker(&pauseLock);
    again:  
    17651763    av_free(output_buffer);
    17661764    sws_freeContext(convert_ctx);
    17671765
    1768     recording = false;
    17691766    close(fd);
    17701767    close(channelfd);
    17711768}
    void NuppelVideoRecorder::DoMJPEG(void)  
    18671864            LOG(VB_GENERAL, LOG_ERR, LOC + "MJPIOC_QBUF_CAPT: " + ENO);
    18681865    }
    18691866
    1870     encoding = true;
    1871     recording = true;
    1872 
    1873     while (encoding)
     1867    while (IsRecordingRequested() && !IsErrored())
    18741868    {
    18751869        {
    18761870            QMutexLocker locker(&pauseLock);
    void NuppelVideoRecorder::DoMJPEG(void)  
    18971891        }
    18981892
    18991893        if (ioctl(fd, MJPIOC_SYNC, &bsync) < 0)
    1900             encoding = false;
     1894        {
     1895            _error = "MJPEG sync error";
     1896            LOG(VB_GENERAL, LOG_ERR, LOC + _error + ENO);
     1897            break;
     1898        }
    19011899
    19021900        BufferIt((unsigned char *)(MJPG_buff + bsync.frame * breq.size),
    19031901                 bsync.length);
    19041902
    19051903        if (ioctl(fd, MJPIOC_QBUF_CAPT, &(bsync.frame)) < 0)
    1906             encoding = false;
     1904        {
     1905            _error = "MJPEG Capture error";
     1906            LOG(VB_GENERAL, LOG_ERR, LOC + _error + ENO);
     1907        }
    19071908    }
    19081909
    19091910    munmap(MJPG_buff, breq.count * breq.size);
    void NuppelVideoRecorder::DoMJPEG(void)  
    19111912
    19121913    FinishRecording();
    19131914
    1914     recording = false;
    19151915    close(fd);
    19161916}
    19171917#else // if !USING_V4L1
    19181918void NuppelVideoRecorder::DoMJPEG(void) {}
    19191919#endif // !USING_V4L1
    19201920
    1921 bool NuppelVideoRecorder::SpawnChildren(void)
    1922 {
    1923     childrenLive = true;
    1924 
    1925     write_thread = new NVRWriteThread(this);
    1926     write_thread->start();
    1927 
    1928     audio_thread = new NVRAudioThread(this);
    1929     audio_thread->start();
    1930 
    1931     if ((vbimode != VBIMode::None) && (OpenVBIDevice() >= 0))
    1932         vbi_thread = new VBIThread(this);
    1933 
    1934     return true;
    1935 }
    1936 
    19371921void NuppelVideoRecorder::KillChildren(void)
    19381922{
    1939     childrenLive = false;
    19401923    {
    19411924        QMutexLocker locker(&pauseLock);
     1925        request_helper = false;
    19421926        unpauseWait.wakeAll();
    19431927    }
    19441928
    void NuppelVideoRecorder::doAudioThread(void)  
    24092393    int act = 0, lastread = 0;
    24102394    audio_bytes_per_sample = audio_channels * audio_bits / 8;
    24112395
    2412     while (childrenLive)
     2396    while (IsHelperRequested() && !IsErrored())
    24132397    {
    24142398        {
    24152399            QMutexLocker locker(&pauseLock);
    void NuppelVideoRecorder::doAudioThread(void)  
    24332417            }
    24342418        }
    24352419
     2420        if (!IsHelperRequested() || IsErrored())
     2421            break;
     2422
    24362423        lastread = audio_device->GetSamples(buffer, audio_buffer_size);
    24372424        if (audio_buffer_size != lastread)
    24382425        {
    void NuppelVideoRecorder::AddTextData(unsigned char *buf, int len,  
    26962683
    26972684void NuppelVideoRecorder::doWriteThread(void)
    26982685{
    2699     while (childrenLive && !IsErrored())
     2686    while (IsHelperRequested() && !IsErrored())
    27002687    {
    27012688        {
    27022689            QMutexLocker locker(&pauseLock);
    void NuppelVideoRecorder::doWriteThread(void)  
    27202707            }
    27212708        }
    27222709
     2710        if (!IsHelperRequested() || IsErrored())
     2711            break;
     2712
    27232713        CheckForRingBufferSwitch();
    27242714
    27252715        enum
    void NuppelVideoRecorder::WriteAudio(unsigned char *buf, int fnum, int timecode)  
    31823172        {
    31833173            LOG(VB_GENERAL, LOG_ERR, LOC +
    31843174                QString("lame error '%1'").arg(lameret));
    3185             errored = true;
     3175            _error = QString("Audio Encoding Error '%1'")
     3176                .arg(lameret);
    31863177            return;
    31873178        }
    31883179        compressedsize = lameret;
    void NuppelVideoRecorder::WriteAudio(unsigned char *buf, int fnum, int timecode)  
    31933184        {
    31943185            LOG(VB_GENERAL, LOG_ERR, LOC +
    31953186                QString("lame error '%1'").arg(lameret));
    3196             errored = true;
     3187            _error = QString("Audio Encoding Error '%1'")
     3188                .arg(lameret);
    31973189            return;
    31983190        }
    31993191        gaplesssize = lameret;
  • mythtv/libs/libmythtv/NuppelVideoRecorder.h

    diff --git a/mythtv/libs/libmythtv/NuppelVideoRecorder.h b/mythtv/libs/libmythtv/NuppelVideoRecorder.h
    index 860571d..67b7d67 100644
    a b class MTV_PUBLIC NuppelVideoRecorder : public V4LRecorder, public CC608Input  
    8686 
    8787    void Initialize(void);
    8888    void run(void);
    89     void StopRecording(void);
    9089   
    9190    virtual void Pause(bool clear = true);
    9291    virtual bool IsPaused(bool holding_lock = false) const;
    9392 
    9493    bool IsRecording(void);
    95     bool IsErrored(void);
    9694
    9795    long long GetFramesWritten(void);
    9896
    class MTV_PUBLIC NuppelVideoRecorder : public V4LRecorder, public CC608Input  
    142140
    143141    bool MJPEGInit(void);
    144142 
    145     bool SpawnChildren(void);
    146143    void KillChildren(void);
    147144   
    148145    void BufferIt(unsigned char *buf, int len = -1, bool forcekey = false);
    class MTV_PUBLIC NuppelVideoRecorder : public V4LRecorder, public CC608Input  
    161158
    162159    void UpdateResolutions(void);
    163160   
    164     bool encoding;
    165    
    166161    int fd; // v4l input file handle
    167162    signed char *strm;
    168163    unsigned int lf, tf;
    class MTV_PUBLIC NuppelVideoRecorder : public V4LRecorder, public CC608Input  
    224219    struct timeval stm;
    225220    struct timezone tzone;
    226221
    227     volatile bool childrenLive;
    228 
    229222    NVRWriteThread *write_thread;
    230223    NVRAudioThread *audio_thread;
    231224
    232225    bool recording;
    233     bool errored;
    234226
    235227    int keyframedist;
    236228    vector<struct seektable_entry> *seektable;
  • mythtv/libs/libmythtv/mpegrecorder.cpp

    diff --git a/mythtv/libs/libmythtv/mpegrecorder.cpp b/mythtv/libs/libmythtv/mpegrecorder.cpp
    index 36e33c7..ced08fb 100644
    a b void MpegRecorder::run(void)  
    933933    {
    934934        QMutexLocker locker(&pauseLock);
    935935        request_recording = true;
     936        request_helper = true;
    936937        recording = true;
    937938        recordingWait.wakeAll();
    938939    }
    void MpegRecorder::run(void)  
    11451146
    11461147    StopEncoding(readfd);
    11471148
     1149    {
     1150        QMutexLocker locker(&pauseLock);
     1151        request_helper = false;
     1152    }
     1153
     1154    if (vbi_thread)
     1155    {
     1156        vbi_thread->wait();
     1157        delete vbi_thread;
     1158        vbi_thread = NULL;
     1159        CloseVBIDevice();
     1160    }
     1161
    11481162    FinishRecording();
    11491163
    11501164    delete[] buffer;
    void MpegRecorder::run(void)  
    11571171    }
    11581172
    11591173    QMutexLocker locker(&pauseLock);
     1174    request_recording = false;
    11601175    recording = false;
    11611176    recordingWait.wakeAll();
    11621177}
  • mythtv/libs/libmythtv/v4lrecorder.cpp

    diff --git a/mythtv/libs/libmythtv/v4lrecorder.cpp b/mythtv/libs/libmythtv/v4lrecorder.cpp
    index 40042b1..7a665da 100644
    a b V4LRecorder::V4LRecorder(TVRec *tv) :  
    3333    ntsc_vbi_width(0),        ntsc_vbi_start_line(0),
    3434    ntsc_vbi_line_count(0),
    3535    vbi608(NULL),
    36     vbi_thread(NULL),         vbi_fd(-1)
     36    vbi_thread(NULL),         vbi_fd(-1),
     37    request_helper(false)
    3738{
    3839}
    3940
    4041V4LRecorder::~V4LRecorder()
    4142{
     43    {
     44        QMutexLocker locker(&pauseLock);
     45        request_helper = false;
     46        unpauseWait.wakeAll();
     47    }
     48
    4249    if (vbi_thread)
    4350    {
     51        vbi_thread->wait();
    4452        delete vbi_thread;
    4553        vbi_thread = NULL;
     54        CloseVBIDevice();
    4655    }
    4756}
    4857
    void V4LRecorder::StopRecording(void)  
    5362        vbi_thread->wait();
    5463}
    5564
     65bool V4LRecorder::IsHelperRequested(void) const
     66{
     67    QMutexLocker locker(&pauseLock);
     68    return request_helper && request_recording;
     69}
     70
    5671void V4LRecorder::SetOption(const QString &name, const QString &value)
    5772{
    5873    if (name == "audiodevice")
    void V4LRecorder::RunVBIDevice(void)  
    252267        ptr_end   = buf + sz;
    253268    }
    254269
    255     while (IsRecordingRequested() && !IsErrored())
     270    while (IsHelperRequested() && !IsErrored())
    256271    {
    257272        if (PauseAndWait())
    258273            continue;
    259274
    260         if (!IsRecordingRequested())
     275        if (!IsHelperRequested() || IsErrored())
    261276            break;
    262277
    263278        struct timeval tv;
  • mythtv/libs/libmythtv/v4lrecorder.h

    diff --git a/mythtv/libs/libmythtv/v4lrecorder.h b/mythtv/libs/libmythtv/v4lrecorder.h
    index 64de6fe..7835d3b 100644
    a b class MTV_PUBLIC V4LRecorder : public DTVRecorder  
    3838    void CloseVBIDevice(void);
    3939    void RunVBIDevice(void);
    4040
     41    virtual bool IsHelperRequested(void) const;
    4142    virtual void FormatTT(struct VBIData *vbidata) {}
    4243    virtual void FormatCC(uint code1, uint code2) {}
    4344
    class MTV_PUBLIC V4LRecorder : public DTVRecorder  
    5455    VBIThread       *vbi_thread;
    5556    QList<struct txtbuffertype*> textbuffer;
    5657    int              vbi_fd;
     58    volatile bool    request_helper;
    5759};
    5860
    5961class VBIThread : public MThread