📄 cvdv.c
字号:
switch (cmd) { case AUDIO_STOP: if (card->audiostate.stream_source!=AUDIO_SOURCE_MEMORY) break; AudioStopDecode(card); card->audiostate.play_state=AUDIO_STOPPED; break; case AUDIO_PLAY: if (card->audiostate.stream_source!=AUDIO_SOURCE_MEMORY) break; AudioSetPlayMode(card, MAUDIO_PLAY); card->audiostate.play_state=AUDIO_PLAYING; break; case AUDIO_PAUSE: card->audiostate.play_state=AUDIO_PAUSED; AudioSetPlayMode(card, MAUDIO_PAUSE); break; case AUDIO_CONTINUE: if (card->audiostate.play_state==AUDIO_PAUSED) { card->audiostate.play_state=AUDIO_PLAYING; AudioSetPlayMode(card, MAUDIO_PLAY); } break; case AUDIO_SELECT_SOURCE: card->audiostate.stream_source= (audio_stream_source_t) arg; break; case AUDIO_SET_MUTE: { AudioMute(card, arg); card->audiostate.mute_state=(boolean) arg; break; } case AUDIO_SET_AV_SYNC: card->videosync=(boolean) arg; card->audiostate.AV_sync_state=(boolean) arg; break; case AUDIO_SET_BYPASS_MODE: return -EINVAL; case AUDIO_CHANNEL_SELECT: card->audiostate.channel_select=(audio_channel_select_t) arg; switch(card->audiostate.channel_select) { case AUDIO_STEREO: break; case AUDIO_MONO_LEFT: break; case AUDIO_MONO_RIGHT: break; default: return -EINVAL; } return 0; case AUDIO_GET_STATUS: if(copy_to_user(parg, &card->audiostate, sizeof(struct audio_status))) return -EFAULT; break; case AUDIO_GET_CAPABILITIES: { int cap=AUDIO_CAP_LPCM| AUDIO_CAP_MP1| AUDIO_CAP_MP2| AUDIO_CAP_AC3; if (copy_to_user(parg, &cap, sizeof(cap))) return -EFAULT; } break; case AUDIO_CLEAR_BUFFER: /* FIXME */ break; case AUDIO_SET_STREAMTYPE: { int f = -1; switch(arg){ case AUDIO_CAP_DTS: case AUDIO_CAP_MP3: case AUDIO_CAP_AAC: case AUDIO_CAP_SDDS: case AUDIO_CAP_OGG: f = audio_none; break; case AUDIO_CAP_LPCM: f = audio_LPCM; break; case AUDIO_CAP_MP1: case AUDIO_CAP_MP2: f = audio_MPEG; break; case AUDIO_CAP_AC3: f = audio_AC3; break; } card->setup.audioselect = (audio_type) f; DecoderPrepareAudio(card); break; } case AUDIO_SET_ID: if (arg < 0 || arg >32) arg = 0; card->setup.audioID = arg; arg = 0; case AUDIO_SET_EXT_ID: if (arg < 0 || arg >32) arg = arg&0x0F; card->setup.audioIDext = arg; attr = card->lastaattr; DecoderSelectAudioID(card); card->lastaattr = attr; break; case AUDIO_SET_MIXER: return -EINVAL; case AUDIO_SET_ATTRIBUTES: SetAudioAttr(card,arg); card->startingDVDA = ((card->setup.audioselect != audio_none) && (card->setup.audioselect != audio_disable)); break; case AUDIO_SET_KARAOKE: { break; } default: return -ENOIOCTLCMD; } return 0;}static intdvb_osd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg){ dvb_device_t *dvbdev=*(dvb_device_t **) file->private_data; struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv; switch (cmd) { case OSD_SEND_CMD: { osd_cmd_t doc; if(copy_from_user(&doc, parg, sizeof(osd_cmd_t))) return -EFAULT; return OSD_DrawCommand(card, &doc); } default: return -EINVAL; }}static unsigned int dvb_video_poll(struct file *file, poll_table *table){ dvb_device_t *dvbdev=*(dvb_device_t **) file->private_data; struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv; if (card != NULL) { poll_wait(file, &card->wqA , table); if ( !card->rbufA.buffy || ring_write_rest(&(card->rbufA)) ) return (POLLOUT | POLLWRNORM); else { return 0; } } else return POLLERR;}static unsigned int dvb_audio_poll(struct file *file, poll_table *table){ dvb_device_t *dvbdev=*(dvb_device_t **) file->private_data; struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv; if (card != NULL) { poll_wait(file, &card->wqB, table); if ( !card->rbufB.buffy || ring_write_rest(&(card->rbufB)) ) return (POLLOUT | POLLWRNORM); else { return 0; } } else return POLLERR;}static struct file_operations dvb_video_fops = { owner: THIS_MODULE, read: 0, write: dvb_video_write, ioctl: dvb_generic_ioctl, open: dvb_video_open, release: dvb_video_release, poll: dvb_video_poll,};static dvb_device_t dvbdev_video = { id: -1, priv: 0, users: 1, writers: 1, fops: &dvb_video_fops, kernel_ioctl: dvb_video_ioctl,};static struct file_operations dvb_audio_fops = { owner: THIS_MODULE, read: 0, write: dvb_audio_write, ioctl: dvb_generic_ioctl, open: dvb_audio_open, release: dvb_audio_release, poll: dvb_audio_poll,};static dvb_device_t dvbdev_audio = { id: -1, priv: 0, users: 1, writers: 1, fops: &dvb_audio_fops, kernel_ioctl: dvb_audio_ioctl,};static struct file_operations dvb_osd_fops = { owner: THIS_MODULE, read: 0, write: 0, ioctl: dvb_generic_ioctl, open: dvb_generic_open, release: dvb_generic_release, poll: 0,};static dvb_device_t dvbdev_osd = { id: -1, priv: 0, users: 1, writers: 1, fops: &dvb_osd_fops, kernel_ioctl: dvb_osd_ioctl,};/****************************************************************************** * driver registration ******************************************************************************/static int dvb_start_feed(dvb_demux_feed_t *dvbdmxfeed){ dvb_demux_t *dvbdmx=dvbdmxfeed->demux; struct cvdv_cards * card = (struct cvdv_cards *)dvbdmx->priv; if (!dvbdmx->dmx.frontend || !card) return -EINVAL; if (dvbdmxfeed->type == DMX_TYPE_TS) { if ((dvbdmxfeed->ts_type & TS_DECODER) && (dvbdmxfeed->pes_type<DMX_TS_PES_OTHER)) { switch (dvbdmx->dmx.frontend->source) { case DMX_MEMORY_FE: if (dvbdmxfeed->ts_type & TS_DECODER) if (dvbdmxfeed->pes_type<2 && dvbdmx->pids[0]!=0xffff && dvbdmx->pids[1]!=0xffff) { setup_ts2pes( &card->tsa, &card->tsv, dvbdmx->pids, dvbdmx->pids+1, pes_write, (void *)card); dvbdmx->playing=1; } break; default: return -EINVAL; break; } } } if (dvbdmxfeed->type == DMX_TYPE_SEC) { int i; for (i=0; i<dvbdmx->filternum; i++) { if (dvbdmx->filter[i].state!=DMX_STATE_READY) continue; if (dvbdmx->filter[i].type!=DMX_TYPE_SEC) continue; if (dvbdmx->filter[i].filter.parent!= &dvbdmxfeed->feed.sec) continue; dvbdmxfeed->feed.sec.is_filtering=1; dvbdmx->filter[i].state=DMX_STATE_GO; } } return 0;}static int dvb_stop_feed(dvb_demux_feed_t *dvbdmxfeed){ dvb_demux_t *dvbdmx=dvbdmxfeed->demux; struct cvdv_cards * card = (struct cvdv_cards *)dvbdmx->priv; if (!card) return -EINVAL; if (dvbdmxfeed->type == DMX_TYPE_TS) { if ((dvbdmxfeed->ts_type & TS_DECODER) && (dvbdmxfeed->pes_type<=1)) { if (dvbdmx->playing) { free_ipack(&card->tsa); free_ipack(&card->tsv); DecoderPause(card); dvbdmx->playing=0; } } } if (dvbdmxfeed->type == DMX_TYPE_SEC) { int i; for (i=0; i<dvbdmx->filternum; i++) if (dvbdmx->filter[i].state==DMX_STATE_GO && dvbdmx->filter[i].filter.parent== &dvbdmxfeed->feed.sec) { dvbdmx->filter[i].state=DMX_STATE_READY; } } return 0;}static uint16_t get_pid(uint8_t *pid){ uint16_t pp = 0; pp = (pid[0] & PID_MASK_HI)<<8; pp |= pid[1]; return pp;}static int dvb_write_to_decoder(dvb_demux_feed_t *dvbdmxfeed, uint8_t *buf, size_t count){ dvb_demux_t *dvbdmx=dvbdmxfeed->demux; struct cvdv_cards * card = (struct cvdv_cards *)dvbdmx->priv; uint16_t pid = 0; int off = 0; ipack *p; if (!card) return -EINVAL; pid = get_pid(buf+1); if (pid == *(card->tsa.pid)) p = &(card->tsa); else if (pid == *(card->tsv.pid)) p = &(card->tsv); else return 0; if (dvbdmxfeed->pes_type>1) return -1; if (!(buf[3]&0x10)) // no payload? return -1; if (count != TS_SIZE) return -1; if ( buf[3] & ADAPT_FIELD) { // adaptation field? off = buf[4] + 1; } if (pid == *(card->tsa.pid)){ MDEBUG(0,"AUDIO count: %d off: %d\n",count,off); margi_write_audio(card, buf+off+4, TS_SIZE-4-off, 0); } else { MDEBUG(0,"VIDEO count: %d off: %d\n",count,off); margi_write(card, buf+off+4, TS_SIZE-4-off, 0); } ts_to_pes( p, buf); // don't need count (=188) return 0;}int dvb_register(struct cvdv_cards *card){ int i,ret; struct dvb_device *dvbd=&card->dvb_dev; dvb_demux_t *dvbdemux = (dvb_demux_t *)&card->demux; if (card->dvb_registered) return -1; if (dvb_register_adapter(&card->dvb_adapter,"Margi")<0) return -1; card->dvb_registered=1; card->audiostate.AV_sync_state=0; card->audiostate.mute_state=0; card->audiostate.play_state=AUDIO_STOPPED; card->audiostate.stream_source=AUDIO_SOURCE_MEMORY; card->audiostate.channel_select=AUDIO_STEREO; card->audiostate.bypass_mode=0; card->videostate.video_blank=0; card->videostate.play_state=VIDEO_STOPPED; card->videostate.stream_source=VIDEO_SOURCE_MEMORY; card->videostate.video_format=VIDEO_FORMAT_4_3; card->videostate.display_format=VIDEO_CENTER_CUT_OUT; // init and register demuxes memcpy(card->demux_id, "demux0_0", 9); card->demux_id[7] = 1+0x30; dvbdemux->priv = (void *) card; dvbdemux->filternum = 256; dvbdemux->feednum = 256; dvbdemux->start_feed = dvb_start_feed; dvbdemux->stop_feed = dvb_stop_feed; dvbdemux->write_to_decoder = dvb_write_to_decoder; dvbdemux->dmx.vendor="CIM"; dvbdemux->dmx.model="sw"; dvbdemux->dmx.id=card->demux_id; dvbdemux->dmx.capabilities=(DMX_TS_FILTERING| DMX_SECTION_FILTERING| DMX_MEMORY_BASED_FILTERING); DvbDmxInit(&card->demux); card->dmxdev.filternum=256; card->dmxdev.demux=&dvbdemux->dmx; card->dmxdev.capabilities=0; DmxDevInit(&card->dmxdev, card->dvb_adapter); card->mem_frontend.id="mem_frontend"; card->mem_frontend.vendor="memory"; card->mem_frontend.model="sw"; card->mem_frontend.source=DMX_MEMORY_FE; ret=dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &card->mem_frontend); if (ret<0) return ret; ret=dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &card->mem_frontend); if (ret<0) return ret; dvbd->priv=(void *) card; dvb_register_device(card->dvb_adapter, &card->video_dev, &dvbdev_video, card, DVB_DEVICE_VIDEO); dvb_register_device(card->dvb_adapter, &card->audio_dev, &dvbdev_audio, card, DVB_DEVICE_AUDIO); dvb_register_device(card->dvb_adapter, &card->osd_dev, &dvbdev_osd, card, DVB_DEVICE_OSD); return 0;}static voiddvb_unregister(struct cvdv_cards *dvb){ dvb_demux_t *dvbdemux=&dvb->demux; if (!dvb->dvb_registered) return; dvbdemux->dmx.close(&dvbdemux->dmx); dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &dvb->mem_frontend); DmxDevRelease(&dvb->dmxdev); DvbDmxRelease(&dvb->demux); dvb_unregister_device(dvb->audio_dev); dvb_unregister_device(dvb->video_dev); dvb_unregister_device(dvb->osd_dev); dvb_unregister_adapter(dvb->dvb_adapter);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -