📄 decoder.c
字号:
/* decoder.c Copyright (C) Christian Wolff for convergence integrated media. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#define __NO_VERSION__#include "decoder.h"#include "l64021.h"#include "video.h"#include "audio.h"#include "streams.h"#include "osd.h"#include "dram.h"#include "cvdv.h"int DecoderGetNavi(struct cvdv_cards *card, u8 *navidata) { if (card->navihead == card->navitail) return 0; MDEBUG(3, ": Retreiving NaviPack\n"); memcpy(navidata, &card->navibuffer[card->navitail], NAVISIZE); card->navitail += NAVISIZE; if (card->navitail >= NAVIBUFFERSIZE) card->navitail = 0; return NAVISIZE;}// returns 1 on overrun, 0 on no errorint DecoderQueueNavi(struct cvdv_cards *card, u8 *navidata) { memcpy(&card->navibuffer[card->navihead], navidata, NAVISIZE); card->navihead += NAVISIZE; if (card->navihead >= NAVIBUFFERSIZE) card->navihead = 0; if (card->navihead == card->navitail) { MDEBUG(3, ": NaviPack buffer overflow\n"); card->navitail += NAVISIZE; if (card->navitail >= NAVIBUFFERSIZE) card->navitail = 0; return 1; } return 0;}u32 ParseSCR(const u8 *data) { u32 SCR_base=0; u8 scrdata[9]; copy_from_user (scrdata, data, 9); if ((!scrdata[0]) && (!scrdata[1]) && (scrdata[2]==1) && (scrdata[3]==0xBA) && ((scrdata[4]&0xC0)==0x40)) { SCR_base=((scrdata[4]>>3)&0x07); SCR_base=(SCR_base<<2) | (scrdata[4]&0x03); SCR_base=(SCR_base<<8) | scrdata[5]; SCR_base=(SCR_base<<5) | ((scrdata[6]>>3)&0x1F); SCR_base=(SCR_base<<2) | (scrdata[6]&0x03); SCR_base=(SCR_base<<8) | scrdata[7]; SCR_base=(SCR_base<<5) | ((scrdata[8]>>3)&0x1F); } return SCR_base;}u32 SetSCR(struct cvdv_cards *card, u32 SCR_base) { MDEBUG(3, ": SCR in DVD Pack: 0x%08X\n",SCR_base); if (DecoderReadByte(card, 0x007) & 0x10) { // SCR already stopped DecoderWriteByte(card,0x009,SCR_base&0xFF); // Set SCR counter DecoderWriteByte(card,0x00A,(SCR_base>>8)&0xFF); DecoderWriteByte(card,0x00B,(SCR_base>>16)&0xFF); DecoderWriteByte(card,0x00C,(SCR_base>>24)&0xFF); } else { DecoderMaskByte(card,0x007,0xD2,0xD2); // Set 0x10, halt SCR counter DecoderWriteByte(card,0x009,SCR_base&0xFF); // Set SCR counter DecoderWriteByte(card,0x00A,(SCR_base>>8)&0xFF); DecoderWriteByte(card,0x00B,(SCR_base>>16)&0xFF); DecoderWriteByte(card,0x00C,(SCR_base>>24)&0xFF); DecoderMaskByte(card,0x007,0xD2,0xC2); // Del 0x10, SCR counter run } return SCR_base;}void DecoderPause(struct cvdv_cards *card) { DecoderMaskByte(card, 0x007, 0xD2, 0xD2); // Set 0x010, halt SCR counter AudioSetPlayMode(card, MAUDIO_PAUSE); DecoderStopDecode(card); card->videostate.play_state=VIDEO_FREEZED; card->videoffwd = 0; card->videoslow = 0;}void DecoderUnPause(struct cvdv_cards *card) { DecoderStartDecode(card); card->videoffwd = 0; AudioSetPlayMode(card, MAUDIO_PLAY); DecoderMaskByte(card, 0x007, 0xD2, 0xC2); // Del 0x010, SCR counter run card->videostate.play_state=VIDEO_PLAYING;; card->videoslow = 0;}void CloseCard(struct cvdv_cards *card) {#ifdef NOINT spin_lock(&card->timelock); del_timer(&card->timer); spin_unlock(&card->timelock);#endif MargiFlush(card); MDEBUG(1, ": Closing card\n"); card->DecoderOpen = 1; DecoderClose(card); DecoderUnPrepare(card); DecoderStreamReset(card); DecoderSetupReset(card); VideoSetBackground(card, 1, 0, 0, 0); AudioClose(card); OSDClose(card); L64021Init(card); MargiFreeBuffers(card); OSDOpen(card, 50, 50, 150, 150, 2, 1); OSDTest(card);}void DecoderReadAudioInfo(struct cvdv_cards *card) { u8 data; static int bitrates[17] = {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0}; struct AudioParam *audio = &card->stream.audio; data = DecoderReadByte(card, 0x150); audio->mpeg.present = data & 0x60; // MPEG Layer Code 00 reserverd, we can assume valid MPEG params if (audio->mpeg.present) { audio->mpeg.MPEG2 = data & 0x80; audio->mpeg.layer = 4 - ((data >> 5) & 0x03); if (data & 0x0F) { if ((data & 0x0F) == 1) audio->mpeg.bitrate = 32; else switch (audio->mpeg.layer) { case 1: audio->mpeg.bitrate = 32 * (data & 0x0F); break; // Layer I case 2: audio->mpeg.bitrate = bitrates[(data & 0x0F) + 1]; break; // Layer II default: audio->mpeg.bitrate = bitrates[data & 0x0F]; // Layer III } } else audio->mpeg.bitrate = 0; data = DecoderReadByte(card, 0x151); switch ((data >> 6) & 0x03) { case 0: audio->mpeg.samplefreq = 44; break; case 1: audio->mpeg.samplefreq = 48; break; case 2: audio->mpeg.samplefreq = 32; break; default: audio->mpeg.samplefreq = 0; // invalid } audio->mpeg.mode = (data >> 3) & 0x03; audio->mpeg.modeext = (data >> 1) & 0x03; audio->mpeg.copyright = data & 0x01; data=DecoderReadByte(card, 0x152); audio->mpeg.original = data & 0x80; audio->mpeg.emphasis = (data >> 5) & 0x03; } data = DecoderReadByte(card, 0x153); audio->ac3.present = (data != 0); // value 0 for bits 0..5 forbidden, we can assume valid ac3 params if (audio->ac3.present) { audio->ac3.acmod = (data >> 5) & 0x07; audio->ac3.dialnorm = data & 0x1F; data = DecoderReadByte(card, 0x154); audio->ac3.bsmod = (data >> 5) & 0x07; audio->ac3.dialnorm2 = data > 0x1F; data = DecoderReadByte(card, 0x155); audio->ac3.surmixlev = (data >> 6) & 0x03; audio->ac3.mixlevel = (data >> 1) & 0x1F; data = DecoderReadByte(card, 0x156); audio->ac3.cmixlev = (data >> 6) & 0x03; audio->ac3.mixlevel2 = (data >> 1) & 0x1F; data = DecoderReadByte(card, 0x157); audio->ac3.fscod = (data >> 6) & 0x03; audio->ac3.lfeon = (data >> 5) & 0x01; audio->ac3.bsid = data & 0x1F; data = DecoderReadByte(card, 0x158); audio->ac3.dsurmod = (data >> 6) & 0x03; audio->ac3.frmsizecod = data & 0x3F; audio->ac3.langcod = DecoderReadByte(card, 0x159); audio->ac3.langcod2 = DecoderReadByte(card, 0x15A); audio->ac3.timecod = DecoderReadByte(card, 0x15B); data = DecoderReadByte(card, 0x15C); audio->ac3.timecod = (audio->ac3.timecod << 6) | ((data >> 2) & 0x3F); audio->ac3.roomtyp = data & 0x03; audio->ac3.timecod2 = DecoderReadByte(card, 0x15D); data = DecoderReadByte(card, 0x15E); audio->ac3.timecod2 = (audio->ac3.timecod2 << 6) | ((data >> 2) & 0x3F); audio->ac3.roomtyp2 = data & 0x03; } audio->pcm.present =! (DecoderReadByte(card, 0x161) & 0x20); // PCM FIFO not empty? Then, we can assume valid LPCM params if (audio->pcm.present) { data = DecoderReadByte(card, 0x15F); audio->pcm.audio_frm_num = (data >> 3) & 0x1F; audio->pcm.num_of_audio_ch = data & 0x07; data = DecoderReadByte(card, 0x160); audio->pcm.Fs = (data >> 6) & 0x03; audio->pcm.quantization = (data >> 4) & 0x03; audio->pcm.emphasis = (data >> 2) & 0x03; audio->pcm.mute_bit = (data >> 1) & 0x01; } switch (card->setup.audioselect) { case audio_disable: audio->valid = 0; break; case audio_none: case audio_DTS: case audio_SDDS: if ((audio->valid = (audio->ac3.present || audio->pcm.present || audio->mpeg.present))) { if (audio->mpeg.present) { card->setup.audioselect = audio_MPEG; } else if (audio->pcm.present) { card->setup.audioselect = audio_LPCM; } else if (audio->ac3.present) { card->setup.audioselect = audio_AC3; } } else { audio->valid = 0; card->setup.audioselect = audio_none; } break; case audio_MPEG: // MPEG Audio case audio_MPEG_EXT: // MPEG Audio with extension stream audio->valid = audio->mpeg.present; break; case audio_LPCM: // Linear Pulse Code fe_modulation_t LPCM audio->valid = audio->pcm.present; break; case audio_AC3: // AC-3 audio->valid = audio->ac3.present; break; } MDEBUG(1, ": -- DecoderReadAudioInfo - type/valid %d/%d:\n", card->setup.audioselect, audio->valid); if (audio->mpeg.present || audio->ac3.present || audio->pcm.present) MDEBUG(1, ": Audio - Decoded parameters:\n"); if (audio->mpeg.present) MDEBUG(1, ": MPEG%s Layer %d, %d kHz, %d kbps, %s, %s%s, %s emphasis\n", ((audio->mpeg.MPEG2) ? "2" : "1"), audio->mpeg.layer, audio->mpeg.samplefreq, audio->mpeg.bitrate, ((audio->mpeg.mode == 0) ? "stereo" : ((audio->mpeg.mode == 1) ? "joint stereo" : ((audio->mpeg.mode == 2) ? "dual channel" : "single channel"))), ((audio->mpeg.copyright) ? "copyrighted " : ""), ((audio->mpeg.original) ? "original" : "copy"), ((audio->mpeg.emphasis == 0) ? "no" : ((audio->mpeg.emphasis == 1) ? "50/15 usec." : ((audio->mpeg.emphasis == 2) ? "invalid" : "J.17"))) ); if (audio->ac3.present) MDEBUG(1, ": 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", audio->ac3.acmod, audio->ac3.bsmod, audio->ac3.dialnorm, audio->ac3.dialnorm2, audio->ac3.surmixlev, audio->ac3.mixlevel, audio->ac3.cmixlev, audio->ac3.mixlevel2, audio->ac3.fscod, audio->ac3.lfeon, audio->ac3.bsid, audio->ac3.dsurmod, audio->ac3.frmsizecod, audio->ac3.langcod, audio->ac3.langcod2, audio->ac3.timecod, audio->ac3.roomtyp, audio->ac3.timecod2, audio->ac3.roomtyp2); if (audio->pcm.present) MDEBUG(1, ": LPCM audio_frm_num=%d num_of_audio_ch=%d Fs=%d quantization=%d emphasis=%d mute_bit=%d\n", audio->pcm.audio_frm_num, audio->pcm.num_of_audio_ch, audio->pcm.Fs, audio->pcm.quantization, audio->pcm.emphasis, audio->pcm.mute_bit);}void DecoderReadAuxFifo(struct cvdv_cards *card) { int i = 0; u8 data; int layer; struct StreamInfo *stream = &card->stream; MDEBUG(3, ": AUX - %03X ", card->AuxFifo[card->AuxFifoTail]); while (card->AuxFifoHead != card->AuxFifoTail) { layer = (card->AuxFifo[card->AuxFifoTail] >> 8) & 0x07; data = card->AuxFifo[card->AuxFifoTail] & 0xFF; card->AuxFifoTail = (card->AuxFifoTail + 1) & FIFO_MASK; if (layer != card->AuxFifoLayer) { // start of a new layer? i = 0; card->AuxFifoLayer = layer; } else i++; switch (layer) { // layer code case 0: // sequence header if (! stream->sh.valid) switch (i) { case 0: stream->sh.hsize = data & 0x0F; break; case 1: stream->sh.hsize = (stream->sh.hsize << 8) | data; stream->hsize = stream->sh.hsize; break; case 2: stream->sh.vsize = data & 0x0F; break; case 3: stream->sh.vsize = (stream->sh.vsize << 8) | data; stream->vsize = stream->sh.vsize; break; case 4: stream->sh.aspectratio = data & 0x0F; break; case 5: stream->sh.frameratecode = data & 0x0F; break; case 6: stream->sh.bitrate = data & 0x03; break; case 7: stream->sh.bitrate = (stream->sh.bitrate << 8) | data; break; case 8: stream->sh.bitrate = (stream->sh.bitrate << 8) | data; stream->bitrate = stream->sh.bitrate; break; case 9: stream->sh.vbvbuffersize = data & 0x03; break; case 10: stream->sh.vbvbuffersize = (stream->sh.vbvbuffersize << 8) | data; stream->vbvbuffersize = stream->sh.vbvbuffersize; break; case 11: stream->sh.constrained = data & 0x01; stream->sh.valid = 1; MDEBUG(1, ": AUX - MPEG1 - %dx%d %s %s fps, %d bps, %d kByte vbv%s\n", stream->sh.hsize, stream->sh.vsize, ((stream->sh.aspectratio == 1) ? "1:1" :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -