Changeset 3872

Show
Ignore:
Timestamp:
02/26/07 14:54:29 (2 years ago)
Author:
hverkuil
Message:

Update to new V4L2 API.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • ivtvtv/trunk/ivtv.h

    r3714 r3872  
    2424#define _LINUX_IVTV_H 
    2525 
    26 #ifndef __KERNEL__ 
    27 #define __user 
    28 #endif 
     26/* ivtv knows several distinct output modes: MPEG streaming, 
     27   YUV streaming, YUV updates through user DMA and the passthrough 
     28   mode. 
    2929 
    30 /* NOTE: the ioctls in this file will eventually be replaced by v4l2 API 
    31    ioctls. */ 
     30   In order to clearly tell the driver that we are in user DMA 
     31   YUV mode you need to call IVTV_IOC_DMA_FRAME with y_source == NULL 
     32   first (althrough if you don't then the first time 
     33   DMA_FRAME is called the mode switch is done automatically). 
    3234 
    33 /* device ioctls should use the range 29-199 */ 
    34 #define IVTV_IOC_START_DECODE      _IOW ('@', 29, struct ivtv_cfg_start_decode) 
    35 #define IVTV_IOC_STOP_DECODE       _IOW ('@', 30, struct ivtv_cfg_stop_decode) 
    36 #define IVTV_IOC_G_SPEED           _IOR ('@', 31, struct ivtv_speed) 
    37 #define IVTV_IOC_S_SPEED           _IOW ('@', 32, struct ivtv_speed) 
    38 #define IVTV_IOC_DEC_STEP          _IOW ('@', 33, int) 
    39 #define IVTV_IOC_DEC_FLUSH         _IOW ('@', 34, int) 
    40 #define IVTV_IOC_PAUSE_BLACK       _IO  ('@', 35) 
    41 #define IVTV_IOC_STOP              _IO  ('@', 36) 
    42 #define IVTV_IOC_PLAY              _IO  ('@', 37) 
    43 #define IVTV_IOC_PAUSE             _IO  ('@', 38) 
    44 #define IVTV_IOC_FRAMESYNC         _IOR ('@', 39, struct ivtv_ioctl_framesync) 
    45 #define IVTV_IOC_GET_TIMING        _IOR ('@', 40, struct ivtv_ioctl_framesync) 
    46 #define IVTV_IOC_S_SLOW_FAST       _IOW ('@', 41, struct ivtv_slow_fast) 
    47 #define IVTV_IOC_GET_FB            _IOR ('@', 44, int) 
    48 #define IVTV_IOC_S_GOP_END         _IOWR('@', 50, int) 
    49 #define IVTV_IOC_S_VBI_PASSTHROUGH _IOW ('@', 51, int) 
    50 #define IVTV_IOC_G_VBI_PASSTHROUGH _IOR ('@', 52, int) 
    51 #define IVTV_IOC_PASSTHROUGH       _IOW ('@', 53, int) 
    52 #define IVTV_IOC_PAUSE_ENCODE      _IO  ('@', 56) 
    53 #define IVTV_IOC_RESUME_ENCODE     _IO  ('@', 57) 
    54 #define IVTV_IOC_DEC_FAST_STOP     _IOW ('@', 59, int)  /* Obsolete: use IVTV_IOC_STOP_DECODE */ 
    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) 
     35   When you close the file handle the user DMA mode is exited again. 
    5936 
    60 struct ivtv_ioctl_framesync { 
    61         __u32 frame; 
    62         __u64 pts; 
    63         __u64 scr; 
     37   While in one mode, you cannot use another mode (EBUSY is returned). 
     38 
     39   All this means that if you want to change the YUV interlacing 
     40   for the user DMA YUV mode you first need to do call IVTV_IOC_DMA_FRAME 
     41   with y_source == NULL before you can set the correct format using 
     42   VIDIOC_S_FMT. 
     43 
     44   Eventually all this should be replaced with a proper V4L2 API, 
     45   but for now we have to do it this way. */ 
     46 
     47struct ivtv_dma_frame { 
     48        enum v4l2_buf_type type; /* V4L2_BUF_TYPE_VIDEO_OUTPUT */ 
     49        __u32 pixelformat;       /* 0 == same as destination */ 
     50        void __user *y_source;   /* if NULL and type == V4L2_BUF_TYPE_VIDEO_OUTPUT, 
     51                                    then just switch to user DMA YUV output mode */ 
     52        void __user *uv_source;  /* Unused for RGB pixelformats */ 
     53        struct v4l2_rect src; 
     54        struct v4l2_rect dst; 
     55        __u32 src_width; 
     56        __u32 src_height; 
    6457}; 
    6558 
    66 struct ivtv_speed { 
    67         int scale;              /* 1-?? (50 for now) */ 
    68         int smooth;             /* Smooth mode when in slow/fast mode */ 
    69         int speed;              /* 0 = slow, 1 = fast */ 
    70         int direction;          /* 0 = forward, 1 = reverse (not supportd */ 
    71         int fr_mask;            /* 0 = I, 1 = I,P, 2 = I,P,B    2 = default! */ 
    72         int b_per_gop;          /* frames per GOP (reverse only) */ 
    73         int aud_mute;           /* Mute audio while in slow/fast mode */ 
    74         int fr_field;           /* 1 = show every field, 0 = show every frame */ 
    75         int mute;               /* # of audio frames to mute on playback resume (unused, does not work) */ 
    76 }; 
     59#define IVTV_IOC_DMA_FRAME  _IOW ('V', BASE_VIDIOC_PRIVATE+0, struct ivtv_dma_frame) 
    7760 
    78 struct ivtv_slow_fast { 
    79         int speed;              /* 0 = slow, 1 = fast */ 
    80         int scale;              /* 1-?? (50 for now) */ 
    81 }; 
    82  
    83 struct ivtv_cfg_start_decode { 
    84         __u32 gop_offset;       /*Frames in GOP to skip before starting */ 
    85         __u32 muted_audio_frames;       /* #of audio frames to mute (unused, does not work) */ 
    86 }; 
    87  
    88 struct ivtv_cfg_stop_decode { 
    89         int flags;              /* bit 0: 1 = hide last frame (go to black frame) after stop, 
    90                                           0 = show last frame 
    91                                    bit 1: 1 = wait until PTS is reached or 
    92                                               until all pending buffers are processed 
    93                                           0 = stop immediately 
    94                                  */ 
    95         __u64 pts;              /* PTS to stop at. Implies IVTV_STOP_FL_WAIT_FOR_END if non-zero. */ 
    96 }; 
    97 #define IVTV_STOP_FL_HIDE_FRAME    (1 << 0) 
    98 #define IVTV_STOP_FL_WAIT_FOR_END  (1 << 1) 
    99  
    100 struct ivtv_ioctl_yuv_interlace{ 
    101         int interlace_mode; /* Takes one of IVTV_YUV_MODE_xxxxxx values */ 
    102         int threshold; /* If mode is auto then if src_height <= this value treat as progressive otherwise treat as interlaced */ 
    103 }; 
    104  
    105 #define IVTV_YUV_MODE_INTERLACED        0x00 
    106 #define IVTV_YUV_MODE_PROGRESSIVE       0x01 
    107 #define IVTV_YUV_MODE_AUTO              0x02 
    108 #define IVTV_YUV_MODE_MASK              0x03 
    109  
    110 #define IVTV_YUV_SYNC_EVEN              0x00 
    111 #define IVTV_YUV_SYNC_ODD               0x04 
    112 #define IVTV_YUV_SYNC_MASK              0x04 
    113  
    114 /* Framebuffer external API */ 
    115  
    116 struct ivtvfb_ioctl_state_info { 
    117         unsigned long status; 
    118         unsigned long alpha; 
    119 }; 
    120  
    121 struct ivtvfb_ioctl_colorkey { 
    122     int state; 
    123     __u32 colorKey; 
    124 }; 
    125  
    126 struct ivtvfb_ioctl_dma_host_to_ivtv_args { 
    127         void __user *source; 
    128         unsigned long dest_offset; 
    129         int count; 
    130 }; 
    131  
    132 struct ivtvyuv_ioctl_dma_host_to_ivtv_args { 
    133         void *y_source; 
    134         void *uv_source; 
    135         unsigned int yuv_type; 
    136         int src_x; 
    137         int src_y; 
    138         unsigned int src_w; 
    139         unsigned int src_h; 
    140         int dst_x; 
    141         int dst_y; 
    142         unsigned int dst_w; 
    143         unsigned int dst_h; 
    144         int srcBuf_width; 
    145         int srcBuf_height; 
    146 }; 
    147  
    148 struct ivtvfb_ioctl_get_frame_buffer { 
    149         void *mem; 
    150         int size; 
    151         int sizex; 
    152         int sizey; 
    153 }; 
    154  
    155 struct ivtv_osd_coords { 
    156         unsigned long offset; 
    157         unsigned long max_offset; 
    158         int pixel_stride; 
    159         int lines; 
    160         int x; 
    161         int y; 
    162 }; 
    163  
    164 struct ivtvfb_ioctl_set_window { 
    165         int width; 
    166         int height; 
    167         int left; 
    168         int top; 
    169 }; 
    170  
    171 struct ivtvfb_alpha { 
    172         int   global_alpha_state; // 0=off : 1=on 
    173         int   local_alpha_state;  // 0=off : 1=on 
    174         int   color_key_state;    // 0=off : 1=on 
    175         __u32 global_alpha;       // Current global alpha 
    176         __u32 color_key;          // Current color key 
    177 }; 
    178  
    179 /* Framebuffer ioctls should use the range 1 - 28 */ 
    180 #define IVTVFB_IOCTL_GET_STATE          _IOR('@', 1, struct ivtvfb_ioctl_state_info) 
    181 #define IVTVFB_IOCTL_SET_STATE          _IOW('@', 2, struct ivtvfb_ioctl_state_info) 
    182 #define IVTVFB_IOCTL_PREP_FRAME         _IOW('@', 3, struct ivtvfb_ioctl_dma_host_to_ivtv_args) 
    183 #define IVTVFB_IOCTL_GET_ACTIVE_BUFFER  _IOR('@', 5, struct ivtv_osd_coords) 
    184 #define IVTVFB_IOCTL_SET_ACTIVE_BUFFER  _IOW('@', 6, struct ivtv_osd_coords) 
    185 #define IVTVFB_IOCTL_GET_FRAME_BUFFER   _IOR('@', 7, struct ivtvfb_ioctl_get_frame_buffer) 
    186 #define IVTVFB_IOCTL_SET_WINDOW         _IOW('@', 11, struct ivtvfb_ioctl_set_window) 
    187 #define IVTVFB_IOCTL_GET_COLORKEY       _IOW('@', 12, struct ivtvfb_ioctl_colorkey) 
    188 #define IVTVFB_IOCTL_SET_COLORKEY       _IOW('@', 13, struct ivtvfb_ioctl_colorkey) 
    189  
    190 #define IVTVFB_STATUS_ENABLED           (1 << 0) 
    191 #define IVTVFB_STATUS_GLOBAL_ALPHA      (1 << 1) 
    192 #define IVTVFB_STATUS_LOCAL_ALPHA       (1 << 2) 
    193 #define IVTVFB_STATUS_FLICKER_REDUCTION (1 << 3) 
    194  
    195 #ifdef IVTV_INTERNAL 
    196 /* Do not use these structures and ioctls in code that you want to release. 
    197    Only to be used for testing and by the utilities ivtvctl, ivtvfbctl and fwapi. */ 
    198  
    199 /* These are the VBI types as they appear in the embedded VBI private packets. 
    200    It is very likely that this will disappear and be replaced by the DVB standard. */ 
     61/* These are the VBI types as they appear in the embedded VBI private packets. */ 
    20162#define IVTV_SLICED_TYPE_TELETEXT_B     (1) 
    20263#define IVTV_SLICED_TYPE_CAPTION_525    (4) 
     
    20465#define IVTV_SLICED_TYPE_VPS            (7) 
    20566 
    206 #define IVTVFB_IOCTL_GET_ALPHA  _IOR('@', 14, struct ivtvfb_alpha) 
    207 #define IVTVFB_IOCTL_SET_ALPHA  _IOW('@', 15, struct ivtvfb_alpha) 
    208 #define IVTV_IOC_G_INDEX        _IOR('@', 64, struct ivtv_index) 
    209 #define IVTV_IOC_S_AUDMODE      _IOW('@', 65, struct ivtv_audmode) 
    210  
    211 struct ivtv_audmode { 
    212         __u32 dual; 
    213         __u32 stereo; 
    214 }; 
    215 #define IVTV_AUDMODE_STEREO 0 
    216 #define IVTV_AUDMODE_LEFT   1 
    217 #define IVTV_AUDMODE_RIGHT  2 
    218 #define IVTV_AUDMODE_MONO   3 
    219 #define IVTV_AUDMODE_SWAP   4 
    220 #define IVTV_AUDMODE_UNCHANGED -1 
    221  
    222 #define IVTV_IDX_FL_P 0 
    223 #define IVTV_IDX_FL_I 1 
    224 #define IVTV_IDX_FL_B 2 
    225  
    226 struct ivtv_index_entry { 
    227         __u64 offset; 
    228         __u64 pts; 
    229         __u32 length; 
    230         __u32 flags; 
    231 }; 
    232  
    233 #define IVTV_INDEX_MAX_ENTRIES (64) 
    234 struct ivtv_index { 
    235         __u32 entries; 
    236         struct ivtv_index_entry entry[IVTV_INDEX_MAX_ENTRIES]; 
    237 }; 
    238  
    239 /* Debug flags */ 
    240 #define IVTV_DBGFLG_WARN  (1 << 0) 
    241 #define IVTV_DBGFLG_INFO  (1 << 1) 
    242 #define IVTV_DBGFLG_API   (1 << 2) 
    243 #define IVTV_DBGFLG_DMA   (1 << 3) 
    244 #define IVTV_DBGFLG_IOCTL (1 << 4) 
    245 #define IVTV_DBGFLG_I2C   (1 << 5) 
    246 #define IVTV_DBGFLG_IRQ   (1 << 6) 
    247 #define IVTV_DBGFLG_DEC   (1 << 7) 
    248 #define IVTV_DBGFLG_YUV   (1 << 8) 
    249  
    250 #endif /* IVTV_INTERNAL */ 
    251  
    25267#endif /* _LINUX_IVTV_H */ 
  • ivtvtv/trunk/ivtvtv.cpp

    r3870 r3872  
    77#include <errno.h> 
    88 
    9 #include <linux/videodev2.h> 
     9#include "videodev2.h" 
     10#include "video.h" 
    1011#include "ivtv.h" 
    1112} 
     
    1415 
    1516int g_skip = 0; 
    16 int g_spd = 0; 
    1717int idx = 0; 
    1818 
    1919static unsigned int osd[576][720]; 
    2020 
    21 #if 0 
    22 struct ivtv_speed { 
    23         int scale;              /* 1-?? (50 for now) */ 
    24         int smooth;             /* Smooth mode when in slow/fast mode */ 
    25         int speed;              /* 0 = slow, 1 = fast */ 
    26         int direction;          /* 0 = forward, 1 = reverse (not supportd */ 
    27         int fr_mask;            /* 0 = I, 1 = I,P, 2 = I,P,B    2 = default! */ 
    28         int b_per_gop;          /* frames per GOP (reverse only) */ 
    29         int aud_mute;           /* Mute audio while in slow/fast mode */ 
    30         int fr_field;           /* 1 = show every field, 0 = show every frame */ 
    31         int mute;               /* # of audio frames to mute on playback resume */ 
    32 }; 
    33 #endif 
    34  
    35 static int __ivtv_api_dec_speed(int ivtvfd, int scale, int smooth, 
    36                                        int _speed, int direction, int fr_mask, 
    37                                        int b_per_gop, int aud_mute, 
    38                                        int fr_field, int mute) 
    39 
    40         struct ivtv_speed speed; 
    41  
    42         speed.scale = scale; 
    43         speed.smooth = smooth; 
    44         speed.speed = _speed; 
    45         speed.direction = direction; 
    46         speed.fr_mask = fr_mask; 
    47         speed.b_per_gop = b_per_gop; 
    48         speed.aud_mute = aud_mute; 
    49         speed.fr_field = fr_field; 
    50         speed.mute = mute; 
    51  
    52         printf("dir %d speed %d  smooth %d fast %d b %d\n", 
    53                         direction, scale, smooth, _speed, b_per_gop); 
    54         if (ioctl(ivtvfd, IVTV_IOC_S_SPEED, &speed) < 0) 
    55                 fprintf(stderr, "ioctl: IVTV_IOC_S_SPEED failed\n"); 
    56         return 0; 
    57 
    58  
    59 static int get_control(int fh, int id) 
    60 
    61         struct v4l2_ext_control ctrl; 
    62         struct v4l2_ext_controls ctrls; 
    63  
    64         memset(&ctrl, 0, sizeof(ctrl)); 
    65         memset(&ctrls, 0, sizeof(ctrls)); 
    66         ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(id); 
    67         ctrls.count = 1; 
    68         ctrls.controls = &ctrl; 
    69         ctrl.id = id; 
    70         ioctl(fh, VIDIOC_G_EXT_CTRLS, &ctrls); 
    71         return ctrl.value; 
    72 
    73  
    74 #define FORWARD 0 
    75 #define REVERSE 1 
    76  
    77 #define NORMAL_SPEED 25 
    78 static int ivtv_api_dec_speed(int ivtvfd, int direction, int speed) 
    79 
    80         int b_per_gop = get_control(ivtvfd, V4L2_CID_MPEG_VIDEO_B_FRAMES); 
    81         int aud_mute = 0; 
    82         int fr_field = 0; 
    83         int mute = 3; 
    84  
    85         int i_frames = 0; 
    86         int ip_frames = 1; 
    87         int ipb_frames = 2; 
    88  
    89         if (speed > 2) 
    90                 speed = 2; 
    91  
    92         /* Make input sane */ 
    93         if (direction > 1) 
    94                 direction = 1; 
    95         else if (direction < 0) 
    96                 direction = 0; 
    97  
    98         if (direction == 0) {   /* Forward */ 
    99                 if (speed < 0) { 
    100                         __ivtv_api_dec_speed(ivtvfd, 
    101                                              -speed+1, 0, 0, direction, 
    102                                              ipb_frames, 0, aud_mute, fr_field, mute); 
    103                 } else if (speed == 0) { 
    104                         __ivtv_api_dec_speed(ivtvfd, 
    105                                              0, 0, 0, direction, ipb_frames, 0, 
    106                                              aud_mute, fr_field, mute); 
    107                 } else if (speed == 1) { 
    108                         __ivtv_api_dec_speed(ivtvfd, 
    109                                              speed, 1, 1, direction, 
    110                                              ipb_frames, 0, aud_mute, fr_field, mute); 
    111                 } else if (speed == 2) { 
    112                         __ivtv_api_dec_speed(ivtvfd, 
    113                                              speed, 1, 1, direction, 
    114                                              ipb_frames, 0, aud_mute, fr_field, mute); 
    115                 } else { 
    116                         __ivtv_api_dec_speed(ivtvfd, 
    117                                              0, 0, 0, direction, ipb_frames, 0, 
    118                                              aud_mute, 0, mute); 
    119                 } 
    120         } else {                /* Reverse */ 
    121                 if (speed < 0) { 
    122                         __ivtv_api_dec_speed(ivtvfd, 
    123                                              -speed+1, 0, 0, direction, ip_frames, 
    124                                              b_per_gop, aud_mute, fr_field, mute); 
    125                 } else if (speed == 0) { 
    126                         __ivtv_api_dec_speed(ivtvfd, 
    127                                              0, 0, 0, direction, ip_frames, 
    128                                              b_per_gop, aud_mute, fr_field, mute); 
    129                 } else if (speed == 1) {        /* 1.5x */ 
    130                         __ivtv_api_dec_speed(ivtvfd, 
    131                                              speed, 0, 1, direction, ip_frames, 
    132                                              b_per_gop, aud_mute, fr_field, mute); 
    133                 } else if (speed == 2) { 
    134                         __ivtv_api_dec_speed(ivtvfd, 
    135                                              speed, 1, 1, direction, ip_frames, 
    136                                              b_per_gop, aud_mute, fr_field, mute); 
    137                 } else { 
    138                         __ivtv_api_dec_speed(ivtvfd, 
    139                                              2, 0, 1, direction, i_frames, 
    140                                              b_per_gop, aud_mute, 0, mute); 
    141                 } 
    142         } 
    143         return 0; 
    144 
    145  
    146 static int dir = 0; 
    147  
    148 void speed(int fh, int delta) 
    149 
    150         g_spd += delta; 
    151         printf("dir = %d spd = %d\n", dir, g_spd); 
    152         ivtv_api_dec_speed(fh, dir, g_spd); 
    153 
     21static int speed = 1000; 
    15422 
    15523void process(int fh, int ch) 
    15624{ 
    157         struct ivtv_cfg_start_decode start = { 0, 0 }
    158         struct ivtv_cfg_stop_decode stop; 
    159         int step = 0
     25        struct video_command cmd
     26 
     27        memset(&cmd, 0, sizeof(cmd))
    16028 
    16129        switch (ch) { 
    16230        case 'p': 
    163                 ioctl(fh, IVTV_IOC_PAUSE, 0); 
     31                cmd.cmd = VIDEO_CMD_FREEZE; 
     32                ioctl(fh, VIDEO_COMMAND, &cmd); 
    16433                break; 
    16534        case 'P': 
    166                 ioctl(fh, IVTV_IOC_PAUSE_BLACK, 0); 
     35                cmd.cmd = VIDEO_CMD_FREEZE; 
     36                cmd.flags = VIDEO_CMD_FREEZE_TO_BLACK; 
     37                ioctl(fh, VIDEO_COMMAND, &cmd); 
    16738                break; 
    16839        case 's': 
    169                 ioctl(fh, IVTV_IOC_DEC_STEP, &step); 
     40                cmd.cmd = VIDEO_CMD_PLAY; 
     41                cmd.play.speed = speed < 0 ? -1 : 1; 
     42                ioctl(fh, VIDEO_COMMAND, &cmd); 
     43                speed = cmd.play.speed; 
    17044                break; 
    17145        case 'r': 
    172                 dir = 0; 
    173                 speed(fh, 0); 
    174 //              ioctl(fh, IVTV_IOC_PLAY, 0); 
     46                cmd.cmd = VIDEO_CMD_PLAY; 
     47                cmd.play.speed = 1000; 
     48                ioctl(fh, VIDEO_COMMAND, &cmd); 
     49                speed = cmd.play.speed; 
    17550                break; 
    17651        case 'd': 
    177                 dir = !dir; 
    178                 stop.flags = 0; 
    179                 stop.pts = 0; 
    180                 ioctl(fh, IVTV_IOC_STOP_DECODE, &stop); 
    181                 start.gop_offset = 0; 
    182                 start.muted_audio_frames = 1; 
    183                 ioctl(fh, IVTV_IOC_START_DECODE, &start); 
    184                 speed(fh, 0); 
    185                 if (dir) idx -= g_skip; 
     52                cmd.cmd = VIDEO_CMD_STOP; 
     53                cmd.flags = VIDEO_CMD_STOP_IMMEDIATELY; 
     54                ioctl(fh, VIDEO_COMMAND, &cmd); 
     55                cmd.cmd = VIDEO_CMD_PLAY; 
     56                cmd.play.speed = -speed; 
     57                ioctl(fh, VIDEO_COMMAND, &cmd); 
     58                speed = cmd.play.speed; 
     59                if (speed < 0) idx -= g_skip; 
    18660                else idx += g_skip; 
    18761                if (idx < 0) idx = 0; 
    18862                break; 
    189         case 'f': 
    190                 stop.flags = 0; 
    191                 stop.pts = 0; 
    192                 ioctl(fh, IVTV_IOC_STOP_DECODE, &stop); 
    193                 static int fr = 0; 
    194                 start.gop_offset = fr; 
    195                 start.muted_audio_frames = fr++; 
    196                 ioctl(fh, IVTV_IOC_START_DECODE, &start); 
    197                 break; 
    198         case '0': 
    199                 speed(fh, 0); 
    200                 break; 
    20163        case '-': 
    20264        case '_': 
    203                 dir = 0; 
    204                 speed(fh, -1); 
     65                if (speed > 2000) 
     66                        speed -= 1000; 
     67                else if (speed < -2000) 
     68                        speed += 1000; 
     69                else 
     70                        speed = speed + (speed < 0 ? 1 : -1); 
     71                if (speed >= -2000 && speed <= 2000) { 
     72                        cmd.cmd = VIDEO_CMD_PLAY; 
     73                        cmd.play.speed = speed; 
     74                        ioctl(fh, VIDEO_COMMAND, &cmd); 
     75                        speed = cmd.play.speed; 
     76                } 
    20577                break;  
    20678        case '=': 
    20779        case '+': 
    208                 dir = 0; 
    209                 speed(fh, 1); 
    210                 break; 
    211         case '1': 
    212                 dir = 1; 
    213                 speed(fh, -1); 
    214                 break; 
    215         case '2': 
    216                 dir = 1; 
    217                 speed(fh, 1); 
    218                 break; 
    219         } 
     80                if (speed >= 2000) 
     81                        speed += 1000; 
     82                else if (speed <= -2000) 
     83                        speed -= 1000; 
     84                else  
     85                        speed = speed + (speed < 0 ? -1 : 1); 
     86                if (speed >= -2000 && speed <= 2000) { 
     87                        cmd.cmd = VIDEO_CMD_PLAY; 
     88                        cmd.play.speed = speed; 
     89                        ioctl(fh, VIDEO_COMMAND, &cmd); 
     90                        speed = cmd.play.speed; 
     91                } 
     92                break; 
     93        } 
     94        printf("speed = %d\n", speed); 
    22095} 
    22196 
     
    311186        if (argc >= 4) { 
    312187                idx = atoi(argv[3]); 
    313                 dir = 1
    314                 speed(fout, 0); 
     188                speed = -1000
     189                //speed(fout, 0); 
    315190        } 
    316191        if (idx >= max_idx) idx = max_idx - 1; 
     
    343218                        int i = idx; 
    344219 
    345                         if (dir) { 
     220                        if (speed < 0) { 
    346221                                if (idx < 0) { 
    347222                                        eof = true; 
    348223                                        break; 
    349224                                } 
    350                                 idx -= g_spd > 2 ? g_spd-1 : 1; 
     225                                idx -= speed > 2000 ? (speed / 1000)-1 : 1; 
    351226                        } 
    352227                        else { 
     
    355230                                        break; 
    356231                                } 
    357                                 idx += g_spd > 2 ? g_spd-1 : 1; 
     232                                idx += (speed > 2000) ? (speed/1000)-1 : 1; 
    358233                        } 
    359234                        lseek64(fin, indices[i].offset, SEEK_SET); 
    360235                        bufsz = indices[i + 1].offset - indices[i].offset; 
    361236                        sz = read(fin, buf, bufsz); 
    362                         struct ivtv_ioctl_framesync info; 
    363                         ioctl(fout, IVTV_IOC_GET_TIMING, &info); 
    364                         printf("frame %d %lld %d\n", info.frame, info.pts, i); 
     237                        unsigned long long pts = 0, frame = 0; 
     238                        ioctl(fout, VIDEO_GET_PTS, &pts); 
     239                        ioctl(fout, VIDEO_GET_FRAME_COUNT, &frame); 
     240                        printf("frame %lld %lld %d\n", frame, pts, i); 
    365241                        cnt++; 
    366242                        t2 = time(NULL); 
     
    370246                                t1 = t2; 
    371247                        } 
    372                         if (info.frame && first) { 
     248                        if (frame && first) { 
    373249                                first = 0; 
    374250                                g_skip = 7; 
     
    393269        } 
    394270        printf("wait for end\n"); 
    395         struct ivtv_cfg_stop_decode stop; 
    396         stop.flags = IVTV_STOP_FL_HIDE_FRAME|IVTV_STOP_FL_WAIT_FOR_END; 
    397         stop.pts = 0; 
    398         ioctl(fout, IVTV_IOC_STOP_DECODE, &stop); 
    399         printf("%d\n", g_spd); 
     271        struct video_command cmd; 
     272        memset(&cmd, 0, sizeof(cmd)); 
     273        cmd.cmd = VIDEO_CMD_STOP; 
     274        cmd.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY; 
     275        ioctl(fout, VIDEO_COMMAND, &cmd); 
     276        printf("%d\n", speed); 
    400277        return 0; 
    401278}