📄 av7110_av.c
字号:
av7110->videostate.video_blank ? 0 : 1); if (!ret) 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; ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); if (ret) break; } if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { if (av7110->playing == RP_AV) { ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); if (ret) break; av7110->playing &= ~RP_VIDEO; } ret = av7110_av_start_play(av7110, RP_VIDEO); } if (!ret) ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); if (!ret) av7110->videostate.play_state = VIDEO_PLAYING; break; case VIDEO_FREEZE: av7110->videostate.play_state = VIDEO_FREEZED; if (av7110->playing & RP_VIDEO) ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0); else ret = vidcom(av7110, VIDEO_CMD_FREEZE, 1); if (!ret) av7110->trickmode = TRICK_FREEZE; break; case VIDEO_CONTINUE: if (av7110->playing & RP_VIDEO) ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0); if (!ret) ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); if (!ret) { 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.display_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) ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Scan_I, 2, AV_PES, 0); else ret = vidcom(av7110, VIDEO_CMD_FFWD, arg); if (!ret) { av7110->trickmode = TRICK_FAST; av7110->videostate.play_state = VIDEO_PLAYING; } break; case VIDEO_SLOWMOTION: if (av7110->playing&RP_VIDEO) { ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); if (!ret) ret = vidcom(av7110, VIDEO_CMD_SLOW, arg); } else { ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); if (!ret) ret = vidcom(av7110, VIDEO_CMD_STOP, 0); if (!ret) ret = vidcom(av7110, VIDEO_CMD_SLOW, arg); } if (!ret) { 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) { ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); if (ret) break; if (av7110->trickmode == TRICK_FAST) ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Scan_I, 2, AV_PES, 0); if (av7110->trickmode == TRICK_SLOW) { ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); if (!ret) ret = vidcom(av7110, VIDEO_CMD_SLOW, arg); } if (av7110->trickmode == TRICK_FREEZE) ret = vidcom(av7110, VIDEO_CMD_STOP, 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; dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd); 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) ret = av7110_av_stop(av7110, RP_AUDIO); else ret = audcom(av7110, AUDIO_CMD_MUTE); if (!ret) av7110->audiostate.play_state = AUDIO_STOPPED; break; case AUDIO_PLAY: if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) ret = av7110_av_start_play(av7110, RP_AUDIO); if (!ret) ret = audcom(av7110, AUDIO_CMD_UNMUTE); if (!ret) av7110->audiostate.play_state = AUDIO_PLAYING; break; case AUDIO_PAUSE: ret = audcom(av7110, AUDIO_CMD_MUTE); if (!ret) av7110->audiostate.play_state = AUDIO_PAUSED; break; case AUDIO_CONTINUE: if (av7110->audiostate.play_state == AUDIO_PAUSED) { av7110->audiostate.play_state = AUDIO_PLAYING; ret = audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16); } break; case AUDIO_SELECT_SOURCE: av7110->audiostate.stream_source = (audio_stream_source_t) arg; break; case AUDIO_SET_MUTE: { ret = audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE); if (!ret) av7110->audiostate.mute_state = (int) arg; break; } case AUDIO_SET_AV_SYNC: av7110->audiostate.AV_sync_state = (int) arg; ret = audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF); 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: ret = audcom(av7110, AUDIO_CMD_STEREO); if (!ret) if (av7110->adac_type == DVB_ADAC_CRYSTAL) i2c_writereg(av7110, 0x20, 0x02, 0x49); break; case AUDIO_MONO_LEFT: ret = audcom(av7110, AUDIO_CMD_MONO_L); if (!ret) if (av7110->adac_type == DVB_ADAC_CRYSTAL) i2c_writereg(av7110, 0x20, 0x02, 0x4a); break; case AUDIO_MONO_RIGHT: ret = audcom(av7110, AUDIO_CMD_MONO_R); if (!ret) if (av7110->adac_type == DVB_ADAC_CRYSTAL) i2c_writereg(av7110, 0x20, 0x02, 0x45); 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) ret = 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; ret = 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; dprintk(2, "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; dprintk(2, "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); dprintk(2, "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; dprintk(2, "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 = NULL, .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 = NULL, .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){ void (*play[])(u8 *, int, void *) = { play_audio_cb, play_video_cb }; int i, ret; av7110->vidmode = VIDEO_MODE_PAL; for (i = 0; i < 2; i++) { struct ipack *ipack = av7110->ipack + i; ret = av7110_ipack_init(ipack, IPACKS, play[i]); if (ret < 0) { if (i) av7110_ipack_free(--ipack); goto out; } ipack->data = 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;out: return ret;}void av7110_av_exit(struct av7110 *av7110){ av7110_ipack_free(&av7110->ipack[0]); av7110_ipack_free(&av7110->ipack[1]);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -