Skip to content

Commit cd40f4a

Browse files
theandi666Android (Google) Code Review
authored andcommitted
Merge "Added better codec statistics to evaluate performance."
2 parents 263aa1e + e5760e3 commit cd40f4a

File tree

1 file changed

+73
-31
lines changed

1 file changed

+73
-31
lines changed

cmds/stagefright/codec.cpp

Lines changed: 73 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
static void usage(const char *me) {
3636
fprintf(stderr, "usage: %s [-a] use audio\n"
3737
"\t\t[-v] use video\n"
38-
"\t\t[-p] playback\n", me);
38+
"\t\t[-p] playback\n"
39+
"\t\t[-S] allocate buffers from a surface\n", me);
3940

4041
exit(1);
4142
}
@@ -49,6 +50,9 @@ struct CodecState {
4950
Vector<sp<ABuffer> > mInBuffers;
5051
Vector<sp<ABuffer> > mOutBuffers;
5152
bool mSawOutputEOS;
53+
int64_t mNumBuffersDecoded;
54+
int64_t mNumBytesDecoded;
55+
bool mIsAudio;
5256
};
5357

5458
} // namespace android
@@ -57,9 +61,12 @@ static int decode(
5761
const android::sp<android::ALooper> &looper,
5862
const char *path,
5963
bool useAudio,
60-
bool useVideo) {
64+
bool useVideo,
65+
const android::sp<android::Surface> &surface) {
6166
using namespace android;
6267

68+
static int64_t kTimeout = 500ll;
69+
6370
sp<NuMediaExtractor> extractor = new NuMediaExtractor;
6471
if (extractor->setDataSource(path) != OK) {
6572
fprintf(stderr, "unable to instantiate extractor.\n");
@@ -78,11 +85,12 @@ static int decode(
7885
AString mime;
7986
CHECK(format->findString("mime", &mime));
8087

81-
if (useAudio && !haveAudio
82-
&& !strncasecmp(mime.c_str(), "audio/", 6)) {
88+
bool isAudio = !strncasecmp(mime.c_str(), "audio/", 6);
89+
bool isVideo = !strncasecmp(mime.c_str(), "video/", 6);
90+
91+
if (useAudio && !haveAudio && isAudio) {
8392
haveAudio = true;
84-
} else if (useVideo && !haveVideo
85-
&& !strncasecmp(mime.c_str(), "video/", 6)) {
93+
} else if (useVideo && !haveVideo && isVideo) {
8694
haveVideo = true;
8795
} else {
8896
continue;
@@ -96,13 +104,17 @@ static int decode(
96104
CodecState *state =
97105
&stateByTrack.editValueAt(stateByTrack.add(i, CodecState()));
98106

107+
state->mNumBytesDecoded = 0;
108+
state->mNumBuffersDecoded = 0;
109+
state->mIsAudio = isAudio;
110+
99111
state->mCodec = MediaCodec::CreateByType(
100112
looper, mime.c_str(), false /* encoder */);
101113

102114
CHECK(state->mCodec != NULL);
103115

104116
err = state->mCodec->configure(
105-
format, NULL /* surfaceTexture */, 0 /* flags */);
117+
format, isVideo ? surface : NULL, 0 /* flags */);
106118

107119
CHECK_EQ(err, (status_t)OK);
108120

@@ -122,6 +134,8 @@ static int decode(
122134

123135
CHECK(!stateByTrack.isEmpty());
124136

137+
int64_t startTimeUs = ALooper::GetNowUs();
138+
125139
for (size_t i = 0; i < stateByTrack.size(); ++i) {
126140
CodecState *state = &stateByTrack.editValueAt(i);
127141

@@ -137,13 +151,7 @@ static int decode(
137151

138152
while (state->mCSDIndex < state->mCSD.size()) {
139153
size_t index;
140-
status_t err = codec->dequeueInputBuffer(&index);
141-
142-
if (err == -EAGAIN) {
143-
usleep(10000);
144-
continue;
145-
}
146-
154+
status_t err = codec->dequeueInputBuffer(&index, -1ll);
147155
CHECK_EQ(err, (status_t)OK);
148156

149157
const sp<ABuffer> &srcBuffer =
@@ -179,7 +187,7 @@ static int decode(
179187

180188
for (;;) {
181189
size_t index;
182-
err = state->mCodec->dequeueInputBuffer(&index);
190+
err = state->mCodec->dequeueInputBuffer(&index, kTimeout);
183191

184192
if (err == -EAGAIN) {
185193
continue;
@@ -204,7 +212,7 @@ static int decode(
204212
CodecState *state = &stateByTrack.editValueFor(trackIndex);
205213

206214
size_t index;
207-
err = state->mCodec->dequeueInputBuffer(&index);
215+
err = state->mCodec->dequeueInputBuffer(&index, kTimeout);
208216

209217
if (err == OK) {
210218
ALOGV("filling input buffer %d", index);
@@ -261,12 +269,15 @@ static int decode(
261269
uint32_t flags;
262270
status_t err = state->mCodec->dequeueOutputBuffer(
263271
&index, &offset, &size, &presentationTimeUs, &flags,
264-
10000ll);
272+
kTimeout);
265273

266274
if (err == OK) {
267275
ALOGV("draining output buffer %d, time = %lld us",
268276
index, presentationTimeUs);
269277

278+
++state->mNumBuffersDecoded;
279+
state->mNumBytesDecoded += size;
280+
270281
err = state->mCodec->releaseOutputBuffer(index);
271282
CHECK_EQ(err, (status_t)OK);
272283

@@ -292,10 +303,27 @@ static int decode(
292303
}
293304
}
294305

306+
int64_t elapsedTimeUs = ALooper::GetNowUs() - startTimeUs;
307+
295308
for (size_t i = 0; i < stateByTrack.size(); ++i) {
296309
CodecState *state = &stateByTrack.editValueAt(i);
297310

298311
CHECK_EQ((status_t)OK, state->mCodec->release());
312+
313+
if (state->mIsAudio) {
314+
printf("track %d: %lld bytes received. %.2f KB/sec\n",
315+
i,
316+
state->mNumBytesDecoded,
317+
state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs);
318+
} else {
319+
printf("track %d: %lld frames decoded, %.2f fps. %lld bytes "
320+
"received. %.2f KB/sec\n",
321+
i,
322+
state->mNumBuffersDecoded,
323+
state->mNumBuffersDecoded * 1E6 / elapsedTimeUs,
324+
state->mNumBytesDecoded,
325+
state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs);
326+
}
299327
}
300328

301329
return 0;
@@ -309,9 +337,10 @@ int main(int argc, char **argv) {
309337
bool useAudio = false;
310338
bool useVideo = false;
311339
bool playback = false;
340+
bool useSurface = false;
312341

313342
int res;
314-
while ((res = getopt(argc, argv, "havp")) >= 0) {
343+
while ((res = getopt(argc, argv, "havpS")) >= 0) {
315344
switch (res) {
316345
case 'a':
317346
{
@@ -331,6 +360,12 @@ int main(int argc, char **argv) {
331360
break;
332361
}
333362

363+
case 'S':
364+
{
365+
useSurface = true;
366+
break;
367+
}
368+
334369
case '?':
335370
case 'h':
336371
default:
@@ -358,23 +393,26 @@ int main(int argc, char **argv) {
358393
sp<ALooper> looper = new ALooper;
359394
looper->start();
360395

361-
if (playback) {
362-
sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
396+
sp<SurfaceComposerClient> composerClient;
397+
sp<SurfaceControl> control;
398+
sp<Surface> surface;
399+
400+
if (playback || (useSurface && useVideo)) {
401+
composerClient = new SurfaceComposerClient;
363402
CHECK_EQ(composerClient->initCheck(), (status_t)OK);
364403

365404
ssize_t displayWidth = composerClient->getDisplayWidth(0);
366405
ssize_t displayHeight = composerClient->getDisplayHeight(0);
367406

368407
ALOGV("display is %ld x %ld\n", displayWidth, displayHeight);
369408

370-
sp<SurfaceControl> control =
371-
composerClient->createSurface(
372-
String8("A Surface"),
373-
0,
374-
displayWidth,
375-
displayHeight,
376-
PIXEL_FORMAT_RGB_565,
377-
0);
409+
control = composerClient->createSurface(
410+
String8("A Surface"),
411+
0,
412+
displayWidth,
413+
displayHeight,
414+
PIXEL_FORMAT_RGB_565,
415+
0);
378416

379417
CHECK(control != NULL);
380418
CHECK(control->isValid());
@@ -384,9 +422,11 @@ int main(int argc, char **argv) {
384422
CHECK_EQ(control->show(), (status_t)OK);
385423
SurfaceComposerClient::closeGlobalTransaction();
386424

387-
sp<Surface> surface = control->getSurface();
425+
surface = control->getSurface();
388426
CHECK(surface != NULL);
427+
}
389428

429+
if (playback) {
390430
sp<SimplePlayer> player = new SimplePlayer;
391431
looper->registerHandler(player);
392432

@@ -396,10 +436,12 @@ int main(int argc, char **argv) {
396436
sleep(60);
397437
player->stop();
398438
player->reset();
439+
} else {
440+
decode(looper, argv[0], useAudio, useVideo, surface);
441+
}
399442

443+
if (playback || (useSurface && useVideo)) {
400444
composerClient->dispose();
401-
} else {
402-
decode(looper, argv[0], useAudio, useVideo);
403445
}
404446

405447
looper->stop();

0 commit comments

Comments
 (0)