Opened 8 years ago

Closed 7 years ago

#9191 closed defect (fixed)

Channel switching doesn't work with cx18 driver

Reported by: Artem Astafyev Owned by: danielk
Priority: minor Milestone: 0.25
Component: MythTV - General Version: 0.23.1
Severity: medium Keywords: cx18 SetInputAndFormat
Cc: Ticket locked: no


I can successfully tune any analog channel but when I try to switch to any other channel I get such error:

2010-11-06 20:51:27.840 TVRec(1): Recorder paused, calling TuningFrequency
2010-11-06 20:51:27.858 Channel(/dev/video0)::SwitchToInput(in 1, '')
2010-11-06 20:51:27.876 Channel(/dev/video0): SetInputAndFormat(1, SECAM-D) (v4l v2)
2010-11-06 20:51:27.885 Channel(/dev/video0) Error: SetInputAndFormat(1, SECAM-D) 
                        while setting format (v4l v2)
                        eno: Device or resource busy (16)
2010-11-06 20:51:27.893 Channel(/dev/video0): SetInputAndFormat() failed
2010-11-06 20:51:27.901 TVRec(1) Error: Failed to set channel to 32. Reverting to kState_None

I get this error only with cx18 driver. After investigating libmythtv code and cx18 driver I found the cause. Here is cut from cx18 driver's function that is called from S_STD ioctl:

        if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ||
            atomic_read(&cx->ana_capturing) > 0) {
                /* Switching standard would turn off the radio or mess
                   with already running streams, prevent that by
                   returning EBUSY. */
                return -EBUSY;

cx->ana_capturing is atomic_t which increased every time V4L2_ENC_CMD_START ioctl is called and decreased on V4L2_ENC_CMD_STOP ioctl. In addition it seems that cx18 driver has no STREAMOFF ioctl so workaround which is used for ConvertX doesn't work: I get EINVAL. I'm not so familiar with mythtv coding or v4l2 but I feel that fix should be simple. I can provide any additional info or test fix if you need.

Change History (9)

comment:1 Changed 8 years ago by sphery

What revision are you using? Please attach the output of mythbackend --version .

There was a workaround for this (driver issue?) in [26695].

comment:2 Changed 8 years ago by Artem Astafyev

mythbackend --version

Please attach all output as a file in bug reports.
MythTV Version   : 26569
MythTV Branch    : branches/release-0-23-fixes/mythtv/
Network Protocol : 23056
Library API      :
QT Version       : 4.6.3
Options compiled in:
 linux release using_oss using_alsa using_pulse using_jack using_pulseoutput using_backend using_dvb using_firewire using_frontend using_hdhomerun using_hdpvr using_iptv using_ivtv using_joystick_menu using_libfftw3 using_lirc using_mheg using_opengl_video using_opengl_vsync using_qtdbus using_qtwebkit using_v4l using_x11 using_xrandr using_xv using_xvmc using_xvmc_vld using_xvmcw using_bindings_perl using_bindings_python using_opengl using_vdpau using_ffmpeg_threads using_libavc_5_3 using_live 

That workaround is for DVB and this issue is in analog part. Strictly saying in libmythtv/v4lchannel.cpp file, function V4LChannel::SetInputAndFormat?. There is check after calling VIDIOC_S_INPUT ioctl if it returned EBUSY. In this case VIDIOC_STREAMOFF ioctl issued. After VIDIOC_S_STD ioctl there is no such check. Anyway cx18 driver has no such ioct, but has V4L2_ENC_CMD_START/STOP ioctls.

comment:3 Changed 8 years ago by Artem Astafyev

I asked ivtv-devel mailing list and below is what Andy Walls answered me:

> I'm testing a new card GoTView PCI DVD3 with patch Alexey Chernov
> provided recently. I have problem changing channel in MythTV but it
> seems that it's not because of this patch. The problem is that cx18
> driver rejects standard changing if there are some active analog
> streams.

That is valid behavior per the V4L2 API:

the driver is allowed to return an errno of EBUSY when it is busy.

That check exists, because it is not possible to change the capture and
MPEG encoding engine between a 525 line standard (NTSC), 625 line
stanadrd (PAL, SECAM), or audio only (FM radio) capture in mid-stream.

Note, the CX23415/6/7/8 chips can only handle one incoming analog video
and audio source at a time.

>  I filed ticket in MythTV trac
> Could somebody take a look at
> it?

Since at least Apr 27, 2007, when ivtv went into the mainline kernel,
ivtv has always returned EBUSY for this case.  cx18 has always returned
EBUSY for this case as well.

Unless MythTV doesn't call close() once on the MPEG stream's file handle
before trying to switch standards, I suspect the MythTV devs will close
it without action.  MythTV needs to close() the MPEG file descriptor, if
trying to switch standards on ivtv and cx18 type devices.

BTW, VIDIOC_STREAMOFF is only supported for Streaming I/O methods.  The
cx18 driver only supports the read() method.  Calling close() once on
all *active* analog capture stream (MPEG, YUV/HM12, PCM, and/or VBI)
file descriptors is required to free up the CX23418's encoding engine.

> I wonder if it's possible to stop streams on standard change? That
> would solve the problem.

The application, i.e. MythTV, needs to be the one to do that.  Also note
that if you are using the cx18-alsa.ko module, pulseaudio *may* have the
PCM analog stream open.

There really is only one analog video and audio stream being processed
by the CX23418 chip.  You can get it in multiple output formats - MPEG,
YUV/HM12, PCM audio only - at the same time, but it's still the same
video and audio stream.

The cx18 driver automatically closing all analog streams (MPEG,
YUV/HM12, PCM, VBI) when someone calls a VIDIOC_S_STD ioctl() on a
device node would be considered a non-compliance with the V4L2 API.  I'm
not sure it would be a desirable feature either.

So I think this issue should be fixed on MythTV side. It seems that this problem exists for a long time and I wonder how nobody else discovered it.

comment:4 Changed 8 years ago by danielk

Artem Astafyev, aside from error messages, does channel changing work properly if you just ignore the return value of SetV4L2DeviceOptions(chanfd); ?

i.e. if you change "ok = SetV4L2DeviceOptions(chanfd);" to "(void) SetV4L2DeviceOptions(chanfd);"

comment:5 Changed 8 years ago by danielk

Please try adding: "requires_special_pause = true;" on line 437, before the VERBOSE(VB_RECORD...

comment:6 in reply to:  5 Changed 8 years ago by anonymous

Replying to danielk:

Please try adding: "requires_special_pause = true;" on line 437, before the VERBOSE(VB_RECORD...


You are likely correct. The problem is at least here:

The cx18 driver is very much like the ivtv driver. An "else if (driver == "cx18")" block is probably needed there. The cx18 driver need the special pause, uses v4l2, has vbi, but I don't think needs the buggy vbi boolean set (I'm not sure though).

Regards, Andy

comment:7 Changed 8 years ago by Artem Astafyev


Below are results of my tests:

  1. line 454

ok = SetV4L2DeviceOptions(chanfd);" to "(void) SetV4L2DeviceOptions(chanfd);

All works fine. The only little inconvinience in this case is that I see garbage and noise between channel switches.

  1. line 437

"requires_special_pause = true;" Channel switching works, but I have distorted picture after switching. It looks like some issue in mpeg encoder pause code. Distorted picture looks like b/w picture with vertical RGB lines. Also there is no sound, only noise. Below is usecase:

  1. Default channel 1.
  2. Start LiveTV. Tuning to default channel 1. Picture and sound fine.
  3. Switch to channel 2. Tuning fine, but picture distorted, noise.
  4. Channel 2 become default.
  5. Stop LiveTV. Start LiveTV. Tuning to default channel 2. Picture and

sound fine.

  1. Switch to channel 1. Tuning fine, but picture distorted, noise.
  2. Swicth any channel. Tuning fine, but picture distorted, noise.

So I can get normal picture and sound only after LiveTV restart.

comment:8 Changed 8 years ago by robertm

Owner: set to danielk
Status: newassigned

comment:9 Changed 7 years ago by Github

Milestone: unknown0.25
Resolution: fixed
Status: assignedclosed

Merge of various recorder changes from mythtv-rec2.

  • Fixes #9191. Channel switching doesn't work with cx18 driver.
  • Fixes #9451. IPTVRecorder doesn't produce proper TS packets for big DVB tables.
  • Fixes #9709. TFW IOBOUND.
  • This also fixes pause status locking in various recorders.
  • This also replaces a few spinlocks with QWaitConditions.
  • This also adds a DVB ASI recorder implementation in just 1033 lines. (Uninteresting to most).
  • This makes changes to the DeviceReadBuffer? to make it more efficient and quicker to respond.
  • This changes the ThreadedFileWriter? so that it can expand the level of buffering it does when there are temporary slowdowns in writing to disk.

This will probably cause some regressions, that's why I'm pushing this on a Monday. This refactors all the recorders and stream readers to eliminate a lot of duplicate code, and also fixes a number of small bugs and long time annoyances see the dkristjansson/mythtv-rec branch for details.

Branch: master Changeset: 9b22460f53bf6313516f33987e4260897c6076a3

Note: See TracTickets for help on using tickets.