流与通道(Stream and Channel in I/O)

本文介绍了Java NIO的核心技术,包括文件与设备的I/O操作、对象序列化、原生态数据缓存、字符集编码与解码、新的I/O抽象通道、支持锁和内存映射的文件接口以及用于编写可伸缩服务器的多分复用非阻塞I/O设备。
1) File and device I/O 文件与设备的I/O
2) Object serialization 对象序列化
3) Buffers for data of primitive types 原生态数据的缓存
4) Character-set encoders and decoders字节集的编码与解码
5) Channels, a new primitive I/O abstraction 通道,一个新的IO抽象
6) A file interface that supports locks and memory mapping 支持锁和内存映射的文件接口
7) A multiplexed, non-blocking I/O facility for writing scalable servers
一个多分复用、非阻塞I/O设备用于编写可伸缩的服务器
audio_io_handle_t AudioPolicyManager::getOutputForDevices( const DeviceVector &devices, audio_session_t session, const audio_attributes_t *attr, const audio_config_t *config, audio_output_flags_t *flags, bool *isSpatialized, sp<PreferredMixerAttributesInfo> prefMixerConfigInfo, bool forceMutingHaptic) { audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; // Discard haptic channel mask when forcing muting haptic channels. audio_channel_mask_t channelMask = forceMutingHaptic ? static_cast<audio_channel_mask_t>(config->channel_mask & ~AUDIO_CHANNEL_HAPTIC_ALL) : config->channel_mask; // open a direct output if required by specified parameters //force direct flag if offload flag is set: offloading implies a direct output stream // and all common behaviors are driven by checking only the direct flag // this should normally be set appropriately in the policy configuration file if ((*flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { *flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_DIRECT); } if ((*flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) { *flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_DIRECT); } audio_stream_type_t stream = mEngine->getStreamTypeForAttributes(*attr); // only allow deep buffering for music stream type if (stream != AUDIO_STREAM_MUSIC) { *flags = (audio_output_flags_t)(*flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER); } else if (/* stream == AUDIO_STREAM_MUSIC && */ *flags == AUDIO_OUTPUT_FLAG_NONE && mConfig->useDeepBufferForMedia()) { // use DEEP_BUFFER as default output for music stream type *flags = (audio_output_flags_t)AUDIO_OUTPUT_FLAG_DEEP_BUFFER; } if (stream == AUDIO_STREAM_TTS) { *flags = AUDIO_OUTPUT_FLAG_TTS; } else if (stream == AUDIO_STREAM_VOICE_CALL && audio_is_linear_pcm(config->format) && (*flags & AUDIO_OUTPUT_FLAG_INCALL_MUSIC) == 0) { *flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_VOIP_RX | AUDIO_OUTPUT_FLAG_DIRECT); ALOGV("Set VoIP and Direct output flags for PCM format"); } // Attach the Ultrasound flag for the AUDIO_CONTENT_TYPE_ULTRASOUND if (attr->content_type == AUDIO_CONTENT_TYPE_ULTRASOUND) { *flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_ULTRASOUND); } // Use the spatializer output if the content can be spatialized, no preferred mixer // was specified and offload or direct playback is not explicitly requested, and there is no // haptic channel included in playback *isSpatialized = false; if (mSpatializerOutput != nullptr && canBeSpatializedInt(attr, config, devices.toTypeAddrVector()) && prefMixerConfigInfo == nullptr && ((*flags & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT)) == 0) && checkHapticCompatibilityOnSpatializerOutput(config, session)) { *isSpatialized = true; return mSpatializerOutput->mIoHandle; } audio_config_t directConfig = *config; directConfig.channel_mask = channelMask; status_t status = openDirectOutput(stream, session, &directConfig, *flags, devices, &output, *attr); if (status != NAME_NOT_FOUND) { return output; } // A request for HW A/V sync cannot fallback to a mixed output because time // stamps are embedded in audio data if ((*flags & (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_MMAP_NOIRQ)) != 0) { return AUDIO_IO_HANDLE_NONE; } // A request for Tuner cannot fallback to a mixed output if ((directConfig.offload_info.content_id || directConfig.offload_info.sync_id)) { return AUDIO_IO_HANDLE_NONE; } // ignoring channel mask due to downmix capability in mixer // open a non direct output // for non direct outputs, only PCM is supported if (audio_is_linear_pcm(config->format)) { // get which output is suitable for the specified stream. The actual // routing change will happen when startOutput() will be called SortedVector<audio_io_handle_t> outputs = getOutputsForDevices(devices, mOutputs); if (prefMixerConfigInfo != nullptr) { for (audio_io_handle_t outputHandle : outputs) { sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputHandle); if (outputDesc->mProfile == prefMixerConfigInfo->getProfile()) { output = outputHandle; break; } } if (output == AUDIO_IO_HANDLE_NONE) { // No output open with the preferred profile. Open a new one. audio_config_t config = AUDIO_CONFIG_INITIALIZER; config.channel_mask = prefMixerConfigInfo->getConfigBase().channel_mask; config.sample_rate = prefMixerConfigInfo->getConfigBase().sample_rate; config.format = prefMixerConfigInfo->getConfigBase().format; sp<SwAudioOutputDescriptor> preferredOutput = openOutputWithProfileAndDevice( prefMixerConfigInfo->getProfile(), devices, nullptr /*mixerConfig*/, &config, prefMixerConfigInfo->getFlags()); if (preferredOutput == nullptr) { ALOGE("%s failed to open output with preferred mixer config", __func__); } else { output = preferredOutput->mIoHandle; } } } else { // at this stage we should ignore the DIRECT flag as no direct output could be // found earlier *flags = (audio_output_flags_t) (*flags & ~AUDIO_OUTPUT_FLAG_DIRECT); if (com::android::media::audioserver:: fix_concurrent_playback_behavior_with_bit_perfect_client()) { // If the preferred mixer attributes is null, do not select the bit-perfect output // unless the bit-perfect output is the only output. // The bit-perfect output can exist while the passed in preferred mixer attributes // info is null when it is a high priority client. The high priority clients are // ringtone or alarm, which is not a bit-perfect use case. size_t i = 0; while (i < outputs.size() && outputs.size() > 1) { auto desc = mOutputs.valueFor(outputs[i]); // The output descriptor must not be null here. if (desc->isBitPerfect()) { outputs.removeItemsAt(i); } else { i += 1; } } } output = selectOutput( outputs, *flags, config->format, channelMask, config->sample_rate, session); } } ALOGW_IF((output == 0), "getOutputForDevices() could not find output for stream %d, " "sampling rate %d, format %#x, channels %#x, flags %#x", stream, config->sample_rate, config->format, channelMask, *flags); return output; }
最新发布
12-18
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值