am 748ba9a9: Merge "NuPlayer now properly sends MEDIA_SET_VIDEOSIZE notifications." into honeycomb

* commit '748ba9a9512dee65d5b09cfe26a34ded753f4aab':
  NuPlayer now properly sends MEDIA_SET_VIDEOSIZE notifications.
This commit is contained in:
Andreas Huber
2011-01-10 11:28:44 -08:00
committed by Android Git Automerger
6 changed files with 200 additions and 13 deletions

View File

@@ -101,6 +101,8 @@ private:
List<sp<AMessage> > mDeferredQueue;
bool mSentFormat;
status_t allocateBuffersOnPort(OMX_U32 portIndex);
status_t freeBuffersOnPort(OMX_U32 portIndex);
status_t freeBuffer(OMX_U32 portIndex, size_t i);
@@ -145,6 +147,8 @@ private:
void deferMessage(const sp<AMessage> &msg);
void processDeferredMessages();
void sendFormatChange();
DISALLOW_EVIL_CONSTRUCTORS(ACodec);
};

View File

@@ -52,6 +52,10 @@ struct AMessage : public RefBase {
void setObject(const char *name, const sp<RefBase> &obj);
void setMessage(const char *name, const sp<AMessage> &obj);
void setRect(
const char *name,
int32_t left, int32_t top, int32_t right, int32_t bottom);
bool findInt32(const char *name, int32_t *value) const;
bool findInt64(const char *name, int64_t *value) const;
bool findSize(const char *name, size_t *value) const;
@@ -62,6 +66,10 @@ struct AMessage : public RefBase {
bool findObject(const char *name, sp<RefBase> *obj) const;
bool findMessage(const char *name, sp<AMessage> *obj) const;
bool findRect(
const char *name,
int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) const;
void post(int64_t delayUs = 0);
// Performs a deep-copy of "this", contained messages are in turn "dup'ed".
@@ -85,11 +93,16 @@ private:
kTypeString,
kTypeObject,
kTypeMessage,
kTypeRect,
};
uint32_t mWhat;
ALooper::handler_id mTarget;
struct Rect {
int32_t mLeft, mTop, mRight, mBottom;
};
struct Item {
union {
int32_t int32Value;
@@ -100,6 +113,7 @@ private:
void *ptrValue;
RefBase *refValue;
AString *stringValue;
Rect rectValue;
} u;
const char *mName;
Type mType;

View File

@@ -309,6 +309,18 @@ void DecoderWrapper::WrapperReader::sendFormatChange() {
realNotify->setInt32("width", width);
realNotify->setInt32("height", height);
int32_t cropLeft, cropTop, cropRight, cropBottom;
if (!meta->findRect(
kKeyCropRect,
&cropLeft, &cropTop, &cropRight, &cropBottom)) {
cropLeft = 0;
cropTop = 0;
cropRight = width - 1;
cropBottom = height - 1;
}
realNotify->setRect("crop", cropLeft, cropTop, cropRight, cropBottom);
}
notify->post();

View File

@@ -271,22 +271,43 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
finishFlushIfPossible();
} else if (what == ACodec::kWhatOutputFormatChanged) {
CHECK(audio);
if (audio) {
int32_t numChannels;
CHECK(codecRequest->findInt32("channel-count", &numChannels));
int32_t numChannels;
CHECK(codecRequest->findInt32("channel-count", &numChannels));
int32_t sampleRate;
CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
int32_t sampleRate;
CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
LOGV("Audio output format changed to %d Hz, %d channels",
sampleRate, numChannels);
LOGV("Audio output format changed to %d Hz, %d channels",
sampleRate, numChannels);
mAudioSink->close();
CHECK_EQ(mAudioSink->open(sampleRate, numChannels), (status_t)OK);
mAudioSink->start();
mAudioSink->close();
CHECK_EQ(mAudioSink->open(sampleRate, numChannels), (status_t)OK);
mAudioSink->start();
mRenderer->signalAudioSinkChanged();
} else {
// video
mRenderer->signalAudioSinkChanged();
int32_t width, height;
CHECK(codecRequest->findInt32("width", &width));
CHECK(codecRequest->findInt32("height", &height));
int32_t cropLeft, cropTop, cropRight, cropBottom;
CHECK(codecRequest->findRect(
"crop",
&cropLeft, &cropTop, &cropRight, &cropBottom));
LOGV("Video output format changed to %d x %d "
"(crop: %d, %d, %d, %d)",
width, height,
cropLeft, cropTop, cropRight, cropBottom);
notifyListener(
MEDIA_SET_VIDEO_SIZE,
cropRight - cropLeft + 1,
cropBottom - cropTop + 1);
}
} else if (what == ACodec::kWhatShutdownCompleted) {
LOGV("%s shutdown completed", audio ? "audio" : "video");
if (audio) {

View File

@@ -299,7 +299,8 @@ private:
////////////////////////////////////////////////////////////////////////////////
ACodec::ACodec()
: mNode(NULL) {
: mNode(NULL),
mSentFormat(false) {
mUninitializedState = new UninitializedState(this);
mLoadedToIdleState = new LoadedToIdleState(this);
mIdleToExecutingState = new IdleToExecutingState(this);
@@ -980,6 +981,103 @@ void ACodec::processDeferredMessages() {
}
}
void ACodec::sendFormatChange() {
sp<AMessage> notify = mNotify->dup();
notify->setInt32("what", kWhatOutputFormatChanged);
OMX_PARAM_PORTDEFINITIONTYPE def;
InitOMXParams(&def);
def.nPortIndex = kPortIndexOutput;
CHECK_EQ(mOMX->getParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
(status_t)OK);
CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
switch (def.eDomain) {
case OMX_PortDomainVideo:
{
OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
notify->setInt32("width", videoDef->nFrameWidth);
notify->setInt32("height", videoDef->nFrameHeight);
OMX_CONFIG_RECTTYPE rect;
InitOMXParams(&rect);
rect.nPortIndex = kPortIndexOutput;
if (mOMX->getConfig(
mNode, OMX_IndexConfigCommonOutputCrop,
&rect, sizeof(rect)) != OK) {
rect.nLeft = 0;
rect.nTop = 0;
rect.nWidth = videoDef->nFrameWidth;
rect.nHeight = videoDef->nFrameHeight;
}
CHECK_GE(rect.nLeft, 0);
CHECK_GE(rect.nTop, 0);
CHECK_GE(rect.nWidth, 0u);
CHECK_GE(rect.nHeight, 0u);
CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
notify->setRect(
"crop",
rect.nLeft,
rect.nTop,
rect.nLeft + rect.nWidth - 1,
rect.nTop + rect.nHeight - 1);
if (mNativeWindow != NULL) {
android_native_rect_t crop;
crop.left = rect.nLeft;
crop.top = rect.nTop;
crop.right = rect.nLeft + rect.nWidth - 1;
crop.bottom = rect.nTop + rect.nHeight - 1;
CHECK_EQ(0, native_window_set_crop(
mNativeWindow.get(), &crop));
}
break;
}
case OMX_PortDomainAudio:
{
OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
CHECK_EQ((int)audioDef->eEncoding, (int)OMX_AUDIO_CodingPCM);
OMX_AUDIO_PARAM_PCMMODETYPE params;
InitOMXParams(&params);
params.nPortIndex = kPortIndexOutput;
CHECK_EQ(mOMX->getParameter(
mNode, OMX_IndexParamAudioPcm,
&params, sizeof(params)),
(status_t)OK);
CHECK(params.nChannels == 1 || params.bInterleaved);
CHECK_EQ(params.nBitPerSample, 16u);
CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
notify->setInt32("channel-count", params.nChannels);
notify->setInt32("sample-rate", params.nSamplingRate);
break;
}
default:
TRESPASS();
}
notify->post();
mSentFormat = true;
}
////////////////////////////////////////////////////////////////////////////////
ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
@@ -1305,6 +1403,10 @@ bool ACodec::BaseState::onOMXFillBufferDone(
info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
}
} else {
if (!mCodec->mSentFormat) {
mCodec->sendFormatChange();
}
if (mCodec->mNativeWindow == NULL) {
info->mData->setRange(rangeOffset, rangeLength);
}
@@ -1717,7 +1819,7 @@ bool ACodec::ExecutingState::onOMXEvent(
{
CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
if (data2 == OMX_IndexParamPortDefinition) {
if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
CHECK_EQ(mCodec->mOMX->sendCommand(
mCodec->mNode,
OMX_CommandPortDisable, kPortIndexOutput),
@@ -1729,6 +1831,8 @@ bool ACodec::ExecutingState::onOMXEvent(
}
mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
} else if (data2 == OMX_IndexConfigCommonOutputCrop) {
mCodec->mSentFormat = false;
} else {
LOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
mCodec->mComponentName.c_str(), data2);
@@ -1816,6 +1920,8 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
} else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
mCodec->mSentFormat = false;
LOGV("[%s] Output port now reenabled.",
mCodec->mComponentName.c_str());
@@ -1869,6 +1975,8 @@ bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
void ACodec::ExecutingToIdleState::stateEntered() {
LOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
mCodec->mSentFormat = false;
}
bool ACodec::ExecutingToIdleState::onOMXEvent(

View File

@@ -171,6 +171,18 @@ void AMessage::setMessage(const char *name, const sp<AMessage> &obj) {
item->u.refValue = obj.get();
}
void AMessage::setRect(
const char *name,
int32_t left, int32_t top, int32_t right, int32_t bottom) {
Item *item = allocateItem(name);
item->mType = kTypeRect;
item->u.rectValue.mLeft = left;
item->u.rectValue.mTop = top;
item->u.rectValue.mRight = right;
item->u.rectValue.mBottom = bottom;
}
bool AMessage::findString(const char *name, AString *value) const {
const Item *item = findItem(name, kTypeString);
if (item) {
@@ -198,6 +210,22 @@ bool AMessage::findMessage(const char *name, sp<AMessage> *obj) const {
return false;
}
bool AMessage::findRect(
const char *name,
int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) const {
const Item *item = findItem(name, kTypeRect);
if (item == NULL) {
return false;
}
*left = item->u.rectValue.mLeft;
*top = item->u.rectValue.mTop;
*right = item->u.rectValue.mRight;
*bottom = item->u.rectValue.mBottom;
return true;
}
void AMessage::post(int64_t delayUs) {
extern ALooperRoster gLooperRoster;