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:
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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(¶ms);
|
||||
params.nPortIndex = kPortIndexOutput;
|
||||
|
||||
CHECK_EQ(mOMX->getParameter(
|
||||
mNode, OMX_IndexParamAudioPcm,
|
||||
¶ms, 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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user