Annotation of margi2/decoder.c, revision 1.4
1.1 cvs 1: /*
2: decoder.c
3:
4: Copyright (C) Christian Wolff for convergence integrated media.
5:
6: This program is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 2 of the License, or
9: (at your option) any later version.
10:
11: This program is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with this program; if not, write to the Free Software
18: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19: */
20:
21: #define __NO_VERSION__
22:
23: #include "decoder.h"
24: #include "l64021.h"
25: #include "video.h"
26: #include "audio.h"
27: #include "streams.h"
28: #include "osd.h"
29: #include "dram.h"
30:
31: int DecoderGetNavi(struct cvdv_cards *card, u8 *navidata)
32: {
33: if (card->navihead == card->navitail) return 0;
34: // printk(KERN_DEBUG LOGNAME ": Retreiving NaviPack\n");
35: memcpy(navidata, &card->navibuffer[card->navitail], NAVISIZE);
36: card->navitail += NAVISIZE;
37: if (card->navitail >= NAVIBUFFERSIZE) card->navitail = 0;
38: return NAVISIZE;
39: }
40:
41: // returns 1 on overrun, 0 on no error
42: int DecoderQueueNavi(struct cvdv_cards *card, u8 *navidata)
43: {
44: memcpy(&card->navibuffer[card->navihead], navidata, NAVISIZE);
45: card->navihead += NAVISIZE;
46: if (card->navihead >= NAVIBUFFERSIZE) card->navihead = 0;
47: if (card->navihead == card->navitail) {
48: // printk(KERN_DEBUG LOGNAME ": NaviPack buffer overflow\n");
49: card->navitail += NAVISIZE;
50: if (card->navitail >= NAVIBUFFERSIZE) card->navitail = 0;
51: return 1;
52: }
53: return 0;
54: }
55:
56: u32 ParseSCR(const u8 *scrdata)
57: {
58: u32 SCR_base=0;
59:
60: if ((!scrdata[0]) && (!scrdata[1]) && (scrdata[2]==1)
61: && (scrdata[3]==0xBA) && ((scrdata[4]&0xC0)==0x40)) {
62: SCR_base=((scrdata[4]>>3)&0x07);
63: SCR_base=(SCR_base<<2) | (scrdata[4]&0x03);
64: SCR_base=(SCR_base<<8) | scrdata[5];
65: SCR_base=(SCR_base<<5) | ((scrdata[6]>>3)&0x1F);
66: SCR_base=(SCR_base<<2) | (scrdata[6]&0x03);
67: SCR_base=(SCR_base<<8) | scrdata[7];
68: SCR_base=(SCR_base<<5) | ((scrdata[8]>>3)&0x1F);
69: }
70: return SCR_base;
71: }
72:
73: u32 SetSCR(struct cvdv_cards *card, u32 SCR_base)
74: {
75: // printk(KERN_ERR LOGNAME ": SCR in DVD Pack: 0x%08X\n",SCR_base);
76: if (DecoderReadByte(card, 0x007) & 0x10) { // SCR already stopped
77: DecoderWriteByte(card,0x009,SCR_base&0xFF); // Set SCR counter
78: DecoderWriteByte(card,0x00A,(SCR_base>>8)&0xFF);
79: DecoderWriteByte(card,0x00B,(SCR_base>>16)&0xFF);
80: DecoderWriteByte(card,0x00C,(SCR_base>>24)&0xFF);
81: } else {
82: DecoderMaskByte(card,0x007,0xD2,0xD2);
83: // Set 0x10, halt SCR counter
84: DecoderWriteByte(card,0x009,SCR_base&0xFF); // Set SCR counter
85: DecoderWriteByte(card,0x00A,(SCR_base>>8)&0xFF);
86: DecoderWriteByte(card,0x00B,(SCR_base>>16)&0xFF);
87: DecoderWriteByte(card,0x00C,(SCR_base>>24)&0xFF);
88: DecoderMaskByte(card,0x007,0xD2,0xC2);
89: // Del 0x10, SCR counter run
90: }
91: return SCR_base;
92: }
93:
94: void DecoderPause(struct cvdv_cards *card)
95: {
96: DecoderMaskByte(card, 0x007, 0xD2, 0xD2);
97: // Set 0x010, halt SCR counter
98: AudioSetPlayMode(card, AUDIO_PAUSE);
99: DecoderStopDecode(card);
100: card->paused = 1;
101: }
102:
103: void DecoderUnPause(struct cvdv_cards *card)
104: {
105: DecoderStartDecode(card);
106: AudioSetPlayMode(card, AUDIO_PLAY);
107: DecoderMaskByte(card, 0x007, 0xD2, 0xC2);
108: // Del 0x010, SCR counter run
109: card->paused = 0;
110: }
111:
112: void CloseCard(struct cvdv_cards *card)
113: {
1.4 ! mocm 114: MargiFlush(card);
1.1 cvs 115: printk(KERN_DEBUG LOGNAME ": Closing card\n");
1.3 rjkm 116: card->DecoderOpen = 1;
117: DecoderClose(card);
118: DecoderUnPrepare(card);
1.1 cvs 119: DecoderStreamReset(card);
120: DecoderSetupReset(card);
121:
122: AudioClose(card);
123: OSDClose(card);
1.4 ! mocm 124: L64021Init(card);
1.1 cvs 125: }
126:
127:
128: void DecoderReadAudioInfo(struct cvdv_cards *card)
129: {
130: u8 data;
131: static int bitrates[17] = {0, 32, 40, 48, 56, 64, 80, 96, 112,
132: 128, 160, 192, 224, 256, 320, 384, 0};
133: struct AudioParam *audio = &card->stream.audio;
134: data = DecoderReadByte(card, 0x150);
135: audio->mpeg.present = data & 0x60;
136: // MPEG Layer Code 00 reserverd, we can assume valid MPEG params
137: if (audio->mpeg.present) {
138: audio->mpeg.MPEG2 = data & 0x80;
139: audio->mpeg.layer = 4 - ((data >> 5) & 0x03);
140: if (data & 0x0F) {
141: if ((data & 0x0F) == 1) audio->mpeg.bitrate = 32;
142: else switch (audio->mpeg.layer) {
143: case 1:
144: audio->mpeg.bitrate = 32 * (data & 0x0F);
145: break; // Layer I
146: case 2:
147: audio->mpeg.bitrate = bitrates[(data & 0x0F) +
148: 1];
149: break; // Layer II
150: default:
151: audio->mpeg.bitrate = bitrates[data & 0x0F];
152: // Layer III
153: }
154: } else audio->mpeg.bitrate = 0;
155: data = DecoderReadByte(card, 0x151);
156: switch ((data >> 6) & 0x03) {
157: case 0:
158: audio->mpeg.samplefreq = 44;
159: break;
160: case 1:
161: audio->mpeg.samplefreq = 48;
162: break;
163: case 2:
164: audio->mpeg.samplefreq = 32;
165: break;
166: default:
167: audio->mpeg.samplefreq = 0; // invalid
168: }
169: audio->mpeg.mode = (data >> 3) & 0x03;
170: audio->mpeg.modeext = (data >> 1) & 0x03;
171: audio->mpeg.copyright = data & 0x01;
172: data=DecoderReadByte(card, 0x152);
173: audio->mpeg.original = data & 0x80;
174: audio->mpeg.emphasis = (data >> 5) & 0x03;
175: }
176: data = DecoderReadByte(card, 0x153);
177: audio->ac3.present = (data != 0);
178: // value 0 for bits 0..5 forbidden, we can assume valid ac3 params
179: if (audio->ac3.present) {
180: audio->ac3.acmod = (data >> 5) & 0x07;
181: audio->ac3.dialnorm = data & 0x1F;
182: data = DecoderReadByte(card, 0x154);
183: audio->ac3.bsmod = (data >> 5) & 0x07;
184: audio->ac3.dialnorm2 = data > 0x1F;
185: data = DecoderReadByte(card, 0x155);
186: audio->ac3.surmixlev = (data >> 6) & 0x03;
187: audio->ac3.mixlevel = (data >> 1) & 0x1F;
188: data = DecoderReadByte(card, 0x156);
189: audio->ac3.cmixlev = (data >> 6) & 0x03;
190: audio->ac3.mixlevel2 = (data >> 1) & 0x1F;
191: data = DecoderReadByte(card, 0x157);
192: audio->ac3.fscod = (data >> 6) & 0x03;
193: audio->ac3.lfeon = (data >> 5) & 0x01;
194: audio->ac3.bsid = data & 0x1F;
195: data = DecoderReadByte(card, 0x158);
196: audio->ac3.dsurmod = (data >> 6) & 0x03;
197: audio->ac3.frmsizecod = data & 0x3F;
198: audio->ac3.langcod = DecoderReadByte(card, 0x159);
199: audio->ac3.langcod2 = DecoderReadByte(card, 0x15A);
200: audio->ac3.timecod = DecoderReadByte(card, 0x15B);
201: data = DecoderReadByte(card, 0x15C);
202: audio->ac3.timecod = (audio->ac3.timecod << 6) |
203: ((data >> 2) & 0x3F);
204: audio->ac3.roomtyp = data & 0x03;
205: audio->ac3.timecod2 = DecoderReadByte(card, 0x15D);
206: data = DecoderReadByte(card, 0x15E);
207: audio->ac3.timecod2 = (audio->ac3.timecod2 << 6) |
208: ((data >> 2) & 0x3F);
209: audio->ac3.roomtyp2 = data & 0x03;
210: }
211: audio->pcm.present =! (DecoderReadByte(card, 0x161) & 0x20);
212: // PCM FIFO not empty? Then, we can assume valid LPCM params
213: if (audio->pcm.present) {
214: data = DecoderReadByte(card, 0x15F);
215: audio->pcm.audio_frm_num = (data >> 3) & 0x1F;
216: audio->pcm.num_of_audio_ch = data & 0x07;
217: data = DecoderReadByte(card, 0x160);
218: audio->pcm.Fs = (data >> 6) & 0x03;
219: audio->pcm.quantization = (data >> 4) & 0x03;
220: audio->pcm.emphasis = (data >> 2) & 0x03;
221: audio->pcm.mute_bit = (data >> 1) & 0x01;
222: }
223: switch (card->setup.audioselect) {
224: case audio_disable:
225: audio->valid = 0;
226: break;
227: case audio_none:
228: case audio_DTS:
229: case audio_SDDS:
230: if ((audio->valid = (audio->ac3.present ||
231: audio->pcm.present ||
232: audio->mpeg.present))) {
233: if (audio->mpeg.present) {
234: card->setup.audioselect = audio_MPEG;
235: } else if (audio->pcm.present) {
236: card->setup.audioselect = audio_LPCM;
237: } else if (audio->ac3.present) {
238: card->setup.audioselect = audio_AC3;
239: }
240: } else {
241: audio->valid = 0;
242: card->setup.audioselect = audio_none;
243: }
244: break;
245: case audio_MPEG: // MPEG Audio
246: case audio_MPEG_EXT: // MPEG Audio with extension stream
247: audio->valid = audio->mpeg.present;
248: break;
249: case audio_LPCM: // Linear Pulse Code Modulation LPCM
250: audio->valid = audio->pcm.present;
251: break;
252: case audio_AC3: // AC-3
253: audio->valid = audio->ac3.present;
254: break;
255: }
256: printk(KERN_DEBUG LOGNAME ": -- DecoderReadAudioInfo - type/valid %d/%d:\n", card->setup.audioselect, audio->valid);
257: if (audio->mpeg.present || audio->ac3.present || audio->pcm.present)
258: printk(KERN_DEBUG LOGNAME ": Audio - Decoded parameters:\n");
259: if (audio->mpeg.present) printk(KERN_DEBUG LOGNAME ": MPEG%s Layer %d, %d kHz, %d kbps, %s, %s%s, %s emphasis\n",
260: ((audio->mpeg.MPEG2) ? "2" : "1"),
261: audio->mpeg.layer,
262: audio->mpeg.samplefreq,
263: audio->mpeg.bitrate,
264: ((audio->mpeg.mode == 0) ? "stereo" : ((audio->mpeg.mode == 1) ? "joint stereo" : ((audio->mpeg.mode == 2) ? "dual channel" : "single channel"))),
265: ((audio->mpeg.copyright) ? "copyrighted " : ""),
266: ((audio->mpeg.original) ? "original" : "copy"),
267: ((audio->mpeg.emphasis == 0) ? "no" : ((audio->mpeg.emphasis == 1) ? "50/15 usec." : ((audio->mpeg.emphasis == 2) ? "invalid" : "J.17")))
268: );
269: if (audio->ac3.present) printk(KERN_DEBUG LOGNAME ": AC3 acmod=%d bsmod=%d dialnorm=%d dialnorm2=%d surmixlev=%d mixlevel=%d cmixlev=%d mixlevel2=%d fscod=%d lfeon=%d bsid=%d dsurmod=%d frmsizecod=%d langcod=%d langcod2=%d timecod=%d roomtyp=%d timecod2=%d roomtyp2=%d\n",
270: audio->ac3.acmod,
271: audio->ac3.bsmod,
272: audio->ac3.dialnorm,
273: audio->ac3.dialnorm2,
274: audio->ac3.surmixlev,
275: audio->ac3.mixlevel,
276: audio->ac3.cmixlev,
277: audio->ac3.mixlevel2,
278: audio->ac3.fscod,
279: audio->ac3.lfeon,
280: audio->ac3.bsid,
281: audio->ac3.dsurmod,
282: audio->ac3.frmsizecod,
283: audio->ac3.langcod,
284: audio->ac3.langcod2,
285: audio->ac3.timecod,
286: audio->ac3.roomtyp,
287: audio->ac3.timecod2,
288: audio->ac3.roomtyp2);
289: if (audio->pcm.present) printk(KERN_DEBUG LOGNAME ": LPCM audio_frm_num=%d num_of_audio_ch=%d Fs=%d quantization=%d emphasis=%d mute_bit=%d\n",
290: audio->pcm.audio_frm_num,
291: audio->pcm.num_of_audio_ch,
292: audio->pcm.Fs,
293: audio->pcm.quantization,
294: audio->pcm.emphasis,
295: audio->pcm.mute_bit);
296: }
297:
298: void DecoderReadAuxFifo(struct cvdv_cards *card)
299: {
300: int i = 0;
301: u8 data;
302: int layer;
303:
304: struct StreamInfo *stream = &card->stream;
305: // printk(KERN_DEBUG LOGNAME ": AUX - ");
306: // printk("%03X ", card->AuxFifo[card->AuxFifoTail]);
307: while (card->AuxFifoHead != card->AuxFifoTail) {
308:
309: layer = (card->AuxFifo[card->AuxFifoTail] >> 8) & 0x07;
310: data = card->AuxFifo[card->AuxFifoTail] & 0xFF;
311: card->AuxFifoTail = (card->AuxFifoTail + 1) & FIFO_MASK;
312: if (layer != card->AuxFifoLayer) { // start of a new layer?
313: i = 0;
314: card->AuxFifoLayer = layer;
315: } else i++;
316: switch (layer) { // layer code
317: case 0: // sequence header
318: if (! stream->sh.valid) switch (i) {
319: case 0:
320: stream->sh.hsize = data & 0x0F;
321: break;
322: case 1:
323: stream->sh.hsize = (stream->sh.hsize << 8)
324: | data;
325: stream->hsize = stream->sh.hsize;
326: break;
327: case 2:
328: stream->sh.vsize = data & 0x0F;
329: break;
330: case 3:
331: stream->sh.vsize = (stream->sh.vsize << 8) |
332: data;
333: stream->vsize = stream->sh.vsize;
334: break;
335: case 4:
336: stream->sh.aspectratio = data & 0x0F;
337: break;
338: case 5:
339: stream->sh.frameratecode = data & 0x0F;
340: break;
341: case 6:
342: stream->sh.bitrate = data & 0x03;
343: break;
344: case 7:
345: stream->sh.bitrate = (stream->sh.bitrate << 8)
346: | data;
347: break;
348: case 8:
349: stream->sh.bitrate = (stream->sh.bitrate << 8)
350: | data;
351: stream->bitrate = stream->sh.bitrate;
352: break;
353: case 9:
354: stream->sh.vbvbuffersize = data & 0x03;
355: break;
356: case 10:
357: stream->sh.vbvbuffersize =
358: (stream->sh.vbvbuffersize << 8) |
359: data;
360: stream->vbvbuffersize =
361: stream->sh.vbvbuffersize;
362: break;
363: case 11:
364: stream->sh.constrained = data & 0x01;
365: stream->sh.valid = 1;
366: printk(KERN_DEBUG LOGNAME ": AUX - MPEG1 - %dx%d %s %s fps, %d bps, %d kByte vbv%s\n", stream->sh.hsize, stream->sh.vsize,
367: ((stream->sh.aspectratio == 1) ? "1:1" :
368: ((stream->sh.aspectratio == 2) ? "3:4" :
369: ((stream->sh.aspectratio == 3) ? "9:16" :
370: ((stream->sh.aspectratio == 4) ? "1:2.21" :
371: "?:?")))),
372: ((stream->sh.frameratecode == 1) ? "23.976" :
373: ((stream->sh.frameratecode == 2) ? "24" :
374: ((stream->sh.frameratecode == 3) ? "25" :
375: ((stream->sh.frameratecode == 4) ? "29.97" :
376: ((stream->sh.frameratecode == 5) ? "30" :
377: ((stream->sh.frameratecode == 6) ? "50" :
378: ((stream->sh.frameratecode == 7) ? "59.94" :
379: ((stream->sh.frameratecode == 8) ? "60" :
380: "?")))))))),
381: stream->sh.bitrate * 400,
382: stream->sh.vbvbuffersize * 16,
383: ((stream->sh.constrained) ? ", constrained" : "")
384: );
385: break;
386: }
387: break;
388: case 1: // group of pictures
389: if (! stream->gop.valid)
390: switch (i) {
391: case 0:
392: stream->gop.timecode = data & 0x01;
393: break;
394: case 1:
395: stream->gop.timecode =
396: (stream->gop.timecode << 8) |
397: data;
398: break;
399: case 2:
400: stream->gop.timecode =
401: (stream->gop.timecode << 8) |
402: data;
403: break;
404: case 3:
405: stream->gop.timecode =
406: (stream->gop.timecode << 8) |
407: data;
408: break;
409: case 4:
410: stream->gop.closedgop = data & 0x01;
411: break;
412: case 5:
413: stream->gop.brokenlink = data & 0x01;
414: stream->gop.valid = 1;
415: break;
416: }
417: break;
418: case 2: // picture
419: if (0)
420: switch (i) {
421: case 0:
422: break;
423: }
424: break;
425: case 7: // extension layer
426: if (i == 0) card->AuxFifoExt = data;
427: else
428: switch (card->AuxFifoExt) { // extension code
429: case 1: // sequence extension
430: if ((stream->sh.valid) &&
431: (! stream->se.valid))
432: switch (i) {
433: case 1:
434: stream->se.profilelevel
435: = data;
436: break;
437: case 2:
438: stream->se.progressive
439: = data & 0x01;
440: break;
441: case 3:
442: stream->se.chroma =
443: (data >> 4) &
444: 0x03;
445: stream->se.hsizeext =
446: (data >> 2) &
447: 0x03;
448: stream->se.vsizeext =
449: data & 0x03;
450: stream->hsize |=
451: (stream->se.hsizeext << 12);
452: stream->vsize |=
453: (stream->se.vsizeext << 12);
454: break;
455: case 4:
456: stream->se.bitrateext =
457: data & 0x0F;
458: break;
459: case 5:
460: stream->se.bitrateext =
461: (stream->se.bitrateext << 8) | data;
462: stream->bitrate |=
463: (stream->se.bitrateext << 18);
464: break;
465: case 6:
466: stream->se.vbvbuffersizeext = data;
467: stream->vbvbuffersize |= (stream->se.vbvbuffersizeext << 10);
468: break;
469: case 7:
470: stream->se.lowdelay =
471: (data >> 7) &
472: 0x01;
473: stream->se.frextn =
474: (data >> 5) &
475: 0x03;
476: stream->se.frextd =
477: data & 0x1F;
478: stream->se.valid = 1;
479: stream->MPEG2 = 1;
480: printk(KERN_DEBUG LOGNAME ": AUX - MPEG2 - %dx%d %s %s*%d/%d fps, %d bps, %d kByte vbv%s%s\n", stream->hsize, stream->vsize,
481: ((stream->sh.aspectratio == 1) ? "1:1" :
482: ((stream->sh.aspectratio == 2) ? "3:4" :
483: ((stream->sh.aspectratio == 3) ? "9:16" :
484: ((stream->sh.aspectratio == 4) ? "1:2.21" :
485: "?:?")))),
486: ((stream->sh.frameratecode == 1) ? "23.976" :
487: ((stream->sh.frameratecode == 2) ? "24" :
488: ((stream->sh.frameratecode == 3) ? "25" :
489: ((stream->sh.frameratecode == 4) ? "29.97" :
490: ((stream->sh.frameratecode == 5) ? "30" :
491: ((stream->sh.frameratecode == 6) ? "50" :
492: ((stream->sh.frameratecode == 7) ? "59.94" :
493: ((stream->sh.frameratecode == 8) ? "60" :
494: "?")))))))),
495: stream->se.frextn + 1,
496: stream->se.frextd + 1,
497: stream->bitrate * 400,
498: stream->vbvbuffersize * 16,
499: ((stream->sh.constrained) ? ", constrained" : ""),
500: ((stream->se.lowdelay) ? ", low delay" : "")
501: );
502: break;
503: }
504: break;
505: case 2: // sequence display extension
506: if (0)
507: switch (i) {
508: case 0:
509: break;
510: }
511: break;
512: case 3: // quant matrix extension
513: if (0)
514: switch (i) {
515: case 0:
516: break;
517: }
518: break;
519: case 4: // copyright extension
520: if (0)
521: switch (i) {
522: case 0:
523: break;
524: }
525: break;
526: case 7: // picture display extension
527: if (0) switch (i) {
528: case 0:
529: break;
530: }
531: break;
532: case 8: // picture coding extension
533: if (0)
534: switch (i) {
535: case 0:
536: break;
537: }
538: break;
539: default:
540: break;
541: }
542: break;
543: default:break;
544: }
545:
546: }
547: }
548:
549: void DecoderReadDataFifo(struct cvdv_cards *card)
550: {
551: // printk(KERN_DEBUG LOGNAME ": DATA - ");
552: while (card->DataFifoHead != card->DataFifoTail) {
553: // printk("%03X ", card->DataFifo[card->DataFifoTail]);
554: card->DataFifoTail = (card->DataFifoTail + 1) & FIFO_MASK;
555: }
556: // printk("\n");
557: }
558:
559: int DecoderReadNavipack(struct cvdv_cards *card)
560: {
561: u32 startaddr, endaddr, writeaddr;
562: u8 navipack[1024];
563: u16 PacketLength;
564: u8 SubStreamID;
565: //struct Navi navi;
566: int i;
567: startaddr = (DecoderReadWord(card, 0x05C) & 0x3FFF) << 7;
568: // 21 bit word address
569: endaddr = (DecoderReadWord(card, 0x05E) & 0x3FFF) << 7;
570: // 21 bit word address
571: writeaddr = DecoderReadByte(card, 0x075) & 0xFF;
572: writeaddr |= (DecoderReadWord(card, 0x077) & 0x0FFF) << 8;
573: //writeaddr <<= 3;
574: //printk(KERN_DEBUG LOGNAME ": -- DecoderReadNavipack 0x%08X-0x%08X, ->0x%08X <-0x%08X\n", startaddr, endaddr, writeaddr, card->NaviPackAddress);
575:
576: if (DecoderReadByte(card, 0x07B) & 0xC0) { // navi pack available?
577: DRAMReadByte(card, card->NaviPackAddress, 1024, navipack, 0);
578: card->reg07B |= 0x20; // decrement navi counter
579: DecoderWriteByte(card, 0x07B, card->reg07B);
580: card->reg07B &= ~0x20;
581: //DecoderSetByte(card, 0x07B, 0x20); // decrement navi counter
582: card->NaviPackAddress += 512; // increment in words
583: if (card->NaviPackAddress >= endaddr)
584: card->NaviPackAddress = startaddr;
585: //printk(KERN_DEBUG LOGNAME ": Navipack %02X %02X %02X %02X %02X %02X %02X %02X\n",
586: // navipack[0], navipack[1], navipack[2], navipack[3], navipack[4], navipack[5], navipack[6], navipack[7]);
587: if ((!navipack[0]) && (!navipack[1]) && (navipack[2] == 1) && (navipack[3] == 0xBF)) {
588: PacketLength = (navipack[4] << 8) | navipack[5];
589: SubStreamID = navipack[6];
590: //printk(KERN_DEBUG LOGNAME ": Navipack Len=%d, ID=%d\n", PacketLength, SubStreamID);
591: i = 7; // start of payload data in navipack[]
592: switch (SubStreamID) {
593: case 0: // Presentation Control Information (PCI)
594: if (PacketLength < 980) return 1; // Packet too small
595: DecoderQueueNavi(card, navipack);
596: break;
597: case 1: // Data Search Information (DSI)
598: if (PacketLength < 1018) return 1; // Packet too small
599: DecoderQueueNavi(card, navipack);
600: break;
601: default:
602: break;
603: }
604: // } else {
605: // printk(KERN_DEBUG LOGNAME ": navi pack format error: %02X %02X %02X %02X %02X %02X %02X %02X.\n",
606: // navipack[0], navipack[1], navipack[2], navipack[3], navipack[4], navipack[5], navipack[6], navipack[7]);
607: }
608: // } else {
609: // printk(KERN_DEBUG LOGNAME ": no navi pack avail.\n");
610: }
611: return 0;
612: }
613:
614: int AudioStart(struct cvdv_cards *card)
615: {
616: DecoderReadAudioInfo(card); // detect audio type
617: if (card->stream.audio.valid) {
618: printk(KERN_DEBUG LOGNAME ": Audio Init in delayed decoder start\n");
619: if (card->AudioInitialized) AudioClose(card);
620: switch (card->setup.audioselect) {
621: case audio_MPEG: // MPEG Audio
622: case audio_MPEG_EXT: // MPEG Audio with ext.
623: printk(KERN_DEBUG LOGNAME ": Using MPEG Audio\n");
624: AudioInit(card, card->stream.audio.mpeg.samplefreq, 0);
625: if (card->stream.audio.mpeg.mode == 3) AudioDualMono(card, 2); // left channel only
626: else AudioDualMono(card, 0);
627: break;
628: case audio_DTS:
629: case audio_LPCM: // Linear Pulse Code Modulation LPCM
630: printk(KERN_DEBUG LOGNAME ": Using LPCM Audio\n");
631: AudioInit(card, 48, 0); // or 96
632: break;
633: case audio_AC3: // AC-3
634: printk(KERN_DEBUG LOGNAME ": Using AC-3 Audio\n");
635: switch (card->stream.audio.ac3.fscod) {
636: case 0:AudioInit(card, 48, 0); break;
637: case 1:AudioInit(card, 44, 0); break;
638: case 2:AudioInit(card, 32, 0); break;
639: }
640: break;
641: case audio_none:
642: case audio_disable:
643: case audio_SDDS:
644: }
645: } else return 1;
646: return 0;
647: }
648:
649: // Slow mode: displays every field <slowfactor> times
650: // slowfactor=0 disables this mode.
651: void VideoSlow(struct cvdv_cards *card, int slowfactor)
652: {
653: if (!slowfactor && card->slowdown) DecoderWriteByte(card, 0x0ED, 0x00); // run
654: card->lastslow = 0;
655: card->slowdown = slowfactor;
656: }
657:
658: // Puts decoder in pause after so many fields
659: void StepsToPause(struct cvdv_cards *card, int steps)
660: {
661: card->videosteps = steps;
662: }
663:
664: u32 DecoderReadSCR(struct cvdv_cards *card, u16 address)
665: {
666: u32 SCR;
667: SCR = DecoderReadByte(card, address);
668: SCR |= ((u32)DecoderReadByte(card, address+1) << 8);
669: SCR |= ((u32)DecoderReadByte(card, address+2) << 16);
670: SCR |= ((u32)DecoderReadByte(card, address+3) << 24);
671: return SCR;
672: }
673:
674: u32 DecoderReadRWAddr(struct cvdv_cards *card, u16 address)
675: {
676: u32 addr;
677: addr = DecoderReadByte(card, address) & 0xFF;
678: addr |= (((u32)DecoderReadByte(card, address+1) & 0xFF) << 8);
679: addr |= (((u32)DecoderReadByte(card, address+2) & 0x0F) << 16);
680: return addr;
681: }
682:
683: int PTSGetFirstPTS(PTSStorage *store, u32 *PTS)
684: {
685: if ( store->end == store->begin ) {
686: return 0;
687: } else {
688: *PTS = store->PTS[store->begin];
689: return 1;
690: }
691: }
692:
693: void PTSStoreAdd(PTSStorage *store, u32 PTS, u32 AddrB, u32 AddrE)
694: {
695: int new;
696:
697: //printk(KERN_DEBUG LOGNAME ": PTSStoreAdd - store in [%d] %08X - %08X\n", store->end, AddrB, AddrE);
698:
699: // cheap fix: don't store if address rollover
700: if ((AddrB & 0x00080000) != (AddrE & 0x00080000)) return;
701:
702: new = store->end;
703:
704: store->end++;
705: if (store->end >= store->size) store->end = 0;
706: if (store->end == store->begin) {
707: store->begin++;
708: if (store->begin >= store->size) store->begin = 0;
709: }
710:
711: store->AddrB[new] = AddrB;
712: store->AddrE[new] = AddrE;
713: store->PTS[new] = PTS;
714: }
715:
716: int PTSGetPTS (PTSStorage *store, u32 Addr, u32 *PTS )
717: {
718: u32 AddrB;
719: u32 AddrE;
720: int i;
721: int found;
722: int search;
723:
724: //printk(KERN_DEBUG LOGNAME ": PTSGetPTS - search %08X\n", Addr);
725:
726: if (store->end == store->begin) {
727: store->LastAddr = Addr;
728: return 0;
729: }
730:
731: // Search for the PTS in the array
732: found = 0;
733: search = 1;
734: while (search && !found) {
735: // Get the first value
736: i = store->begin;
737: AddrB = store->AddrB[i];
738: AddrE = store->AddrE[i];
739:
740: //printk(KERN_DEBUG LOGNAME ": PTSGetPTS - search in [%d] %08X - %08X\n", i, AddrB, AddrE);
741:
742: //If in range, keep it
743: if ((Addr >= AddrB) && (Addr <= AddrE)) {
744: *PTS = store->PTS[i];
745: found = 1;
746: } else {
747: if ((Addr & 0x00080000) == (AddrB & 0x00080000)) {
748: if (Addr < AddrB ) search = 0;
749: } else {
750: if ((store->LastAddr & 0x00080000) == (Addr & 0x00080000)) search = 0;
751: }
752: }
753: if (search) {
754: store->begin++;
755: if (store->begin >= store->size) store->begin = 0;
756: if (store->end == store->begin ) search = 0;
757: }
758: }
759: store->LastAddr = Addr;
760: return found;
761: }
762:
763:
764: u32 GetPTS(u8 *data, u32* MediaPointer, int mpeg, int hlength,int off)
765: {
766: u32 PTS = 0xFFFFFFFFUL;
767: int p = 0;
768:
769: // Read PTS, if present
770: if ((mpeg == 2 && data[p + 7] & 0x80) ||
771: (mpeg == 1 && off)) {
772: if (mpeg == 1) p = off-9;
773: PTS = (data[p + 9] >> 1) & 0x03UL;
774: PTS = (PTS << 8) | (data[p + 10] & 0xFFUL);
775: PTS = (PTS << 7) | ((data[p + 11] >> 1) & 0x7FUL);
776: PTS = (PTS << 8) | (data[p + 12] & 0xFFULL);
777: PTS = (PTS << 7) | ((data[p + 13] >> 1) & 0x7FUL);
778: }
779: // Now, skip rest of PES header and stuffing
780: if (mpeg == 2){
781: p += (9 + (data[p + 8] & 0xFF));
782: p = ((p + 7) / 8) * 8;
783: } else p = hlength+7;
784: if (!(data[p++] | data[p++] | data[p++] | data[p++])) {
785: *MediaPointer = (u32)data[p++] & 0xFF;
786: *MediaPointer = (*MediaPointer << 8) | ((u32)data[p++] & 0xFF);
787: *MediaPointer = (*MediaPointer << 8) | ((u32)data[p++] & 0xFF);
788: *MediaPointer = (*MediaPointer << 8) | ((u32)data[p++] & 0xFF);
789: } else {
790: *MediaPointer = 0xFFFFFFFFUL;
791: }
792: return PTS;
793: }
794:
795: int ReadPESChunk(struct cvdv_cards *card, u32 *addr, u8 *data, u32 start, u32 end)
796: {
797: int i = 5, err = -1;
798: while (err && (i--)) err &= DRAMReadByte(card, *addr << 2, 8, &data[0], 0);
799: if (err) return 1;
800: (*addr)++;
801: if (*addr >= end) *addr = start;
802: return 0;
803: }
804:
805: void ReadPESHeaders(struct cvdv_cards *card)
806: {
807: u8 startcode[] = {0x00, 0x00, 0x01};
808: int LoopCount;
809: u32 LastVAddr; // Current Video Address
810: u32 LastAAddr; // Current Audio Address
811: u32 Addr; // Current Header Address
812: u32 PESAddr; // Pointer from Header Block
813: u32 PTS; // PTS from Header Block
814: u8 Data[32];
815: u32 AudioPESStart;
816: u32 AudioPESEnd;
817: int i, j, p, fail;
818: u32 FailAddr;
819: int hlength=0;
820: int mpeg=0;
821: int check;
822: int mp=0;
823: int off=0;
824:
825: AudioPESStart = (DecoderReadWord(card, 0x058) & 0x3FFF) << 5;
826: AudioPESEnd = ((DecoderReadWord(card, 0x05A) & 0x3FFF) + 1) << 5;
827:
828: LastVAddr = DecoderReadRWAddr(card, 0x060);
829: LastAAddr = DecoderReadRWAddr(card, 0x063);
830:
831: if (card->LastAddr == 0) card->LastAddr = AudioPESStart;
832:
833: //card->AudioPES .. (((DecoderReadWord(card,0x05A) & 0x3FFF) + 1) << 5)
834:
835: //Read the PES header buffer
836: Addr = DecoderReadRWAddr(card, 0x072) & 0x0007FFFF;
837: if (Addr >= AudioPESEnd) {
838: Addr = card->LastAddr = AudioPESStart;
839: }
840:
841: LoopCount = 0;
842: while ((card->LastAddr != Addr) && (LoopCount++ < 200)) {
843: //printk(KERN_DEBUG LOGNAME ": Read PES header: round %d 0x%08X -> 0x%08X\n", LoopCount, card->LastAddr, Addr);
844: FailAddr = card->LastAddr;
845: fail = 0;
846: p = 0;
847:
848: if (ReadPESChunk(card, &card->LastAddr, &Data[p], AudioPESStart, AudioPESEnd)) continue;
849: p+=8;
850: j=1;
851:
852:
853: //printk(KERN_DEBUG LOGNAME ": PES header: %02X %02X %02X %02X %02X %02X %02X %02X\n", Data[0],Data[1],Data[2],Data[3],Data[4],Data[5],Data[6],Data[7]);
854: if (memcmp(Data, startcode, 3)) continue;
855: if ((Data[3] == 0xE0) || (Data[3] == 0xBD)
856: || ((Data[3] & 0xE0) == 0xC0)) {
857:
858: fail |= ReadPESChunk(card, &card->LastAddr,
859: &Data[p], AudioPESStart,
860: AudioPESEnd);
861:
862:
863: p+=8;
864: j++;
865: if ( (Data[6] & 0xC0) == 0x80 ){
866: hlength = 9+Data[8];
867: mpeg = 2;
868: } else {
869: mpeg = 1;
870: mp = 6;
871: check = Data[mp];
872: mp++;
873: while (check == 0xFF){
874: if (!fail && mp == p) {
875: fail |= ReadPESChunk(
876: card,
877: &card->LastAddr,
878: &Data[p],
879: AudioPESStart,
880: AudioPESEnd);
881: p+=8;
882: j++;
883: }
884: check = Data[mp];
885: mp++;
886: }
887: if (!fail && mp == p) {
888: fail |= ReadPESChunk(
889: card,
890: &card->LastAddr,
891: &Data[p],
892: AudioPESStart,
893: AudioPESEnd);
894: p+=8;
895: j++;
896: }
897:
898: if ( !fail && (check & 0xC0) == 0x40){
899: check = Data[mp];
900: mp++;
901: if (!fail && mp == p) {
902: fail |= ReadPESChunk(
903: card,
904: &card->LastAddr,
905: &Data[p],
906: AudioPESStart,
907: AudioPESEnd);
908: p+=8;
909: j++;
910: }
911: check = Data[mp];
912: mp++;
913: }
914: if ( !fail && (check & 0x20)){
915: if (check & 0x30) hlength = mp+10;
916: else hlength = mp+5;
917: off = mp-1;
918: }
919: //printk(KERN_DEBUG LOGNAME ": PTS: %02X %02X %02X %02X %02X\n", Data[off],Data[off+1],Data[off+2],Data[off+3],Data[off+4]);
920:
921:
922: }
923:
924: for (i = 1; (i < ((hlength+7) / 8)) && (!fail);
925: i++) {
926: fail |= ReadPESChunk(card, &card->LastAddr, &Data[p], AudioPESStart, AudioPESEnd);
927: p+=8;
928: j++;
929: }
930:
931: //printk(KERN_DEBUG LOGNAME ": PES header: %d chunks read, HL = %d\n", j, Data[8]);
932: if (!fail) {
933: PTS = GetPTS(Data, &PESAddr,
934: mpeg, hlength,off);
935: //printk(KERN_DEBUG LOGNAME ": PTS from PES header: %d @ 0x%08X\n", PTS, PESAddr);
936: if ((PTS != 0xFFFFFFFF) && (PESAddr != 0xFFFFFFFF)) {
937: if (Data[3] == 0xE0) { // Video
938: //printk(KERN_DEBUG LOGNAME ": Video PTS from PES header: %d @ 0x%08X - 0x%08X\n", PTS, PESAddr, LastVAddr);
939: PTSStoreAdd(&card->VideoPTSStore, PTS, PESAddr, LastVAddr);
940: } else { // Audio
941: //printk(KERN_DEBUG LOGNAME ": Audio PTS from PES header: %d @ 0x%08X - 0x%08X\n", PTS, PESAddr, LastAAddr);
942: PTSStoreAdd(&card->AudioPTSStore, PTS, PESAddr, LastAAddr);
943: }
944: }
945: }
946: } else {
947: //card->LastAddr = Addr;
948: }
949: // In case of error, rewind and try again
950: if (fail) card->LastAddr = FailAddr;
951: }
952: }
953:
954: void L64021Intr(struct cvdv_cards *card)
955: {
956: //static void L64021Intr(struct cvdv_cards *card) {
957: // struct cvdv_cards *card=dev_id;
958: u32 SCR_base, SCR_compareV, SCR_compareA;
959: u32 VideoAddr, AudioAddr, PTS;
960: int i, a, v, as, vs, ap, vp;
961: // int err, h;
962: u8 intr[5];
963: u8 layer;
964: //u8 oldlayer = 0;
965: long ISRTime, DeltaSyncTime, Offset;
966:
967: int used = 0;
968: u8 err;
969:
970: err = DecoderReadByte(card, 0x095);
971: if (err & 0x17) {
972: printk(KERN_DEBUG LOGNAME ": Packet Error: 0x%02X\n", err);
973: }
974:
975: ISRTime = 0; // TODO system time
976:
977: for (i = 0; i < 5; i++)
978: if ((intr[i] = DecoderReadByte(card, i))) used = 1;
979: if (used) {
980: //printk(KERN_DEBUG LOGNAME ": Int - L64021: %02X %02X %02X %02X %02X\n", intr[0], intr[1], intr[2], intr[3], intr[4]);
981: //printk(KERN_DEBUG LOGNAME ": Int - L64021 Aux/Data Fifo: %02X %02X\n",
982: // DecoderReadByte(card, 0x040),
983: // DecoderReadByte(card, 0x041));
984: //printk(KERN_DEBUG LOGNAME ": Int - L64021 VideoES w/r addr: %08X %08X\n",
985: // (DecoderReadByte(card, 0x060) | (DecoderReadByte(card, 0x061) << 8) | (DecoderReadByte(card, 0x062) << 16)) << 2,
986: // (DecoderReadByte(card, 0x06C) | (DecoderReadByte(card, 0x06D) << 8) | (DecoderReadByte(card, 0x06E) << 16)) << 2);
987:
988:
989: //if (DecoderReadByte(card, 0x005) & 0x04) DecoderDelByte(card, 0x005, 0x04);
990: //if (DecoderReadByte(card, 0x005) & 0x04) DecoderWriteByte(card, 0x005, 0x03);
991: //DecoderMaskByte(card, 0x007, 0x0C, 1 << 2); // Stream Select: MPEG1 System / MPEG2 Program Stream
992: //DecoderWriteByte(card, 0x005, 0x03);
993: //DecoderWriteByte(card, 0x007, 0xC7);
994: //printk(KERN_DEBUG LOGNAME ": Int - L64021 Channel Status: %02X %02X\n",
995: // DecoderReadByte(card, 0x007),
996: // DecoderReadByte(card, 0x005));
997:
998:
999: if (intr[0] & 0x80) { // new field
1000: card->fields++;
1001:
1002: if (card->slowdown > 0) {
1003: if (card->lastslow == 0) {
1004: DecoderWriteByte(card, 0x0ED, 0x03); // repeat frame
1005: card->lastslow++;
1006: } else if (card->lastslow == card->slowdown) {
1007: DecoderWriteByte(card, 0x0ED, 0x00); // run
1008: } else card->lastslow++;
1009: }
1010:
1011: if (card->videosteps > 0) {
1012: card->videosteps--;
1013: if (!card->videosteps) DecoderPause(card);
1014: }
1015:
1016: if (card->videodelay > 0) {
1017: //printk(KERN_DEBUG LOGNAME ": Video delay %d\n", card->videodelay);
1018: if( (DecoderReadByte(card, 0x0ED) & 0x01) == 0x00) {
1019: card->videodelay--;
1020: if(card->videodelay){
1021: DecoderWriteByte(card, 0x0ED, 0x01);
1022: } else {
1023: DecoderWriteByte(card, 0x0ED, 0x00);
1024: }
1025: }
1026: } else if (card->videorip > 0) {
1027: //printk(KERN_DEBUG LOGNAME ": Video rip %d\n", card->videorip);
1028: if ((DecoderReadByte(card, 0x0EC) & 0x03) == 0x00) {
1029: if (DecoderReadWord(card, 0x096) > 5) { // pictures in video ES channel
1030: card->videorip--;
1031: if(card->videorip) {
1032: DecoderWriteByte(card, 0x0EC, 0x01);
1033: } else {
1034: DecoderWriteByte(card, 0x0EC, 0x00);
1035: }
1036: } else {
1037: card->videorip = 0;
1038: DecoderWriteByte (card, 0x0EC, 0x00);
1039: }
1040: }
1041: }
1042:
1043:
1044: i = (DecoderReadByte(card, 0x113) & 0xFC) | (DecoderReadByte(card, 0x114) & 0x01);
1045: v = DecoderGetVideoESLevel(card);
1046: if (card->startingV) {
1047: vs = card->VideoESSize;
1048: if (vs > 0) vp = (100 * v) / vs;
1049: else vp = 0;
1.4 ! mocm 1050: if (vp > 40) {
1.1 cvs 1051: printk(KERN_DEBUG LOGNAME ": Delayed Video Decoder start\n");
1052: card->startingV = 0;
1053: DecoderStartDecode(card);
1054: //DecoderWriteByte(card, 0x0EC, 0x05); // Skip B Frames
1055: //DecoderWriteByte(card, 0x0EC, 0x06); // Skip B and P Frames
1056: //DecoderWriteByte(card, 0x0EE, 0x03); // Rip forward mode
1057: //DecoderWriteByte(card, 0x0ED, 0x03); // Repeat frame mode
1058: // DecoderSetVideoPanic(card, 1, 3); // video panic at 3 pictures
1059: //DecoderSetVideoPanic(card, 0, DecoderGetVideoESSize(card) / 4); // video panic at 25 percent
1060: //VideoSetBackground(card, 0, 0, 0, 0); // Video on black
1061: }
1062: }
1063: a = DecoderGetAudioESLevel(card);
1064: if (card->startingA) {
1065: as = card->AudioESSize;
1066: if (as > 0) ap = (100 * a) / as;
1067: else ap = 0;
1.4 ! mocm 1068: if (ap > 40) {
1.1 cvs 1069: printk(KERN_DEBUG LOGNAME ": Delayed Audio Decoder start\n");
1070: AudioSetPlayMode(card, AUDIO_PLAY);
1071: if (!AudioStart(card)) {
1072: card->startingA = 0;
1073: }
1074: }
1075: }
1076: if (card->fields >= 250) { // 5 seconds (PAL)
1077: //SCR_base = DecoderReadByte(card, 0x09);
1078: //SCR_base = SCR_base | (DecoderReadMWord(card, 0x0A) << 8);
1079: SCR_base = DecoderReadSCR(card, 0x009);
1080: SCR_compareA = DecoderReadSCR(card, 0x014);
1081: SCR_compareV = DecoderReadSCR(card, 0x00D);
1082: if (DecoderReadByte(card, 0x013) & 0x03)
1083: // printk(KERN_DEBUG LOGNAME ": SCR 0x%08X, videocmp=0x%08X, audiocmp=0x%08X %02X\n", SCR_base, SCR_compareV, SCR_compareA, DecoderReadByte(card, 0x013));
1084: //if (DecoderReadByte(card, 0x013) & 0x03)
1085: //printk(KERN_DEBUG LOGNAME ": SCR 0x%08X, videocmp=0x%08X, audiocmp=0x%08X %02X\n", SCR_base, DecoderReadDWord(card, 0x00D), DecoderReadDWord(card, 0x014), DecoderReadByte(card, 0x013));
1086: card->fields = 0;
1087: }
1088: }
1089:
1090: if (intr[0] & 0x04) { // First Slice Start Code
1091: //printk(KERN_DEBUG LOGNAME ": Int - First Slice Start Code\n");
1092: if (card->showvideo) {
1093: // Unmute card video if first picture slice detected
1094: VideoSetBackground(card, 0, 0, 0, 0); // Video on black
1095: card->showvideo = 0;
1096: }
1097: }
1098:
1099: if (intr[0] & 0x02 ) { // Aux/User Data Fifo
1100: // printk(KERN_DEBUG LOGNAME ": Int - Aux/Data FIFO Ready\n");
1101: used = 0;
1102: while ( (used++ < 1000) &&
1103: (layer = DecoderReadByte(card, 0x040)) & 0x03){
1104: card->AuxFifo[card->AuxFifoHead] = ((layer << 6) & 0x0700) | DecoderReadByte(card, 0x043);
1105: card->AuxFifoHead = (card->AuxFifoHead + 1) & FIFO_MASK;
1106: }
1107: if (used < 1000) DecoderReadAuxFifo(card);
1108: used = 0;
1109:
1110: while ( (used++ < 1000) &&
1111: (layer = DecoderReadByte(card, 0x041)) & 0x03){
1112: card->DataFifo[card->DataFifoHead] = ((layer << 6) & 0x0300) | DecoderReadByte(card, 0x043);
1113: card->DataFifoHead = (card->DataFifoHead + 1) & FIFO_MASK;
1114: }
1115: if (used < 1000 ) DecoderReadDataFifo(card);
1116: }
1117:
1118: if ((intr[0] & 0x01) != card->intdecodestatus) { // decode status
1119: card->intdecodestatus = intr[0] & 0x01;
1120: printk(KERN_DEBUG LOGNAME ": Int - decode status now %s\n", ((card->intdecodestatus) ? "running" : "stopped"));
1121: if (card->intdecodestatus) { // now running
1122: // DecoderSetVideoPanic(card, 1, 3); // video panic at 3 pictures
1123: DecoderSetVideoPanic(card, 0, card->VideoESSize / 4);
1124: card->showvideo = 1;
1125: //VideoSetBackground(card, 0, 0, 0, 0); // Video on black
1126: } else { // now stopped
1127: if (card->closing) {
1128: card->closing = 0;
1129: CloseCard(card);
1130: }
1131: }
1132:
1133: }
1134:
1135: // if (intr[1] & 0x80) { // SCR compare
1136: //printk(KERN_DEBUG LOGNAME ": Int - SCR compare\n");
1137: //DecoderDelByte(card, 0x013, 0x02);
1138: //VideoSetBackground(card, 0, 0, 0, 0); // Video on black
1139: // }
1140: // if (intr[1] & 0x40) { // SCR Overflow
1141: //printk(KERN_DEBUG LOGNAME ": Int - SCR Overflow\n");
1142: // }
1143: // if (intr[1] & 0x20) { // Begin Vertical Blank
1144: // }
1145: if (intr[1] & 0x10) { // Begin Active Video
1146: if (card->highlight_valid) {
1147: for (i = 0; i < 10; i++) DecoderWriteByte(card, 0x1C0 + i, card->highlight[i]);
1148: card->highlight_valid = 0;
1149: }
1150: }
1151: //if (intr[1] & 0x08) { // SPU Start Code Detected
1152: //printk(KERN_DEBUG LOGNAME ": Int - SPU Start Code Detected\n");
1153: //}
1154: if (intr[1] & 0x04) { // SCR compare audio
1155: printk(KERN_DEBUG LOGNAME ": Int - SCR compare audio\n");
1156: DecoderDelByte(card, 0x013, 0x01);
1157: AudioStart(card);
1158: }
1159: // both follwing are used in A/V-sync below
1160: // if (intr[1] & 0x02) { // picture start code detected
1161: //printk(KERN_DEBUG LOGNAME ": Int - picture start code detected\n");
1162: // }
1163: // if (intr[1] & 0x01) { // audio sync code detected
1164: //printk(KERN_DEBUG LOGNAME ": Int - audio sync code detected\n");
1165: // }
1166:
1167: // if (! card->stream.audio.valid) DecoderReadAudioInfo(card);
1168:
1169: if (intr[2] & 0x20) { // DSI PES data ready
1170: //printk(KERN_DEBUG LOGNAME ": Int - DSI PES data ready\n");
1171: DecoderReadNavipack(card);
1172: }
1173:
1174: if (intr[2] & 0x06) { // Audio / Video PES data ready
1175: ReadPESHeaders(card);
1176: }
1177:
1178: if (intr[3] & 0x40) { // CSS
1179: card->css.status = DecoderReadByte(card, 0x0B0);
1180: printk(KERN_DEBUG LOGNAME ": Int - CSS Status 0x%02X\n", card->css.status);
1181: if (card->css.status&0x01) card->css.ChallengeReady = 1; // challenge ready
1182: if (card->css.status&0x02) card->css.ResponseReady = 1; // response ready
1183: if (card->css.status&0x04) card->css.DiskKey = 1; // Disk key ready
1184: if (card->css.status&0x08) card->css.Error = 1; // Disk key error
1185: if (card->css.status&0x10) card->css.TitleKey = 1; // Title key ready
1186: if (card->css.status&0x20) card->css.TitleKeyDiff = 1; // Title key error
1187: }
1188:
1189:
1190: if (intr[3] & 0x30) { // Audio/Video ES channel buffer underflow
1191: //printk(KERN_DEBUG LOGNAME ": Int - ES channel buffer underflow\n");
1192: if (card->closing) {
1193: card->closing = 0;
1194: CloseCard(card);
1195: }
1196: }
1197:
1198: // if (intr[3] & 0x08) { // Data Dump channel PES data ready
1199: // }
1200:
1201: if (intr[4] & 0x10 ) { // SPU decode error
1202: printk(KERN_DEBUG LOGNAME ": Int - SPU decode error: (1CA)=0x%02X\n", DecoderReadByte(card, 0x1CA));
1203: DecoderDelByte(card, 0x1A0, 0x01); // SPU decode stop
1204: DecoderSetByte(card, 0x1A0, 0x01); // SPU decode start
1205: }
1206:
1207: // Audio / Video Syncronisation
1208:
1209: if (card->videosync && !card->videorip && !card->videodelay && !card->slowdown) {
1210: SCR_base = DecoderReadSCR(card, 0x009);
1211: SCR_compareV = DecoderReadSCR(card, 0x00D);
1212: //printk(KERN_DEBUG LOGNAME ": Sync: SCR = %08X\n", SCR_compareV);
1213: if (intr[1] & 0x02) { // picture start code detected
1214: //printk(KERN_DEBUG LOGNAME ": Sync: picture start code\n");
1215: DecoderMaskByte(card, 0x011, 0x03, 0x01); // Set SCR compare/capture mode to capture
1216: DecoderSetByte(card, 0x11, 0x04); // Set "capture on picture start"
1217: if (intr[1] & 0x01) { // audio sync code detected
1218: //printk(KERN_DEBUG LOGNAME ": Sync: audio sync code, too\n");
1219: DecoderSetByte(card, 0x11, 0x08); // Set "capture on audio sync code"
1220: }
1221: VideoAddr = DecoderReadRWAddr(card,0x080);
1222: if (PTSGetPTS(&card->VideoPTSStore, VideoAddr, &PTS)) {
1223: //printk(KERN_DEBUG LOGNAME ": Sync: video PTS found for 0x%08X = %08X\n", VideoAddr, PTS);
1224: card->oldVPTS = card->VPTS;
1225: card->VPTS = PTS;
1226: card->VSCR = ((long)SCR_compareV - (long)PTS) / 2;
1227: // card->VideoTime = ISRTime;
1228: }
1229: } else if (intr[1] & 0x01) { // audio sync code detected
1230: //printk(KERN_DEBUG LOGNAME ": Sync: audio sync code, only\n");
1231: DecoderMaskByte(card, 0x011, 0x03, 0x01); // Set SCR compare/capture mode to capture
1232: DecoderSetByte(card, 0x11, 0x08); // Set "capture on audio sync code"
1233: AudioAddr = DecoderReadRWAddr(card,0x083);
1234: //printk(KERN_DEBUG LOGNAME ": Sync: audio PTS search for 0x%08X\n", AudioAddr);
1235: if (PTSGetPTS(&card->AudioPTSStore, AudioAddr, &PTS)) {
1236: //printk(KERN_DEBUG LOGNAME ": Sync: audio PTS found for 0x%08X = %08X\n", AudioAddr, PTS);
1237: card->oldAPTS = card->APTS;
1238: card->APTS = PTS;
1239: card->ASCR = ((long)SCR_compareV - (long)PTS) / 2;
1240: // card->AudioTime = ISRTime;
1241: } else {
1242: card->ASCR = 0x7FFFFFFF;
1243: }
1244:
1245: if (card->VSCR != 0x7FFFFFFF) {
1246: if (card->ASCR != 0x7FFFFFFF) {
1247: DeltaSyncTime = ISRTime - card->SyncTime;
1248: card->SyncTime = ISRTime;
1249:
1250: // Calculate Audio and Video SCR difference
1251: Offset = (card->ASCR - card->VSCR - (10 * 736)) / 736;
1252: //printk(KERN_DEBUG LOGNAME ": Sync: compare SCRs: Audio = %ld Video = %ld -> %ld\n", card->ASCR, card->VSCR, Offset);
1253:
1254: // if the APTS and SCR are off update SCR to keep SubPic synced
1255: if ((SCR_compareV > card->APTS) || ((card->APTS - SCR_compareV) > 10000)) {
1256: Offset = 0;
1257: SetSCR(card, card->APTS);
1258: }
1259:
1260: // if more than 3 frames away
1261: if ((Offset > 3) || (Offset < -3)) {
1262: if (Offset > 0 ) {
1263: card->videodelay = 0;
1264: if (Offset < 100) {
1265: if (Offset < 10) {
1266: card->videodelay = 1;
1267: } else {
1268: card->videodelay = Offset / 2;
1269: if (card->videodelay > 20) {
1270: card->videodelay = 20;
1271: }
1272: }
1273: printk(KERN_DEBUG LOGNAME ": <<< Pausing %d\n", card->videodelay);
1274: } else {
1275: }
1276: } else {
1277: card->videorip = 0;
1278: if (Offset > -100) {
1279: if (Offset < -10) {
1280: card->videorip = 10;
1281: } else {
1282: card->videorip = 3;
1283: }
1284: printk(KERN_DEBUG LOGNAME ": >>> FForward %d\n", card->videorip);
1285: }
1286: }
1287: } else {
1288: }
1289: card->VSCR = 0x7FFFFFFF;
1290: }
1291: }
1292: }
1293: }
1294: }
1295: DecoderWriteByte(card, 0x006, 0x01); // Clear Interrupt Pin
1296: }
1297:
1298: // Enable the IRQ Masks
1299: void L64021InstallIntr(struct cvdv_cards *card) {
1300: u8 data;
1301:
1302: data=0;
1303: data |= 0x80; // new field
1304: data |= 0x40; // audio sync recovery
1305: data |= 0x20; // SPU SCR compare
1306: // data |= 0x10; // SDRAM Transfer Done
1307: // data |= 0x08; // Sequence End Code Detect
1308: data |= 0x04; // First Slice Start Code
1309: data |= 0x02; // Aux/User Data Fifo
1310: data |= 0x01; // decode status
1311: DecoderWriteByte(card, 0x000, (~data) & 0xFF);
1312:
1313: data = 0;
1314: // data |= 0x80; // SCR compare
1315: // data |= 0x40; // SCR Overflow
1316: // data |= 0x20; // Begin Vertical Blank
1317: data |= 0x10; // Begin Active Video
1318: data |= 0x08; // SPU Start Code Detected
1319: data |= 0x04; // SCR compare audio
1320: data |= 0x02; // picture start code detected
1321: data |= 0x01; // audio sync code detected
1322: DecoderWriteByte(card, 0x001, (~data) & 0xFF);
1323:
1324: data = 0;
1325: // data |= 0x80; // DTS video event
1326: // data |= 0x40; // DTS audio event
1327: data |= 0x20; // DSI PES data ready
1328: // data |= 0x10; // Seq end code in video channel
1329: data |= 0x08; // SPU PES data ready
1330: data |= 0x04; // Video PES data ready
1331: data |= 0x02; // Audio PES data ready
1332: // data |= 0x01; // Pack data ready
1333: DecoderWriteByte(card, 0x002, (~data) & 0xFF);
1334:
1335: data = 0;
1336: // data |= 0x80; // Reserved
1337: data |= 0x40; // CSS
1338: data |= 0x20; // Video ES channel buffer underflow
1339: data |= 0x10; // Audio ES channel buffer underflow
1340: // data |= 0x08; // Data Dump channel PES data ready
1341: data |= 0x04; // SPU channel buffer overflow
1342: data |= 0x02; // Video ES channel buffer overflow
1343: data |= 0x01; // Audio ES channel buffer overflow
1344: DecoderWriteByte(card, 0x003, (~data) & 0xFF);
1345:
1346: data = 0;
1347: // data |= 0x80; // S/PDIF channel buffer underflow
1348: // data |= 0x40; // packet error
1349: // data |= 0x20; // reserved
1350: data |= 0x10; // SPU decode error
1351: // data |= 0x08; // Audio Sync error
1352: // data |= 0x04; // Audio CRC or illegal bit error
1353: // data |= 0x02; // context error
1354: // data |= 0x01; // VLC or Run length error
1355: DecoderWriteByte(card, 0x004, (~data) & 0xFF);
1356: card->IntInstalled = 1;
1357: }
1358:
1359: int L64021RemoveIntr(struct cvdv_cards *card) {
1360: // Disable the IRQ Masks
1361: DecoderWriteByte(card, 0x000, 0xFF); // No ints
1362: DecoderWriteByte(card, 0x001, 0xFF); // No ints
1363: DecoderWriteByte(card, 0x002, 0xFF); // No ints
1364: DecoderWriteByte(card, 0x003, 0xFF); // No ints
1365: DecoderWriteByte(card, 0x004, 0xFF); // No ints
1366: card->IntInstalled = 0;
1367: return 0;
1368: }
1369:
1370: int L64021Reset(struct cvdv_cards *card) {
1371: L64021RemoveIntr(card); // Stop interrupts
1372: // Reset
1373: printk(KERN_DEBUG LOGNAME ": L64021 Software reset...\n");
1374: //DecoderSetByte(card, 0x007, 0x20); // reset on
1375: DecoderMaskByte(card, 0x007, 0xE2, 0xE2); // reset on
1376: while (!(DecoderReadByte(card, 0x007) & 0x02)) ; // wait until reset is done
1377: //DecoderDelByte(card, 0x007, 0x20); // reset off
1378: DecoderMaskByte(card, 0x007, 0xE2, 0xC2); // reset off
1379: printk(KERN_DEBUG LOGNAME ": L64021 Software reset done.\n");
1380: DecoderStopChannel(card);
1381: DecoderStopDecode(card);
1382: DecoderStreamReset(card);
1383: DecoderSetupReset(card);
1384: printk(KERN_INFO LOGNAME ": L64021 Rev. 0x%02X reset successfully.\n", DecoderReadByte(card, 0x0F5));
1385: return 0;
1386: }
1387:
1388: int L64021Setup(struct cvdv_cards *card) {
1389: printk(KERN_DEBUG LOGNAME ": -- L64021Setup\n");
1390: DecoderWriteByte(card, 0x0C1, 0x88); //
1391: switch (card->videomode) {
1392: case NTSC: // NTSC M, N. America, Taiwan, Japan
1393: DecoderMaskByte(card, 0x122, 0x03, 0x01); // Television Standard: NTSC
1394: /* Default values:
1395: DecoderWriteByte(card, 0x116, 90); // Main Reads per Line
1396: DecoderWriteByte(card, 0x11A, 4); // Vline Count Init
1397: DecoderWriteByte(card, 0x11C, 0x13); // Pixel State Reset Value / BT.656 Mode / Sync Active Low
1398: DecoderWriteByte(card, 0x129, 23); // Start- and End Row
1399: DecoderWriteByte(card, 0x12A, 262 & 0xFF);
1400: DecoderWriteByte(card, 0x12B, (262>>4)&0x70);
1401: DecoderWriteByte(card, 0x12C, 244 & 0xFF); // Start- and End Column
1402: DecoderWriteByte(card, 0x12D, 1683 & 0xFF);
1403: DecoderWriteByte(card, 0x12E, ((1683>>4)&0x70)|((244>>8)&0x07));
1404: DecoderWriteByte(card, 0x132, 240 & 0xFF); // SAV Column
1405: DecoderWriteByte(card, 0x133, 1684 & 0xFF); // EAV Column
1406: DecoderWriteByte(card, 0x134, ((1684>>4)&0x70)|((240>>8)&0x07));
1407: DecoderWriteByte(card, 0x12F, (21&0x1F)|((262>>3)&0x20)|(1<<6)|((265>>1)&0x80)); // VCode Zero...
1408: DecoderWriteByte(card, 0x130, 262&0xFF); // ... and VCode Even
1409: DecoderWriteByte(card, 0x131, 265&0xFF); // ... and FCode
1410: */
1411: break;
1412: case PAL: // PAL-B, D, G, H, I, Europe, Asia
1413: DecoderMaskByte(card, 0x122, 0x03, 0x02); // Television Standard: PAL
1414: /* Default values:
1415: DecoderWriteByte(card, 0x116, 90); // Main Reads per Line
1416: DecoderWriteByte(card, 0x11A, 1); // Vline Count Init
1417: DecoderWriteByte(card, 0x11C, 0x13); // Pixel State Reset Value / BT.656 Mode / Sync Active Low
1418: DecoderWriteByte(card, 0x129, 23); // Start- and End Row
1419: DecoderWriteByte(card, 0x12A, 310 & 0xFF);
1420: DecoderWriteByte(card, 0x12B, (310>>4)&0x70);
1421: DecoderWriteByte(card, 0x12C, 264 & 0xFF); // Start- and End Column
1422: DecoderWriteByte(card, 0x12D, 1703 & 0xFF);
1423: DecoderWriteByte(card, 0x12E, ((1703>>4)&0x70)|((264>>8)&0x07));
1424: DecoderWriteByte(card, 0x132, 260 & 0xFF); // SAV Column
1425: DecoderWriteByte(card, 0x133, 1704 & 0xFF); // EAV Column
1426: DecoderWriteByte(card, 0x134, ((1704>>4)&0x70)|((260>>8)&0x07));
1427: DecoderWriteByte(card, 0x12F, (21&0x1F)|((310>>3)&0x20)|(0<<6)|((312>>1)&0x80)); // VCode Zero...
1428: DecoderWriteByte(card, 0x130, 310&0xFF); // ... and VCode Even
1429: DecoderWriteByte(card, 0x131, 312&0xFF); // ... and FCode
1430: */
1431: break;
1432: case PAL60: // PAL 60Hz
1433: case NTSC60: // NTSC 60Hz, USA HDTV
1434: case PALM: // PAL-M normal, Brazil
1435: case PALM60: // PAL-M HDTV, Brazil
1436: case PALN: // PAL-N, Uruguay, Paraguay
1437: case PALNc: // PAL-Nc, Argentinia
1438: default: // TODO: set mode according to other standards
1439: DecoderMaskByte(card, 0x122, 0x03, 0x00); // Television Standard: User programmed
1440: DecoderWriteByte(card, 0x116, 90); // Main Reads per Line
1441: DecoderWriteByte(card, 0x11A, 1); // Vline Count Init
1442: DecoderWriteByte(card, 0x11C, 0x13); // Pixel State Reset Value / BT.656 Mode / Sync Active Low
1443: DecoderWriteByte(card, 0x129, 23); // Start- and End Row
1444: DecoderWriteByte(card, 0x12A, 310 & 0xFF);
1445: DecoderWriteByte(card, 0x12B, (310>>4)&0x70);
1446: DecoderWriteByte(card, 0x12C, 264 & 0xFF); // Start- and End Column
1447: DecoderWriteByte(card, 0x12D, 1703 & 0xFF);
1448: DecoderWriteByte(card, 0x12E, ((1703>>4)&0x70)|((264>>8)&0x07));
1449: DecoderWriteByte(card, 0x132, 260 & 0xFF); // SAV Column
1450: DecoderWriteByte(card, 0x133, 1704 & 0xFF); // EAV Column
1451: DecoderWriteByte(card, 0x134, ((1704>>4)&0x70)|((260>>8)&0x07));
1452: DecoderWriteByte(card, 0x12F, (21&0x1F)|((310>>3)&0x20)|(0<<6)|((312>>1)&0x80)); // VCode Zero...
1453: DecoderWriteByte(card, 0x130, 310&0xFF); // ... and VCode Even
1454: DecoderWriteByte(card, 0x131, 312&0xFF); // ... and FCode
1455: break;
1456: }
1457: DecoderWriteByte(card, 0x045, 0x00); // disable compares and panic mode
1458: DecoderWriteByte(card, 0x094, 0x00); // disable TOS Detect
1459: DecoderMaskByte(card, 0x109, 0x30, 0x00); // Display Override off, don't change OSD, Background
1460: DecoderWriteByte(card, 0x112, 0x00); // Disable Horizontal 2:1 Filter
1461: DecoderWriteByte(card, 0x113, 0x14); // FreezeMode 1 / 3:2 Pulldown / Repeat First Field / Top Field First
1462: DecoderWriteByte(card, 0x114, ( 5 <<3)|( 0 <<1)|( 0 <<2)|( 1 <<7)); // VideoMode/FilterEnable/FilterAB/FieldSyncEnable
1463: DecoderWriteByte(card, 0x115, 0); // Horizontal Filter Scale
1464: DecoderWriteByte(card, 0x117, 0x80); // Automatic Field Inversion Correction
1465: // DecoderWriteByte(card, 0x117, 0x00); // no Automatic Field Inversion Correction
1466: DecoderWriteByte(card, 0x118, 0); // Horizontal Pan and Scan Word Offset (signed)
1467: DecoderWriteByte(card, 0x119, 0); // Vertical Pan and Scan Line Offset
1468: DecoderWriteByte(card, 0x11B, 0x00); // Override Picture Width
1469: // if (0) { // letterbox
1470: // DecoderWriteByte(card, 0x114, (DecoderReadByte(card, 0x114) & ~0x78) | 0x40); // mode 8
1471: // DecoderWriteByte(card, 0x129, 0x35);
1472: // DecoderWriteByte(card, 0x12A, 0xE7);
1473: // DecoderWriteByte(card, 0x114, DecoderReadByte(card, 0x114) & ~0x77); // ???
1474: // } else {
1475: // if (0) { // MPEG-1
1476: // DecoderWriteByte(card, 0x114, (DecoderReadByte(card, 0x114) & ~0x78) | 0x10); // mode 2
1477: // } else { // MPEG-2
1478: // DecoderWriteByte(card, 0x114, (DecoderReadByte(card, 0x114) & ~0x78) | 0x28); // mode 5
1479: // }
1480: // }
1481: L64021InstallIntr(card); // Set the interrupt masks, again
1482:
1483: return 0;
1484: }
1485:
1486: int L64021Init(struct cvdv_cards *card) {
1487: printk(KERN_DEBUG LOGNAME ": -- L64021Init\n");
1488: L64021Reset(card);
1489: L64021Setup(card);
1490: VideoSetBackground(card, 1, 0, 0, 0); // black
1491: DecoderWriteByte(card, 0x135, 0x01); // Enable Video Out, Disable SPU Mix
1492: DecoderWriteByte(card,0x11C,0x13); // Pixel State Reset Value / BT.656 Mode / Sync Active Low
1493: L64021InstallIntr(card);
1494: return 0;
1495: }
1496:
1497:
LinuxTV legacy CVS <linuxtv.org/cvs>