--- margi2/cvdv.c 2001/05/23 14:24:08 1.16 +++ margi2/cvdv.c 2001/06/01 16:43:07 1.17 @@ -493,7 +493,7 @@ int DecoderWriteBlock(struct cvdv_cards if (size > 0) { if (!card->use_ringA) - MargiSetABuffers(card, NBBUF * CHANNELBUFFERSIZE); + MargiSetBuffers(card, NBBUF*CHANNELBUFFERSIZE,0); if (card->startingDVDV || card->startingDVDA) setSCR = 1; @@ -547,11 +547,12 @@ int DecoderWriteBlock(struct cvdv_cards static long margi_write(struct cvdv_cards *card, const char *data, unsigned long count, int nonblock) { - struct StreamSetup *setup = &card->setup; int res; long int out=0; - int wc = 0; + int free; + + free = ring_write_rest(&(card->rbufA)); card->nonblock = nonblock; @@ -559,24 +560,16 @@ static long margi_write(struct cvdv_card if (count > 0) { // Do we have data? if ((res = Prepare(card))) return res; - - if ((setup->streamtype != stream_ES) - && (setup->streamtype != stream_PES)){ - if (!card->use_ringA) - MargiSetABuffers(card, NBBUF* - CHANNELBUFFERSIZE); - - while (wc < 100 && - !card->nonblock && out < count){ - wc++; - out += MargiPushA(card, count, data); - if (out < count){ - interruptible_sleep_on(&card->wqA); - } - } - if (card->nonblock) { - out = MargiPushA(card, count, data); - } + if (!card->use_ringA) + MargiSetBuffers(card, NBBUF*CHANNELBUFFERSIZE, + 0); + if (!nonblock && + !wait_event_interruptible(card->wqA, + free >count )){ + out = MargiPushA(card, count, + data); + } else { + out = MargiPushA(card, count, data); } } return out; @@ -587,6 +580,7 @@ static long margi_write(struct cvdv_card } } + static long margi_write_audio(struct cvdv_cards *card, const char *data, unsigned long count, int nonblock) { @@ -594,7 +588,9 @@ static long margi_write_audio(struct cvd int res; long int out=0; - int wc = 0; + int free; + + free = ring_write_rest(&(card->rbufB)); card->nonblock = nonblock; @@ -602,22 +598,17 @@ static long margi_write_audio(struct cvd if (count > 0) { // Do we have data? if ((res = Prepare(card))) return res; - if ((setup->streamtype == stream_ES) - && (setup->streamtype == stream_PES)){ + || (setup->streamtype == stream_PES)){ if (!card->use_ringB) - MargiSetBBuffers(card, NBBUF* - CHANNELBUFFERSIZE); - - while (wc < 1000 && - !card->nonblock && out < count){ - wc++; - out += MargiPushB(card, count, data); - if (out < count){ - interruptible_sleep_on(&card->wqB); - } - } - if (card->nonblock) { + MargiSetBuffers(card, NBBUF* + CHANNELBUFFERSIZE,1); + if (!nonblock && + !wait_event_interruptible(card->wqB, + free >count )){ + out = MargiPushB(card, count, + data); + } else { out = MargiPushB(card, count, data); } } @@ -635,7 +626,6 @@ void pes_write(uint8_t *buf, int count, struct cvdv_cards *card = (struct cvdv_cards *) priv; margi_write(card, buf, count, 0); - } @@ -644,8 +634,7 @@ static ssize_t PSwrite(struct file *file { struct cvdv_cards *card = minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV]; // minor number modulo 16 - return margi_write(card, data, count, 1); - + return margi_write(card, data, count, file->f_flags&O_NONBLOCK); } static unsigned int PSpoll(struct file *file, poll_table * table) @@ -663,6 +652,21 @@ static unsigned int PSpoll(struct file * return POLLERR; } +static unsigned int poll_audio(struct file *file, poll_table * table) +{ + struct cvdv_cards *card = + minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV]; // minor number modulo 16 + 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 int OSD_DrawCommand(struct cvdv_cards *card,osd_cmd_t *dc) { @@ -998,7 +1002,7 @@ static int margi_open(struct cvdv_cards if (card->open) closed = 0; if (closed) { // first open() for this card? - MargiFreeBuffers(card); + MargiFreeBuffers(card,2); VideoSetBackground(card, 1, 0, 0, 0); // black } card->open++; @@ -1017,7 +1021,7 @@ static int PSopen(struct inode *inode, s { struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV]; card->audiostate.AVSyncState=true; - return margi_open(card,0); + return margi_open(card, file->f_flags); } @@ -1085,7 +1089,6 @@ dvbdev_open(struct dvb_device *dvbdev, i struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv; int type=num2type(card, num); int ret=0; - struct StreamSetup *setup = &card->setup; if (type<0) return -EINVAL; @@ -1102,10 +1105,11 @@ dvbdev_open(struct dvb_device *dvbdev, i card->video_blank=true; card->audiostate.AVSyncState=true; card->videostate.streamSource=VIDEO_SOURCE_DEMUX; - margi_open(card, 0); + margi_open(card, file->f_flags); break; case DVB_DEVICE_AUDIO_0: + card->audiostate.AVSyncState=true; card->audiostate.streamSource=AUDIO_SOURCE_DEMUX; break; @@ -1115,9 +1119,8 @@ dvbdev_open(struct dvb_device *dvbdev, i ret=DmxDevFilterAlloc(&card->dmxdev, file); break; case DVB_DEVICE_DVR_0: - setup->streamtype = stream_PES; - setup->audioselect = audio_MPEG; - margi_open(card, 0); + card->audiostate.AVSyncState=true; + margi_open(card, file->f_flags); ret=DmxDevDVROpen(&card->dmxdev, file); break; @@ -1196,9 +1199,8 @@ dvbdev_write(struct dvb_device *dvbdev, if ( card->setup.streamtype != stream_PES ) return -EPERM; -// return margi_write_audio(card, buf, count, -// file->f_flags&O_NONBLOCK); - return count; + return margi_write_audio(card, buf, count, + file->f_flags&O_NONBLOCK); case DVB_DEVICE_DVR_0: return DmxDevDVRWrite(&card->dmxdev, file, buf, count, ppos); @@ -1242,6 +1244,7 @@ dvbdev_ioctl(struct dvb_device *dvbdev, struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv; void *parg=(void *)arg; int type=num2type(card, num); + uint16_t attr; switch (type) { case DVB_DEVICE_VIDEO_0: @@ -1385,11 +1388,93 @@ dvbdev_ioctl(struct dvb_device *dvbdev, case VIDEO_CAP_CSS: f = stream_DVD; } - card->setup.streamtype = f; + } break; + case VIDEO_SET_ID: + card->setup.videoID = arg; + DecoderPrepareVideo(card); + break; + + case VIDEO_SET_SYSTEM: + card->videomode = (videosystem) arg; + SetVideoSystem(card); + break; + + case VIDEO_SET_HIGHLIGHT: + { + uint8_t data1[4]; + uint8_t data2[6]; + videoHighlight_t vh; + + if(copy_from_user(&vh, parg, sizeof(videoHighlight_t))) + return -EFAULT; + + data1[0] = vh.contrast1; + data1[1] = vh.contrast2; + data1[2] = vh.color1; + data1[3] = vh.color2; + data2[0] = vh.ypos & 0xFF; + data2[1] = (uint8_t) ((vh.ypos >> 1) & 0xFF); + data2[2] = (uint8_t) ((vh.ypos >> 2) & 0xFF); + data2[3] = vh.xpos & 0xFF; + data2[4] = (uint8_t) ((vh.xpos >> 1) & 0xFF); + data2[5] = (uint8_t) ((vh.xpos >> 2) & 0xFF); + return DecoderHighlight(card, vh.active, data1, data2); + break; + } + + case VIDEO_SET_SPU: + { + videoSPU_t spu; + + if(copy_from_user(&spu, parg, sizeof(videoSPU_t))) + return -EFAULT; + + return DecoderSPUStream(card, spu.streamID, spu.active); + break; + } + + case VIDEO_SET_SPU_Palette: + { + videoSPUPalette_t spup; + + if(copy_from_user(&spup, parg, sizeof(videoSPUPalette_t))) + return -EFAULT; + + return DecoderSPUPalette(card, spup.length, spup.palette); + break; + } + + case VIDEO_GET_NAVI: + { + videoNaviPack_t navi; + + navi.length = DecoderGetNavi(card, &(navi.data)); + if(copy_to_user(parg, &navi, sizeof(videoNaviPack_t))) + return -EFAULT; + } + break; + + case VIDEO_SET_ATTRIBUTES: + { + if (!card->ChannelBuffersAllocated) { + DecoderStreamReset(card); + MargiFlush(card); + + card->setup.streamtype = stream_DVD; + card->setup.videoID = 0; + DecoderPrepareVideo(card); + DecoderPreparePS(card, 0, 0, 2, 2, 3, 1); + } + + SetVideoAttr(card, arg); + card->startingDVDV = 1; + } + break; + default: return -ENOIOCTLCMD; } @@ -1515,8 +1600,37 @@ dvbdev_ioctl(struct dvb_device *dvbdev, card->setup.audioselect = (audio_type) f; DecoderPrepareAudio(card); + break; } - 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 = 0; + 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; @@ -1565,7 +1679,7 @@ dvbdev_poll(struct dvb_device *dvbdev, i return PSpoll(file, wait); case DVB_DEVICE_AUDIO_0: - return POLLOUT;//PSpoll(file, wait); + return poll_audio(file, wait); case DVB_DEVICE_CA_0: break;