📄 av7110_av.c
字号:
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; unsigned long arg = (unsigned long) parg; int ret = 0; DEB_EE(("av7110: %p\n", av7110)); if ((file->f_flags & O_ACCMODE) == O_RDONLY) { if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT && cmd != VIDEO_GET_SIZE ) { return -EPERM; } } switch (cmd) { case VIDEO_STOP: av7110->videostate.play_state = VIDEO_STOPPED; if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) av7110_av_stop(av7110, RP_VIDEO); else vidcom(av7110, 0x000e, av7110->videostate.video_blank ? 0 : 1); av7110->trickmode = TRICK_NONE; break; case VIDEO_PLAY: av7110->trickmode = TRICK_NONE; if (av7110->videostate.play_state == VIDEO_FREEZED) { av7110->videostate.play_state = VIDEO_PLAYING; vidcom(av7110, 0x000d, 0); } if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { if (av7110->playing == RP_AV) { av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); av7110->playing &= ~RP_VIDEO; } av7110_av_start_play(av7110, RP_VIDEO); vidcom(av7110, 0x000d, 0); } else { //av7110_av_stop(av7110, RP_VIDEO); vidcom(av7110, 0x000d, 0); } av7110->videostate.play_state = VIDEO_PLAYING; break; case VIDEO_FREEZE: av7110->videostate.play_state = VIDEO_FREEZED; if (av7110->playing & RP_VIDEO) av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0); else vidcom(av7110, 0x0102, 1); av7110->trickmode = TRICK_FREEZE; break; case VIDEO_CONTINUE: if (av7110->playing & RP_VIDEO) av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0); vidcom(av7110, 0x000d, 0); av7110->videostate.play_state = VIDEO_PLAYING; av7110->trickmode = TRICK_NONE; break; case VIDEO_SELECT_SOURCE: av7110->videostate.stream_source = (video_stream_source_t) arg; break; case VIDEO_SET_BLANK: av7110->videostate.video_blank = (int) arg; break; case VIDEO_GET_STATUS: memcpy(parg, &av7110->videostate, sizeof(struct video_status)); break; case VIDEO_GET_EVENT: ret=dvb_video_get_event(av7110, parg, file->f_flags); break; case VIDEO_GET_SIZE: memcpy(parg, &av7110->video_size, sizeof(video_size_t)); break; case VIDEO_SET_DISPLAY_FORMAT: { video_displayformat_t format = (video_displayformat_t) arg; u16 val = 0; switch (format) { case VIDEO_PAN_SCAN: val = VID_PAN_SCAN_PREF; break; case VIDEO_LETTER_BOX: val = VID_VC_AND_PS_PREF; break; case VIDEO_CENTER_CUT_OUT: val = VID_CENTRE_CUT_PREF; break; default: ret = -EINVAL; } if (ret < 0) break; av7110->videostate.video_format = format; ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType, 1, (u16) val); break; } case VIDEO_SET_FORMAT: if (arg > 1) { ret = -EINVAL; break; } av7110->display_ar = arg; ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType, 1, (u16) arg); break; case VIDEO_STILLPICTURE: { struct video_still_picture *pic = (struct video_still_picture *) parg; av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY; dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); ret = play_iframe(av7110, pic->iFrame, pic->size, file->f_flags & O_NONBLOCK); break; } case VIDEO_FAST_FORWARD: //note: arg is ignored by firmware if (av7110->playing & RP_VIDEO) av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Scan_I, 2, AV_PES, 0); else vidcom(av7110, 0x16, arg); av7110->trickmode = TRICK_FAST; av7110->videostate.play_state = VIDEO_PLAYING; break; case VIDEO_SLOWMOTION: if (av7110->playing&RP_VIDEO) { av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); vidcom(av7110, 0x22, arg); } else { vidcom(av7110, 0x0d, 0); vidcom(av7110, 0x0e, 0); vidcom(av7110, 0x22, arg); } av7110->trickmode = TRICK_SLOW; av7110->videostate.play_state = VIDEO_PLAYING; break; case VIDEO_GET_CAPABILITIES: *(int *)parg = VIDEO_CAP_MPEG1 | VIDEO_CAP_MPEG2 | VIDEO_CAP_SYS | VIDEO_CAP_PROG; break; case VIDEO_CLEAR_BUFFER: dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); av7110_ipack_reset(&av7110->ipack[1]); if (av7110->playing == RP_AV) { av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); if (av7110->trickmode == TRICK_FAST) av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Scan_I, 2, AV_PES, 0); if (av7110->trickmode == TRICK_SLOW) { av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); vidcom(av7110, 0x22, arg); } if (av7110->trickmode == TRICK_FREEZE) vidcom(av7110, 0x000e, 1); } break; case VIDEO_SET_STREAMTYPE: break; default: ret = -ENOIOCTLCMD; break; } return ret;}static int dvb_audio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg){ struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; unsigned long arg = (unsigned long) parg; int ret = 0; DEB_EE(("av7110: %p\n", av7110)); if (((file->f_flags & O_ACCMODE) == O_RDONLY) && (cmd != AUDIO_GET_STATUS)) return -EPERM; switch (cmd) { case AUDIO_STOP: if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) av7110_av_stop(av7110, RP_AUDIO); else audcom(av7110, 1); av7110->audiostate.play_state = AUDIO_STOPPED; break; case AUDIO_PLAY: if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) av7110_av_start_play(av7110, RP_AUDIO); audcom(av7110, 2); av7110->audiostate.play_state = AUDIO_PLAYING; break; case AUDIO_PAUSE: audcom(av7110, 1); av7110->audiostate.play_state = AUDIO_PAUSED; break; case AUDIO_CONTINUE: if (av7110->audiostate.play_state == AUDIO_PAUSED) { av7110->audiostate.play_state = AUDIO_PLAYING; audcom(av7110, 0x12); } break; case AUDIO_SELECT_SOURCE: av7110->audiostate.stream_source = (audio_stream_source_t) arg; break; case AUDIO_SET_MUTE: { audcom(av7110, arg ? 1 : 2); av7110->audiostate.mute_state = (int) arg; break; } case AUDIO_SET_AV_SYNC: av7110->audiostate.AV_sync_state = (int) arg; audcom(av7110, arg ? 0x0f : 0x0e); break; case AUDIO_SET_BYPASS_MODE: ret = -EINVAL; break; case AUDIO_CHANNEL_SELECT: av7110->audiostate.channel_select = (audio_channel_select_t) arg; switch(av7110->audiostate.channel_select) { case AUDIO_STEREO: audcom(av7110, 0x80); break; case AUDIO_MONO_LEFT: audcom(av7110, 0x100); break; case AUDIO_MONO_RIGHT: audcom(av7110, 0x200); break; default: ret = -EINVAL; break; } break; case AUDIO_GET_STATUS: memcpy(parg, &av7110->audiostate, sizeof(struct audio_status)); break; case AUDIO_GET_CAPABILITIES: *(int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; break; case AUDIO_CLEAR_BUFFER: dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); av7110_ipack_reset(&av7110->ipack[0]); if (av7110->playing == RP_AV) av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); break; case AUDIO_SET_ID: break; case AUDIO_SET_MIXER: { struct audio_mixer *amix = (struct audio_mixer *)parg; av7110_set_volume(av7110, amix->volume_left, amix->volume_right); break; } case AUDIO_SET_STREAMTYPE: break; default: ret = -ENOIOCTLCMD; } return ret;}static int dvb_video_open(struct inode *inode, struct file *file){ struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; int err; DEB_EE(("av7110: %p\n", av7110)); if ((err = dvb_generic_open(inode, file)) < 0) return err; if ((file->f_flags & O_ACCMODE) != O_RDONLY) { dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); av7110->video_blank = 1; av7110->audiostate.AV_sync_state = 1; av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; /* empty event queue */ av7110->video_events.eventr = av7110->video_events.eventw = 0; } return 0;}static int dvb_video_release(struct inode *inode, struct file *file){ struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; DEB_EE(("av7110: %p\n", av7110)); if ((file->f_flags & O_ACCMODE) != O_RDONLY) { av7110_av_stop(av7110, RP_VIDEO); } return dvb_generic_release(inode, file);}static int dvb_audio_open(struct inode *inode, struct file *file){ struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; int err=dvb_generic_open(inode, file); DEB_EE(("av7110: %p\n", av7110)); if (err < 0) return err; dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX; return 0;}static int dvb_audio_release(struct inode *inode, struct file *file){ struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; DEB_EE(("av7110: %p\n", av7110)); av7110_av_stop(av7110, RP_AUDIO); return dvb_generic_release(inode, file);}/****************************************************************************** * driver registration ******************************************************************************/static struct file_operations dvb_video_fops = { .owner = THIS_MODULE, .write = dvb_video_write, .ioctl = dvb_generic_ioctl, .open = dvb_video_open, .release = dvb_video_release, .poll = dvb_video_poll,};static struct dvb_device dvbdev_video = { .priv = 0, .users = 6, .readers = 5, /* arbitrary */ .writers = 1, .fops = &dvb_video_fops, .kernel_ioctl = dvb_video_ioctl,};static struct file_operations dvb_audio_fops = { .owner = THIS_MODULE, .write = dvb_audio_write, .ioctl = dvb_generic_ioctl, .open = dvb_audio_open, .release = dvb_audio_release, .poll = dvb_audio_poll,};static struct dvb_device dvbdev_audio = { .priv = 0, .users = 1, .writers = 1, .fops = &dvb_audio_fops, .kernel_ioctl = dvb_audio_ioctl,};int av7110_av_register(struct av7110 *av7110){ av7110->audiostate.AV_sync_state = 0; av7110->audiostate.mute_state = 0; av7110->audiostate.play_state = AUDIO_STOPPED; av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX; av7110->audiostate.channel_select = AUDIO_STEREO; av7110->audiostate.bypass_mode = 0; av7110->videostate.video_blank = 0; av7110->videostate.play_state = VIDEO_STOPPED; av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; av7110->videostate.video_format = VIDEO_FORMAT_4_3; av7110->videostate.display_format = VIDEO_CENTER_CUT_OUT; av7110->display_ar = VIDEO_FORMAT_4_3; init_waitqueue_head(&av7110->video_events.wait_queue); spin_lock_init(&av7110->video_events.lock); av7110->video_events.eventw = av7110->video_events.eventr = 0; av7110->video_events.overflow = 0; memset(&av7110->video_size, 0, sizeof (video_size_t)); dvb_register_device(av7110->dvb_adapter, &av7110->video_dev, &dvbdev_video, av7110, DVB_DEVICE_VIDEO); dvb_register_device(av7110->dvb_adapter, &av7110->audio_dev, &dvbdev_audio, av7110, DVB_DEVICE_AUDIO); return 0;}void av7110_av_unregister(struct av7110 *av7110){ dvb_unregister_device(av7110->audio_dev); dvb_unregister_device(av7110->video_dev);}int av7110_av_init(struct av7110 *av7110){ av7110->vidmode = VIDEO_MODE_PAL; av7110_ipack_init(&av7110->ipack[0], IPACKS, play_audio_cb); av7110->ipack[0].data = (void *) av7110; av7110_ipack_init(&av7110->ipack[1], IPACKS, play_video_cb); av7110->ipack[1].data = (void *) av7110; dvb_ringbuffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN); dvb_ringbuffer_init(&av7110->aout, av7110->iobuf + AVOUTLEN, AOUTLEN); av7110->kbuf[0] = (u8 *)(av7110->iobuf + AVOUTLEN + AOUTLEN + BMPLEN); av7110->kbuf[1] = av7110->kbuf[0] + 2 * IPACKS; return 0;}int av7110_av_exit(struct av7110 *av7110){ av7110_ipack_free(&av7110->ipack[0]); av7110_ipack_free(&av7110->ipack[1]); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -