Ticket #5866: mpegrecorder-hdpvr-v1.1.patch

File mpegrecorder-hdpvr-v1.1.patch, 18.1 KB (added by jppoet@…, 15 years ago)

Update for trunk r19054. Replaces mpegrecorder-hdpvr.patch *and* hdpvr-fix-channel-changes.patch

  • libs/libmythtv/mpegrecorder.h

     
    8080    uint GetFilteredAudioLayer(void) const;
    8181    uint GetFilteredAudioBitRate(uint audio_layer) const;
    8282
     83    void RestartEncoding(void);
    8384    bool StartEncoding(int fd);
    8485    bool StopEncoding(int fd);
    8586
    8687    void ResetForNewFile(void);
    8788
     89    bool WaitFor_HDPVR(void);
    8890    void HandleResolutionChanges(void);
    8991
    9092    inline bool CheckCC(uint pid, uint cc);
     
    104106    // State
    105107    bool recording;
    106108    bool encoding;
    107     bool needs_resolution;
    108109    mutable QMutex start_stop_encoding_lock;
    109110    QMutex recording_wait_lock;
    110111    QWaitCondition recording_wait;
     
    113114    bool cleartimeonpause;
    114115
    115116    // Encoding info
    116     int width, height;
     117    uint width, height;
    117118    int bitrate, maxbitrate, streamtype, aspectratio;
    118119    int audtype, audsamplerate, audbitratel1, audbitratel2, audbitratel3;
    119120    int audvolume;
  • libs/libmythtv/mpegrecorder.cpp

     
    1919#include <sys/stat.h>
    2020#include <sys/ioctl.h>
    2121#include <sys/time.h>
     22#include <sys/poll.h>
    2223
    2324// avlib headers
    2425extern "C" {
     
    8687    requires_special_pause(false),
    8788    // State
    8889    recording(false),         encoding(false),
    89     needs_resolution(false),  start_stop_encoding_lock(QMutex::Recursive),
     90    start_stop_encoding_lock(QMutex::Recursive),
    9091    recording_wait_lock(),    recording_wait(),
    9192    // Pausing state
    9293    cleartimeonpause(false),
     
    487488
    488489bool MpegRecorder::SetFormat(int chanfd)
    489490{
     491    uint   idx;
    490492    struct v4l2_format vfmt;
    491493    bzero(&vfmt, sizeof(vfmt));
    492494
    493495    vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    494496
    495     if (ioctl(chanfd, VIDIOC_G_FMT, &vfmt) < 0)
     497    for (idx = 0; idx < 20; ++idx)
    496498    {
     499        if (ioctl(chanfd, VIDIOC_G_FMT, &vfmt) == 0)
     500            break;
     501        usleep(100 * 1000);
     502    }
     503
     504    if (idx == 10)
     505    {
    497506        VERBOSE(VB_IMPORTANT, LOC_ERR + "Error getting format" + ENO);
    498507        return false;
    499508    }
     
    501510    vfmt.fmt.pix.width = width;
    502511    vfmt.fmt.pix.height = height;
    503512
    504     if (ioctl(chanfd, VIDIOC_S_FMT, &vfmt) < 0)
     513    for (idx = 0; idx < 20; ++idx)
    505514    {
     515        if (ioctl(chanfd, VIDIOC_S_FMT, &vfmt) == 0)
     516            break;
     517        usleep(100 * 1000);
     518    }
     519
     520    if (idx == 20)
     521    {
    506522        VERBOSE(VB_IMPORTANT, LOC_ERR + "Error setting format" + ENO);
    507523        return false;
    508524    }
     
    513529/// Set audio language mode
    514530bool MpegRecorder::SetLanguageMode(int chanfd)
    515531{
     532    uint   idx;
    516533    struct v4l2_tuner vt;
    517534    bzero(&vt, sizeof(struct v4l2_tuner));
    518     if (ioctl(chanfd, VIDIOC_G_TUNER, &vt) < 0)
     535
     536    for (idx = 0; idx < 20; ++idx)
    519537    {
     538        if (ioctl(chanfd, VIDIOC_G_TUNER, &vt) == 0)
     539            break;
     540        usleep(100 * 1000);
     541    }
     542
     543    if (idx == 20)
     544    {
    520545        VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to get audio mode" + ENO);
    521546        return false;
    522547    }
     
    549574        success = false;
    550575    }
    551576
    552     if (ioctl(chanfd, VIDIOC_S_TUNER, &vt) < 0)
     577    for (idx = 0; idx < 20; ++idx)
    553578    {
     579        if (ioctl(chanfd, VIDIOC_S_TUNER, &vt) == 0)
     580            break;
     581        usleep(100 * 1000);
     582    }
     583
     584    if (idx == 20)
     585    {
    554586        VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to set audio mode" + ENO);
    555587        success = false;
    556588    }
     
    561593bool MpegRecorder::SetRecordingVolume(int chanfd)
    562594{
    563595    // Get volume min/max values
     596    uint   idx;
    564597    struct v4l2_queryctrl qctrl;
    565598    qctrl.id = V4L2_CID_AUDIO_VOLUME;
    566     if (ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) < 0)
     599
     600    for (idx = 0; idx < 20; ++idx)
    567601    {
     602        if (ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) == 0)
     603            break;
     604        usleep(100 * 1000);
     605    }
     606
     607    if (idx == 20)
     608    {
    568609        VERBOSE(VB_IMPORTANT, LOC_WARN +
    569610                "Unable to get recording volume parameters(max/min)" + ENO +
    570611                "\n\t\t\tusing default range [0,65535].");
     
    582623    ctrl.id = V4L2_CID_AUDIO_VOLUME;
    583624    ctrl.value = ctrl_volume;
    584625
    585     if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) < 0)
     626    for (idx = 0; idx < 20; ++idx)
    586627    {
     628        if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) == 0)
     629            break;
     630        usleep(100 * 1000);
     631    }
     632
     633    if (idx == 20)
     634    {
    587635        VERBOSE(VB_IMPORTANT, LOC_WARN +
    588636                "Unable to set recording volume" + ENO + "\n\t\t\t" +
    589637                "If you are using an AverMedia M179 card this is normal.");
     
    765813
    766814    for (uint i = 0; i < ext_ctrls.size(); i++)
    767815    {
     816        uint   idx;
    768817        struct v4l2_ext_controls ctrls;
    769818        bzero(&ctrls, sizeof(struct v4l2_ext_controls));
    770819
     
    774823        ctrls.count       = 1;
    775824        ctrls.controls    = &ext_ctrls[i];
    776825           
    777         if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
     826        for (idx = 0; idx < 20; ++idx)
    778827        {
     828            if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls) == 0)
     829                break;
     830            usleep(100 * 1000);
     831        }
     832
     833        if (idx == 20)
     834        {
    779835            QMutexLocker locker(&control_description_lock);
    780836            VERBOSE(VB_IMPORTANT, QString("mpegrecorder.cpp:set_ctrls(): ") +
    781837                    QString("Could not set %1 to %2")
     
    814870    {
    815871        maxbitrate = high_mpeg4peakbitrate;
    816872        bitrate    = high_mpeg4avgbitrate;
     873
     874        // query supported audio codecs and prefer AC3
     875        uint   idx;
     876        struct v4l2_queryctrl qctrl;
     877        qctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING;
     878
     879        for (idx = 0; idx < 20; ++idx)
     880        {
     881            if (ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) == 0)
     882                break;
     883            usleep(100 * 1000);
     884        }
     885
     886        if (idx == 20)
     887        {
     888            VERBOSE(VB_IMPORTANT, LOC_WARN +
     889                    "Unable to get supported audio codecs." + ENO);
     890        }
     891        else
     892        {
     893            if (qctrl.minimum != qctrl.maximum)
     894                add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_AUDIO_ENCODING,
     895                             qctrl.maximum);
     896        }
    817897    }
    818898    maxbitrate = std::max(maxbitrate, bitrate);
    819899
     
    837917    int audioinput = audiodevice.toUInt(&ok);
    838918    if (ok)
    839919    {
     920        uint   idx;
    840921        struct v4l2_audio ain;
    841922        bzero(&ain, sizeof(ain));
    842923        ain.index = audioinput;
    843         if (ioctl(chanfd, VIDIOC_ENUMAUDIO, &ain) < 0)
     924
     925        for (idx = 0; idx < 20; ++idx)
    844926        {
     927            if (ioctl(chanfd, VIDIOC_ENUMAUDIO, &ain) == 0)
     928                break;
     929            usleep(100 * 1000);
     930        }
     931
     932        if (idx == 20)
     933        {
    845934            VERBOSE(VB_IMPORTANT, LOC_WARN +
    846935                    "Unable to get audio input.");
    847936        }
    848937        else
    849938        {
    850939            ain.index = audioinput;
    851             if (ioctl(chanfd, VIDIOC_S_AUDIO, &ain) < 0)
     940
     941            for (idx = 0; idx < 20; ++idx)
    852942            {
     943                if (ioctl(chanfd, VIDIOC_S_AUDIO, &ain) == 0)
     944                    break;
     945                usleep(100 * 1000);
     946            }
     947
     948            if (idx == 20)
     949            {
    853950                VERBOSE(VB_IMPORTANT, LOC_WARN +
    854951                        "Unable to set audio input.");
    855952            }
     
    10361133    if (deviceIsMpegFile)
    10371134        elapsedTimer.start();
    10381135    else if (_device_read_buffer)
    1039         _device_read_buffer->Start();
     1136    {
     1137        VERBOSE(VB_RECORD, LOC + "Initial startup of recorder");
    10401138
    1041     needs_resolution = (driver == "hdpvr");
     1139        if (StartEncoding(readfd))
     1140            _device_read_buffer->Start();
     1141        else
     1142        {
     1143            VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to start recording");
     1144            recording = false;
     1145            QMutexLocker locker(&recording_wait_lock);
     1146            recording_wait.wakeAll();
     1147            _error = true;
     1148        }
     1149    }
    10421150
    10431151    QByteArray vdevice = videodevice.toAscii();
    10441152    while (encoding && !_error)
    10451153    {
    10461154        if (PauseAndWait(100))
    10471155            continue;
    1048 
    1049         HandleResolutionChanges();
    10501156       
    10511157        if (deviceIsMpegFile)
    10521158        {
     
    10901196            {
    10911197                VERBOSE(VB_IMPORTANT, LOC_ERR + "Device error detected");
    10921198
    1093                 _device_read_buffer->Stop();
    1094 
    1095                 QMutexLocker locker(&start_stop_encoding_lock);
    1096 
    1097                 StopEncoding(readfd);
    1098 
    1099                 // Make sure the next things in the file are a PAT & PMT
    1100                 if (_stream_data->PATSingleProgram() &&
    1101                     _stream_data->PMTSingleProgram())
    1102                 {
    1103                     bool tmp = _wait_for_keyframe_option;
    1104                     _wait_for_keyframe_option = false;
    1105                     HandleSingleProgramPAT(_stream_data->PATSingleProgram());
    1106                     HandleSingleProgramPMT(_stream_data->PMTSingleProgram());
    1107                     _wait_for_keyframe_option = tmp;
    1108                 }
    1109 
    1110                 if (StartEncoding(readfd))
    1111                 {
    1112                     _device_read_buffer->Start();
    1113                 }
    1114                 else
    1115                 {
    1116                     if (0 != close(readfd))
    1117                         VERBOSE(VB_IMPORTANT, LOC_ERR + "Close error" + ENO);
    1118                    
    1119                     // Force card to be reopened on next iteration..
    1120                     readfd = -1;
    1121                 }
     1199                RestartEncoding();
    11221200            }
    11231201            else if (_device_read_buffer->IsEOF())
    11241202            {
     
    12161294        }
    12171295    }
    12181296
     1297    VERBOSE(VB_RECORD, LOC + "StartRecording finishing up");
     1298
    12191299    if (_device_read_buffer)
    12201300    {
    12211301        if (_device_read_buffer->IsRunning())
     
    12241304        delete _device_read_buffer;
    12251305        _device_read_buffer = NULL;
    12261306    }
     1307
    12271308    StopEncoding(readfd);
    12281309
    12291310    FinishRecording();
     
    13731454
    13741455        if (!paused)
    13751456        {
     1457            VERBOSE(VB_RECORD, LOC + "PauseAndWait pause");
     1458
     1459            // Some drivers require streaming to be disabled before
     1460            // an input switch and other channel format setting.
     1461            if (requires_special_pause)
     1462                StopEncoding(readfd);
     1463
    13761464            if (_device_read_buffer)
    13771465            {
    13781466                QMutex drb_lock;
    13791467                drb_lock.lock();
    1380 
    13811468                _device_read_buffer->SetRequestPause(true);
    1382 
    13831469                pauseWait.wait(&drb_lock, timeout);
    13841470            }
    13851471            else
    1386             {
    1387                 paused = true;
    13881472                pauseWait.wakeAll();
    1389             }
    13901473
    1391             // Some drivers require streaming to be disabled before
    1392             // an input switch and other channel format setting.
    1393             if (requires_special_pause)
    1394                 StopEncoding(readfd);
    1395 
     1474            paused = true;
    13961475            if (tvrec)
    13971476                tvrec->RecorderPaused();
    13981477        }
    13991478
    14001479        unpauseWait.wait(&waitlock, timeout);
    14011480    }
    1402     if (!request_pause)
     1481
     1482    if (!request_pause && paused)
    14031483    {
    1404         if (paused)
     1484        VERBOSE(VB_RECORD, LOC + "PauseAndWait unpause");
     1485
     1486        if (driver == "hdpvr")
    14051487        {
    1406             // Some drivers require streaming to be disabled before
    1407             // an input switch and other channel format setting.
    1408             if (requires_special_pause)
    1409                 StartEncoding(readfd);
     1488            m_h264_parser.Reset();
     1489            _wait_for_keyframe_option = true;
     1490            _seen_sps = false;
    14101491
    1411             if (_device_read_buffer)
    1412                 _device_read_buffer->SetRequestPause(false);
     1492            // Sleep any less than 1.5 seconds, and the HD-PVR will
     1493            // return the old resolution, when the resolution is changing.
     1494            usleep(1500 * 1000);
     1495        }
    14131496
    1414             if (_stream_data)
    1415                 _stream_data->Reset(_stream_data->DesiredProgram());
    1416         }
     1497        // Some drivers require streaming to be disabled before
     1498        // an input switch and other channel format setting.
     1499        if (requires_special_pause)
     1500            StartEncoding(readfd);
     1501       
     1502        if (_device_read_buffer)
     1503            _device_read_buffer->SetRequestPause(false);
     1504       
     1505        if (_stream_data)
     1506            _stream_data->Reset(_stream_data->DesiredProgram());
     1507
    14171508        paused = false;
    14181509    }
     1510
    14191511    return paused;
    14201512}
    14211513
     1514void MpegRecorder::RestartEncoding(void)
     1515{
     1516    VERBOSE(VB_RECORD, LOC + "RestartEncoding");
     1517
     1518    _device_read_buffer->Stop();
     1519   
     1520    QMutexLocker locker(&start_stop_encoding_lock);
     1521   
     1522    StopEncoding(readfd);
     1523   
     1524    // Make sure the next things in the file are a PAT & PMT
     1525    if (_stream_data->PATSingleProgram() &&
     1526        _stream_data->PMTSingleProgram())
     1527    {
     1528        _wait_for_keyframe_option = false;
     1529        HandleSingleProgramPAT(_stream_data->PATSingleProgram());
     1530        HandleSingleProgramPMT(_stream_data->PMTSingleProgram());
     1531    }
     1532   
     1533    if (StartEncoding(readfd))
     1534    {
     1535        _device_read_buffer->Start();
     1536    }
     1537    else
     1538    {
     1539        if (0 != close(readfd))
     1540            VERBOSE(VB_IMPORTANT, LOC_ERR + "Close error" + ENO);
     1541       
     1542        readfd = -1;
     1543    }
     1544}
     1545
    14221546bool MpegRecorder::StartEncoding(int fd)
    14231547{
    14241548    QMutexLocker locker(&start_stop_encoding_lock);
     
    14271551    memset(&command, 0, sizeof(struct v4l2_encoder_cmd));
    14281552    command.cmd = V4L2_ENC_CMD_START;
    14291553
     1554    if (driver == "hdpvr")
     1555        HandleResolutionChanges();
     1556
    14301557    VERBOSE(VB_RECORD, LOC + "StartEncoding");
    1431     needs_resolution = (driver == "hdpvr");
    14321558
    1433     for (int idx = 0; idx < 10; ++idx)
     1559    for (int idx = 0; idx < 20; ++idx)
    14341560    {
    14351561        if (ioctl(fd, VIDIOC_ENCODER_CMD, &command) == 0)
    14361562        {
     1563            if (driver == "hdpvr")
     1564            {
     1565                m_h264_parser.Reset();
     1566                _wait_for_keyframe_option = true;
     1567                _seen_sps = false;
     1568            }
     1569
    14371570            VERBOSE(VB_RECORD, LOC + "Encoding started");
    14381571            return true;
    14391572        }
     
    14441577            return false;
    14451578        }
    14461579
    1447         usleep(250 * 1000);
     1580        usleep(100 * 1000);
    14481581    }
    14491582
    14501583    VERBOSE(VB_IMPORTANT, LOC_ERR + "StartEncoding - giving up" + ENO);
     
    14611594
    14621595    VERBOSE(VB_RECORD, LOC + "StopEncoding");
    14631596
    1464     for (int idx = 0; idx < 10; ++idx)
     1597    for (int idx = 0; idx < 20; ++idx)
    14651598    {
    1466 
    14671599        if (ioctl(fd, VIDIOC_ENCODER_CMD, &command) == 0)
    14681600        {
    14691601            VERBOSE(VB_RECORD, LOC + "Encoding stopped");
     
    14761608            return false;
    14771609        }
    14781610
    1479         usleep(250 * 1000);
     1611        usleep(100 * 1000);
    14801612    }
    14811613
    14821614    VERBOSE(VB_IMPORTANT, LOC_ERR + "StopEncoding - giving up" + ENO);
     
    15441676void MpegRecorder::HandleSingleProgramPMT(ProgramMapTable *pmt)
    15451677{
    15461678    if (!pmt)
    1547 {
     1679    {
    15481680        return;
    15491681    }
    15501682
     
    15641696        DTVRecorder::BufferedWrite(*(reinterpret_cast<TSPacket*>(&buf[i])));
    15651697}
    15661698
     1699bool MpegRecorder::WaitFor_HDPVR(void)
     1700{
     1701    // After a resolution change, it can take the HD-PVR a few
     1702    // seconds before it is usable again.
     1703
     1704    // Tell it to start encoding, then wait for it to actually feed us
     1705    // some data.
     1706    QMutexLocker locker(&start_stop_encoding_lock);
     1707
     1708    struct v4l2_encoder_cmd command;
     1709    struct pollfd polls;
     1710    int    idx;
     1711
     1712    memset(&command, 0, sizeof(struct v4l2_encoder_cmd));
     1713    command.cmd = V4L2_ENC_CMD_START;
     1714
     1715    for (idx = 0; idx < 20; ++idx)
     1716    {
     1717        if (ioctl(readfd, VIDIOC_ENCODER_CMD, &command) == 0)
     1718            break;
     1719        usleep(100 * 1000);
     1720    }
     1721
     1722    if (idx == 20)
     1723        return false;
     1724
     1725    polls.fd      = readfd;
     1726    polls.events  = POLLIN;
     1727    polls.revents = 0;
     1728
     1729    for (idx = 0; idx < 10; ++idx)
     1730    {
     1731        if (poll(&polls, 1, 250) > 0)
     1732            break;
     1733    }
     1734
     1735    if (idx == 10)
     1736        return false;
     1737
     1738    // HD-PVR should now be "ready"
     1739    command.cmd = V4L2_ENC_CMD_STOP;
     1740
     1741    for (idx = 0; idx < 20; ++idx)
     1742    {
     1743        if (ioctl(readfd, VIDIOC_ENCODER_CMD, &command) == 0)
     1744            return true;
     1745        usleep(100 * 1000);
     1746    }
     1747
     1748    return false;
     1749}
     1750
    15671751void MpegRecorder::HandleResolutionChanges(void)
    15681752{
    1569     if (!needs_resolution)
    1570         return;
    1571 
    15721753    VERBOSE(VB_RECORD, LOC + "Checking Resolution");
    15731754    struct v4l2_format vfmt;
    15741755    memset(&vfmt, 0, sizeof(vfmt));
    15751756    vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    15761757           
     1758    if (driver == "hdpvr")
     1759        WaitFor_HDPVR();
     1760
     1761    uint idx;
    15771762    uint pix = 0;
     1763
     1764    for (idx = 0; idx < 20; ++idx)
     1765    {
    15781766    if (0 == ioctl(chanfd, VIDIOC_G_FMT, &vfmt))
    15791767    {
    15801768        VERBOSE(VB_RECORD, LOC + QString("Got Resolution %1x%2")
    15811769                .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height));
    15821770        pix = vfmt.fmt.pix.width * vfmt.fmt.pix.height;
    1583         needs_resolution = false;
     1771            break;
     1772        }
     1773        // Typically takes 0.9 seconds after a resolution change
     1774        usleep(100 * 1000);
    15841775    }
    15851776
    15861777    if (!pix)
     1778    {
     1779        VERBOSE(VB_RECORD, LOC + "Giving up detecting resolution");
    15871780        return; // nothing to do, we don't have a resolution yet
     1781    }
    15881782
    15891783    int old_max = maxbitrate, old_avg = bitrate;
    15901784    if (pix <= 768*568)
     
    16091803        if (old_max == old_avg)
    16101804        {
    16111805            VERBOSE(VB_RECORD, LOC +
    1612                     QString("Old bitrate %1 CBR").arg(old_avg));
     1806                    QString("Old bitrate %1 CBR for %2x%3")
     1807                    .arg(old_avg).arg(width).arg(height));
    16131808        }
    16141809        else
    16151810        {
    16161811            VERBOSE(VB_RECORD, LOC +
    1617                     QString("Old bitrate %1/%2 VBR")
    1618                     .arg(old_avg).arg(old_max));
     1812                    QString("Old bitrate %1/%2 VBR for %3x%4")
     1813                    .arg(old_avg).arg(old_max).arg(width).arg(height));
    16191814        }
    16201815
    16211816        if (maxbitrate == bitrate)
     
    16421837                     maxbitrate * 1000);
    16431838
    16441839        set_ctrls(readfd, ext_ctrls);
     1840
    16451841    }
    1646 
    1647     // Restart streaming. Shouldn't be needed? seems to be with current driver.
    1648     QMutexLocker locker(&start_stop_encoding_lock);
    1649     StopEncoding(readfd);
    1650     StartEncoding(readfd);
    1651 
    1652     needs_resolution = false;
    16531842}