//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DriverParametersKeyWrite -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // NTSTATUS DriverParametersKeyWrite( WDFDRIVER Driver, DtString* pKeyName, DtString* pValueName, Int64 BinValue, DtString* pStrValue) { NTSTATUS NtStatus; WDFKEY ParametersKey; WDFKEY Key = NULL; WDFSTRING WdfString; DT_ASSERT(KeGetCurrentIrql()<=PASSIVE_LEVEL); // Check if the registry path already exists. If not, create the registry path. if (!DT_SUCCESS(CheckAndCreateRegistryPath(Driver, pKeyName))) return STATUS_UNSUCCESSFUL; // Open the drivers parameters key (under services) NtStatus = WdfDriverOpenParametersRegistryKey(Driver, KEY_WRITE, WDF_NO_OBJECT_ATTRIBUTES, &ParametersKey); if (!NT_SUCCESS(NtStatus)) { DtDbgOut(ERR, SAL, "WdfDriverOpenParametersRegistryKey failed. Error: 0x%x", NtStatus); return NtStatus; } // Open the key (including part of path) NtStatus = WdfRegistryOpenKey(ParametersKey, pKeyName, KEY_WRITE, WDF_NO_OBJECT_ATTRIBUTES, &Key); if (!NT_SUCCESS(NtStatus)) DtDbgOut(ERR, SAL, "WdfRegistryOpenKey failed. Error: 0x%x", NtStatus); if (NT_SUCCESS(NtStatus)) { // Write string or binary value if (pStrValue != NULL) { // Set string attributes with the key as parent object, so that the string // object is freed when the key object is destroyed. If we donot do this the // string object is freed when the driver unloads, meaning that the each call // to DriverParametersKeyWrite result in an increase of memory usage, only // to be freed on the unload. WDF_OBJECT_ATTRIBUTES WdfStringAttr; WDF_OBJECT_ATTRIBUTES_INIT(&WdfStringAttr); WdfStringAttr.ParentObject = Key; NtStatus = WdfStringCreate(pStrValue, &WdfStringAttr, &WdfString); if (NT_SUCCESS(NtStatus)) NtStatus = WdfRegistryAssignString(Key, pValueName, WdfString); } else NtStatus = WdfRegistryAssignValue(Key, pValueName, REG_QWORD, sizeof(Int64), &BinValue); if (!NT_SUCCESS(NtStatus)) DtDbgOut(ERR, SAL, "WdfRegistryAssignValue failed. Error: 0x%x", NtStatus); } if (Key != NULL) WdfRegistryClose(Key); WdfRegistryClose(ParametersKey); return NtStatus; }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaPPBufferWriteData -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // // This function adds data to the current ping/pong buffer. If the buffer is full, // an error is returned // DtStatus DtaPPBufferWriteData( UInt8* pSourceBuffer, PPBuffer* pPPBuffer, UInt DataSize) { UInt8* pDst = NULL; UInt PPBufferIndex = pPPBuffer->m_CurRwBufferId; DT_ASSERT(pPPBuffer->m_pDmaChannel->m_DmaDirection == DT_DMA_DIRECTION_TO_DEVICE); DT_ASSERT(!DtaPPBufferIsFull(pPPBuffer, PPBufferIndex)); // Check if we do not exceed the size of the available buffer space // If so, we have an overflow situation! if (pPPBuffer->m_BufTransferSize[PPBufferIndex]+DataSize > pPPBuffer->m_BufSize[PPBufferIndex]) return DT_STATUS_BUFFER_OVERFLOW; // Calculate current location of the destiny for ping or pong buffer pDst = pPPBuffer->m_pBufStart + pPPBuffer->m_BufOffset[PPBufferIndex] + pPPBuffer->m_BufTransferSize[PPBufferIndex]; DtMemCopy(pDst, pSourceBuffer, DataSize); pPPBuffer->m_BufTransferSize[PPBufferIndex] += DataSize; return DT_STATUS_OK; }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsUnrefEventsObject -.-.-.-.-.-.-.-.-.-.-.-.-.-.-. // static void DtaEventsUnrefEventsObject(DtaDeviceData* pDvcData, DtaEvents* pDtaEvents) { if (DtAtomicDecrementReturn(&pDtaEvents->m_RefCount) == 0) { DT_ASSERT(pDtaEvents->m_pPrev == NULL); DT_ASSERT(pDtaEvents->m_pNext == NULL); DtMemFreePool(pDtaEvents, DTA_TAG); } }
void DtDpcWorker(unsigned long pContext) #endif { Bool DeQueue; Int OldState; DtDpc* pDpc = (DtDpc*)pContext; // Assume running... pDpc->m_pWorker(&pDpc->m_Args); do { DeQueue = FALSE; // Done, set to idle OldState = DtAtomicCompareExchange((Int*)&pDpc->m_State, DPC_STATE_BIT_RUNNING, 0); if (OldState != DPC_STATE_BIT_RUNNING) { // Failed, maybe queuing pending? if (OldState == (DPC_STATE_BIT_RUNNING|DPC_STATE_BIT_QUEUING)) { // Just set running flag to zero, but hold queuing OldState = DtAtomicCompareExchange((Int*)&pDpc->m_State, DPC_STATE_BIT_RUNNING|DPC_STATE_BIT_QUEUING, DPC_STATE_BIT_QUEUING); if (OldState != (DPC_STATE_BIT_RUNNING|DPC_STATE_BIT_QUEUING)) { // Whoops failed, queuing is now done so we can dequeue... DT_ASSERT(OldState == (DPC_STATE_BIT_RUNNING|DPC_STATE_BIT_QUEUING |DPC_STATE_BIT_QUEUED)); DeQueue = TRUE; } } else { DT_ASSERT(OldState == (DPC_STATE_BIT_RUNNING|DPC_STATE_BIT_QUEUING|DPC_STATE_BIT_QUEUED)); DeQueue = TRUE; } } if (DeQueue) { // Copy args pDpc->m_Args = pDpc->m_QueuedArgs; // Release queue, but keep running flag DtAtomicCompareExchange((Int*)&pDpc->m_State, DPC_STATE_BIT_RUNNING|DPC_STATE_BIT_QUEUING|DPC_STATE_BIT_QUEUED, DPC_STATE_BIT_RUNNING); // Run worker again with new args pDpc->m_pWorker(&pDpc->m_Args); } } while (DeQueue); }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaPPBufferReadDataFinished -.-.-.-.-.-.-.-.-.-.-.-.-.-.-. // void DtaPPBufferReadDataFinished(PPBuffer* pPPBuffer) { DtDbgOut(MAX, PP, "Start"); DT_ASSERT(pPPBuffer->m_pDmaChannel->m_DmaDirection == DT_DMA_DIRECTION_FROM_DEVICE); DtaPPBufferRWFinished(pPPBuffer); DtDbgOut(MAX, PP, "Exit"); }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaPPBufferInitialise -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // void DtaPPBufferInitialise( PPBuffer* pPPBuffer, UInt8* pBufferStart, DtPageList* pPageList, UInt BufSize, DmaChannel* pDmaChannel, DtaPPBufferGetLocAddrFunc pGetLocAddrFunc, void* pGetLocAddrContext, Bool AutoTransferAfterComplete) { UInt SizePerBufferPart; DT_ASSERT(BufSize % 2 == 0); SizePerBufferPart = BufSize/2; // Initialize pingpong buffer pPPBuffer->m_pBufStart = pBufferStart; pPPBuffer->m_pPageList = pPageList; pPPBuffer->m_BufSize[DTA_PPBUF_PING_ID] = SizePerBufferPart; pPPBuffer->m_BufSize[DTA_PPBUF_PONG_ID] = SizePerBufferPart; pPPBuffer->m_BufOffset[DTA_PPBUF_PING_ID] = 0; pPPBuffer->m_BufOffset[DTA_PPBUF_PONG_ID] = SizePerBufferPart; pPPBuffer->m_pDmaChannel = pDmaChannel; pPPBuffer->m_pGetLocAddrFunc = pGetLocAddrFunc; pPPBuffer->m_pGetLocAddrContext = pGetLocAddrContext; pPPBuffer->m_AutoTransferAfterComplete = AutoTransferAfterComplete; // Initialize internal values that may change during processing DtaPPBufferInitInternalStates(pPPBuffer, pDmaChannel->m_DmaDirection); DtaDmaReInitCallback(pDmaChannel, DtaPPBufferTransferDataCompleted, pPPBuffer); }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaGenlockApplyFracModeConfig -.-.-.-.-.-.-.-.-.-.-.-.-.-.- // DtStatus DtaGenlockApplyFracModeConfig(DtaDeviceData* pDvcData) { Int i, NewFracMode; DtaNonIpPort* pNonIpPort = NULL; DtaGenlock* pGenlData = &pDvcData->m_Genlock; DT_ASSERT(pGenlData->m_IsSupported); // Scan all ports to see if there is one for which frac mode is enabled NewFracMode = DTA_GENLOCK_FRACMODE_NA; for (i=0; i<pDvcData->m_NumNonIpPorts; i++) { pNonIpPort = &pDvcData->m_pNonIpPorts[i]; if (!pNonIpPort->m_CapFracMode) continue; // skip if port it doesnot support fractional mode if (pNonIpPort->m_IoCfg[DT_IOCONFIG_FRACMODE].m_Value == DT_IOCONFIG_FALSE) NewFracMode = DTA_GENLOCK_FRACMODE_OFF; else if (pNonIpPort->m_IoCfg[DT_IOCONFIG_FRACMODE].m_Value == DT_IOCONFIG_TRUE) NewFracMode = DTA_GENLOCK_FRACMODE_ON; // Currently fracmode must be the same for all ports, so we can exit the loop here break; } // If new mode is the same as current do nothing if (NewFracMode == pGenlData->m_FracMode) return DT_STATUS_OK; // Cache setting pGenlData->m_FracMode = NewFracMode; // Re-apply genref config to reflect new mode return DtaGenlockApplyGenRefConfig(pDvcData); }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaNonIpHdmiInterruptDisable -.-.-.-.-.-.-.-.-.-.-.-.-.-.- // DtStatus DtaNonIpHdmiInterruptDisable(DtaNonIpPort* pNonIpPort) { DT_ASSERT(pNonIpPort->m_CapHdmiRx); DT_RETURN_ON_ERROR(DtaI2cmInterruptDisable(&pNonIpPort->m_HdmiRx.m_I2c)); return DT_STATUS_OK; }
ff_audio_decoder_info::ff_audio_decoder_info(const AVCodecContext * _CodecContext): audio_decoder_info( new av_audio_decoder_info_impl(_CodecContext) ) { DT_ASSERT(NULL != _CodecContext); if (NULL == _CodecContext) { BOOST_THROW_EXCEPTION(errors::invalid_argument()); } }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaGetPerIntItvUS -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // // Returns the current periodic interval in micro seconds // UInt32 DtaGetPerIntItvUS(DtaDeviceData* pDvcData) { UInt64 Value64; DT_ASSERT(pDvcData->m_DevInfo.m_PerIntClkBit >= 17); Value64 = 1000000 * ((UInt64)1<<pDvcData->m_DevInfo.m_PerIntClkBit); return (UInt32)DtDivide64(Value64, pDvcData->m_DevInfo.m_RefClk, NULL); }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaPPBufferRWFinished -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // static void DtaPPBufferRWFinished(PPBuffer* pPPBuffer) { UInt OldState = pPPBuffer->m_BufState; UInt AddState; if (pPPBuffer->m_CurRwBufferId == DTA_PPBUF_PING_ID) AddState = DTA_PPBUF_STAT_PING; else AddState = DTA_PPBUF_STAT_PONG; DT_ASSERT((OldState & AddState) == 0); while (OldState != DtAtomicCompareExchange(&pPPBuffer->m_BufState, OldState, OldState | AddState)) { OldState = pPPBuffer->m_BufState; DT_ASSERT((OldState & AddState) == 0); } DtDbgOut(MAX, PP, "OldState: %xh NewState: %xh", OldState, OldState | AddState); DtaPPBufferSwap(&pPPBuffer->m_CurRwBufferId); }
video_decoder_ptr video_decoder_creator::create(video_decoder_info * _DecoderInfo, const additional_settings * _AdditionalSettings) { switch (_DecoderInfo->get_codec_base()) { case CODEC_BASE_FFMPEG: return video_decoder_ptr(new ff_video_decoder(_DecoderInfo, _AdditionalSettings)); break; default: DT_ASSERT(false); return video_decoder_ptr((video_decoder*)NULL); break; } }
void create_buffer(const audio_format * _AudioFormat, double _DurationMS, uint8_t * & _OutBuffer, size_t & _OutSizeBytes, int & _OutSamplesCount) { const double samplesCountDbl = _DurationMS / 1000.0 *_AudioFormat->get_sample_rate(); DT_ASSERT( samplesCountDbl < (double)(std::numeric_limits<int>::max)() ); // TODO? const int samplesCount = static_cast<int>(samplesCountDbl); const size_t sizeBytes = samplesCount * _AudioFormat->get_sample_align(); uint8_t * buffer = audio_data_common::alloc_buffer(sizeBytes); _OutBuffer = buffer; _OutSizeBytes = sizeBytes; _OutSamplesCount = samplesCount; }
audio_buffer_ptr audio_buffer::create(AudioBufferType bufferType, const audio_format * audioFormat) { audio_buffer * audioBuffer = NULL; switch (bufferType) { case audio_buffer_SameFormat: audioBuffer = new audio_buffer_same_format(audioFormat); break; default: DT_ASSERT(false); break; } return audio_buffer_ptr(audioBuffer); }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaM235x4Init -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // DtStatus DtaM235x4Init(DtaNonIpPort* pNonIpPort) { UInt32 Data; // Port must has a matrix-API register interface if (!pNonIpPort->m_CapMatrix) return DT_STATUS_NOT_SUPPORTED; DT_ASSERT(pNonIpPort->m_AsiSdiDeserItfType == ASI_SDI_DESER_ITF_FPGA_M23544G); DT_RETURN_ON_ERROR(DtaM235x4WriteRegister(pNonIpPort, M235X4_REG_JIT_DETECT, 0x24)); // Read revision DT_RETURN_ON_ERROR(DtaM235x4ReadRegister(pNonIpPort, M235X4_REG_DIE_REVISION, &Data)); switch (Data) { case 1: // The reclocker VCO may not lock at any SDI data rates because its VCO is // out of range. To center the M235x4's VCO locking range, the following register // settings must be written to the device: //Products Affected: M23544G-12P, die ID (register 01h) = 01h // M23554G-12P, die ID (register 01h) = 01h DT_RETURN_ON_ERROR(DtaM235x4WriteRegister(pNonIpPort, 0x22, 0x09)); DT_RETURN_ON_ERROR(DtaM235x4WriteRegister(pNonIpPort, 0x32, 0x3F)); DT_RETURN_ON_ERROR(DtaM235x4WriteRegister(pNonIpPort, 0x3F, 0x03)); DT_RETURN_ON_ERROR(DtaM235x4WriteRegister(pNonIpPort, 0x42, 0x2C)); DT_RETURN_ON_ERROR(DtaM235x4WriteRegister(pNonIpPort, M235X4_REG_RESET, 0x2)); break; case 4: DT_RETURN_ON_ERROR(DtaM235x4WriteRegister(pNonIpPort, 0x32, 0x3F)); DT_RETURN_ON_ERROR(DtaM235x4WriteRegister(pNonIpPort, 0x3F, 0x03)); DT_RETURN_ON_ERROR(DtaM235x4WriteRegister(pNonIpPort, M235X4_REG_RESET, 0x2)); break; case 5: // No errata. break; case 20: // No errata break; } // Use lower output swing of 400mVppd for port 0 DT_RETURN_ON_ERROR(DtaM235x4WriteRegister(pNonIpPort, M235X4_REG_OUTPUT0, 0x0D)); // Powerdown unsused port 1 DT_RETURN_ON_ERROR(DtaM235x4WriteRegister(pNonIpPort, M235X4_REG_OUTPUT1, 0x0C)); return DT_STATUS_OK; }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DriverParametersKeyDelete -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // NTSTATUS DriverParametersKeyDelete( WDFDRIVER Driver, DtString* pKeyName) { NTSTATUS NtStatus; WDFKEY ParametersKey; WDFKEY Key = NULL; DT_ASSERT(KeGetCurrentIrql()<=PASSIVE_LEVEL); // Open the drivers parameters key (under services) NtStatus = WdfDriverOpenParametersRegistryKey(Driver, KEY_WRITE, WDF_NO_OBJECT_ATTRIBUTES, &ParametersKey); if (!NT_SUCCESS(NtStatus)) { DtDbgOut(ERR, SAL, "WdfDriverOpenParametersRegistryKey failed. Error: 0x%x", NtStatus); return NtStatus; } // Open subkey NtStatus = WdfRegistryOpenKey(ParametersKey, pKeyName, KEY_WRITE, WDF_NO_OBJECT_ATTRIBUTES, &Key); if (!NT_SUCCESS(NtStatus)) { if (NtStatus == STATUS_OBJECT_NAME_NOT_FOUND) DtDbgOut(MAX, SAL, "WdfRegistryOpenKey error:'STATUS_OBJECT_NAME_NOT_FOUND'"); else DtDbgOut(ERR, SAL, "WdfRegistryOpenKey failed. Error: 0x%x", NtStatus); } if (NT_SUCCESS(NtStatus)) { // Delete the key NtStatus = WdfRegistryRemoveKey(Key); if (!NT_SUCCESS(NtStatus)) DtDbgOut(ERR, SAL, "WdfRegistryRemoveKey failed. Error: 0x%x", NtStatus); else Key = NULL; } if (Key != NULL) WdfRegistryClose(Key); WdfRegistryClose(ParametersKey); return NtStatus; }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaNonIpTxProcessFlags -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. // // This routine is called from: // - General periodic DPC to update status flags: DtaNonIpTxProcessFlagsFromDpc // - DeviceIoCtrl (GetFlags): DtaNonIpTxProcessFlagsFromUser // // Pre: Spinlock m_FlagsSpinlock is acquired // void DtaNonIpTxProcessFlags(DtaNonIpPort* pNonIpPort) { Int Status = 0; UInt32 TxStatus; DT_ASSERT(pNonIpPort->m_pTxRegs != NULL); if (pNonIpPort->m_CapMatrix) { TxStatus = DtaRegHdStatusGet(pNonIpPort->m_pTxRegs); if (TxStatus & DT_HD_STATUS_TXUFLERRINT_MSK) { Status |= DTA_TX_FIFO_UFL; DtaRegHdStatClrTxUflErrInt(pNonIpPort->m_pTxRegs); } if (TxStatus & DT_HD_STATUS_TXSYNCERRINT_MSK) { Status |= DTA_TX_SYNC_ERR; DtaRegHdStatClrTxSyncErrInt(pNonIpPort->m_pTxRegs); } } else { TxStatus = DtaRegTxStatGet(pNonIpPort->m_pTxRegs); if (TxStatus & DT_TXSTAT_UFLINT_MSK) { Status |= DTA_TX_FIFO_UFL; DtaRegTxStatClrUflInt(pNonIpPort->m_pTxRegs); } if (TxStatus & DT_TXSTAT_SYNCINT_MSK) { Status |= DTA_TX_SYNC_ERR; DtaRegTxStatClrSyncInt(pNonIpPort->m_pTxRegs); } if (TxStatus & DT_TXSTAT_SHORTINT_MSK) { Status |= DTA_TX_READBACK_ERR; DtaRegTxStatClrShortInt(pNonIpPort->m_pTxRegs); } } // Latch status flags pNonIpPort->m_FlagsLatched |= Status; pNonIpPort->m_Flags = Status; }
audio_encoder_queue_lame_impl::audio_encoder_queue_lame_impl(const audio_format * _AudioFormat, const audio_encoder_lame_utils::properties * _Properties) : m_Lame(NULL), m_AudioBuffer( audio_buffer::create( audio_buffer::audio_buffer_SameFormat, _AudioFormat ) ) , sampleRate_( _AudioFormat ? _AudioFormat->get_sample_rate() : 0 ), lastData_(false) { std::auto_ptr<lame_encoder_impl_internal> lameEnc = std::auto_ptr<lame_encoder_impl_internal>( new lame_encoder_impl_internal() ); lameEnc->set_input_sample_rate( _AudioFormat->get_sample_rate() ); lameEnc->set_channels_count( _AudioFormat->get_channels_count() ); if (1 == _AudioFormat->get_channels_count()) { lameEnc->set_stereo_mode( lame_encoder_impl_internal::StereoMode_MONO ); } // TODO: default preset // if (_Properties->bitrate() > 0) lameEnc->set_bit_rate(_Properties->bitrate()); else { lameEnc->set_preset( lame_encoder_impl_internal::PresetMode_V2); } lameEnc->set_quality(5); if (!_Properties->artist_w().empty()) lameEnc->set_artist(_Properties->artist_w().c_str()); if (!_Properties->title_w().empty()) lameEnc->set_title(_Properties->title_w().c_str()); lameEnc->start(); boost::shared_ptr<openmedia::codec_extra_data_common> extraData = boost::make_shared<openmedia::codec_extra_data_common>(); unsigned char mp3buffer[LAME_MAXMP3BUFFER]; int imp3 = lame_get_id3v2_tag(lameEnc->lame().get(), mp3buffer, sizeof(mp3buffer)); DT_ASSERT(imp3 <= LAME_MAXMP3BUFFER); extraData->setter()->add_data("ID3V2TAG", mp3buffer, imp3, openmedia::bufferAllocNew); m_CodecExtraData = extraData; m_Lame = lameEnc.release(); }
ff_stream_info_impl::ff_stream_info_impl(const AVStream * _AVStream) { DT_ASSERT(NULL != _AVStream); if (NULL == _AVStream) BOOST_THROW_EXCEPTION(errors::invalid_pointer()); m_index = _AVStream->index; m_id = _AVStream->id; m_frame_rate = FF2DTType(_AVStream->r_frame_rate); m_first_dts = _AVStream->first_dts; m_time_base = FF2DTType(_AVStream->time_base); m_start_time = _AVStream->start_time; m_duration = _AVStream->duration; m_language = /*_AVStream->language*/""; // remove from ffmpeg 0.8 m_frames_count = _AVStream->nb_frames; m_sample_aspect_ratio = FF2DTType(_AVStream->sample_aspect_ratio); m_metadata = metadata_ptr(/*new ff_metadata(_AVStream->metadata)*/); m_avg_frame_rate = FF2DTType(_AVStream->avg_frame_rate); m_decoder_info = create_ff_decoder_info(_AVStream->codec); }
ff_stream_info_impl::ff_stream_info_impl(const AVFormatContext * avFormatContext, const AVStream * _AVStream) { DT_ASSERT(NULL != _AVStream); if (NULL == _AVStream) BOOST_THROW_EXCEPTION(errors::invalid_pointer()); m_index = _AVStream->index; m_id = _AVStream->id; m_frame_rate = FF2DTType(_AVStream->r_frame_rate); m_first_dts = _AVStream->first_dts; m_time_base = FF2DTType(_AVStream->time_base); m_start_time = _AVStream->start_time; const AVRational tb = {1, AV_TIME_BASE}; m_duration = (_AVStream->duration != AV_NOPTS_VALUE) ? _AVStream->duration : convertDuration(avFormatContext->duration, tb, _AVStream->time_base);; m_language = /*_AVStream->language*/""; // remove from ffmpeg 0.8 m_frames_count = _AVStream->nb_frames; m_sample_aspect_ratio = FF2DTType(_AVStream->sample_aspect_ratio); m_metadata = metadata_ptr(/*new ff_metadata(_AVStream->metadata)*/); m_avg_frame_rate = FF2DTType(_AVStream->avg_frame_rate); m_decoder_info = create_ff_decoder_info(_AVStream->codec); }
media_packet_ptr audio_encoder_queue_lame_impl::receive_packet() { const size_t encodedSamples = sampleRate_; if (m_AudioBuffer->get_samples_count() > encodedSamples) { audio_data_ptr toEncode = m_AudioBuffer->pop_front(encodedSamples); media_packet_ptr mediaPacket = m_Lame->encode( toEncode.get() ); return mediaPacket; } else if ( lastData_) { if ( m_AudioBuffer->get_samples_count() ) { audio_data_ptr toEncode = m_AudioBuffer->pop_front(m_AudioBuffer->get_samples_count()); media_packet_ptr mediaPacket = m_Lame->encode( toEncode.get() ); return mediaPacket; } else { media_packet_ptr mediaPacket = m_Lame->encode( NULL ); unsigned char mp3buffer[LAME_MAXMP3BUFFER]; int imp3 = lame_get_id3v1_tag(m_Lame->lame().get(), mp3buffer, sizeof(mp3buffer)); DT_ASSERT(imp3 <= LAME_MAXMP3BUFFER); m_CodecExtraData->setter()->add_data("ID3V1TAG", mp3buffer, imp3, openmedia::bufferAllocNew); imp3 = lame_get_lametag_frame(m_Lame->lame().get(), mp3buffer, sizeof(mp3buffer)); m_CodecExtraData->setter()->add_data("LAMETAG", mp3buffer, imp3, openmedia::bufferAllocNew); lastData_ = false; return mediaPacket; } } else return media_packet_ptr(); }
decoder_info_ptr create_ff_decoder_info(AVCodecContext * _Codec) { DT_ASSERT(NULL != _Codec); if (NULL == _Codec) { BOOST_THROW_EXCEPTION(errors::invalid_pointer()); return decoder_info_ptr((decoder_info*)NULL); } decoder_info_ptr decoderInfo; switch (_Codec->codec_type) { case AVMEDIA_TYPE_VIDEO: decoderInfo = ff_video_decoder_info::create(_Codec); break; case AVMEDIA_TYPE_AUDIO: decoderInfo = ff_audio_decoder_info::create(_Codec); break; default: decoderInfo = ff_decoder_info::create(_Codec); break; } return decoderInfo; }
audio_data::audio_data(audio_data::Impl * _Impl) { DT_ASSERT(NULL != _Impl); m_pImpl = _Impl; }
/* * disc_position_at_time * * Finds where the disc will be at time t where t is a millisecond value as * returned by SDL_GetTicks. * * Parameters: disc_path - The path of the disc that we want to use. * t - The number of milliseconds. * pos_x, pos_y, pos_z - Will be filled in with the return values. * * Returns: One of DISC_POSITION_CALC_RET_CODES. */ int disc_position_at_time(DISC_PATH *disc_path, Uint32 t, DISC_POS_CALC_TYPE calc_type, VECTOR3 *result) { /* * Local Variables. */ DISC_POSITION *curr_position; DISC_POSITION *position_before; DISC_POSITION *position_after; int ret_code = DISC_POSITION_CALC_OK; Uint32 delta_t; int num_intervals; int ii; /* * Check the input variables. */ DT_ASSERT(disc_path != NULL); DT_ASSERT(disc_path->start_position != NULL); if (t < disc_path->time_created) { ret_code = DISC_POSITION_CALC_INPUT_TIME_BEFORE; goto EXIT_LABEL; } /* * If the time entered is after the disc will have stopped then we just return * the finish position for the path and set a return code so that the calling * function can handle it. This is NOT an error. */ if (t >= disc_path->time_to_stop) { vector_copy_values(result, &(disc_path->end_position->position)); ret_code = DISC_POSITION_CALC_DISC_STOPPED; } /* * Find the number of intervals between the start of the disc path and the * end. * * The division below is integer division. */ delta_t = t - disc_path->time_created; num_intervals = delta_t / disc_path->interval; /* * Find the position that the disc is in after that number of intervals. We * know that this should exist because we have already checked that the time * Inputed lies between the start time and the end time of the disc path. */ curr_position = disc_path->start_position; for (ii = 0; ii < num_intervals; ii++) { curr_position = curr_position->next; DT_ASSERT(curr_position != NULL); } position_before = curr_position; position_after = curr_position->next; /* * There are various methods that we can use for determining what positions * to return back. These are enumerated below and each have their own comment * explaining what and why. * * INTERPOLATE - A simple linear interpolation between the two intervals * either side of the required time. * NEAREST - The closest of the two pre calculated intervals. * PREVIOUS - The interval before the required time. * NEXT - The interval after the required time. */ switch(calc_type) { case INTERPOLATE: disc_path_find_interp_distance(disc_path, position_before, position_after, t, num_intervals * disc_path->interval, result); break; case NEAREST: disc_path_find_nearest_pos(disc_path, position_before, position_after, t, num_intervals * disc_path->interval, result); break; case PREVIOUS: vector_copy_values(result, &(position_before->position)); break; case NEXT: vector_copy_values(result, &(position_after->position)); break; default: ret_code = DISC_POSITION_CALC_BAD_CALC_TYPE; break; } EXIT_LABEL: return(ret_code); }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- EzUsbInit -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // DtStatus EzUsbInit(DtuDeviceData* pDvcData, Bool* pReEnumerate) { DtStatus Status = DT_STATUS_OK; const DtuIntelHexRecord* pEzUsbFirmware = NULL; DtPropertyData* pPropData = &pDvcData->m_PropData; Bool IsEzUsbFwLoaded=FALSE, IsPldFwLoaded=FALSE; Int FirmwareEndpoint; Int ReadEndpoint; Int WriteEndpoint; // Initialize properties FirmwareEndpoint = DtPropertiesGetInt(pPropData, "USB_END_POINT_FIRMWARE", -1); ReadEndpoint = DtPropertiesGetInt(pPropData, "USB_END_POINT_READ", -1); WriteEndpoint = DtPropertiesGetInt(pPropData, "USB_END_POINT_WRITE", -1); // Check if no property error occurred Status = DtuPropertiesReportDriverErrors(pDvcData); if (!DT_SUCCESS(Status)) return Status; // Check if we need to load firmware. NOTE: there are two conditions to load the // firmware namely: // 1. EzUsb firmware is not loaded yet // 2. PLD firmware is loaded already, which suggest a warm-reboot which we want to // treat as a cold roboot => upload EzUsb firmware, but no re-enumeration *pReEnumerate = FALSE; IsEzUsbFwLoaded = EzUsbIsFirmwareLoaded(pDvcData); IsPldFwLoaded = FALSE; if (IsEzUsbFwLoaded && !(pDvcData->m_DevInfo.m_TypeNumber>=300 && pDvcData->m_DevInfo.m_TypeNumber<400)) IsPldFwLoaded = DtuPldIsFirmwareLoaded(pDvcData); if (!IsEzUsbFwLoaded || IsPldFwLoaded) { if (IsPldFwLoaded) DtDbgOut(MIN, DTU, "PLD FW is already loaded => warm reboot"); else DtDbgOut(MIN, DTU, "No EzUsb firmware loaded => cold reboot"); if (pDvcData->m_DevInfo.m_TypeNumber>=300 && pDvcData->m_DevInfo.m_TypeNumber<400) { // Lookup firmware const DtuFx3HexRecord* pFx3Firmware = Dtu3GetFx3Firmware( pDvcData->m_DevInfo.m_TypeNumber, -1, pDvcData->m_DevInfo.m_HardwareRevision); if (pFx3Firmware == NULL) DtDbgOut(ERR, DTU, "FX3 firmware not found for Typenumber: %d," " HardwareRev: 0x%X", pDvcData->m_DevInfo.m_TypeNumber, pDvcData->m_DevInfo.m_HardwareRevision); if (!DtUsbManufNameEq(&pDvcData->m_Device, "Cypress")) { DtDbgOut(ERR, DTU, "DTU-3XX vid/pid found but wrong manufacturer string"); return DT_STATUS_FAIL; } if (pDvcData->m_DevInfo.m_ProductId == DTU3_PID_UNIT_EEPROM) pDvcData->m_BootState = DTU_BOOTSTATE_FACTORY_COLD; else pDvcData->m_BootState = DTU_BOOTSTATE_COLD; //TODOTM: verify product string is "DTU-351" // Upload firmware for EzUsb chip Status = EzUsbLoadFirmwareFx3(pDvcData, pFx3Firmware); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Failed to upload FX3 firmware (Status=0x%08X)", Status); return Status; } DtDbgOut(ERR, DTU, "FX3 firmware uploaded"); } else { // Lookup firmware pEzUsbFirmware = DtuGetEzUsbFirmware(pDvcData->m_DevInfo.m_ProductId, -1, pDvcData->m_DevInfo.m_HardwareRevision); if (pEzUsbFirmware == NULL) { DtDbgOut(ERR, DTU, "No EzUsb firmware available for DTU-%d", pDvcData->m_DevInfo.m_TypeNumber); return DT_STATUS_FAIL; } // Upload firmware for EzUsb chip Status = EzUsbLoadFirmware(pDvcData, pEzUsbFirmware); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Failed to upload FX2 firmware (Status=0x%08X)", Status); return Status; } } *pReEnumerate = !IsPldFwLoaded; // Device will reenumerate, if cold reboot if (!IsPldFwLoaded) return DT_STATUS_OK; // In case of cold reboot we are done (will reenumerate) } // Convert endpoint to pipe numbers if (FirmwareEndpoint != -1) { // Convert endpoint to pipe number pDvcData->m_EzUsb.m_FirmwarePipe = DtUsbGetBulkPipeNumber(&pDvcData->m_Device, DT_USB_HOST_TO_DEVICE, FirmwareEndpoint); DT_ASSERT(pDvcData->m_EzUsb.m_FirmwarePipe != -1); } if (ReadEndpoint != -1) { // Convert endpoint to pipe number pDvcData->m_EzUsb.m_ReadPipe = DtUsbGetBulkPipeNumber(&pDvcData->m_Device, DT_USB_DEVICE_TO_HOST, ReadEndpoint); DT_ASSERT(pDvcData->m_EzUsb.m_ReadPipe != -1); } if (WriteEndpoint != -1) { // Convert endpoint to pipe number pDvcData->m_EzUsb.m_WritePipe = DtUsbGetBulkPipeNumber(&pDvcData->m_Device, DT_USB_HOST_TO_DEVICE, WriteEndpoint); DT_ASSERT(pDvcData->m_EzUsb.m_WritePipe != -1); } return Status; }
lame_ptr dt_create_lame_encoder() { lame_global_flags * lame = lame_init(); DT_ASSERT(NULL != lame); return lame_ptr(lame , dt_destruct_lame_encoder() ); }
decoder::decoder(decoder::Impl * _Impl): m_pImpl(_Impl) { DT_ASSERT(NULL != _Impl); }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtAvGetFrameProps -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // // Returns the AV frame properties for the given video standard // DtStatus DtAvGetFrameProps(Int VidStd, DtAvFrameProps* pProps) { DT_ASSERT(pProps != NULL); switch (VidStd) { case DT_VIDSTD_525I59_94: pProps->m_NumLines = 525; pProps->m_Fps = 30; pProps->m_IsFractional = TRUE; pProps->m_IsInterlaced = TRUE; pProps->m_IsHd = FALSE; pProps->m_Field1Start = 1; pProps->m_Field1End = 262; pProps->m_Field1ActVidStart = 17; pProps->m_Field1ActVidEnd = 260; pProps->m_SwitchingLines[0] = 7; pProps->m_Field2Start = 263; pProps->m_Field2End = 525; pProps->m_Field2ActVidStart = 280; pProps->m_Field2ActVidEnd = 522; pProps->m_SwitchingLines[1] = 270; pProps->m_VancNumS = pProps->m_ActVidNumS = 720*2; pProps->m_HancNumS = 268; pProps->m_SavNumS = 4; pProps->m_EavNumS = 4; pProps->m_SyncPointPixelOff = 16; // Sync point @pixel 16 break; case DT_VIDSTD_525P59_94: case DT_VIDSTD_480P59_94: pProps->m_NumLines = 525; pProps->m_Fps = 60; pProps->m_IsFractional = TRUE; pProps->m_IsInterlaced = FALSE; pProps->m_IsHd = FALSE; pProps->m_Field1Start = 1; pProps->m_Field1End = 525; pProps->m_Field1ActVidStart = 17; pProps->m_Field1ActVidEnd = 496; pProps->m_SwitchingLines[0] = 7; pProps->m_SwitchingLines[1] = -1; pProps->m_Field2Start = 0; pProps->m_Field2End = 0; pProps->m_Field2ActVidStart = 0; pProps->m_Field2ActVidEnd = 0; if (VidStd == DT_VIDSTD_480P59_94) pProps->m_VancNumS = pProps->m_ActVidNumS = 640*2; else pProps->m_VancNumS = pProps->m_ActVidNumS = 720*2; pProps->m_HancNumS = 268; pProps->m_SavNumS = 4; pProps->m_EavNumS = 4; pProps->m_SyncPointPixelOff = 0; break; case DT_VIDSTD_625I50: pProps->m_NumLines = 625; pProps->m_Fps = 25; pProps->m_IsFractional = FALSE; pProps->m_IsInterlaced = TRUE; pProps->m_IsHd = FALSE; pProps->m_Field1Start = 1; pProps->m_Field1End = 312; pProps->m_Field1ActVidStart = 23; pProps->m_Field1ActVidEnd = 310; pProps->m_SwitchingLines[0] = 6; pProps->m_Field2Start = 313; pProps->m_Field2End = 625; pProps->m_Field2ActVidStart = 336; pProps->m_Field2ActVidEnd = 623; pProps->m_SwitchingLines[1] = 319; pProps->m_VancNumS = pProps->m_ActVidNumS = 720*2; pProps->m_HancNumS = 280; pProps->m_SavNumS = 4; pProps->m_EavNumS = 4; pProps->m_SyncPointPixelOff = 12; // Sync point @pixel 12 break; case DT_VIDSTD_625P50: pProps->m_NumLines = 625; pProps->m_Fps = 50; pProps->m_IsFractional = FALSE; pProps->m_IsInterlaced = FALSE; pProps->m_IsHd = FALSE; pProps->m_Field1Start = 1; pProps->m_Field1End = 625; pProps->m_Field1ActVidStart = 23; pProps->m_Field1ActVidEnd = 598; pProps->m_SwitchingLines[0] = 6; pProps->m_SwitchingLines[1] = -1; pProps->m_Field2Start = 0; pProps->m_Field2End = 0; pProps->m_Field2ActVidStart = 0; pProps->m_Field2ActVidEnd = 0; pProps->m_VancNumS = pProps->m_ActVidNumS = 720*2; pProps->m_HancNumS = 280; pProps->m_SavNumS = 4; pProps->m_EavNumS = 4; pProps->m_SyncPointPixelOff = 0; break; case DT_VIDSTD_2160P60: case DT_VIDSTD_2160P60B: case DT_VIDSTD_2160P59_94: case DT_VIDSTD_2160P59_94B: case DT_VIDSTD_2160P50: case DT_VIDSTD_2160P50B: case DT_VIDSTD_1080P60: case DT_VIDSTD_1080P60B: case DT_VIDSTD_1080P59_94: case DT_VIDSTD_1080P59_94B: case DT_VIDSTD_1080P50: case DT_VIDSTD_1080P50B: pProps->m_NumLines = 1125; if (VidStd==DT_VIDSTD_1080P50 || VidStd==DT_VIDSTD_1080P50B || VidStd==DT_VIDSTD_2160P50 || VidStd==DT_VIDSTD_2160P50B) pProps->m_Fps = 50; else pProps->m_Fps = 60; pProps->m_IsFractional = (VidStd==DT_VIDSTD_1080P59_94 || VidStd==DT_VIDSTD_1080P59_94B || VidStd==DT_VIDSTD_2160P59_94 || VidStd==DT_VIDSTD_2160P59_94B); pProps->m_IsInterlaced = FALSE; pProps->m_IsHd = TRUE; pProps->m_Field1Start = 1; pProps->m_Field1End = 1125; pProps->m_Field1ActVidStart = 42; pProps->m_Field1ActVidEnd = 1121; pProps->m_SwitchingLines[0] = 7; pProps->m_SwitchingLines[1] = -1; pProps->m_Field2Start = 0; pProps->m_Field2End = 0; pProps->m_Field2ActVidStart = 0; pProps->m_Field2ActVidEnd = 0; pProps->m_VancNumS = pProps->m_ActVidNumS = 1920*2; if (VidStd==DT_VIDSTD_1080P60 || VidStd==DT_VIDSTD_1080P60B || VidStd==DT_VIDSTD_1080P59_94 || VidStd==DT_VIDSTD_1080P59_94B || VidStd==DT_VIDSTD_2160P60 || VidStd==DT_VIDSTD_2160P60B || VidStd==DT_VIDSTD_2160P59_94 || VidStd==DT_VIDSTD_2160P59_94B) { pProps->m_HancNumS = 268*2; // Set Sync point pProps->m_SyncPointPixelOff = 88; // Sync point @pixel 88 } else if (VidStd==DT_VIDSTD_1080P50 || VidStd==DT_VIDSTD_1080P50B || VidStd==DT_VIDSTD_2160P50 || VidStd==DT_VIDSTD_2160P50B) { pProps->m_HancNumS = 708*2; pProps->m_SyncPointPixelOff = 528; // Sync point @pixel 528 } else DT_ASSERT(1==0); pProps->m_EavNumS = 8*2; pProps->m_SavNumS = 4*2; break; case DT_VIDSTD_2160P30: case DT_VIDSTD_2160P29_97: case DT_VIDSTD_2160P25: case DT_VIDSTD_2160P24: case DT_VIDSTD_2160P23_98: case DT_VIDSTD_1080P30: case DT_VIDSTD_1080P29_97: case DT_VIDSTD_1080P25: case DT_VIDSTD_1080P24: case DT_VIDSTD_1080P23_98: pProps->m_NumLines = 1125; if (VidStd==DT_VIDSTD_1080P30 || VidStd==DT_VIDSTD_1080P29_97 || VidStd==DT_VIDSTD_2160P30 || VidStd==DT_VIDSTD_2160P29_97) pProps->m_Fps = 30; else if (VidStd==DT_VIDSTD_1080P25 || VidStd==DT_VIDSTD_2160P25) pProps->m_Fps = 25; else if (VidStd==DT_VIDSTD_1080P24 || VidStd==DT_VIDSTD_1080P23_98 || VidStd==DT_VIDSTD_2160P24 || VidStd==DT_VIDSTD_2160P23_98) pProps->m_Fps = 24; else DT_ASSERT(1==0); pProps->m_IsFractional = (VidStd==DT_VIDSTD_1080P29_97 || VidStd==DT_VIDSTD_1080P23_98 || VidStd==DT_VIDSTD_2160P29_97 || VidStd==DT_VIDSTD_2160P23_98); pProps->m_IsInterlaced = FALSE; pProps->m_IsHd = TRUE; pProps->m_Field1Start = 1; pProps->m_Field1End = 1125; pProps->m_Field1ActVidStart = 42; pProps->m_Field1ActVidEnd = 1121; pProps->m_SwitchingLines[0] = 7; pProps->m_Field2Start = 0; pProps->m_Field2End = 0; pProps->m_Field2ActVidStart = 0; pProps->m_Field2ActVidEnd = 0; pProps->m_SwitchingLines[1] = -1; pProps->m_VancNumS = pProps->m_ActVidNumS = 1920*2; if (VidStd==DT_VIDSTD_1080P30 || VidStd==DT_VIDSTD_1080P29_97 || VidStd==DT_VIDSTD_2160P30 || VidStd==DT_VIDSTD_2160P29_97) { pProps->m_HancNumS = 268*2; pProps->m_SyncPointPixelOff = 88; // Sync point @pixel 88 } else if (VidStd==DT_VIDSTD_1080P25 || VidStd==DT_VIDSTD_2160P25) { pProps->m_HancNumS = 708*2; pProps->m_SyncPointPixelOff = 528; // Sync point @pixel 528 } else if (VidStd==DT_VIDSTD_1080P24 || VidStd==DT_VIDSTD_1080P23_98 || VidStd==DT_VIDSTD_2160P24 || VidStd==DT_VIDSTD_2160P23_98) { pProps->m_HancNumS = 818*2; pProps->m_SyncPointPixelOff = 638; // Sync point @pixel 638 } else DT_ASSERT(1==0); pProps->m_EavNumS = 8*2; pProps->m_SavNumS = 4*2; break; case DT_VIDSTD_1080I60: case DT_VIDSTD_1080I59_94: case DT_VIDSTD_1080I50: case DT_VIDSTD_1080PSF30: case DT_VIDSTD_1080PSF29_97: case DT_VIDSTD_1080PSF25: case DT_VIDSTD_1080PSF24: case DT_VIDSTD_1080PSF23_98: pProps->m_NumLines = 1125; if (VidStd==DT_VIDSTD_1080I60 || VidStd==DT_VIDSTD_1080I59_94 || VidStd==DT_VIDSTD_1080PSF30 || VidStd==DT_VIDSTD_1080PSF29_97) pProps->m_Fps = 30; else if (VidStd==DT_VIDSTD_1080I50 || VidStd==DT_VIDSTD_1080PSF25) pProps->m_Fps = 25; else if (VidStd==DT_VIDSTD_1080PSF24 || VidStd==DT_VIDSTD_1080PSF23_98) pProps->m_Fps = 24; else DT_ASSERT(1==0); pProps->m_IsFractional = (VidStd==DT_VIDSTD_1080I59_94 || VidStd==DT_VIDSTD_1080PSF29_97 || VidStd==DT_VIDSTD_1080PSF23_98); pProps->m_IsInterlaced = TRUE; pProps->m_IsHd = TRUE; pProps->m_Field1Start = 1; pProps->m_Field1End = 563; pProps->m_Field1ActVidStart = 21; pProps->m_Field1ActVidEnd = 560; pProps->m_SwitchingLines[0] = 7; pProps->m_Field2Start = 564; pProps->m_Field2End = 1125; pProps->m_Field2ActVidStart = 584; pProps->m_Field2ActVidEnd = 1123; pProps->m_SwitchingLines[1] = 569; pProps->m_VancNumS = pProps->m_ActVidNumS = 1920*2; if (VidStd==DT_VIDSTD_1080I60 || VidStd==DT_VIDSTD_1080I59_94 || VidStd==DT_VIDSTD_1080PSF30 || VidStd==DT_VIDSTD_1080PSF29_97) { pProps->m_HancNumS = 268*2; pProps->m_SyncPointPixelOff = 88; // Sync point @pixel 88 } else if (VidStd==DT_VIDSTD_1080I50 || VidStd==DT_VIDSTD_1080PSF25) { pProps->m_HancNumS = 708*2; pProps->m_SyncPointPixelOff = 528; // Sync point @pixel 528 } else if (VidStd==DT_VIDSTD_1080PSF24 || VidStd==DT_VIDSTD_1080PSF23_98) { pProps->m_HancNumS = 818*2; pProps->m_SyncPointPixelOff = 638; // Sync point @pixel 638 } else DT_ASSERT(1==0); pProps->m_EavNumS = 8*2; pProps->m_SavNumS = 4*2; break; case DT_VIDSTD_720P60: case DT_VIDSTD_720P59_94: case DT_VIDSTD_720P50: case DT_VIDSTD_720P30: case DT_VIDSTD_720P29_97: case DT_VIDSTD_720P25: case DT_VIDSTD_720P24: case DT_VIDSTD_720P23_98: pProps->m_NumLines = 750; if (VidStd==DT_VIDSTD_720P60 || VidStd==DT_VIDSTD_720P59_94) pProps->m_Fps = 60; else if (VidStd==DT_VIDSTD_720P50) pProps->m_Fps = 50; else if (VidStd==DT_VIDSTD_720P30 || VidStd==DT_VIDSTD_720P29_97) pProps->m_Fps = 30; else if (VidStd==DT_VIDSTD_720P25) pProps->m_Fps = 25; else if (VidStd==DT_VIDSTD_720P24 || VidStd==DT_VIDSTD_720P23_98) pProps->m_Fps = 24; else DT_ASSERT(1==0); pProps->m_IsFractional = (VidStd==DT_VIDSTD_720P59_94 || VidStd==DT_VIDSTD_720P29_97 || VidStd==DT_VIDSTD_720P23_98); pProps->m_IsInterlaced = FALSE; pProps->m_IsHd = TRUE; pProps->m_Field1Start = 1; pProps->m_Field1End = 750; pProps->m_Field1ActVidStart = 26; pProps->m_Field1ActVidEnd = 745; pProps->m_SwitchingLines[0] = 7; pProps->m_Field2Start = 0; pProps->m_Field2End = 0; pProps->m_Field2ActVidStart = 0; pProps->m_Field2ActVidEnd = 0; pProps->m_SwitchingLines[1] = -1; pProps->m_VancNumS = pProps->m_ActVidNumS = 1280*2; if (VidStd==DT_VIDSTD_720P60 || VidStd==DT_VIDSTD_720P59_94) { pProps->m_HancNumS = 358*2; pProps->m_SyncPointPixelOff = 110; // Sync point @pixel 110 } else if (VidStd==DT_VIDSTD_720P50) { pProps->m_HancNumS = 688*2; pProps->m_SyncPointPixelOff = 440; // Sync point @pixel 440 } else if (VidStd==DT_VIDSTD_720P30 || VidStd==DT_VIDSTD_720P29_97) { pProps->m_HancNumS = 2008*2; pProps->m_SyncPointPixelOff = 1760; // Sync point @pixel 88 } else if (VidStd==DT_VIDSTD_720P25) { pProps->m_HancNumS = 2668*2; pProps->m_SyncPointPixelOff = 2420; // Sync point @pixel 88 } else if (VidStd==DT_VIDSTD_720P24 || VidStd==DT_VIDSTD_720P23_98) { pProps->m_HancNumS = 2833*2; pProps->m_SyncPointPixelOff = 2585; // Sync point @pixel 88 } else DT_ASSERT(1==0); pProps->m_EavNumS = 8*2; pProps->m_SavNumS = 4*2; break; default: DtDbgOut(ERR, AV, "Unknown IO-standard"); return DT_STATUS_INVALID_PARAMETER; } // Store the video video standard pProps->m_VidStd = VidStd; return DT_STATUS_OK; }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuLoadDemodFirmware -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // DtStatus DtuLoadDemodFirmware( DtuDeviceData* pDvcData, const DtuDemodFirmwareStore* pDemodFirmware) { DtStatus Status = DT_STATUS_OK; UInt8 Buffer[2]; Int i, j; UInt DvcAddr = pDemodFirmware->m_DemodI2cAddress; DT_ASSERT(pDemodFirmware != NULL); // First do the PRE-upload register writes if (pDemodFirmware->m_pPreUpload != NULL) { const DtuInitRegisterStruct* pInitRegisterData = pDemodFirmware->m_pPreUpload; for (i=0; i<pInitRegisterData->m_RegisterDataCount; i++) { Buffer[0] = pInitRegisterData->m_RegData[i].m_Data[0]; Buffer[1] = pInitRegisterData->m_RegData[i].m_Data[1]; Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 2, Buffer); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error writing I2C pre-upload data. (Status=0x%08X)", Status); return Status; } } } // Upload demodulator firmware if (pDemodFirmware->m_pFirmware != NULL) { const Int MAX_BYTES_TO_TRY = 60; UInt8 AddrHigh; UInt8 AddrLow; Int DataCount; Int BytesToTry; const DtuHexStruct* pFirmware = pDemodFirmware->m_pFirmware; UInt8* pHexData=NULL; // First allocate memory for temporary helper buffer pHexData = DtMemAllocPool(DtPoolNonPaged, 4096, DTU_TAG); if (pHexData == NULL) return DT_STATUS_OUT_OF_MEMORY; for (i=0; i<pFirmware->m_HexBlockCount; i++) { const DtuHexBlockStruct* pHexBlock = &(pFirmware->m_HexBlock[i]); DataCount = pHexBlock->m_DataCount; BytesToTry = 0; while (DataCount > 0) { AddrHigh = (UInt8)((pHexBlock->m_Address + pHexBlock->m_DataCount-DataCount) >> 8); AddrLow = (UInt8)(pHexBlock->m_Address + pHexBlock->m_DataCount-DataCount); // Write high address Buffer[0] = (UInt8)pDemodFirmware->m_AddrRegH; Buffer[1] = AddrHigh; Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 2, Buffer); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error writing I2C high address. (Status=0x%08X)", Status); DtMemFreePool(pHexData, DTU_TAG); return Status; } // Write low address Buffer[0] = (UInt8)pDemodFirmware->m_AddrRegL; Buffer[1] = AddrLow; Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 2, Buffer); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error writing I2C low address. (Status=0x%08X)", Status); DtMemFreePool(pHexData, DTU_TAG); return Status; } // Write data pHexData[0] = (UInt8)pDemodFirmware->m_DataReg; BytesToTry = (DataCount<=MAX_BYTES_TO_TRY ? DataCount : MAX_BYTES_TO_TRY); for (j=0; j<BytesToTry; j++) pHexData[j + 1] = pHexBlock->m_Data[j + pHexBlock->m_DataCount - DataCount]; Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, BytesToTry+1, pHexData); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error writing I2C data. (Status=0x%08X)", Status); DtMemFreePool(pHexData, DTU_TAG); return Status; } DataCount -= BytesToTry; } } DtMemFreePool(pHexData, DTU_TAG); } // Do the STOP-upload register writes if (pDemodFirmware->m_pStopUpload != NULL) { const DtuInitRegisterStruct* pInitRegisterData = pDemodFirmware->m_pStopUpload; for (i=0; i<pInitRegisterData->m_RegisterDataCount; i++) { Buffer[0] = pInitRegisterData->m_RegData[i].m_Data[0]; Buffer[1] = pInitRegisterData->m_RegData[i].m_Data[1]; Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 2, Buffer); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error writing I2C stop-upload data. (Status=0x%08X)", Status); return Status; } } } // Wait until AP is running if (pDemodFirmware->m_pFirmware != NULL) { Int TimeOut; Buffer[0] = (UInt8)pDemodFirmware->m_ApStatReg; Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 1, Buffer); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error writing I2C apstat data. (Status=0x%08X)", Status); return Status; } // Wait until ready Buffer[0] = 1; TimeOut = 0; while (Buffer[0]==1 && TimeOut<250) // Wait max. 250ms { DtSleep(10); TimeOut += 10; // Read the app status Status = DtuI2cRead(pDvcData, NULL, DvcAddr, 1, Buffer); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error reading I2C apstat data. (Status=0x%08X)", Status); return Status; } } if (Buffer[0] == 1) { DtDbgOut(ERR, DTU, "TIMEOUT! APSTAT = %x.", (Int)(Buffer[0])); } } //Do the post-upload register writes if (pDemodFirmware->m_pPostUpload != NULL) { const DtuInitRegisterStruct* pInitRegisterData = pDemodFirmware->m_pPostUpload; for (i=0; i<pInitRegisterData->m_RegisterDataCount; i++) { Buffer[0] = pInitRegisterData->m_RegData[i].m_Data[0]; Buffer[1] = pInitRegisterData->m_RegData[i].m_Data[1]; Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 2, Buffer); if (!DT_SUCCESS(Status)) { DtDbgOut(ERR, DTU, "Error writing I2C post-upload data. (Status=0x%08X)", Status); return Status; } } } return Status; }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtDpcSchedule -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // DtStatus DtDpcSchedule(DtDpc* pDpc, DtDpcArgs* pArgs) { DtStatus Result = DT_STATUS_OK; Int OldState; Bool DoRun = FALSE; Bool DoQueue = FALSE; DT_ASSERT(pDpc->m_SchedulingEnabled); // Try to set running from idle state OldState = DtAtomicCompareExchange((Int*)&pDpc->m_State, 0, DPC_STATE_BIT_RUNNING); if (OldState == 0) // Successfully running DoRun = TRUE; else if (pDpc->m_QueueIfRunning) { // Try to set Queuing OldState = DtAtomicCompareExchange((Int*)&pDpc->m_State, DPC_STATE_BIT_RUNNING, DPC_STATE_BIT_RUNNING|DPC_STATE_BIT_QUEUING); if (OldState == DPC_STATE_BIT_RUNNING) // Successfully set to queuing DoQueue = TRUE; // Not running anymore? // Try to set running again to be sure a full execution of the worker is pending // after the call the DtDpcSchedule... else if ((OldState&DPC_STATE_BIT_RUNNING) == 0) { // Retry to set running from idle state OldState = DtAtomicCompareExchange((Int*)&pDpc->m_State, 0, DPC_STATE_BIT_RUNNING); if (OldState == 0) // Successfully set to running DoRun = TRUE; else Result = DT_STATUS_IN_USE; } else Result = DT_STATUS_IN_USE; } if (!DT_SUCCESS(Result)) return Result; // Queue DPC? if (DoQueue) { // Copy arguments pDpc->m_QueuedArgs = *pArgs; // Set to queued (running|queuing|queued) OldState = DtAtomicCompareExchange((Int*)&pDpc->m_State, DPC_STATE_BIT_RUNNING|DPC_STATE_BIT_QUEUING, DPC_STATE_BIT_RUNNING|DPC_STATE_BIT_QUEUING|DPC_STATE_BIT_QUEUED); // Check if we failed because we were not running anymore if (OldState == DPC_STATE_BIT_QUEUING) { // Choose running slot --> try to set from queuing to running instead of // queued OldState = DtAtomicCompareExchange((Int*)&pDpc->m_State, DPC_STATE_BIT_QUEUING, DPC_STATE_BIT_RUNNING); if (OldState == DPC_STATE_BIT_QUEUING) DoRun = TRUE; else { Result = DT_STATUS_IN_USE; // Can not happen? DT_ASSERT(FALSE); } } } // Start initial DPC? if (DoRun) { pDpc->m_Args = *pArgs; #ifdef WINBUILD KeInsertQueueDpc(&pDpc->m_Kdpc, NULL, NULL); #else tasklet_schedule(&pDpc->m_Tasklet); #endif // Running flag is already set... } return Result; }