Ticket #4466: 4466-hack-v1.patch

File 4466-hack-v1.patch, 5.4 KB (added by danielk, 16 years ago)

Possible workaround. This still needs to be tested with 2.6.24, but Hans suggested this might work instead of the more crazy close/open hack employed in other applications.

  • libs/libmythtv/channel.cpp

     
    746746    return fmt;
    747747}
    748748
     749static bool convertx_hack(
     750    const QString &loc_err_msg,
     751    int videofd, int inputNumV4L, int &ioctlval, bool &undo_convertx_hack)
     752{
     753    bool ok = true;
     754    undo_convertx_hack = false;
     755
     756    // ConvertX (wis-go7007) requires streaming to be disabled
     757    // before an input switch, do this if initial switch failed.
     758    int  streamType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
     759
     760    ioctlval = ioctl(videofd, VIDIOC_STREAMOFF, &streamType);
     761    if (ioctlval < 0)
     762    {
     763        VERBOSE(VB_IMPORTANT, loc_err_msg +
     764                "\n\t\t\twhile disabling streaming (v4l v2)" + ENO);
     765
     766        ok = false;
     767        ioctlval = 0;
     768    }
     769    else
     770    {
     771        undo_convertx_hack = true;
     772
     773        // Resend the input switch ioctl.
     774        ioctlval = ioctl(videofd, VIDIOC_S_INPUT, &inputNumV4L);
     775    }
     776
     777    return ok;
     778}
     779
     780static bool convertx_unhack(const QString &loc_err_msg, int videofd)
     781{
     782    bool ok = true;
     783
     784    // ConvertX (wis-go7007) requires streaming to be disabled
     785    // before an input switch, here we try to re-enable streaming.
     786    int  streamType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
     787
     788    int ioctlval = ioctl(videofd, VIDIOC_STREAMON, &streamType);
     789    if (ioctlval < 0)
     790    {
     791        VERBOSE(VB_IMPORTANT, loc_err_msg +
     792                "\n\t\t\twhile reenabling ivtv streaming (v4l v2)" + ENO);
     793
     794        ok = false;
     795    }
     796
     797    return ok;
     798}
     799
     800static bool ivtv_hack(
     801    const QString &loc_err_msg,
     802    int videofd, int inputNumV4L, int &ioctlval, bool &undo_ivtv_hack)
     803{
     804    bool ok = true;
     805    undo_ivtv_hack = false;
     806
     807    // The ivtv 0.10.6+ drivers require streaming to be disabled
     808    // before an input switch, do this if initial switch failed.
     809    struct v4l2_encoder_cmd command;
     810    memset(&command, 0, sizeof(struct v4l2_encoder_cmd));
     811    command.cmd   = V4L2_ENC_CMD_PAUSE;
     812    command.flags = V4L2_ENC_CMD_STOP_AT_GOP_END;
     813
     814    ioctlval = ioctl(videofd, VIDIOC_ENCODER_CMD, &command);
     815    if (ioctlval < 0)
     816    {
     817        VERBOSE(VB_IMPORTANT, loc_err_msg +
     818                "\n\t\t\twhile disabling ivtv streaming (v4l v2)" + ENO);
     819
     820        ok = false;
     821        ioctlval = 0;
     822    }
     823    else
     824    {
     825        undo_ivtv_hack = true;
     826
     827        // Resend the input switch ioctl.
     828        ioctlval = ioctl(videofd, VIDIOC_S_INPUT, &inputNumV4L);
     829    }
     830
     831    return ok;
     832}
     833
     834static bool ivtv_unhack(const QString &loc_err_msg, int videofd)
     835{
     836    bool ok = true;
     837
     838    // The ivtv 0.10.6+ drivers require streaming to be disabled
     839    // before an input switch, here we try to re-enable streaming.
     840    struct v4l2_encoder_cmd command;
     841    memset(&command, 0, sizeof(struct v4l2_encoder_cmd));
     842    command.cmd = V4L2_ENC_CMD_RESUME;
     843
     844    int ioctlval = ioctl(videofd, VIDIOC_ENCODER_CMD, &command);
     845    if (ioctlval < 0)
     846    {
     847        VERBOSE(VB_IMPORTANT, loc_err_msg +
     848                "\n\t\t\twhile reenabling ivtv streaming (v4l v2)" + ENO);
     849
     850        ok = false;
     851    }
     852
     853    return ok;
     854}
     855
    749856bool Channel::SetInputAndFormat(int inputNum, QString newFmt)
    750857{
    751858    InputMap::const_iterator it = inputs.find(inputNum);
     
    765872
    766873        int ioctlval = ioctl(videofd, VIDIOC_S_INPUT, &inputNumV4L);
    767874
    768         // ConvertX (wis-go7007) requires streaming to be disabled
    769         // before an input switch, do this if initial switch failed.
    770         bool streamingDisabled = false;
    771         int  streamType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    772         if ((ioctlval < 0) && (errno == EBUSY))
     875        bool undo_convertx_hack = false;
     876        bool undo_ivtv_hack = false;
     877        if ((driver_name == "ivtv") && (ioctlval < 0) && (errno == EBUSY))
    773878        {
    774             ioctlval = ioctl(videofd, VIDIOC_STREAMOFF, &streamType);
    775             if (ioctlval < 0)
    776             {
    777                 VERBOSE(VB_IMPORTANT, LOC_ERR + msg +
    778                         "\n\t\t\twhile disabling streaming (v4l v2)" + ENO);
    779 
    780                 ok = false;
    781                 ioctlval = 0;
    782             }
    783             else
    784             {
    785                 streamingDisabled = true;
    786 
    787                 // Resend the input switch ioctl.
    788                 ioctlval = ioctl(videofd, VIDIOC_S_INPUT, &inputNumV4L);
    789             }
     879            ok = ivtv_hack(LOC_ERR + msg, videofd, inputNumV4L,
     880                           ioctlval, undo_ivtv_hack);
    790881        }
     882        else if ((ioctlval < 0) && (errno == EBUSY))
     883        {
     884            ok = convertx_hack(LOC_ERR + msg, videofd, inputNumV4L,
     885                               ioctlval, undo_convertx_hack);
     886        }
    791887
    792888        if (ioctlval < 0)
    793889        {
     
    807903            ok = false;
    808904        }
    809905
    810         // ConvertX (wis-go7007) requires streaming to be disabled
    811         // before an input switch, here we try to re-enable streaming.
    812         if (streamingDisabled)
    813         {
    814             ioctlval = ioctl(videofd, VIDIOC_STREAMON, &streamType);
    815             if (ioctlval < 0)
    816             {
    817                 VERBOSE(VB_IMPORTANT, LOC_ERR + msg +
    818                         "\n\t\t\twhile reenabling streaming (v4l v2)" + ENO);
    819 
    820                 ok = false;
    821             }
    822         }
     906        if (undo_convertx_hack)
     907            ok &= convertx_unhack(LOC_ERR + msg, videofd);
     908        if (undo_ivtv_hack)
     909            ok &= ivtv_unhack(LOC_ERR + msg, videofd);
    823910    }
    824911
    825912    if (usingv4l1)