Ticket #2954: 2954-v5.patch

File 2954-v5.patch, 49.6 KB (added by danielk, 19 years ago)

Updated patch, prevents unsupported v4l/ivtv options from being passed to driver w/warning

  • libs/libmythtv/cardutil.h

     
    173173
    174174    // V4L info
    175175    static bool         hasV4L2(int videofd);
    176     static bool         GetV4LInfo(int videofd, QString &card,QString &driver);
     176    static bool         GetV4LInfo(int videofd, QString &card, QString &driver,
     177                                   uint32_t &version);
     178    static bool         GetV4LInfo(int videofd, QString &card, QString &driver)
     179        { uint32_t dummy; return GetV4LInfo(videofd, card, driver, dummy); }
    177180    static InputNames   probeV4LInputs(int videofd, bool &ok);
    178181
    179182  private:
  • libs/libmythtv/mpegrecorder.h

     
    5555    bool OpenV4L2DeviceAsInput(void);
    5656    bool SetIVTVDeviceOptions(int chanfd);
    5757    bool SetV4L2DeviceOptions(int chanfd);
     58    bool SetVBIOptions(int chanfd);
     59    uint GetFilteredStreamType(void) const;
     60    uint GetFilteredAudioSampleRate(void) const;
     61    uint GetFilteredAudioLayer(void) const;
     62    uint GetFilteredAudioBitRate(uint audio_layer) const;
    5863
    5964    void ResetForNewFile(void);
    6065
    6166    bool deviceIsMpegFile;
    6267    int bufferSize;
    6368
     69    // Driver info
     70    QString  card;
     71    QString  driver;
     72    uint32_t version;
     73    bool     usingv4l2;
     74    bool     has_buggy_vbi;
     75    bool     has_v4l2_vbi;
     76
    6477    // State
    6578    bool recording;
    6679    bool encoding;
     
    7588    // Encoding info
    7689    int width, height;
    7790    int bitrate, maxbitrate, streamtype, aspectratio;
    78     int audtype, audsamplerate, audbitratel1, audbitratel2;
     91    int audtype, audsamplerate, audbitratel1, audbitratel2, audbitratel3;
    7992    int audvolume;
    8093    unsigned int language; ///< 0 is Main Lang; 1 is SAP Lang; 2 is Dual
    8194
     
    102115
    103116    static const int   audRateL1[];
    104117    static const int   audRateL2[];
     118    static const int   audRateL3[];
    105119    static const char *streamType[];
    106120    static const char *aspectRatio[];
    107121    static const unsigned int kBuildBufferMaxSize;
  • libs/libmythtv/ivtv_myth.h

     
    1 #define IVTV_IOC_FWAPI          0xFFEE7701 /*just some values i picked for now*/
    2 #define IVTV_IOC_ZCOUNT         0xFFEE7702
    3 #ifdef __FreeBSD__
    4 #define IVTV_IOC_G_CODEC        _IOR  ('V', 73, struct ivtv_ioctl_codec)
    5 #define IVTV_IOC_S_CODEC        _IOWR ('V', 74, struct ivtv_ioctl_codec)
    6 #else
    7 #define IVTV_IOC_G_CODEC        0xFFEE7703
    8 #define IVTV_IOC_S_CODEC        0xFFEE7704
    9 #endif
     1/*
     2    Public ivtv API header
     3    Copyright (C) 2003-2004  Kevin Thayer <nufan_wfk at yahoo.com>
    104
    11 #define IVTV_MBOX_MAX_DATA 16
     5    VBI portions:
     6    Copyright (C) 2004  Hans Verkuil <hverkuil@xs4all.nl>
    127
    13 #define IVTV_SLICED_TELETEXT_B  (1 << 0)
    14 #define IVTV_SLICED_CAPTION_625 (1 << 1)
    15 #define IVTV_SLICED_CAPTION_525 (1 << 2)
    16 #define IVTV_SLICED_WSS_625     (1 << 3)
    17 #define IVTV_SLICED_VPS         (1 << 4)
     8    This program is free software; you can redistribute it and/or modify
     9    it under the terms of the GNU General Public License as published by
     10    the Free Software Foundation; either version 2 of the License, or
     11    (at your option) any later version.
    1812
    19 struct ivtv_sliced_vbi_format {
    20         unsigned long service_set;      /* one or more of the IVTV_SLICED_ defines */
    21         unsigned long packet_size;      /* the size in bytes of the ivtv_sliced_data packet */
    22         unsigned long io_size;          /* maximum number of bytes passed by one read() call */
    23         unsigned long reserved;
    24 };
     13    This program is distributed in the hope that it will be useful,
     14    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16    GNU General Public License for more details.
    2517
    26 /* This structure is the same as the proposed v4l2_sliced_data structure */
    27 /* id is one of the VBI_SLICED_ flags. */
    28 struct ivtv_sliced_data {
    29         unsigned long id;
    30         unsigned long line;
    31         unsigned char *data;
    32 };
     18    You should have received a copy of the GNU General Public License
     19    along with this program; if not, write to the Free Software
     20    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     21 */
    3322
    34 /* The four bit VBI data type found in the embedded VBI data of an
    35    MPEG stream has one of the following values: */
    36 #define VBI_TYPE_TELETEXT       0x1     // Teletext (uses lines 6-22 for PAL, 10-21 for NTSC)
    37 #define VBI_TYPE_CC             0x4     // Closed Captions (line 21 NTSC, line 22 PAL)
    38 #define VBI_TYPE_WSS            0x5     // Wide Screen Signal (line 20 NTSC, line 23 PAL)
    39 #define VBI_TYPE_VPS            0x7     // Video Programming System (PAL) (line 16)
     23#ifndef _LINUX_IVTV_H
     24#define _LINUX_IVTV_H
    4025
    41 /* allow direct access to the saa7115 registers for testing */
    42 #define SAA7115_GET_REG         0xFFEE7705
    43 #define SAA7115_SET_REG         0xFFEE7706
     26#define __u32 uint32_t
     27#define __u64 uint64_t
    4428
    45 /* to set audio options */
    46 #define DECODER_SET_AUDIO       0xFFEE7707
    47 #define DECODER_AUDIO_32_KHZ    0
    48 #define DECODER_AUDIO_441_KHZ   1
    49 #define DECODER_AUDIO_48_KHZ    2
     29/* NOTE: the ioctls in this file will eventually be replaced by v4l2 API
     30   ioctls. */
    5031
    51 #define IVTV_IOC_PLAY           0xFFEE7781
    52 #define IVTV_IOC_PAUSE          0xFFEE7782
    53 #define IVTV_IOC_FRAMESYNC      0xFFEE7783
    54 #define IVTV_IOC_GET_TIMING     0xFFEE7784
    55 #define IVTV_IOC_S_SLOW_FAST    0xFFEE7785
    56 #define IVTV_IOC_S_START_DECODE 0xFFEE7786
    57 #define IVTV_IOC_S_STOP_DECODE  0xFFEE7787
    58 #define IVTV_IOC_S_OSD          0xFFEE7788
    59 #define IVTV_IOC_GET_FB         0xFFEE7789
     32/* device ioctls should use the range 29-199 */
     33#define IVTV_IOC_START_DECODE      _IOW ('@', 29, struct ivtv_cfg_start_decode)
     34#define IVTV_IOC_STOP_DECODE       _IOW ('@', 30, struct ivtv_cfg_stop_decode)
     35#define IVTV_IOC_G_SPEED           _IOR ('@', 31, struct ivtv_speed)
     36#define IVTV_IOC_S_SPEED           _IOW ('@', 32, struct ivtv_speed)
     37#define IVTV_IOC_DEC_STEP          _IOW ('@', 33, int)
     38#define IVTV_IOC_DEC_FLUSH         _IOW ('@', 34, int)
     39#define IVTV_IOC_PAUSE_BLACK       _IO  ('@', 35)
     40#define IVTV_IOC_STOP              _IO  ('@', 36)
     41#define IVTV_IOC_PLAY              _IO  ('@', 37)
     42#define IVTV_IOC_PAUSE             _IO  ('@', 38)
     43#define IVTV_IOC_FRAMESYNC         _IOR ('@', 39, struct ivtv_ioctl_framesync)
     44#define IVTV_IOC_GET_TIMING        _IOR ('@', 40, struct ivtv_ioctl_framesync)
     45#define IVTV_IOC_S_SLOW_FAST       _IOW ('@', 41, struct ivtv_slow_fast)
     46#define IVTV_IOC_GET_FB            _IOR ('@', 44, int)
     47#define IVTV_IOC_S_GOP_END         _IOWR('@', 50, int)
     48#define IVTV_IOC_S_VBI_PASSTHROUGH _IOW ('@', 51, int)
     49#define IVTV_IOC_G_VBI_PASSTHROUGH _IOR ('@', 52, int)
     50#define IVTV_IOC_PASSTHROUGH       _IOW ('@', 53, int)
     51#define IVTV_IOC_PAUSE_ENCODE      _IO  ('@', 56)
     52#define IVTV_IOC_RESUME_ENCODE     _IO  ('@', 57)
     53#define IVTV_IOC_DEC_SPLICE        _IOW ('@', 58, int)
     54#define IVTV_IOC_DEC_FAST_STOP     _IOW ('@', 59, int)
     55#define IVTV_IOC_PREP_FRAME_YUV    _IOW ('@', 60, struct ivtvyuv_ioctl_dma_host_to_ivtv_args)
     56#define IVTV_IOC_G_YUV_INTERLACE   _IOR ('@', 61, struct ivtv_ioctl_yuv_interlace)
     57#define IVTV_IOC_S_YUV_INTERLACE   _IOW ('@', 62, struct ivtv_ioctl_yuv_interlace)
     58#define IVTV_IOC_G_PTS             _IOR ('@', 63, u64)
    6059
    61 #define IVTV_IOC_START_DECODE  _IOW ('@', 29, struct ivtv_cfg_start_decode)
    62 #define IVTV_IOC_STOP_DECODE   _IOW ('@', 30, struct ivtv_cfg_stop_decode)
    63 #define IVTV_IOC_G_SPEED       _IOR ('@', 31, struct ivtv_speed)
    64 #define IVTV_IOC_S_SPEED       _IOW ('@', 32, struct ivtv_speed)
    65 #define IVTV_IOC_DEC_STEP      _IOW ('@', 33, int)
    66 #define IVTV_IOC_DEC_FLUSH     _IOW ('@', 34, int)
    67 #define IVTV_IOC_S_VBI_MODE    _IOWR('@', 35, struct ivtv_sliced_vbi_format)
    68 #define IVTV_IOC_G_VBI_MODE    _IOR ('@', 36, struct ivtv_sliced_vbi_format)
    69 #define IVTV_IOC_S_VBI_EMBED   _IOW ('@', 54, int)
    70 #define IVTV_IOC_G_VBI_EMBED   _IOR ('@', 55, int)
    71 
    72 /* ioctl for MSP_SET_MATRIX will have to be registered */
    73 #define MSP_SET_MATRIX     _IOW('m',17,struct msp_matrix)
    74 
    75 
    7660/* Custom v4l controls */
    7761#ifndef V4L2_CID_PRIVATE_BASE
    7862#define V4L2_CID_PRIVATE_BASE                   0x08000000
    79 #endif
     63#endif /* V4L2_CID_PRIVATE_BASE */
    8064
    81 #define V4L2_CID_IVTV_FREQ      (V4L2_CID_PRIVATE_BASE)
    82 #define V4L2_CID_IVTV_ENC       (V4L2_CID_PRIVATE_BASE + 1)
    83 #define V4L2_CID_IVTV_BITRATE   (V4L2_CID_PRIVATE_BASE + 2)
    84 #define V4L2_CID_IVTV_MONO      (V4L2_CID_PRIVATE_BASE + 3)
    85 #define V4L2_CID_IVTV_JOINT     (V4L2_CID_PRIVATE_BASE + 4)
    86 #define V4L2_CID_IVTV_EMPHASIS  (V4L2_CID_PRIVATE_BASE + 5)
    87 #define V4L2_CID_IVTV_CRC       (V4L2_CID_PRIVATE_BASE + 6)
    88 #define V4L2_CID_IVTV_COPYRIGHT (V4L2_CID_PRIVATE_BASE + 7)
    89 #define V4L2_CID_IVTV_GEN       (V4L2_CID_PRIVATE_BASE + 8)
     65#define V4L2_CID_IVTV_FREQ      (V4L2_CID_PRIVATE_BASE + 0) /* old control */
     66#define V4L2_CID_IVTV_ENC       (V4L2_CID_PRIVATE_BASE + 1) /* old control */
     67#define V4L2_CID_IVTV_BITRATE   (V4L2_CID_PRIVATE_BASE + 2) /* old control */
     68#define V4L2_CID_IVTV_MONO      (V4L2_CID_PRIVATE_BASE + 3) /* old control */
     69#define V4L2_CID_IVTV_JOINT     (V4L2_CID_PRIVATE_BASE + 4) /* old control */
     70#define V4L2_CID_IVTV_EMPHASIS  (V4L2_CID_PRIVATE_BASE + 5) /* old control */
     71#define V4L2_CID_IVTV_CRC       (V4L2_CID_PRIVATE_BASE + 6) /* old control */
     72#define V4L2_CID_IVTV_COPYRIGHT (V4L2_CID_PRIVATE_BASE + 7) /* old control */
     73#define V4L2_CID_IVTV_GEN       (V4L2_CID_PRIVATE_BASE + 8) /* old control */
    9074
    91 #define IVTV_V4L2_AUDIO_MENUCOUNT 9 /* # of v4l controls */
     75#define V4L2_CID_IVTV_DEC_SMOOTH_FF     (V4L2_CID_PRIVATE_BASE + 9)
     76#define V4L2_CID_IVTV_DEC_FR_MASK       (V4L2_CID_PRIVATE_BASE + 10)
     77#define V4L2_CID_IVTV_DEC_SP_MUTE       (V4L2_CID_PRIVATE_BASE + 11)
     78#define V4L2_CID_IVTV_DEC_FR_FIELD      (V4L2_CID_PRIVATE_BASE + 12)
     79#define V4L2_CID_IVTV_DEC_AUD_SKIP      (V4L2_CID_PRIVATE_BASE + 13)
     80#define V4L2_CID_IVTV_DEC_NUM_BUFFERS   (V4L2_CID_PRIVATE_BASE + 14)
     81#define V4L2_CID_IVTV_DEC_PREBUFFER     (V4L2_CID_PRIVATE_BASE + 15)
    9282
    93 #define IVTV_DEC_PRIVATE_BASE   (V4L2_CID_PRIVATE_BASE + IVTV_V4L2_AUDIO_MENUCOUNT)
    94 
    95 #define V4L2_CID_IVTV_DEC_SMOOTH_FF     (IVTV_DEC_PRIVATE_BASE + 0)
    96 #define V4L2_CID_IVTV_DEC_FR_MASK       (IVTV_DEC_PRIVATE_BASE + 1)
    97 #define V4L2_CID_IVTV_DEC_SP_MUTE       (IVTV_DEC_PRIVATE_BASE + 2)
    98 #define V4L2_CID_IVTV_DEC_FR_FIELD      (IVTV_DEC_PRIVATE_BASE + 3)
    99 #define V4L2_CID_IVTV_DEC_AUD_SKIP      (IVTV_DEC_PRIVATE_BASE + 4)
    100 #define V4L2_CID_IVTV_DEC_NUM_BUFFERS   (IVTV_DEC_PRIVATE_BASE + 5)
    101 #define V4L2_CID_IVTV_DEC_PREBUFFER     (IVTV_DEC_PRIVATE_BASE + 6)
    102 
    103 #define IVTV_V4L2_DEC_MENUCOUNT 7
    104 
    105 struct ivtv_ioctl_fwapi {
    106         uint32_t cmd;
    107         uint32_t result;
    108         int32_t args;
    109         uint32_t data[IVTV_MBOX_MAX_DATA];
    110 };
    111 
    11283struct ivtv_ioctl_framesync {
    113         uint32_t frame;
    114         uint64_t pts;
    115         uint64_t scr;
     84        __u32 frame;
     85        __u64 pts;
     86        __u64 scr;
    11687};
    11788
    11889struct ivtv_speed {
    119         int scale;      /* 1-?? (50 for now) */
    120         int smooth;     /* Smooth mode when in slow/fast mode */
    121         int speed;      /* 0 = slow, 1 = fast */
    122         int direction;  /* 0 = forward, 1 = reverse (not supportd */
    123         int fr_mask;    /* 0 = I, 1 = I,P, 2 = I,P,B    2 = default!*/
    124         int b_per_gop;  /* frames per GOP (reverse only) */
    125         int aud_mute;   /* Mute audio while in slow/fast mode */
    126         int fr_field;   /* 1 = show every field, 0 = show every frame */
    127         int mute;       /* # of audio frames to mute on playback resume */
     90        int scale;              /* 1-?? (50 for now) */
     91        int smooth;             /* Smooth mode when in slow/fast mode */
     92        int speed;              /* 0 = slow, 1 = fast */
     93        int direction;          /* 0 = forward, 1 = reverse (not supportd */
     94        int fr_mask;            /* 0 = I, 1 = I,P, 2 = I,P,B    2 = default! */
     95        int b_per_gop;          /* frames per GOP (reverse only) */
     96        int aud_mute;           /* Mute audio while in slow/fast mode */
     97        int fr_field;           /* 1 = show every field, 0 = show every frame */
     98        int mute;               /* # of audio frames to mute on playback resume */
    12899};
    129100
    130101struct ivtv_slow_fast {
    131         int speed; /* 0 = slow, 1 = fast */
    132         int scale; /* 1-?? (50 for now) */
    133 };     
     102        int speed;              /* 0 = slow, 1 = fast */
     103        int scale;              /* 1-?? (50 for now) */
     104};
    134105
    135106struct ivtv_cfg_start_decode {
    136         uint32_t    gop_offset;        /*Frames in GOP to skip before starting */
    137         uint32_t     muted_audio_frames;/* #of audio frames to mute */
     107        __u32 gop_offset;       /*Frames in GOP to skip before starting */
     108        __u32 muted_audio_frames;       /* #of audio frames to mute */
    138109};
    139110
    140111struct ivtv_cfg_stop_decode {
    141         int             hide_last; /* 1 = show black after stop,
    142                                       0 = show last frame */
    143         uint64_t        pts_stop; /* PTS to stop at */
     112        int hide_last;          /* 1 = show black after stop,
     113                                   0 = show last frame */
     114        __u64 pts_stop; /* PTS to stop at */
    144115};
    145116
    146 
    147 /* For use with IVTV_IOC_G_CODEC and IVTV_IOC_S_CODEC */
    148 struct ivtv_ioctl_codec {
    149         uint32_t aspect;
    150         uint32_t audio_bitmask;
    151         uint32_t bframes;
    152         uint32_t bitrate_mode;
    153         uint32_t bitrate;
    154         uint32_t bitrate_peak;
    155         uint32_t dnr_mode;
    156         uint32_t dnr_spatial;
    157         uint32_t dnr_temporal;
    158         uint32_t dnr_type;
    159         uint32_t framerate;
    160         uint32_t framespergop;
    161         uint32_t gop_closure;
    162         uint32_t pulldown;
    163         uint32_t stream_type;
     117struct ivtv_ioctl_yuv_interlace{
     118        int interlace_mode; /* Takes one of IVTV_YUV_MODE_xxxxxx values */
     119        int threshold; /* If mode is auto then if src_height <= this value treat as progressive otherwise treat as interlaced */
    164120};
     121#define IVTV_YUV_MODE_INTERLACED        0
     122#define IVTV_YUV_MODE_PROGRESSIVE       1
     123#define IVTV_YUV_MODE_AUTO              2
    165124
    166 
    167 struct msp_matrix {
    168     int input;
    169     int output;
    170 };
    171 
    172125/* Framebuffer external API */
    173 /* NOTE: These must *exactly* match the structures and constants in driver/ivtv.h */
    174126
    175127struct ivtvfb_ioctl_state_info {
    176   unsigned long status;
    177   unsigned long alpha;
     128        unsigned long status;
     129        unsigned long alpha;
    178130};
    179131
     132struct ivtvfb_ioctl_colorkey {
     133    int state;
     134    __u32 colorKey;
     135};
     136
    180137struct ivtvfb_ioctl_blt_copy_args {
    181   int x, y, width, height, source_offset, source_stride;
     138        int x, y, width, height, source_offset, source_stride;
    182139};
    183140
    184141struct ivtvfb_ioctl_blt_fill_args {
    185     int rasterop, alpha_mode, alpha_mask, width, height, x, y;
    186     unsigned int destPixelMask, colour;
     142        int rasterop, alpha_mode, alpha_mask, width, height, x, y;
     143        unsigned int destPixelMask, colour;
    187144
    188145};
    189146
    190147struct ivtvfb_ioctl_dma_host_to_ivtv_args {
    191   void* source;
    192   unsigned long dest_offset;
    193   int count;
     148        void *source;
     149        unsigned long dest_offset;
     150        int count;
    194151};
    195152
     153struct ivtvyuv_ioctl_dma_host_to_ivtv_args {
     154        void *y_source;
     155        void *uv_source;
     156        unsigned int yuv_type;
     157        int src_x;
     158        int src_y;
     159        unsigned int src_w;
     160        unsigned int src_h;
     161        int dst_x;
     162        int dst_y;
     163        unsigned int dst_w;
     164        unsigned int dst_h;
     165        int srcBuf_width;
     166        int srcBuf_height;
     167};
     168
    196169struct ivtvfb_ioctl_get_frame_buffer {
    197   void* mem;
    198   int  size;
    199   int  sizex;
    200   int  sizey;
     170        void *mem;
     171        int size;
     172        int sizex;
     173        int sizey;
    201174};
    202175
    203176struct ivtv_osd_coords {
    204   unsigned long offset;
    205   unsigned long max_offset;
    206   int pixel_stride;
    207   int lines;
    208   int x;
    209   int y;
     177        unsigned long offset;
     178        unsigned long max_offset;
     179        int pixel_stride;
     180        int lines;
     181        int x;
     182        int y;
    210183};
    211184
    212185struct rectangle {
    213   int x0;
    214   int y0;
    215   int x1;
    216   int y1;
     186        int x0;
     187        int y0;
     188        int x1;
     189        int y1;
    217190};
    218191
     192struct ivtvfb_ioctl_set_window {
     193        int width;
     194        int height;
     195        int left;
     196        int top;
     197};
     198
     199
     200
     201/* Framebuffer ioctls should use the range 1 - 28 */
    219202#define IVTVFB_IOCTL_GET_STATE          _IOR('@', 1, struct ivtvfb_ioctl_state_info)
    220203#define IVTVFB_IOCTL_SET_STATE          _IOW('@', 2, struct ivtvfb_ioctl_state_info)
    221204#define IVTVFB_IOCTL_PREP_FRAME         _IOW('@', 3, struct ivtvfb_ioctl_dma_host_to_ivtv_args)
     
    224207#define IVTVFB_IOCTL_SET_ACTIVE_BUFFER  _IOW('@', 6, struct ivtv_osd_coords)
    225208#define IVTVFB_IOCTL_GET_FRAME_BUFFER   _IOR('@', 7, struct ivtvfb_ioctl_get_frame_buffer)
    226209#define IVTVFB_IOCTL_BLT_FILL           _IOW('@', 8, struct ivtvfb_ioctl_blt_fill_args)
     210#define IVTVFB_IOCTL_PREP_FRAME_BUF     _IOW('@', 9, struct ivtvfb_ioctl_dma_host_to_ivtv_args)
     211#define IVTVFB_IOCTL_SET_WINDOW         _IOW('@', 11, struct ivtvfb_ioctl_set_window)
     212#define IVTVFB_IOCTL_GET_COLORKEY       _IOW('@', 12, struct ivtvfb_ioctl_colorkey)
     213#define IVTVFB_IOCTL_SET_COLORKEY       _IOW('@', 13, struct ivtvfb_ioctl_colorkey)
    227214
    228215#define IVTVFB_STATUS_ENABLED           (1 << 0)
    229216#define IVTVFB_STATUS_GLOBAL_ALPHA      (1 << 1)
    230217#define IVTVFB_STATUS_LOCAL_ALPHA       (1 << 2)
    231218#define IVTVFB_STATUS_FLICKER_REDUCTION (1 << 3)
    232219
    233 #define IVTV_IOCTL_SET_DEBUG_LEVEL _IOWR('@', 98, int *)
    234 #define IVTV_IOCTL_GET_DEBUG_LEVEL _IOR('@', 99, int *)
     220/********************************************************************/
     221/* Old stuff */
     222
     223/* Good for versions 0.2.0 through 0.7.x */
     224#define IVTV_IOC_G_CODEC      _IOR ('@', 48, struct ivtv_ioctl_codec)
     225#define IVTV_IOC_S_CODEC      _IOW ('@', 49, struct ivtv_ioctl_codec)
     226
     227/* For use with IVTV_IOC_G_CODEC and IVTV_IOC_S_CODEC */
     228struct ivtv_ioctl_codec {
     229        __u32 aspect;
     230        __u32 audio_bitmask;
     231        __u32 bframes;
     232        __u32 bitrate_mode;
     233        __u32 bitrate;
     234        __u32 bitrate_peak;
     235        __u32 dnr_mode;
     236        __u32 dnr_spatial;
     237        __u32 dnr_temporal;
     238        __u32 dnr_type;
     239        __u32 framerate;
     240        __u32 framespergop;
     241        __u32 gop_closure;
     242        __u32 pulldown;
     243        __u32 stream_type;
     244};
     245
     246/********************************************************************/
     247
     248/* Good for versions 0.2.0 through 0.3.x */
     249#define IVTV_IOC_S_VBI_MODE   _IOWR('@', 35, struct ivtv_sliced_vbi_format)
     250#define IVTV_IOC_G_VBI_MODE   _IOR ('@', 36, struct ivtv_sliced_vbi_format)
     251
     252/* Good for version 0.2.0 through 0.3.7 */
     253#define IVTV_IOC_S_VBI_EMBED  _IOW ('@', 54, int)
     254#define IVTV_IOC_G_VBI_EMBED  _IOR ('@', 55, int)
     255
     256/* Good for version 0.2.0 through 0.3.7 */
     257struct ivtv_sliced_vbi_format {
     258        unsigned long service_set;      /* one or more of the IVTV_SLICED_ defines */
     259        unsigned long packet_size;      /* the size in bytes of the ivtv_sliced_data packet */
     260        unsigned long io_size;          /* maximum number of bytes passed by one read() call */
     261        unsigned long reserved;
     262};
     263
     264/* Good for version 0.2.0 through 0.3.7 */
     265struct ivtv_sliced_data {
     266        unsigned long id;
     267        unsigned long line;
     268        unsigned char *data;
     269};
     270
     271/* Good for version 0.2.0 through 0.3.7 for IVTV_IOC_G_VBI_MODE */
     272/* Good for version 0.3.8 through 0.7.x for IVTV_IOC_S_VBI_PASSTHROUGH */
     273#define VBI_TYPE_TELETEXT 0x1 // Teletext (uses lines 6-22 for PAL, 10-21 for NTSC)
     274#define VBI_TYPE_CC       0x4 // Closed Captions (line 21 NTSC, line 22 PAL)
     275#define VBI_TYPE_WSS      0x5 // Wide Screen Signal (line 20 NTSC, line 23 PAL)
     276#define VBI_TYPE_VPS      0x7 // Video Programming System (PAL) (line 16)
     277
     278#endif /* _LINUX_IVTV_H */
  • libs/libmythtv/cardutil.cpp

     
    483483#endif // !USING_V4L
    484484}
    485485
    486 bool CardUtil::GetV4LInfo(int videofd, QString &card, QString &driver)
     486bool CardUtil::GetV4LInfo(
     487    int videofd, QString &card, QString &driver, uint32_t &version)
    487488{
    488489    card = driver = QString::null;
     490    version = 0;
    489491
    490492    if (videofd < 0)
    491493        return false;
     
    498500    {
    499501        card.setAscii((char*)capability.card);
    500502        driver.setAscii((char*)capability.driver);
     503        version = capability.version;
    501504    }
    502505    else // Fallback to V4L1 query
    503506    {
  • libs/libmythtv/mpegrecorder.cpp

     
    3333#include "tv_rec.h"
    3434#include "videodev_myth.h"
    3535#include "util.h"
     36#include "cardutil.h"
    3637
    3738// ivtv header
    3839extern "C" {
     
    4344#endif
    4445}
    4546
     47#define IVTV_KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
     48
    4649#define LOC QString("MPEGRec(%1): ").arg(videodevice)
    4750#define LOC_WARN QString("MPEGRec(%1) Warning: ").arg(videodevice)
    4851#define LOC_ERR QString("MPEGRec(%1) Error: ").arg(videodevice)
     
    5760    32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0
    5861};
    5962
     63const int MpegRecorder::audRateL3[] =
     64{
     65    32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0
     66};
     67
    6068const char* MpegRecorder::streamType[] =
    6169{
    6270    "MPEG-2 PS", "MPEG-2 TS",     "MPEG-1 VCD",    "PES AV",
     
    7785    // Debugging variables
    7886    deviceIsMpegFile(false),
    7987    bufferSize(4096),
     88    // Driver info
     89    card(QString::null),      driver(QString::null),
     90    version(0),               usingv4l2(false),
     91    has_buggy_vbi(true),      has_v4l2_vbi(false),
    8092    // State
    8193    recording(false),         encoding(false),
    8294    errored(false),
     
    90102    streamtype(0),            aspectratio(2),
    91103    audtype(2),               audsamplerate(48000),
    92104    audbitratel1(14),         audbitratel2(14),
     105    audbitratel3(10),
    93106    audvolume(80),            language(0),
    94107    // Input file descriptors
    95108    chanfd(-1),               readfd(-1),
     
    125138    }
    126139}
    127140
     141static int find_index(const int *audio_rate, int value)
     142{
     143    for (uint i = 0; audio_rate[i] != 0; i++)
     144    {
     145        if (audio_rate[i] == value)
     146            return i;
     147    }
     148
     149    return -1;
     150}
     151
    128152void MpegRecorder::SetOption(const QString &opt, int value)
    129153{
    130     bool found = false;
    131154    if (opt == "width")
    132155        width = value;
    133156    else if (opt == "height")
     
    140163        audsamplerate = value;
    141164    else if (opt == "mpeg2audbitratel1")
    142165    {
    143         for (int i = 0; audRateL1[i] != 0; i++)
     166        int index = find_index(audRateL1, value);
     167        if (index >= 0)
     168            audbitratel1 = index + 1;
     169        else
    144170        {
    145             if (audRateL1[i] == value)
    146             {
    147                 audbitratel1 = i + 1;
    148                 found = true;
    149                 break;
    150             }
    151         }
    152 
    153         if (!found)
    154         {
    155171            VERBOSE(VB_IMPORTANT, LOC_ERR + "Audiorate(L1): " +
    156172                    QString("%1 is invalid").arg(value));
    157173        }
    158174    }
    159175    else if (opt == "mpeg2audbitratel2")
    160176    {
    161         for (int i = 0; audRateL2[i] != 0; i++)
     177        int index = find_index(audRateL2, value);
     178        if (index >= 0)
     179            audbitratel2 = index + 1;
     180        else
    162181        {
    163             if (audRateL2[i] == value)
    164             {
    165                 audbitratel2 = i + 1;
    166                 found = true;
    167                 break;
    168             }
     182            VERBOSE(VB_IMPORTANT, LOC_ERR + "Audiorate(L2): " +
     183                    QString("%1 is invalid").arg(value));
    169184        }
    170 
    171         if (!found)
     185    }
     186    else if (opt == "mpeg2audbitratel3")
     187    {
     188        int index = find_index(audRateL3, value);
     189        if (index >= 0)
     190            audbitratel3 = index + 1;
     191        else
    172192        {
    173193            VERBOSE(VB_IMPORTANT, LOC_ERR + "Audiorate(L2): " +
    174194                    QString("%1 is invalid").arg(value));
     
    236256            audtype = 1;
    237257        else if (value == "Layer II")
    238258            audtype = 2;
     259        else if (value == "Layer III")
     260            audtype = 3;
    239261        else
    240262        {
    241263            VERBOSE(VB_IMPORTANT, LOC_ERR + "MPEG2 audio layer: " +
     
    282304    SetStrOption(profile, "mpeg2audtype");
    283305    SetIntOption(profile, "mpeg2audbitratel1");
    284306    SetIntOption(profile, "mpeg2audbitratel2");
     307    SetIntOption(profile, "mpeg2audbitratel3");
    285308    SetIntOption(profile, "mpeg2audvolume");
    286309
    287310    SetIntOption(profile, "width");
     
    311334        return false;
    312335    }
    313336
     337    if (CardUtil::GetV4LInfo(chanfd, card, driver, version))
     338    {
     339        if (driver == "ivtv")
     340        {
     341            usingv4l2     = (version >= IVTV_KERNEL_VERSION(0, 8, 0));
     342            has_v4l2_vbi  = (version >= IVTV_KERNEL_VERSION(0, 3, 8));
     343            has_buggy_vbi = (version <  IVTV_KERNEL_VERSION(0, 10, 0));
     344        }
     345        else
     346        {
     347            VERBOSE(VB_IMPORTANT, "\n\nNot ivtv driver??\n\n");
     348            usingv4l2 = has_v4l2_vbi = true;
     349            has_buggy_vbi = false;
     350        }
     351    }
     352
     353    VERBOSE(VB_RECORD, LOC + QString("usingv4l2(%1) has_v4l2_vbi(%2) "
     354                                     "has_buggy_vbi(%3)")
     355            .arg(usingv4l2).arg(has_v4l2_vbi).arg(has_buggy_vbi));
     356
    314357    struct v4l2_format vfmt;
    315358    bzero(&vfmt, sizeof(vfmt));
    316359
     
    350393    language = (language > 2) ? 0 : language;
    351394    vt.audmode = v4l2_lang[language];
    352395
    353     if (do_audmode_set && (2 == language) && (1 == audtype))
     396    int audio_layer = GetFilteredAudioLayer();
     397    if (do_audmode_set && (2 == language) && (1 == audio_layer))
    354398    {
    355399        VERBOSE(VB_GENERAL, "Dual audio mode incompatible with Layer I audio."
    356400                "\n\t\t\tFalling back to Main Language");
     
    374418                "If you are using an AverMedia M179 card this is normal.");
    375419    }
    376420
    377     if (!SetV4L2DeviceOptions(chanfd) && !SetIVTVDeviceOptions(chanfd))
     421    bool ok = true;
     422    if (usingv4l2)
     423        ok = SetV4L2DeviceOptions(chanfd);
     424    else
     425    {
     426        ok = SetIVTVDeviceOptions(chanfd);
     427        if (!ok)
     428            usingv4l2 = ok = SetV4L2DeviceOptions(chanfd);
     429    }
     430
     431    if (!ok)
    378432        return false;
    379433
     434    SetVBIOptions(chanfd);
     435
    380436    readfd = open(videodevice.ascii(), O_RDWR | O_NONBLOCK);
    381437    if (readfd < 0)
    382438    {
     
    387443    return true;
    388444}
    389445
     446uint MpegRecorder::GetFilteredStreamType(void) const
     447{
     448    uint st = (uint) streamtype;
     449
     450    if (driver == "ivtv")
     451    {
     452        switch (st)
     453        {
     454            case 2:  st = 2;  break;
     455            case 10:
     456            case 13:
     457            case 14: st = 10; break;
     458            case 11: st = 11; break;
     459            case 12: st = 12; break;
     460            default: st = 0;  break;   
     461        }
     462    }
     463
     464    if (st != (uint) streamtype)
     465    {
     466        VERBOSE(VB_IMPORTANT, LOC_WARN +
     467                QString("Stream type '%1'\n\t\t\t"
     468                        "is not supported by %2 driver, using '%3' instead.")
     469                .arg(streamType[streamtype]).arg(driver).arg(streamType[st]));
     470    }
     471
     472    return st;
     473}
     474
     475uint MpegRecorder::GetFilteredAudioSampleRate(void) const
     476{
     477    uint sr = (uint) audsamplerate;
     478
     479    sr = (driver == "ivtv") ? 48000 : sr; // only 48kHz works properly.
     480
     481    if (sr != (uint) audsamplerate)
     482    {
     483        VERBOSE(VB_IMPORTANT, LOC_WARN +
     484                QString("Audio sample rate %1 Hz\n\t\t\t"
     485                        "is not supported by %2 driver, using %3 Hz instead.")
     486                .arg(audsamplerate).arg(driver).arg(sr));
     487    }
     488
     489    switch (sr)
     490    {
     491        case 32000: return V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000;
     492        case 44100: return V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100;
     493        case 48000: return V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
     494        default:    return V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
     495    }
     496}
     497
     498uint MpegRecorder::GetFilteredAudioLayer(void) const
     499{
     500    uint layer = (uint) audtype;
     501
     502    layer = max(min(layer, 3U), 1U);
     503
     504    layer = (driver == "ivtv") ? 2 : layer;
     505
     506    if (layer != (uint) audtype)
     507    {
     508        VERBOSE(VB_IMPORTANT, LOC_WARN +
     509                QString("MPEG layer %1 does not work properly\n\t\t\t"
     510                        "with %2 driver. Using MPEG layer %3 audio instead.")
     511                .arg(audtype).arg(driver).arg(layer));
     512    }
     513
     514    return layer;
     515}
     516
     517uint MpegRecorder::GetFilteredAudioBitRate(uint audio_layer) const
     518{
     519    return ((2 == audio_layer) ? max(audbitratel2, 10) :
     520            ((3 == audio_layer) ? audbitratel3 : max(audbitratel1, 6)));
     521}
     522
    390523bool MpegRecorder::SetIVTVDeviceOptions(int chanfd)
    391524{
    392525    struct ivtv_ioctl_codec ivtvcodec;
     
    403536        return false;
    404537    }
    405538
    406     audbitratel1 = max(audbitratel1, 6);
    407     audbitratel2 = max(audbitratel2, 10);
     539    uint audio_rate  = GetFilteredAudioSampleRate();
     540    uint audio_layer = GetFilteredAudioLayer();
     541    uint audbitrate  = GetFilteredAudioBitRate(audio_layer);
    408542
    409     int audio_rate = 1; // only 48kHz works properly.
    410     int audbitrate = (2 == audtype) ? audbitratel2 : audbitratel1;
    411 
    412     ivtvcodec.audio_bitmask  = audio_rate | (audtype << 2);
     543    ivtvcodec.audio_bitmask  = audio_rate | (audio_layer << 2);
    413544    ivtvcodec.audio_bitmask |= audbitrate << 4;
    414545    ivtvcodec.aspect         = aspectratio;
    415546    ivtvcodec.bitrate        = min(bitrate, maxbitrate) * 1000;
    416547    ivtvcodec.bitrate_peak   = maxbitrate * 1000;
    417548    ivtvcodec.framerate      = ntsc_framerate ? 0 : 1; // 1->25fps, 0->30fps
    418     ivtvcodec.stream_type    = streamtype;
     549    ivtvcodec.stream_type    = GetFilteredStreamType();
    419550
    420551    if (ioctl(chanfd, IVTV_IOC_S_CODEC, &ivtvcodec) < 0)
    421552    {
     
    425556
    426557    keyframedist = (ivtvcodec.framerate) ? 12 : keyframedist;
    427558
    428     if (vbimode)
     559    return true;
     560}
     561
     562static int streamtype_ivtv_to_v4l2(int st)
     563{
     564    switch (st)
    429565    {
    430 #ifdef IVTV_IOC_S_VBI_MODE
    431         struct ivtv_sliced_vbi_format vbifmt;
    432         bzero(&vbifmt, sizeof(struct ivtv_sliced_vbi_format));
    433         vbifmt.service_set = (1 == vbimode) ? VBI_TYPE_TELETEXT : VBI_TYPE_CC;
    434 
    435         if (ioctl(chanfd, IVTV_IOC_S_VBI_MODE, &vbifmt) < 0)
    436 #endif // IVTV_IOC_S_VBI_MODE
    437         {
    438 #ifdef V4L2_CAP_SLICED_VBI_CAPTURE
    439             struct v4l2_format vbi_fmt;
    440             bzero(&vbi_fmt, sizeof(struct v4l2_format));
    441             vbi_fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
    442             vbi_fmt.fmt.sliced.service_set = (1 == vbimode) ?
    443                 V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
    444 
    445             if (ioctl(chanfd, VIDIOC_S_FMT, &vbi_fmt) < 0)
    446 #endif // V4L2_CAP_SLICED_VBI_CAPTURE
    447             {
    448                 VERBOSE(VB_IMPORTANT, "Can't enable VBI recording" + ENO);
    449             }
    450         }
    451 
    452 #ifdef IVTV_IOC_S_VBI_EMBED
    453         int embedon = 1;
    454         if (ioctl(chanfd, IVTV_IOC_S_VBI_EMBED, &embedon) < 0)
    455 #endif // IVTV_IOC_S_VBI_EMBED
    456         {
    457             VERBOSE(VB_IMPORTANT, LOC + "Can't enable VBI recording (2)"+ENO);
    458         }
    459 
    460 #ifdef IVTV_IOC_G_VBI_MODE
    461         ioctl(chanfd, IVTV_IOC_G_VBI_MODE, &vbifmt);
    462 
    463         VERBOSE(VB_RECORD, LOC + QString(
    464                     "VBI service:%1, packet size:%2, io size:%3")
    465                 .arg(vbifmt.service_set).arg(vbifmt.packet_size)
    466                 .arg(vbifmt.io_size));
    467 #endif // IVTV_IOC_G_VBI_MODE
     566        case 0:  return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
     567        case 1:  return V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
     568        case 2:  return V4L2_MPEG_STREAM_TYPE_MPEG1_VCD;
     569        case 3:  return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;  /* PES A/V    */
     570        case 5:  return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;  /* PES V      */
     571        case 7:  return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;  /* PES A      */
     572        case 10: return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD;
     573        case 11: return V4L2_MPEG_STREAM_TYPE_MPEG1_VCD; /* VCD */
     574        case 12: return V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD;
     575        case 13: return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD; /* DVD-Special 1 */
     576        case 14: return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD; /* DVD-Special 2 */
     577        default: return V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
    468578    }
    469 
    470     return true;
    471579}
    472580
    473581bool MpegRecorder::SetV4L2DeviceOptions(int chanfd)
    474582{
    475     static const int kNumControls = 7;
     583    static const uint kNumControls = 7;
    476584    struct v4l2_ext_controls ctrls;
    477585    struct v4l2_ext_control ext_ctrl[kNumControls];
     586    QString control_description[kNumControls] =
     587    {
     588        "Audio Sampling Frequency",
     589        "Video Aspect ratio",
     590        "Audio Encoding",
     591        "Audio L2 Bitrate",
     592        "Video Average Bitrate",
     593        "Video Peak Bitrate",
     594        "MPEG Stream type",
     595    };
    478596
    479597    // Set controls
    480598    bzero(&ctrls,    sizeof(struct v4l2_ext_controls));
    481599    bzero(&ext_ctrl, sizeof(struct v4l2_ext_control) * kNumControls);
    482600
    483     audbitratel1 = max(audbitratel1, 6);
    484     audbitratel2 = max(audbitratel2, 10);
     601    uint audio_layer = GetFilteredAudioLayer();
     602    uint audbitrate  = GetFilteredAudioBitRate(audio_layer);
    485603
    486     int audbitrate = (2 == audtype) ? audbitratel2 : audbitratel1;
    487 
    488     if (audtype != 2)
    489     {
    490         VERBOSE(VB_IMPORTANT, LOC_WARN +
    491                 "MPEG Layer1 does not work properly with ivtv driver. "
    492                 "\n\t\t\tUsing MPEG layer 2 audio instead.");
    493     }
    494 
    495     // only 48kHz works properly.
    496604    ext_ctrl[0].id    = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
    497     ext_ctrl[0].value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
     605    ext_ctrl[0].value = GetFilteredAudioSampleRate();
    498606
    499607    ext_ctrl[1].id    = V4L2_CID_MPEG_VIDEO_ASPECT;
    500608    ext_ctrl[1].value = aspectratio - 1;
    501609
    502610    ext_ctrl[2].id    = V4L2_CID_MPEG_AUDIO_ENCODING;
    503     ext_ctrl[2].value = audtype - 1;
     611    ext_ctrl[2].value = audio_layer - 1;
    504612
    505613    ext_ctrl[3].id    = V4L2_CID_MPEG_AUDIO_L2_BITRATE;
    506614    ext_ctrl[3].value = audbitrate - 1;
     
    512620    ext_ctrl[5].value = maxbitrate * 1000;
    513621
    514622    ext_ctrl[6].id    = V4L2_CID_MPEG_STREAM_TYPE;
    515     ext_ctrl[6].value = V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
     623    ext_ctrl[6].value = streamtype_ivtv_to_v4l2(GetFilteredStreamType());
    516624
    517     ctrls.ctrl_class  = V4L2_CTRL_CLASS_MPEG;
    518     ctrls.count       = kNumControls;
    519     ctrls.controls    = ext_ctrl;
     625    for (uint i = 0; i < kNumControls; i++)
     626    {
     627        int value = ext_ctrl[i].value;
    520628
    521     if (ioctl(chanfd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
    522     {
    523         if (ctrls.error_idx >= ctrls.count)
     629        ctrls.ctrl_class  = V4L2_CTRL_CLASS_MPEG;
     630        ctrls.count       = 1;
     631        ctrls.controls    = ext_ctrl + i;
     632
     633        if (ioctl(chanfd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
    524634        {
    525635            VERBOSE(VB_IMPORTANT, LOC_ERR +
    526                     "Could not set MPEG controls" + ENO);
     636                    QString("Could not set %1 to %2")
     637                    .arg(control_description[i]).arg(value) + ENO);
    527638        }
    528         else
    529         {
    530             VERBOSE(VB_IMPORTANT, LOC_ERR +
    531                     QString("Could not set MPEG controls %1 through %2.")
    532                     .arg(ctrls.error_idx)
    533                     .arg(ext_ctrl[ctrls.error_idx].value) + ENO);
    534         }
    535         return false;
    536639    }
    537640
    538641    // Get controls
     
    552655
    553656    keyframedist = ext_ctrl[0].value;
    554657
    555     // VBI is not yet working as of July 11th, 2006 with IVTV driver.
    556     // V4L2_CID_MPEG_STREAM_VBI_FMT needs to be finished/supported first.
    557     if (vbimode)
     658    return true;
     659}
     660
     661bool MpegRecorder::SetVBIOptions(int chanfd)
     662{
     663    if (!vbimode)
     664        return true;
     665
     666    if (has_buggy_vbi)
    558667    {
     668        VERBOSE(VB_IMPORTANT, LOC_WARN + "VBI recording with broken drivers."
     669                "\n\t\t\tUpgrade to ivtv 0.10.0 if you experience problems.");
     670    }
     671
     672    /****************************************************************/
     673    /** First tell driver which services we want to capture.       **/
     674
     675#ifdef IVTV_IOC_S_VBI_EMBED
     676    // used for ivtv driver versions 0.2.0-0.3.7
     677    if (!has_v4l2_vbi)
     678    {
     679        struct ivtv_sliced_vbi_format vbifmt;
     680        bzero(&vbifmt, sizeof(struct ivtv_sliced_vbi_format));
     681        vbifmt.service_set = (1 == vbimode) ? VBI_TYPE_TELETEXT : VBI_TYPE_CC;
     682
     683        if (ioctl(chanfd, IVTV_IOC_S_VBI_MODE, &vbifmt) < 0)
     684        {
     685            VERBOSE(VB_IMPORTANT, LOC_WARN +
     686                    "Can't enable VBI recording (1)" + ENO);
     687
     688            return false;
     689        }
     690
     691        if (ioctl(chanfd, IVTV_IOC_G_VBI_MODE, &vbifmt) >= 0)
     692        {
     693            VERBOSE(VB_RECORD, LOC + QString(
     694                        "VBI service:%1, packet size:%2, io size:%3")
     695                    .arg(vbifmt.service_set).arg(vbifmt.packet_size)
     696                    .arg(vbifmt.io_size));
     697        }
     698    }
     699#endif // IVTV_IOC_S_VBI_EMBED
     700
     701#ifdef V4L2_CAP_SLICED_VBI_CAPTURE
     702    // used for ivtv driver versions 0.3.8+
     703    if (has_v4l2_vbi)
     704    {
    559705        struct v4l2_format vbifmt;
    560706        bzero(&vbifmt, sizeof(struct v4l2_format));
    561707        vbifmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
    562         /* vbifmt.fmt.sliced.service_set = (1==vbimode) ?
    563                                            VBI_TYPE_TELETEXT : VBI_TYPE_CC; */
    564         if (1 == vbimode)
    565             vbifmt.fmt.sliced.service_set |= V4L2_SLICED_VBI_625;
    566         else
    567             vbifmt.fmt.sliced.service_set |= V4L2_SLICED_VBI_525;
     708        vbifmt.fmt.sliced.service_set |= (1 == vbimode) ?
     709            V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
    568710
    569711        if (ioctl(chanfd, VIDIOC_S_FMT, &vbifmt) < 0)
    570712        {
    571             VERBOSE(VB_IMPORTANT, "Can't enable VBI recording" + ENO);
     713            VERBOSE(VB_IMPORTANT, LOC_WARN +
     714                    "Can't enable VBI recording (3)" + ENO);
     715
     716            return false;
    572717        }
    573718
    574         struct v4l2_ext_control vbi_fmt;
    575         vbi_fmt.id    = V4L2_CID_MPEG_STREAM_VBI_FMT;
    576         vbi_fmt.value = V4L2_MPEG_STREAM_VBI_FMT_IVTV;
     719        if (ioctl(chanfd, VIDIOC_G_FMT, &vbifmt) >= 0)
     720        {
     721            VERBOSE(VB_RECORD, LOC + QString("VBI service: %1, io size: %2")
     722                    .arg(vbifmt.fmt.sliced.service_set)
     723                    .arg(vbifmt.fmt.sliced.io_size));
     724        }
     725    }
     726#endif // V4L2_CAP_SLICED_VBI_CAPTURE
     727
     728    /****************************************************************/
     729    /** Second, tell driver to embed the captions in the stream.   **/
     730
     731#ifdef IVTV_IOC_S_VBI_EMBED
     732    // used for ivtv driver versions 0.2.0-0.7.x
     733    if (!usingv4l2)
     734    {
     735        int embedon = 1;
     736        if (ioctl(chanfd, IVTV_IOC_S_VBI_EMBED, &embedon) < 0)
     737        {
     738            VERBOSE(VB_IMPORTANT, LOC_WARN +
     739                    "Can't enable VBI recording (4)" + ENO);
     740
     741            return false;
     742        }
     743    }
     744#endif // IVTV_IOC_S_VBI_EMBED
     745
     746#ifdef V4L2_CAP_SLICED_VBI_CAPTURE
     747    // used for ivtv driver versions 0.8.0+
     748    if (usingv4l2)
     749    {
     750        struct v4l2_ext_control vbi_ctrl;
     751        vbi_ctrl.id      = V4L2_CID_MPEG_STREAM_VBI_FMT;
     752        vbi_ctrl.value   = V4L2_MPEG_STREAM_VBI_FMT_IVTV;
     753
     754        struct v4l2_ext_controls ctrls;
     755        bzero(&ctrls, sizeof(struct v4l2_ext_controls));
    577756        ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
    578757        ctrls.count      = 1;
    579         ctrls.controls   = &vbi_fmt;
     758        ctrls.controls   = &vbi_ctrl;
     759
    580760        if (ioctl(chanfd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
    581761        {
    582             VERBOSE(VB_IMPORTANT, LOC + "Can't enable VBI recording (2)"+ENO);
     762            VERBOSE(VB_IMPORTANT, LOC_WARN +
     763                    "Can't enable VBI recording (5)" + ENO);
     764
     765            return false;
    583766        }
    584 
    585         ioctl(chanfd, VIDIOC_G_FMT, &vbifmt);
    586 
    587         VERBOSE(VB_RECORD, LOC + QString(
    588                 "VBI service:%1, io size:%3")
    589                 .arg(vbifmt.fmt.sliced.service_set)
    590                 .arg(vbifmt.fmt.sliced.io_size));
    591767    }
     768#endif // V4L2_CAP_SLICED_VBI_CAPTURE
    592769
    593770    return true;
    594771}
  • libs/libmythtv/recordingprofile.cpp

     
    122122        else
    123123        {
    124124            addSelection("48000");
     125            setEnabled(false);
    125126            //addSelection("44100");
    126127            //addSelection("32000");
    127128        }
     
    134135class MPEG2audType : public ComboBoxSetting, public CodecParamStorage
    135136{
    136137  public:
    137     MPEG2audType(const RecordingProfile &parent) :
    138         ComboBoxSetting(this), CodecParamStorage(this, parent, "mpeg2audtype")
     138    MPEG2audType(const RecordingProfile &parent,
     139                 bool layer1, bool layer2, bool layer3) :
     140        ComboBoxSetting(this), CodecParamStorage(this, parent, "mpeg2audtype"),
     141        allow_layer1(layer1), allow_layer2(layer2), allow_layer3(layer3)
    139142    {
    140143        setLabel(QObject::tr("Type"));
     144
     145        if (allow_layer1)
     146            addSelection("Layer I");
     147        if (allow_layer2)
     148            addSelection("Layer II");
     149        if (allow_layer3)
     150            addSelection("Layer III");
     151
     152        uint allowed_cnt = 0;
     153        allowed_cnt += ((allow_layer1) ? 1 : 0);
     154        allowed_cnt += ((allow_layer2) ? 1 : 0);
     155        allowed_cnt += ((allow_layer3) ? 1 : 0);
     156
     157        if (1 == allowed_cnt)
     158            setEnabled(false);
     159
    141160        setHelpText(QObject::tr("Sets the audio type"));
    142161    }
     162
     163    void load(void)
     164    {
     165        CodecParamStorage::load();
     166        QString val = getValue();
     167
     168        if ((val == "Layer I") && !allow_layer1)
     169        {
     170            val = (allow_layer2) ? "Layer II" :
     171                ((allow_layer3) ? "Layer III" : val);
     172        }
     173
     174        if ((val == "Layer II") && !allow_layer2)
     175        {
     176            val = (allow_layer3) ? "Layer III" :
     177                ((allow_layer1) ? "Layer I" : val);
     178        }
     179
     180        if ((val == "Layer III") && !allow_layer3)
     181        {
     182            val = (allow_layer2) ? "Layer II" :
     183                ((allow_layer1) ? "Layer I" : val);
     184        }
     185
     186        if (getValue() != val)
     187        {
     188            int which = getValueIndex(val);
     189            if (which >= 0)
     190                setValue(which);
     191        }
     192    }
     193
     194  private:
     195    bool allow_layer1;
     196    bool allow_layer2;
     197    bool allow_layer3;
    143198};
    144199
    145200class MPEG2audBitrateL1 : public ComboBoxSetting, public CodecParamStorage
     
    198253    };
    199254};
    200255
     256class MPEG2audBitrateL3 : public ComboBoxSetting, public CodecParamStorage
     257{
     258  public:
     259    MPEG2audBitrateL3(const RecordingProfile &parent) :
     260        ComboBoxSetting(this),
     261        CodecParamStorage(this, parent, "mpeg2audbitratel3")
     262    {
     263        setLabel(QObject::tr("Bitrate"));
     264
     265        addSelection("32 kbps", "32");
     266        addSelection("40 kbps", "40");
     267        addSelection("48 kbps", "48");
     268        addSelection("56 kbps", "56");
     269        addSelection("64 kbps", "64");
     270        addSelection("80 kbps", "80");
     271        addSelection("96 kbps", "96");
     272        addSelection("112 kbps", "112");
     273        addSelection("128 kbps", "128");
     274        addSelection("160 kbps", "160");
     275        addSelection("192 kbps", "192");
     276        addSelection("224 kbps", "224");
     277        addSelection("256 kbps", "256");
     278        addSelection("320 kbps", "320");
     279        setValue(10);
     280        setHelpText(QObject::tr("Sets the audio bitrate"));
     281    };
     282};
     283
    201284class MPEG2audVolume : public SliderSetting, public CodecParamStorage
    202285{
    203286  public:
     
    215298class MPEG2AudioBitrateSettings : public TriggeredConfigurationGroup
    216299{
    217300  public:
    218     MPEG2AudioBitrateSettings(const RecordingProfile &parent) :
     301    MPEG2AudioBitrateSettings(const RecordingProfile &parent,
     302                              bool layer1, bool layer2, bool layer3,
     303                              uint default_layer) :
    219304        TriggeredConfigurationGroup(false, true, true, true)
    220305    {
     306        const QString layers[3] = { "Layer I", "Layer II", "Layer III", };
     307
    221308        SetVertical(false);
    222309        setLabel(QObject::tr("Bitrate Settings"));
    223         MPEG2audType* audType = new MPEG2audType(parent);
     310
     311        MPEG2audType *audType = new MPEG2audType(
     312            parent, layer1, layer2, layer3);
     313
    224314        addChild(audType);
    225315        setTrigger(audType);
    226316
    227         ConfigurationGroup *audbr =
    228             new VerticalConfigurationGroup(false, true, true, true);
    229         audbr->addChild(new MPEG2audBitrateL1(parent));
    230         audbr->setLabel("Layer I");
    231         addTarget("Layer I", audbr);
    232         audType->addSelection("Layer I");
     317        addTarget(layers[0], new MPEG2audBitrateL1(parent));
     318        addTarget(layers[1], new MPEG2audBitrateL2(parent));
     319        addTarget(layers[2], new MPEG2audBitrateL3(parent));
    233320
    234         audbr = new VerticalConfigurationGroup(false, true, true, true);
    235         audbr->addChild(new MPEG2audBitrateL2(parent));
    236         audbr->setLabel("Layer II");
    237         addTarget("Layer II", audbr);
    238         audType->addSelection("Layer II");
    239         audType->setValue(1);
     321        uint desired_layer = max(min(3U, default_layer), 1U) - 1;
     322        int which = audType->getValueIndex(layers[desired_layer]);
     323        if (which >= 0)
     324            audType->setValue(which);
    240325    };
    241326};
    242327
     
    288373        params = new VerticalConfigurationGroup(false, false, true, true);
    289374        params->setLabel("MPEG-2 Hardware Encoder");
    290375        params->addChild(new SampleRate(parent, false));
    291         params->addChild(new MPEG2AudioBitrateSettings(parent));
     376        params->addChild(new MPEG2AudioBitrateSettings(
     377                             parent, false, true, false, 2));
    292378        params->addChild(new MPEG2Language(parent));
    293379        params->addChild(new MPEG2audVolume(parent));
    294380        addTarget("MPEG-2 Hardware Encoder", params);
     
    847933    class Width : public SpinBoxSetting, public CodecParamStorage
    848934    {
    849935      public:
    850         Width(const RecordingProfile &parent, int maxwidth = 704,
     936        Width(const RecordingProfile &parent,
     937              uint defaultwidth, uint maxwidth,
    851938              bool transcoding = false) :
    852939            SpinBoxSetting(this, transcoding ? 0 : 160,
    853940                           maxwidth, 16, false,
     
    855942            CodecParamStorage(this, parent, "width")
    856943        {
    857944            setLabel(QObject::tr("Width"));
    858             setValue(480);
    859             if (transcoding)
    860                 setHelpText(QObject::tr("If the width is set to 'Auto', "
    861                             "the width will be calculated based on the height "
    862                             "and the recording's physical aspect ratio."));
     945            setValue(defaultwidth);
     946
     947            QString help = (transcoding) ?
     948                QObject::tr("If the width is set to 'Auto', the width "
     949                            "will be calculated based on the height and "
     950                            "the recording's physical aspect ratio.") :
     951                QObject::tr("Width to use for encoding. "
     952                            "Note: PVR-150 and PVR-500 devices do not "
     953                            "function correctly unless this is set to 720.");
     954
     955            setHelpText(help);
    863956        };
    864957    };
    865958
    866959    class Height: public SpinBoxSetting, public CodecParamStorage
    867960    {
    868961      public:
    869         Height(const RecordingProfile &parent, int maxheight=576,
     962        Height(const RecordingProfile &parent,
     963               uint defaultheight, uint maxheight,
    870964               bool transcoding = false):
    871965            SpinBoxSetting(this, transcoding ? 0 : 160,
    872966                           maxheight, 16, false,
     
    874968            CodecParamStorage(this, parent, "height")
    875969        {
    876970            setLabel(QObject::tr("Height"));
    877             setValue(480);
    878             if (transcoding)
    879                 setHelpText(QObject::tr("If the height is set to 'Auto', "
    880                             "the height will be calculated based on the width "
    881                             "and the recording's physical aspect ratio."));
     971            setValue(defaultheight);
     972
     973            QString help = (transcoding) ?
     974                QObject::tr("If the height is set to 'Auto', the height "
     975                            "will be calculated based on the width and "
     976                            "the recording's physical aspect ratio.") :
     977                QObject::tr("Height to use for encoding. "
     978                            "Note: PVR-150 and PVR-500 devices do not "
     979                            "function correctly unless this is set to "
     980                            "480 or 576 for NTSC and PAL, respectively.");
     981
     982            setHelpText(help);
    882983        };
    883984    };
    884985
     
    894995            labelName = profName + "->" + QObject::tr("Image size");
    895996        setLabel(labelName);
    896997
    897         QString fullsize, halfsize;
    898         int maxwidth, maxheight;
    899         bool transcoding = false;
    900         if (profName.left(11) == "Transcoders") {
    901             maxwidth = 1920;
    902             maxheight = 1088;
    903             transcoding = true;
    904         } else if ((tvFormat.lower() == "ntsc") ||
    905                    (tvFormat.lower() == "ntsc-jp")) {
    906             maxwidth = 720;
    907             maxheight = 480;
    908         } else if (tvFormat.lower() == "atsc") {
    909             maxwidth = 1920;
    910             maxheight = 1088;
    911         } else {
    912             maxwidth = 768;
    913             maxheight = 576;
     998        QSize defaultsize(768, 576), maxsize(768, 576);
     999        bool transcoding = profName.left(11) == "Transcoders";
     1000        bool ivtv = profName.left(34) == "MPEG-2 Encoders (PVR-x50, PVR-500)";
     1001
     1002        if (transcoding)
     1003        {
     1004            maxsize     = QSize(1920, 1088);
     1005            defaultsize = QSize(480, 480);
    9141006        }
     1007        else if (tvFormat.lower().left(4) == "ntsc")
     1008        {
     1009            maxsize     = QSize(720, 480);
     1010            defaultsize = (ivtv) ? QSize(720, 480) : QSize(480, 480);
     1011        }
     1012        else if (tvFormat.lower() == "atsc")
     1013        {
     1014            maxsize     = QSize(1920, 1088);
     1015            defaultsize = QSize(1920, 1088);
     1016        }
     1017        else
     1018        {
     1019            maxsize     = QSize(768, 576);
     1020            defaultsize = (ivtv) ? QSize(720, 576) : QSize(480, 576);
     1021        }
    9151022
    916         imgSize->addChild(new Width(parent, maxwidth, transcoding));
    917         imgSize->addChild(new Height(parent, maxheight, transcoding));
     1023        imgSize->addChild(new Width(parent, defaultsize.width(),
     1024                                    maxsize.width(), transcoding));
     1025        imgSize->addChild(new Height(parent, defaultsize.height(),
     1026                                     maxsize.height(), transcoding));
     1027
    9181028        addChild(imgSize);
    9191029    };
    9201030};
     
    10011111{
    10021112    MSqlQuery result(MSqlQuery::InitCon());
    10031113    result.prepare(
    1004         "SELECT cardtype "
     1114        "SELECT cardtype, profilegroups.name "
    10051115        "FROM profilegroups, recordingprofiles "
    10061116        "WHERE profilegroups.id     = recordingprofiles.profilegroup AND "
    10071117        "      recordingprofiles.id = :PROFILEID");
     
    10131123    else if (result.next())
    10141124    {
    10151125        type = result.value(0).toString();
     1126        if (profileName.isEmpty())
     1127            profileName = result.value(1).toString();
    10161128        isEncoder = CardUtil::IsEncoder(type);
    10171129    }
    10181130