/* * Copyright (c) 1999-2003 WIDE Project * All rights reserved. * * Author : Akimichi OGAWA (akimichi@sfc.wide.ad.jp) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code MUST retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form MUST reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * MUST display the following acknowledgement: * This product includes software developed by Akimichi OGAWA. * 4. The name of the author MAY NOT be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ /* * Copyright (c) 2003 * Hidetoshi Shimokawa. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * * This product includes software developed by Hidetoshi Shimokawa. * * 4. Neither the name of the author nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: write-freebsd.c,v 1.10 2003/05/10 13:26:06 simokawa Exp $ */ #ifdef HAVE_CONFIG_H #include #endif /* HAVE_CONFIG_H */ #include #include #include #include #include #include #include #include #include #include #include "write.h" #include "ieee1394.h" #include "shm.h" /* blocks used for [u_int32_t outbuf] */ #define NBLOCKS 400 #define USE_SILENT_AUDIO 0x00000001 struct frac { int n,d; }; struct frac frame_cycle[2] = { {8000*100, 2997}, /* NTSC 8000 cycle / 29.97 Hz */ {320, 1}, /* PAL 8000 cycle / 25 Hz */ }; struct frac pad_rate[2] = { {203, 2997}, /* = (8000 - 29.97 * 250)/(29.97 * 250) */ {1, 15}, /* = (8000 - 25 * 300)/(25 * 300) */ }; #define CYCLE_FRAC 0xc00 struct audio_buf { struct dv_difblock dbn[9]; }; int cycle_offset; void ieee1394dv_write_loop (struct dvrecv_param *dvrecv_param) { u_long silent_audio[dvrecv_param->maxdifseq*9*80/4]; u_long silent_audio_flag = 0; u_long same_audio_count = 0; u_int32_t outbuf[3 * NBLOCKS]; struct iovec vec[2 * NBLOCKS]; u_char seq = 0; u_char dseq, sct, dbn; int i, nvec, audio_off, audio_dbn; int ieee1394_pkt_count = 0; int count; u_int32_t system, pad_acc, cycle_acc, cycle, f_cycle, f_frac, packets; struct ciphdr *ciph; struct dv1394_pkts *dvframe; struct audio_buf *audio_seq; /* check video system */ if (dvrecv_param->format == DV_FORMAT_NTSC) system = 0; else if (dvrecv_param->format == DV_FORMAT_PAL) system = 1; else return; /* prepare DV DIF block without any sound */ memset(silent_audio, 0, sizeof(silent_audio)); sct = SCT_AUDIO; for (dseq=0; dseqmaxdifseq; dseq++) { for (dbn=0; dbn<9; dbn++) { silent_audio[(dseq*9*80 + dbn*80)/4] = htonl((sct & 0x7) << 29 | (seq & 0xf) << 24 | (dseq & 0xf) << 20 | (dbn & 0xff) << 8); } } memset(outbuf, 0, sizeof(outbuf)); for (i=0; ivideo_framebuf->next->framebuf->lock == DVFRAME_DATA_READY) { dvrecv_param->video_framebuf = dvrecv_param->video_framebuf->next; dvrecv_param->video_framebuf->framebuf->lock = DVFRAME_WRITING_IEEE1394; } if (dvrecv_param->audio_framebuf->next->framebuf->lock == DVFRAME_DATA_READY) { same_audio_count = 0; silent_audio_flag = 0; dvrecv_param->audio_framebuf = dvrecv_param->audio_framebuf->next; dvrecv_param->audio_framebuf->framebuf->lock = DVFRAME_WRITING_IEEE1394; } else { same_audio_count++; if (same_audio_count > 5) { if (same_audio_count == 6) { printf("MUTE AUDIO\n"); } same_audio_count = 10; silent_audio_flag = USE_SILENT_AUDIO; } } dvframe = &dvrecv_param->video_framebuf->framebuf->dvframe; if (silent_audio_flag) audio_seq = (struct audio_buf *)&silent_audio[0]; else audio_seq = (struct audio_buf *) &dvrecv_param->audio_framebuf->framebuf->dseq[0].dbn[0]; for (dseq=0; dseqmaxdifseq; dseq++) { audio_off = 6; audio_dbn = 0; for (count=0; count= pad_rate[system].d) { pad_acc -= pad_rate[system].d; outbuf[ieee1394_pkt_count*3] = 8 << 16 | 0x00007fa0; ciph = (struct ciphdr *)&outbuf[ieee1394_pkt_count*3 + 1]; ciph->dbc = packets % 256; if (ieee1394_pkt_count == 0) ciph->fdf.dv.cyc = htons(cycle << 12 | f_frac); else ciph->fdf.dv.cyc = htons(0xffff); vec[nvec].iov_base = (char *)&outbuf[ieee1394_pkt_count*3]; vec[nvec].iov_len = 12; nvec ++; ieee1394_pkt_count++; cycle ++; } outbuf[ieee1394_pkt_count*3] = 488 << 16 | 0x00007fa0; ciph = (struct ciphdr *)&outbuf[ieee1394_pkt_count*3 + 1]; ciph->dbc = packets % 256; if (ieee1394_pkt_count == 0) ciph->fdf.dv.cyc = htons(cycle << 12 | f_frac); else ciph->fdf.dv.cyc = htons(0xffff); vec[nvec].iov_base = (char *)&outbuf[ieee1394_pkt_count*3]; vec[nvec].iov_len = 12; nvec ++; /* audio block is in (6 + 16*i)th block. */ if (audio_off < 6) { if (audio_off != 0) { vec[nvec].iov_base = (char *)&dvframe->pkt[dseq][count][0]; vec[nvec].iov_len = 80 * audio_off; nvec ++; } vec[nvec].iov_base = (char *)&audio_seq[dseq].dbn[audio_dbn++]; vec[nvec].iov_len = 80; if (audio_off != 5) { nvec ++; vec[nvec].iov_base = (char *) &dvframe->pkt[dseq][count][80/4*(audio_off+1)]; vec[nvec].iov_len = 80 * (5 - audio_off); } audio_off += 16; } else { vec[nvec].iov_base = (char *)&dvframe->pkt[dseq][count][0]; vec[nvec].iov_len = 80*6; } audio_off -= 6; nvec ++; ieee1394_pkt_count++; cycle ++; } /* end of for(count=0; countmaxdifseq; dseq++) */ if (writev(dvrecv_param->ieee1394dv.fd, vec, nvec) < 0) { warn("writev error\n"); break; } dvrecv_param->video_framebuf->framebuf->lock = DVFRAME_READY; dvrecv_param->audio_framebuf->framebuf->lock = DVFRAME_READY; } }