Skip to content

Commit 9e7a6fc

Browse files
theandi666Android (Google) Code Review
authored andcommitted
Merge "Various improvements to nuplayer playback"
2 parents d679098 + 115cac8 commit 9e7a6fc

File tree

12 files changed

+149
-63
lines changed

12 files changed

+149
-63
lines changed

media/libmediaplayerservice/nuplayer/NuPlayer.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,12 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
299299
sampleRate, numChannels);
300300

301301
mAudioSink->close();
302-
CHECK_EQ(mAudioSink->open(sampleRate, numChannels), (status_t)OK);
302+
CHECK_EQ(mAudioSink->open(
303+
sampleRate,
304+
numChannels,
305+
AUDIO_FORMAT_PCM_16_BIT,
306+
8 /* bufferCount */),
307+
(status_t)OK);
303308
mAudioSink->start();
304309

305310
mRenderer->signalAudioSinkChanged();

media/libmediaplayerservice/nuplayer/NuPlayer.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,19 @@ struct NuPlayer : public AHandler {
7070
struct StreamingSource;
7171

7272
enum {
73-
kWhatSetDataSource,
74-
kWhatSetVideoNativeWindow,
75-
kWhatSetAudioSink,
76-
kWhatMoreDataQueued,
77-
kWhatStart,
78-
kWhatScanSources,
79-
kWhatVideoNotify,
80-
kWhatAudioNotify,
81-
kWhatRendererNotify,
82-
kWhatReset,
83-
kWhatSeek,
84-
kWhatPause,
85-
kWhatResume,
73+
kWhatSetDataSource = '=DaS',
74+
kWhatSetVideoNativeWindow = '=NaW',
75+
kWhatSetAudioSink = '=AuS',
76+
kWhatMoreDataQueued = 'more',
77+
kWhatStart = 'strt',
78+
kWhatScanSources = 'scan',
79+
kWhatVideoNotify = 'vidN',
80+
kWhatAudioNotify = 'audN',
81+
kWhatRendererNotify = 'renN',
82+
kWhatReset = 'rset',
83+
kWhatSeek = 'seek',
84+
kWhatPause = 'paus',
85+
kWhatResume = 'rsme',
8686
};
8787

8888
wp<NuPlayerDriver> mDriver;

media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,21 @@ void NuPlayer::Decoder::configure(const sp<MetaData> &meta) {
5959
format->setObject("native-window", mNativeWindow);
6060
}
6161

62+
// Current video decoders do not return from OMX_FillThisBuffer
63+
// quickly, violating the OpenMAX specs, until that is remedied
64+
// we need to invest in an extra looper to free the main event
65+
// queue.
66+
bool needDedicatedLooper = !strncasecmp(mime, "video/", 6);
67+
6268
mCodec = new ACodec;
63-
looper()->registerHandler(mCodec);
69+
70+
if (needDedicatedLooper && mCodecLooper == NULL) {
71+
mCodecLooper = new ALooper;
72+
mCodecLooper->setName("NuPlayerDecoder");
73+
mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
74+
}
75+
76+
(needDedicatedLooper ? mCodecLooper : looper())->registerHandler(mCodec);
6477

6578
mCodec->setNotificationMessage(notifyMsg);
6679
mCodec->initiateSetup(format);

media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,14 @@ struct NuPlayer::Decoder : public AHandler {
4343

4444
private:
4545
enum {
46-
kWhatCodecNotify,
46+
kWhatCodecNotify = 'cdcN',
4747
};
4848

4949
sp<AMessage> mNotify;
5050
sp<NativeWindowWrapper> mNativeWindow;
5151

5252
sp<ACodec> mCodec;
53+
sp<ALooper> mCodecLooper;
5354

5455
Vector<sp<ABuffer> > mCSD;
5556
size_t mCSDIndex;

media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,24 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
118118

119119
mDrainAudioQueuePending = false;
120120

121-
onDrainAudioQueue();
122-
123-
postDrainAudioQueue();
121+
if (onDrainAudioQueue()) {
122+
uint32_t numFramesPlayed;
123+
CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed),
124+
(status_t)OK);
125+
126+
uint32_t numFramesPendingPlayout =
127+
mNumFramesWritten - numFramesPlayed;
128+
129+
// This is how long the audio sink will have data to
130+
// play back.
131+
int64_t delayUs =
132+
mAudioSink->msecsPerFrame()
133+
* numFramesPendingPlayout * 1000ll;
134+
135+
// Let's give it more data after about half that time
136+
// has elapsed.
137+
postDrainAudioQueue(delayUs / 2);
138+
}
124139
break;
125140
}
126141

@@ -182,7 +197,7 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
182197
}
183198
}
184199

185-
void NuPlayer::Renderer::postDrainAudioQueue() {
200+
void NuPlayer::Renderer::postDrainAudioQueue(int64_t delayUs) {
186201
if (mDrainAudioQueuePending || mSyncQueues || mPaused) {
187202
return;
188203
}
@@ -194,19 +209,33 @@ void NuPlayer::Renderer::postDrainAudioQueue() {
194209
mDrainAudioQueuePending = true;
195210
sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, id());
196211
msg->setInt32("generation", mAudioQueueGeneration);
197-
msg->post();
212+
msg->post(delayUs);
198213
}
199214

200215
void NuPlayer::Renderer::signalAudioSinkChanged() {
201216
(new AMessage(kWhatAudioSinkChanged, id()))->post();
202217
}
203218

204-
void NuPlayer::Renderer::onDrainAudioQueue() {
205-
for (;;) {
206-
if (mAudioQueue.empty()) {
207-
break;
208-
}
219+
bool NuPlayer::Renderer::onDrainAudioQueue() {
220+
uint32_t numFramesPlayed;
221+
CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
222+
223+
ssize_t numFramesAvailableToWrite =
224+
mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
225+
226+
#if 0
227+
if (numFramesAvailableToWrite == mAudioSink->frameCount()) {
228+
LOGI("audio sink underrun");
229+
} else {
230+
LOGV("audio queue has %d frames left to play",
231+
mAudioSink->frameCount() - numFramesAvailableToWrite);
232+
}
233+
#endif
209234

235+
size_t numBytesAvailableToWrite =
236+
numFramesAvailableToWrite * mAudioSink->frameSize();
237+
238+
while (numBytesAvailableToWrite > 0 && !mAudioQueue.empty()) {
210239
QueueEntry *entry = &*mAudioQueue.begin();
211240

212241
if (entry->mBuffer == NULL) {
@@ -216,20 +245,7 @@ void NuPlayer::Renderer::onDrainAudioQueue() {
216245

217246
mAudioQueue.erase(mAudioQueue.begin());
218247
entry = NULL;
219-
return;
220-
}
221-
222-
uint32_t numFramesPlayed;
223-
CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
224-
225-
ssize_t numFramesAvailableToWrite =
226-
mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
227-
228-
size_t numBytesAvailableToWrite =
229-
numFramesAvailableToWrite * mAudioSink->frameSize();
230-
231-
if (numBytesAvailableToWrite == 0) {
232-
break;
248+
return false;
233249
}
234250

235251
if (entry->mOffset == 0) {
@@ -274,10 +290,14 @@ void NuPlayer::Renderer::onDrainAudioQueue() {
274290
entry = NULL;
275291
}
276292

277-
mNumFramesWritten += copy / mAudioSink->frameSize();
293+
numBytesAvailableToWrite -= copy;
294+
size_t copiedFrames = copy / mAudioSink->frameSize();
295+
mNumFramesWritten += copiedFrames;
278296
}
279297

280298
notifyPosition();
299+
300+
return !mAudioQueue.empty();
281301
}
282302

283303
void NuPlayer::Renderer::postDrainVideoQueue() {
@@ -344,7 +364,14 @@ void NuPlayer::Renderer::onDrainVideoQueue() {
344364
int64_t mediaTimeUs;
345365
CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
346366

347-
LOGI("rendering video at media time %.2f secs", mediaTimeUs / 1E6);
367+
int64_t realTimeUs = mediaTimeUs - mAnchorTimeMediaUs + mAnchorTimeRealUs;
368+
int64_t lateByUs = ALooper::GetNowUs() - realTimeUs;
369+
370+
if (lateByUs > 40000) {
371+
LOGI("video late by %lld us (%.2f secs)", lateByUs, lateByUs / 1E6);
372+
} else {
373+
LOGV("rendering video at media time %.2f secs", mediaTimeUs / 1E6);
374+
}
348375
#endif
349376

350377
entry->mNotifyConsumed->setInt32("render", true);

media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ struct NuPlayer::Renderer : public AHandler {
4545
void resume();
4646

4747
enum {
48-
kWhatEOS,
49-
kWhatFlushComplete,
50-
kWhatPosition,
48+
kWhatEOS = 'eos ',
49+
kWhatFlushComplete = 'fluC',
50+
kWhatPosition = 'posi',
5151
};
5252

5353
protected:
@@ -57,14 +57,14 @@ struct NuPlayer::Renderer : public AHandler {
5757

5858
private:
5959
enum {
60-
kWhatDrainAudioQueue,
61-
kWhatDrainVideoQueue,
62-
kWhatQueueBuffer,
63-
kWhatQueueEOS,
64-
kWhatFlush,
65-
kWhatAudioSinkChanged,
66-
kWhatPause,
67-
kWhatResume,
60+
kWhatDrainAudioQueue = 'draA',
61+
kWhatDrainVideoQueue = 'draV',
62+
kWhatQueueBuffer = 'queB',
63+
kWhatQueueEOS = 'qEOS',
64+
kWhatFlush = 'flus',
65+
kWhatAudioSinkChanged = 'auSC',
66+
kWhatPause = 'paus',
67+
kWhatResume = 'resm',
6868
};
6969

7070
struct QueueEntry {
@@ -102,8 +102,8 @@ struct NuPlayer::Renderer : public AHandler {
102102

103103
int64_t mLastPositionUpdateUs;
104104

105-
void onDrainAudioQueue();
106-
void postDrainAudioQueue();
105+
bool onDrainAudioQueue();
106+
void postDrainAudioQueue(int64_t delayUs = 0);
107107

108108
void onDrainVideoQueue();
109109
void postDrainVideoQueue();

media/libmediaplayerservice/nuplayer/StreamingSource.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ bool NuPlayer::StreamingSource::feedMoreTSData() {
5252
return false;
5353
}
5454

55-
for (int32_t i = 0; i < 10; ++i) {
55+
for (int32_t i = 0; i < 50; ++i) {
5656
char buffer[188];
5757
sp<AMessage> extra;
5858
ssize_t n = mStreamListener->read(buffer, sizeof(buffer), &extra);

media/libstagefright/ACodec.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,8 +1377,13 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
13771377
memcpy(info->mData->data(), buffer->data(), buffer->size());
13781378
}
13791379

1380-
LOGV("[%s] calling emptyBuffer %p",
1381-
mCodec->mComponentName.c_str(), bufferID);
1380+
if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
1381+
LOGV("[%s] calling emptyBuffer %p w/ codec specific data",
1382+
mCodec->mComponentName.c_str(), bufferID);
1383+
} else {
1384+
LOGV("[%s] calling emptyBuffer %p w/ time %lld us",
1385+
mCodec->mComponentName.c_str(), bufferID, timeUs);
1386+
}
13821387

13831388
CHECK_EQ(mCodec->mOMX->emptyBuffer(
13841389
mCodec->mNode,
@@ -1396,7 +1401,7 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
13961401
LOGV("[%s] Signalling EOS on the input port",
13971402
mCodec->mComponentName.c_str());
13981403

1399-
LOGV("[%s] calling emptyBuffer %p",
1404+
LOGV("[%s] calling emptyBuffer %p signalling EOS",
14001405
mCodec->mComponentName.c_str(), bufferID);
14011406

14021407
CHECK_EQ(mCodec->mOMX->emptyBuffer(
@@ -1457,8 +1462,8 @@ bool ACodec::BaseState::onOMXFillBufferDone(
14571462
int64_t timeUs,
14581463
void *platformPrivate,
14591464
void *dataPtr) {
1460-
LOGV("[%s] onOMXFillBufferDone %p",
1461-
mCodec->mComponentName.c_str(), bufferID);
1465+
LOGV("[%s] onOMXFillBufferDone %p time %lld us",
1466+
mCodec->mComponentName.c_str(), bufferID, timeUs);
14621467

14631468
ssize_t index;
14641469
BufferInfo *info =
@@ -1686,7 +1691,11 @@ void ACodec::UninitializedState::onSetup(
16861691
++matchIndex) {
16871692
componentName = matchingCodecs.itemAt(matchIndex).string();
16881693

1694+
pid_t tid = androidGetTid();
1695+
int prevPriority = androidGetThreadPriority(tid);
1696+
androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
16891697
status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
1698+
androidSetThreadPriority(tid, prevPriority);
16901699

16911700
if (err == OK) {
16921701
break;

media/libstagefright/chromium_http/support.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,32 @@ bool logMessageHandler(
7474
return false;
7575
}
7676

77+
struct AutoPrioritySaver {
78+
AutoPrioritySaver()
79+
: mTID(androidGetTid()),
80+
mPrevPriority(androidGetThreadPriority(mTID)) {
81+
androidSetThreadPriority(mTID, ANDROID_PRIORITY_NORMAL);
82+
}
83+
84+
~AutoPrioritySaver() {
85+
androidSetThreadPriority(mTID, mPrevPriority);
86+
}
87+
88+
private:
89+
pid_t mTID;
90+
int mPrevPriority;
91+
92+
DISALLOW_EVIL_CONSTRUCTORS(AutoPrioritySaver);
93+
};
7794

7895
static void InitializeNetworkThreadIfNecessary() {
7996
Mutex::Autolock autoLock(gNetworkThreadLock);
97+
8098
if (gNetworkThread == NULL) {
99+
// Make sure any threads spawned by the chromium framework are
100+
// running at normal priority instead of inheriting this thread's.
101+
AutoPrioritySaver saver;
102+
81103
gNetworkThread = new base::Thread("network");
82104
base::Thread::Options options;
83105
options.message_loop_type = MessageLoop::TYPE_IO;

media/libstagefright/foundation/AMessage.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,15 @@ AString AMessage::debugString(int32_t indent) const {
385385
item.u.refValue)->debugString(
386386
indent + strlen(item.mName) + 14).c_str());
387387
break;
388+
case kTypeRect:
389+
tmp = StringPrintf(
390+
"Rect %s(%d, %d, %d, %d)",
391+
item.mName,
392+
item.u.rectValue.mLeft,
393+
item.u.rectValue.mTop,
394+
item.u.rectValue.mRight,
395+
item.u.rectValue.mBottom);
396+
break;
388397
default:
389398
TRESPASS();
390399
}

0 commit comments

Comments
 (0)