我已将 Android 中的默认媒体框架从 Stagefright 更改为 Gstreamer。这样做是为了使其对我们的项目具有灵活性。
但是当我运行一些 apk 时,应用程序的所有声音都在应用程序启动时播放,并且在显示来自 Soundpool 的错误“sample # not READY”之后它不会播放。例如,在 App Baby 钢琴中,当我启动应用程序时,会播放钢琴音节的声音,而当我在进入播放模式后实际点击钢琴时,它不会被播放。
我认为的问题是,当声音被加载到 Soundpool 中时,会创建 Gstreamer Mediaplayer 对象并播放它,并且它是在应用程序启动时完成的。
在它显示的日志中,Sample Channel Count(0) 超出范围。它发生在下面部分的 SoundPoool.cpp 文件中。
status_t Sample::doLoad() {
uint32_t sampleRate;
int numChannels;
int format;
sp<IMemory> p;
LOGW("Start decode");
if (mUrl) {
p = MediaPlayer::decode(mUrl, &sampleRate, &numChannels, &format);
} else {
p = MediaPlayer::decode(mFd, mOffset, mLength, &sampleRate, &numChannels, &format);
LOGW("close(%d)", mFd);
::close(mFd);
mFd = -1;
}
if (p == 0) {
LOGE("Unable to load sample: %s", mUrl);
return -1;
}
LOGW("pointer = %p, size = %u, sampleRate = %u, numChannels = %d",
p->pointer(), p->size(), sampleRate, numChannels);
if (sampleRate > kMaxSampleRate) {
LOGE("Sample rate (%u) out of range", sampleRate);
return - 1;
}
if ((numChannels < 1) || (numChannels > 2)) {
LOGE("Sample channel count (%d) out of range", numChannels);
return - 1;
}
//_dumpBuffer(p->pointer(), p->size());
uint8_t* q = static_cast<uint8_t*>(p->pointer()) + p->size() - 10;
//_dumpBuffer(q, 10, 10, false);
mData = p;
mSize = p->size();
mSampleRate = sampleRate;
mNumChannels = numChannels;
mFormat = format;
mState = READY;
return 0; }
并且 MediaPlayerService 解码函数从下面的代码部分将所有值返回为 null
sp<IMemory> MediaPlayerService::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
{
LOGD("decode(%d, %lld, %lld)", fd, offset, length);
sp<MemoryBase> mem;
sp<MediaPlayerBase> player;
player_type playerType = getPlayerType(fd, offset, length);
LOGD("player type = %d", playerType);
// create the right type of player
sp<AudioCache> cache = new AudioCache("decode_fd");
player = android::createPlayer(playerType, cache.get(), cache->notify);
if (player == NULL) goto Exit;
if (player->hardwareOutput()) goto Exit;
static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache);
// set data source
if (player->setDataSource(fd, offset, length) != NO_ERROR) goto Exit;
LOGD("prepare");
player->prepareAsync();
LOGD("wait for prepare");
if (cache->wait() != NO_ERROR) goto Exit;
LOGD("start");
player->start();
LOGD("wait for playback complete");
if (cache->wait() != NO_ERROR) goto Exit;
mem = new MemoryBase(cache->getHeap(), 0, cache->size());
*pSampleRate = cache->sampleRate();//Nes
*pNumChannels = cache->channelCount();
*pFormat = cache->format();
LOGD("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat);
Exit:
if (player != 0) player->reset();
::close(fd);
return mem;
}
该函数返回的采样率、通道等的值为 0。
在此之后,当播放样本时,它显示错误““样本#未就绪”
int SoundPool::play(int sampleID, float leftVolume, float rightVolume,
int priority, int loop, float rate)
{
LOGW("sampleID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f",
sampleID, leftVolume, rightVolume, priority, loop, rate);
sp<Sample> sample;
SoundChannel* channel;
int channelID;
// scope for lock
{
Mutex::Autolock lock(&mLock);
// is sample ready?
sample = findSample(sampleID);
if ((sample == 0) || (sample->state() != Sample::READY)) {
LOGW(" sample %d not READY", sampleID);
return 0;
}
dump();
// allocate a channel
channel = allocateChannel(priority);
// no channel allocated - return 0
if (!channel) {
LOGW("No channel allocated");
return 0;
}
channelID = ++mNextChannelID;
}
LOGW("channel state = %d", channel->state());
channel->play(sample, channelID, leftVolume, rightVolume, priority, loop, rate);
return channelID;
}
有没有解决这个问题的方法..请帮助..