Annotation of margi2/streams.c, revision 1.1
1.1 ! cvs 1: /*
! 2: streams.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 "streams.h"
! 24: #include "dram.h"
! 25: #include "l64021.h"
! 26: #include "video.h"
! 27: #include "audio.h"
! 28:
! 29: // Frees allocated channel buffers
! 30: int DecoderKillChannelBuffers(struct cvdv_cards *card)
! 31: {
! 32: printk(KERN_DEBUG LOGNAME ": -- DecoderKillChannelBuffers\n");
! 33: DecoderStopDecode(card);
! 34: DRAMFree(card, card->VideoES);
! 35: card->VideoES = BLANK;
! 36: DRAMFree(card, card->AudioES);
! 37: card->AudioES = BLANK;
! 38: DRAMFree(card, card->VideoPES);
! 39: card->VideoPES = BLANK;
! 40: DRAMFree(card, card->DataDump);
! 41: card->DataDump = BLANK;
! 42: DRAMFree(card, card->AudioPES);
! 43: card->AudioPES = BLANK;
! 44: DRAMFree(card, card->NaviBank);
! 45: card->NaviBank = BLANK;
! 46: card->ChannelBuffersAllocated = 0;
! 47: // DecoderWriteWord(
! 48: return 0;
! 49: }
! 50:
! 51: // Allocates channel buffers
! 52: // All sizes in bytes, preferably multiple of 256 (will be rounded up otherwise)
! 53: int DecoderSetChannelBuffers(struct cvdv_cards *card, int VideoES, // Video ES Channel Buffer size, e.g. 229376 byte for NTSC
! 54: int AudioES, // Audio ES Channel Buffer size, 4096 byte
! 55: int VideoPES, // Video PES Header / SPU Channel Buffer size, 512 byte
! 56: int DataDump, // Data Dump Channel Buffer size, e.g. 80896 byte
! 57: int AudioPES, // Audio PES Header / System Channel Buffer size, 512 byte
! 58: int NaviBank)
! 59: { // Navi Bank Channel Buffer size, 2048 byte
! 60: #define BUFFERSET(buf,adr,align) if (buf>0) {\
! 61: if (buf&((1<<align)-1)) buf=(buf&~((1<<align)-1))+(1<<align);\
! 62: addr=DRAMAlloc(card,buf,1<<align);\
! 63: if (addr==BLANK) return adr;\
! 64: card->buf=addr;\
! 65: addr>>=align;\
! 66: DecoderWriteByte(card,adr,addr&0xFF);\
! 67: DecoderWriteByte(card,adr+1,(addr>>8)&(0x003F));\
! 68: addr+=(buf>>align);\
! 69: DecoderWriteByte(card,adr+2,(addr-1)&0xFF);\
! 70: DecoderWriteByte(card,adr+3,((addr-1)>>8)&0x003F);\
! 71: }
! 72: u32 addr;
! 73: printk(KERN_DEBUG LOGNAME ": -- DecoderSetChannelBuffers\n");
! 74: //DecoderStopDecode(card);
! 75: DecoderStopChannel(card);
! 76: VideoES >>= 1; // change to word sizes
! 77: AudioES >>= 1;
! 78: VideoPES >>= 1;
! 79: DataDump >>= 1;
! 80: AudioPES >>= 1;
! 81: NaviBank >>= 1;
! 82: if (card->ChannelBuffersAllocated)
! 83: DecoderKillChannelBuffers(card);
! 84: BUFFERSET(VideoES, 0x048, 7);
! 85: BUFFERSET(AudioES, 0x04C, 7);
! 86: BUFFERSET(VideoPES, 0x050, 7);
! 87: BUFFERSET(DataDump, 0x054, 7);
! 88: BUFFERSET(AudioPES, 0x058, 7);
! 89: BUFFERSET(NaviBank, 0x05C, 7);
! 90:
! 91: card->VideoESSize = VideoES;
! 92: card->AudioESSize = AudioES;
! 93: card->VideoPESSize = VideoPES;
! 94: card->DataDumpSize = DataDump;
! 95: card->AudioPESSize = AudioPES;
! 96: card->NaviBankSize = NaviBank;
! 97:
! 98: DecoderWriteByte(card, 0x044, 0x7F);
! 99: DecoderWriteByte(card, 0x044, 0x01);
! 100: if (NaviBank) {
! 101: card->reg07B |= 0x10; // navi pack counter enable
! 102: DecoderWriteByte(card, 0x07B, card->reg07B);
! 103: //DecoderSetByte(card,0x07B,0x10); // navi pack counter enable
! 104: card->NaviPackAddress =
! 105: (DecoderReadWord(card, 0x05C) & 0x3FFF) << 7;
! 106: //printk(KERN_DEBUG LOGNAME ": navi bank init'ed: 0x%08X\n",card->NaviPackAddress);
! 107: } else {
! 108: card->reg07B &= ~0x10; // navi pack counter disable
! 109: DecoderWriteByte(card, 0x07B, card->reg07B);
! 110: //DecoderDelByte(card,0x07B,0x10); // navi pack counter disable
! 111: card->NaviPackAddress = 0;
! 112: }
! 113: card->ChannelBuffersAllocated = 1;
! 114: #undef BUFFERSET
! 115: return 0;
! 116: }
! 117:
! 118: //int DecoderReadFifo
! 119:
! 120: int DecoderUnPrepare(struct cvdv_cards *card)
! 121: {
! 122: printk(KERN_ERR LOGNAME ": -- DecoderUnPrepare\n");
! 123: //DecoderStopDecode(card);
! 124: DecoderStopChannel(card);
! 125: DecoderKillChannelBuffers(card);
! 126: return 0;
! 127: }
! 128:
! 129: void DecoderPrepare(struct cvdv_cards *card)
! 130: {
! 131: //VideoSetBackground(card,0,0,0,0); // Video on black
! 132: VideoSetBackground(card, 1, 0, 0, 0); // black
! 133: //VideoSetBackground(card,2,83,90,249); // Red
! 134: //VideoSetBackground(card,2,155,53,53); // Green
! 135: //VideoSetBackground(card,2,35,212,114); // Blue
! 136: //VideoSetBackground(card,2,4,128,128); // Black
! 137: //VideoSetBackground(card,3,155,53,53); // Video on Green
! 138:
! 139: // DecoderWriteByte(card,0x044,0x00); // Reset channel buffers on error
! 140: // DecoderWriteByte(card,0x044,0x01); // don't Reset channel buffers on error
! 141:
! 142: DecoderWriteByte(card, 0x040, 0x01); // Reset Aux FIFO
! 143: DecoderWriteByte(card, 0x041, 0x01); // Reset Data FIFO
! 144: //DecoderWriteByte(card,0x044,0x7E); // Reset channel buffers, Reset channel buffers on error
! 145: DecoderWriteByte(card, 0x044, 0x7F); // Reset channel buffers, don't Reset channel buffers on error
! 146: // udelay(100);
! 147: // DecoderWriteByte(card,0x040,0x00); // Reset Aux FIFO
! 148: // DecoderWriteByte(card,0x041,0x00); // Reset Data FIFO
! 149: // DecoderDelByte(card,0x044,0x7E); // Reset channel buffers
! 150: }
! 151:
! 152: // Selects audio type MPEG and sets stream ID's
! 153: // AID: -1=all MPEG, Audio Stream ID: 0..31
! 154: // AExt: -1=unused, Audio Stream Extension ID: 0..31, only used if AType=5
! 155: void DecoderSelectAudioID(struct cvdv_cards *card)
! 156: {
! 157: int AID = card->setup.audioID;
! 158: int AExt = card->setup.audioIDext;
! 159: printk(KERN_DEBUG LOGNAME ": -- SelectAudio %d %d\n", AID, AExt);
! 160: DecoderWriteByte(card, 0x07C, AExt & 0x1F); // Audio Stream Extension ID
! 161: card->reg08F = (card->reg08F & ~0x1F) | (AID & 0x1F);
! 162: DecoderWriteByte(card, 0x08F, card->reg08F);
! 163: //DecoderMaskByte(card,0x08F,0x1F,AID&0x1F); // Set Stream ID
! 164: }
! 165:
! 166: // AHeader: 0=No Headers, 1=first PTS/DTS header, 2=all headers, 3=All with PTS/DTS
! 167: // AType: 0=disable audio, 1=MPEG ID (MPEG 1), 2=Lin.PCM ID, 3=AC3 ID, 4=all MPEG (use only, if just one MPEG audio stream), 5=MPEG multichannel ID (MPEG 2)
! 168: // AID: -1=all MPEG, Audio Stream ID: 0..31
! 169: // AExt: -1=unused, Audio Stream Extension ID: 0..31, only used if AType=5
! 170: // IEC956: 0:MPEG/AC3 data on digital out 1:IEC956 data on digital S/PDIF out
! 171: void DecoderPrepareAudio(struct cvdv_cards *card)
! 172: {
! 173: int AHeader = 2;
! 174: int AType = 3;
! 175: int AID = card->setup.audioID;
! 176: int AExt = card->setup.audioIDext;
! 177: int IEC956 = card->setup.SPDIFmode;
! 178: printk(KERN_DEBUG LOGNAME ": -- PrepAudio %d %d %d %d %d\n",
! 179: AHeader, card->setup.audioselect, AID, AExt, IEC956);
! 180: switch (card->setup.audioselect) {
! 181: case audio_disable:
! 182: case audio_none:
! 183: case audio_SDDS:
! 184: AType = 0;
! 185: break;
! 186: case audio_MPEG: // MPEG Audio
! 187: AType = 1;
! 188: break;
! 189: case audio_MPEG_EXT: // MPEG Audio with extension stream
! 190: AType = 5;
! 191: break;
! 192: case audio_LPCM: // Linear Pulse Code Modulation LPCM
! 193: AType = 2;
! 194: break;
! 195: case audio_AC3: // AC-3
! 196: AType = 3;
! 197: break;
! 198: case audio_DTS: // DTS
! 199: AType = 8;
! 200: break;
! 201: }
! 202: if (AType <= 0) {
! 203: card->reg08F = 0x00; // disable audio and discard all packets
! 204: DecoderWriteByte(card, 0x08F, card->reg08F);
! 205: //DecoderWriteByte(card,0x08F,0x00); // disable audio and discard all packets
! 206: //DecoderMaskByte(card,0x093,0xC3,0xC0); // write no headers
! 207: card->reg093 = (card->reg093 & ~0x03); // write no headers
! 208: DecoderWriteByte(card, 0x093, card->reg093);
! 209: } else {
! 210: AudioOpen(card);
! 211: DecoderMaskByte(card, 0x165, 0x1F, 0x00); // reset the register
! 212: if (AType == 8) { // DTS
! 213: card->reg090 |= 0x01; // DTS in Transport Private 1 Stream stored in AudioES channel buffer
! 214: DecoderWriteByte(card, 0x090, card->reg090);
! 215: //DecoderSetByte(card,0x090,0x01); // DTS in Transport Private 1 Stream stored in AudioES channel buffer
! 216: AudioSetMode(card, 0);
! 217: DecoderSetByte(card, 0x165, 0x01);
! 218: AudioStartFormat(card);
! 219: } else if (AType == 3) { // AC3
! 220: card->reg090 |= 0x01; // AC3 in Transport Private 1 Stream stored in AudioES channel buffer
! 221: DecoderWriteByte(card, 0x090, card->reg090);
! 222: //DecoderSetByte(card,0x090,0x01); // AC3 in Transport Private 1 Stream stored in AudioES channel buffer
! 223: AudioSetMode(card, ((IEC956) ? 1 : 3));
! 224: } else if (AType == 2) { // PCM
! 225: card->reg090 |= 0x01; // PCM in Transport Private 1 Stream stored in AudioES channel buffer
! 226: DecoderWriteByte(card, 0x090, card->reg090);
! 227: //DecoderSetByte(card,0x090,0x01); // PCM in Transport Private 1 Stream stored in AudioES channel buffer
! 228: AudioSetMode(card, 4);
! 229: } else { // MPEG
! 230: card->reg090 &= ~0x01; // MPEG Audio stored in AudioES channel buffer
! 231: DecoderWriteByte(card, 0x090, card->reg090);
! 232: //DecoderDelByte(card,0x090,0x01); // MPEG Audio stored in AudioES channel buffer
! 233: if (AID < 0)
! 234: AType = 4;
! 235: if (AExt >= 0)
! 236: AType = 5;
! 237: else
! 238: AExt = -1;
! 239: AudioSetMode(card, ((IEC956) ? 0 : 2));
! 240: }
! 241: card->setup.audioID = AID;
! 242: card->setup.audioIDext = AExt;
! 243: DecoderSelectAudioID(card);
! 244: card->reg08F = (card->reg08F & ~0xE0) | ((AType & 0x07) << 5); // Set Stream Type
! 245: DecoderWriteByte(card, 0x08F, card->reg08F);
! 246: //DecoderMaskByte(card,0x08F,0xE0,(AType&0x07)<<5); // Set Stream Type
! 247: AudioSetVolume(card, 0xFF); // Set PCM scale to full volume
! 248: //DecoderMaskByte(card,0x093,0xC3,(AHeader&0x03)|0xC0); // write header select
! 249: card->reg093 = (card->reg093 & ~0x03) | (AHeader & 0x03); // write header select
! 250: DecoderWriteByte(card, 0x093, card->reg093);
! 251: // Mute the card and put it in play mode, then wait for the parameters to be parsed and un-mute if successful
! 252: //AudioMute(card,1);
! 253: if (AType > 0) {
! 254: AudioStartDecode(card);
! 255: //AudioSetPlayMode(card,AUDIO_PLAY);
! 256: AudioSetPlayMode(card, AUDIO_PAUSE);
! 257: }
! 258: //card->startingA=1;
! 259: }
! 260: card->lastaattr = 0;
! 261: }
! 262:
! 263: // VHeader: -1=disable Video, 0=No Headers, 1=first PTS/DTS header, 2=all headers, 3=All with PTS/DTS
! 264: // VID: -1=all MPEG, 0..15=Video Stream ID
! 265: void DecoderPrepareVideo(struct cvdv_cards *card)
! 266: {
! 267: int VHeader = 3;
! 268: int VID = card->setup.videoID;
! 269: if (VHeader < 0) {
! 270: card->reg091 = 0x00;
! 271: DecoderWriteByte(card, 0x091, card->reg091);
! 272: //DecoderWriteByte(card,0x091,0x00);
! 273: } else {
! 274: if (VID < 0) {
! 275: card->reg091 = ((VHeader & 0x03) << 6) | (2 << 4);
! 276: DecoderWriteByte(card, 0x091, card->reg091);
! 277: //DecoderWriteByte(card,0x091,((VHeader&0x03)<<6)|(2<<4));
! 278: } else {
! 279: card->reg091 =
! 280: ((VHeader & 0x03) << 6) | (1 << 4) | (VID &
! 281: 0x0F);
! 282: DecoderWriteByte(card, 0x091, card->reg091);
! 283: //DecoderWriteByte(card,0x091,((VHeader&0x03)<<6)|(1<<4)|(VID&0x0F));
! 284: }
! 285: }
! 286: }
! 287:
! 288: // Prepare Decoder for Elementary Streams, Disable Preparser
! 289: int DecoderPrepareES(struct cvdv_cards *card)
! 290: {
! 291: int i;
! 292: printk(KERN_DEBUG LOGNAME ": -- PrepareES\n");
! 293: //DecoderStopDecode(card);
! 294:
! 295: // DecoderWriteByte(card,0x05,0x00);
! 296:
! 297: DecoderMaskByte(card, 0x007, 0xCE, 0xC2 | (3 << 2)); // Stream Select: A/V Elementary Stream
! 298: //printk(KERN_DEBUG LOGNAME ": Int - A VideoES w/r addr: %08X %08X\n",
! 299: // (DecoderReadByte(card,0x060)|(DecoderReadByte(card,0x061)<<8)|(DecoderReadByte(card,0x062)<<16))<<2,
! 300: // (DecoderReadByte(card,0x06C)|(DecoderReadByte(card,0x06D)<<8)|(DecoderReadByte(card,0x06E)<<16))<<2);
! 301: // set the decoding buffers
! 302: card->reg093 = (card->reg093 & ~0xFC); // write no header
! 303: DecoderWriteByte(card, 0x093, card->reg093);
! 304: if ((i = DecoderSetChannelBuffers(card, 256000, 4096, 0, 0, 0, 0))) {
! 305: printk(KERN_ERR LOGNAME
! 306: ": SetDecoderBuffers failed for buffer at 0x%03X\n",
! 307: i);
! 308: DecoderKillChannelBuffers(card);
! 309: return 1;
! 310: }
! 311: //printk(KERN_DEBUG LOGNAME ": Int - B VideoES w/r addr: %08X %08X\n",
! 312: // (DecoderReadByte(card,0x060)|(DecoderReadByte(card,0x061)<<8)|(DecoderReadByte(card,0x062)<<16))<<2,
! 313: // (DecoderReadByte(card,0x06C)|(DecoderReadByte(card,0x06D)<<8)|(DecoderReadByte(card,0x06E)<<16))<<2);
! 314:
! 315: //printk(KERN_DEBUG LOGNAME ": Int - C VideoES w/r addr: %08X %08X\n",
! 316: // (DecoderReadByte(card,0x060)|(DecoderReadByte(card,0x061)<<8)|(DecoderReadByte(card,0x062)<<16))<<2,
! 317: // (DecoderReadByte(card,0x06C)|(DecoderReadByte(card,0x06D)<<8)|(DecoderReadByte(card,0x06E)<<16))<<2);
! 318:
! 319: // DecoderStartChannel(card);
! 320: // DecoderStartDecode(card);
! 321:
! 322: //printk(KERN_DEBUG LOGNAME ": Int - D VideoES w/r addr: %08X %08X\n",
! 323: // (DecoderReadByte(card,0x060)|(DecoderReadByte(card,0x061)<<8)|(DecoderReadByte(card,0x062)<<16))<<2,
! 324: // (DecoderReadByte(card,0x06C)|(DecoderReadByte(card,0x06D)<<8)|(DecoderReadByte(card,0x06E)<<16))<<2);
! 325:
! 326: DecoderPrepare(card);
! 327:
! 328: return 0;
! 329: }
! 330:
! 331: // Prepare Decoder for Packetised Elementary Streams, set parameters of Preparser
! 332: int DecoderPreparePES(struct cvdv_cards *card)
! 333: {
! 334:
! 335: // SPUID: -1=No SPU, 0..31=Display SPU of this ID
! 336: // DataDump: 0=disable DataDump, 1=process DataDump Substreams
! 337: // PackHeader: 0=write no headers, 1=write one header, 2=write all headers
! 338: // SysHeader: 0=write no headers, 1=write one header, 2=write all headers
! 339: // DSIHeader: 0=write no headers, 3=write PCI and DSI headers and packets
! 340: int i;
! 341: int SPUID = -1;
! 342: int DataDump = 0;
! 343: int PackHeader = 0;
! 344: int SysHeader = 0;
! 345: int DSIHeader = 0;
! 346:
! 347: printk(KERN_DEBUG LOGNAME ": -- PreparePES\n");
! 348: DecoderMaskByte(card, 0x007, 0xCE, 0xC2 | (0 << 2)); // Stream Select: A/V PES Packets
! 349:
! 350: if (SPUID < 0)
! 351: card->reg092 = 0; // Do we use SPU?
! 352: else
! 353: card->reg092 = 0x20 | (SPUID & 0x1F);
! 354: if (DataDump)
! 355: card->reg092 |= 0x40; // Do we use DataDump?
! 356: DecoderWriteByte(card, 0x092, card->reg092);
! 357: //DecoderMaskByte(card,0x093,0xFC,((DSIHeader&0x03)<<6)|((PackHeader&0x03)<<4)|((SysHeader&0x03)<<2));
! 358: card->reg093 =
! 359: (card->reg093 & ~0xFC) | (((DSIHeader & 0x03) << 6) |
! 360: ((PackHeader & 0x03) << 4) |
! 361: ((SysHeader & 0x03) << 2));
! 362: DecoderWriteByte(card, 0x093, card->reg093);
! 363: // set the decoding buffers
! 364: if (
! 365: (i =
! 366: DecoderSetChannelBuffers(card, 256000, 4096, 512, 0, 512,
! 367: 0))) {
! 368: printk(KERN_ERR LOGNAME
! 369: ": SetDecoderBuffers failed for buffer at 0x%03X\n",
! 370: i);
! 371: DecoderKillChannelBuffers(card);
! 372: return 1;
! 373: }
! 374:
! 375: DecoderPrepare(card);
! 376:
! 377: return 0;
! 378: }
! 379:
! 380:
! 381: // Prepare Decoder for MPEG 1 Systems Streams or MPEG 2 Program Streams
! 382: // SPUID: -1:ignore, 0...15 SPU Substream ID
! 383: // DataDump: 0:disable data dump stream, 1:enable data dump stream
! 384: // PackHeader: 0:write no headers, 1:write one header, 2:write all headers, 3:always discard
! 385: // SysHeader: 0:always discard, 1:write one header, 2:write all headers, 3:always discard
! 386: // DSIHeader: 0:write no DSI or PCI headers, 3:write DSI and PCI headers + packets
! 387: // DVD: 0: normal MPEG-2 data, 1: DVD stream with navi pack data
! 388: int DecoderPreparePS(struct cvdv_cards *card,
! 389: int SPUID, int DataDump,
! 390: int PackHeader, int SysHeader, int DSIHeader, int DVD)
! 391: {
! 392: int i=0;
! 393: printk(KERN_DEBUG LOGNAME ": -- PreparePS %s\n",
! 394: ((DVD) ? "DVD" : ""));
! 395: //DecoderStopDecode(card);
! 396: DecoderMaskByte(card, 0x007, 0xCE, 0xC2 | (1 << 2)); // Stream Select: MPEG1 System / MPEG2 Program Stream
! 397:
! 398: if (SPUID < 0)
! 399: card->reg092 = 0; // Do we use SPU?
! 400: else
! 401: card->reg092 = 0x20 | (SPUID & 0x1F);
! 402: if (DataDump)
! 403: card->reg092 |= 0x40; // Do we use DataDump?
! 404: DecoderWriteByte(card, 0x092, card->reg092);
! 405: //DecoderMaskByte(card,0x093,0xFC,((DSIHeader&0x03)<<6)|((PackHeader&0x03)<<4)|((SysHeader&0x03)<<2));
! 406: card->reg093 =
! 407: (card->reg093 & ~0xFC) | (((DSIHeader & 0x03) << 6) |
! 408: ((PackHeader & 0x03) << 4) |
! 409: ((SysHeader & 0x03) << 2));
! 410: DecoderWriteByte(card, 0x093, card->reg093);
! 411: // set the decoding buffers
! 412: if (DVD) { // do we need SPU-, navi- and datadump-buffers?
! 413:
! 414: // if(card->videomode == NTSC)
! 415: i = DecoderSetChannelBuffers(card, 340000, 32768, 16384, 0,
! 416: 512,2048) ;
! 417: //else
! 418: // i = DecoderSetChannelBuffers(card, 291878, 16384, 512, 0,
! 419: // 512,0) ;
! 420:
! 421: if (i) {
! 422: printk(KERN_ERR LOGNAME
! 423: ": SetDecoderBuffers failed for buffer at 0x%03X\n",
! 424: i);
! 425: DecoderKillChannelBuffers(card);
! 426: return 1;
! 427: }
! 428:
! 429: } else { // normal PS
! 430: if (
! 431: (i =
! 432: DecoderSetChannelBuffers(card, 300000, 64288, 512,
! 433: 0, 512, 0))) {
! 434: printk(KERN_ERR LOGNAME
! 435: ": SetDecoderBuffers failed for buffer at 0x%03X\n",
! 436: i);
! 437: DecoderKillChannelBuffers(card);
! 438: return 1;
! 439: }
! 440: }
! 441:
! 442: DecoderPrepare(card);
! 443:
! 444: return 0;
! 445: }
LinuxTV legacy CVS <linuxtv.org/cvs>