Merge "audioflinger: fix logcat" into nyc-mr1-dev
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index f4d0acd..4f2517c 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -314,11 +314,12 @@
status_t handleSetSurface(const sp<Surface> &surface);
status_t setupNativeWindowSizeFormatAndUsage(
- ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */);
+ ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */,
+ bool reconnect);
status_t configureOutputBuffersFromNativeWindow(
OMX_U32 *nBufferCount, OMX_U32 *nBufferSize,
- OMX_U32 *nMinUndequeuedBuffers);
+ OMX_U32 *nMinUndequeuedBuffers, bool preregister);
status_t allocateOutputMetadataBuffers();
status_t submitOutputMetadataBuffer();
void signalSubmitOutputMetadataBufferIfEOS_workaround();
diff --git a/include/media/stagefright/SurfaceUtils.h b/include/media/stagefright/SurfaceUtils.h
index c1a9c0a..13d580c 100644
--- a/include/media/stagefright/SurfaceUtils.h
+++ b/include/media/stagefright/SurfaceUtils.h
@@ -24,9 +24,14 @@
namespace android {
+/**
+ * Configures |nativeWindow| for given |width|x|height|, pixel |format|, |rotation| and |usage|.
+ * If |reconnect| is true, reconnects to the native window before hand.
+ * @return first error encountered, or NO_ERROR on success.
+ */
status_t setNativeWindowSizeFormatAndUsage(
ANativeWindow *nativeWindow /* nonnull */,
- int width, int height, int format, int rotation, int usage);
+ int width, int height, int format, int rotation, int usage, bool reconnect);
status_t pushBlankBuffersToNativeWindow(ANativeWindow *nativeWindow /* nonnull */);
} // namespace android
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index cbc28e3..d97d5b1 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -674,7 +674,10 @@
}
int usageBits = 0;
- status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow, &usageBits);
+ // no need to reconnect as we will not dequeue all buffers
+ status_t err = setupNativeWindowSizeFormatAndUsage(
+ nativeWindow, &usageBits,
+ !storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment /* reconnect */);
if (err != OK) {
return err;
}
@@ -948,7 +951,8 @@
}
status_t ACodec::setupNativeWindowSizeFormatAndUsage(
- ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */) {
+ ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */,
+ bool reconnect) {
OMX_PARAM_PORTDEFINITIONTYPE def;
InitOMXParams(&def);
def.nPortIndex = kPortIndexOutput;
@@ -986,12 +990,14 @@
def.format.video.nFrameHeight,
def.format.video.eColorFormat,
mRotationDegrees,
- usage);
+ usage,
+ reconnect);
}
status_t ACodec::configureOutputBuffersFromNativeWindow(
OMX_U32 *bufferCount, OMX_U32 *bufferSize,
- OMX_U32 *minUndequeuedBuffers) {
+ OMX_U32 *minUndequeuedBuffers, bool preregister) {
+
OMX_PARAM_PORTDEFINITIONTYPE def;
InitOMXParams(&def);
def.nPortIndex = kPortIndexOutput;
@@ -1000,7 +1006,8 @@
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
if (err == OK) {
- err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get(), &mNativeWindowUsageBits);
+ err = setupNativeWindowSizeFormatAndUsage(
+ mNativeWindow.get(), &mNativeWindowUsageBits, preregister /* reconnect */);
}
if (err != OK) {
mNativeWindowUsageBits = 0;
@@ -1082,7 +1089,7 @@
status_t ACodec::allocateOutputBuffersFromNativeWindow() {
OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
status_t err = configureOutputBuffersFromNativeWindow(
- &bufferCount, &bufferSize, &minUndequeuedBuffers);
+ &bufferCount, &bufferSize, &minUndequeuedBuffers, true /* preregister */);
if (err != 0)
return err;
mNumUndequeuedBuffers = minUndequeuedBuffers;
@@ -1168,7 +1175,8 @@
status_t ACodec::allocateOutputMetadataBuffers() {
OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
status_t err = configureOutputBuffersFromNativeWindow(
- &bufferCount, &bufferSize, &minUndequeuedBuffers);
+ &bufferCount, &bufferSize, &minUndequeuedBuffers,
+ mLegacyAdaptiveExperiment /* preregister */);
if (err != 0)
return err;
mNumUndequeuedBuffers = minUndequeuedBuffers;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index e8cd58a..1cbcaa9 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1791,9 +1791,8 @@
err = BAD_VALUE;
} else {
err = connectToSurface(surface);
- if (err == BAD_VALUE) {
- // assuming reconnecting to same surface
- // TODO: check if it is the same surface
+ if (err == ALREADY_EXISTS) {
+ // reconnecting to same surface
err = OK;
} else {
if (err == OK) {
@@ -2683,11 +2682,14 @@
status_t MediaCodec::connectToSurface(const sp<Surface> &surface) {
status_t err = OK;
if (surface != NULL) {
+ if (mSurface != NULL
+ && surface->getConsumerName() == mSurface->getConsumerName()) {
+ ALOGI("connecting to native window with same name. Assuming no change of surface");
+ return ALREADY_EXISTS;
+ }
+
err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
- if (err == BAD_VALUE) {
- ALOGI("native window already connected. Assuming no change of surface");
- return err;
- } else if (err == OK) {
+ if (err == OK) {
// Require a fresh set of buffers after each connect by using a unique generation
// number. Rely on the fact that max supported process id by Linux is 2^22.
// PID is never 0 so we don't have to worry that we use the default generation of 0.
@@ -2709,7 +2711,8 @@
ALOGE("native_window_api_connect returned an error: %s (%d)", strerror(-err), err);
}
}
- return err;
+ // do not return ALREADY_EXISTS unless surfaces are the same
+ return err == ALREADY_EXISTS ? BAD_VALUE : err;
}
status_t MediaCodec::disconnectFromSurface() {
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index a62e1a2..377f5fd 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -22,6 +22,7 @@
#include <utils/Log.h>
#include <gui/Surface.h>
+#include "include/avc_utils.h"
#include "include/StagefrightMetadataRetriever.h"
#include <media/ICrypto.h>
@@ -237,6 +238,15 @@
int64_t timeUs;
size_t retriesLeft = kRetryCount;
bool done = false;
+ const char *mime;
+ bool success = format->findCString(kKeyMIMEType, &mime);
+ if (!success) {
+ ALOGE("Could not find mime type");
+ return NULL;
+ }
+
+ bool isAvcOrHevc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)
+ || !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC);
do {
size_t inputIndex = -1;
@@ -276,6 +286,11 @@
memcpy(codecBuffer->data(),
(const uint8_t*)mediaBuffer->data() + mediaBuffer->range_offset(),
mediaBuffer->range_length());
+ if (isAvcOrHevc && IsIDR(codecBuffer)) {
+ // Only need to decode one IDR frame.
+ haveMoreInputs = false;
+ flags |= MediaCodec::BUFFER_FLAG_EOS;
+ }
}
mediaBuffer->release();
diff --git a/media/libstagefright/SurfaceUtils.cpp b/media/libstagefright/SurfaceUtils.cpp
index 9940822..568837a 100644
--- a/media/libstagefright/SurfaceUtils.cpp
+++ b/media/libstagefright/SurfaceUtils.cpp
@@ -26,8 +26,25 @@
status_t setNativeWindowSizeFormatAndUsage(
ANativeWindow *nativeWindow /* nonnull */,
- int width, int height, int format, int rotation, int usage) {
- status_t err = native_window_set_buffers_dimensions(nativeWindow, width, height);
+ int width, int height, int format, int rotation, int usage, bool reconnect) {
+ status_t err = NO_ERROR;
+
+ // In some cases we need to reconnect so that we can dequeue all buffers
+ if (reconnect) {
+ err = native_window_api_disconnect(nativeWindow, NATIVE_WINDOW_API_MEDIA);
+ if (err != NO_ERROR) {
+ ALOGE("native_window_api_disconnect failed: %s (%d)", strerror(-err), -err);
+ return err;
+ }
+
+ err = native_window_api_connect(nativeWindow, NATIVE_WINDOW_API_MEDIA);
+ if (err != NO_ERROR) {
+ ALOGE("native_window_api_connect failed: %s (%d)", strerror(-err), -err);
+ return err;
+ }
+ }
+
+ err = native_window_set_buffers_dimensions(nativeWindow, width, height);
if (err != NO_ERROR) {
ALOGE("native_window_set_buffers_dimensions failed: %s (%d)", strerror(-err), -err);
return err;
@@ -124,7 +141,8 @@
}
err = setNativeWindowSizeFormatAndUsage(
- nativeWindow, 1, 1, HAL_PIXEL_FORMAT_RGBX_8888, 0, GRALLOC_USAGE_SW_WRITE_OFTEN);
+ nativeWindow, 1, 1, HAL_PIXEL_FORMAT_RGBX_8888, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
+ false /* reconnect */);
if (err != NO_ERROR) {
goto error;
}
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index 4824974..cb39244 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -124,6 +124,7 @@
switch (mState) {
case STATE_IN_RECONFIG:
case STATE_CONFIGURED:
+ case STATE_ABANDONED:
// OK
break;
default:
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 3aff684..299435a 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -653,9 +653,9 @@
*buffer = 0;
ALOGW("%s: the released buffer has already been freed by the buffer queue!", __FUNCTION__);
} else if (res != OK) {
- // Other errors are fatal.
+ // Treat other errors as abandonment
ALOGE("%s: detach next buffer failed: %s (%d).", __FUNCTION__, strerror(-res), res);
- mState = STATE_ERROR;
+ mState = STATE_ABANDONED;
return res;
}