Merge "LiveSession: re-buffer on under run to avoid stutter" into lmp-dev
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
index 0d1ab71..5b2ab84 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -134,6 +134,12 @@
}
uint8_t *bitstream = inHeader->pBuffer + inHeader->nOffset;
+ uint32_t *start_code = (uint32_t *)bitstream;
+ bool volHeader = *start_code == 0xB0010000;
+ if (volHeader) {
+ PVCleanUpVideoDecoder(mHandle);
+ mInitialized = false;
+ }
if (!mInitialized) {
uint8_t *vol_data[1];
@@ -141,7 +147,7 @@
vol_data[0] = NULL;
- if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+ if ((inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) || volHeader) {
vol_data[0] = bitstream;
vol_size = inHeader->nFilledLen;
}
@@ -169,21 +175,26 @@
PVSetPostProcType((VideoDecControls *) mHandle, 0);
+ bool hasFrameData = false;
if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
inInfo->mOwnedByUs = false;
inQueue.erase(inQueue.begin());
inInfo = NULL;
notifyEmptyBufferDone(inHeader);
inHeader = NULL;
+ } else if (volHeader) {
+ hasFrameData = true;
}
mInitialized = true;
- if (mode == MPEG4_MODE && portSettingsChanged()) {
+ if (mode == MPEG4_MODE && handlePortSettingsChange()) {
return;
}
- continue;
+ if (!hasFrameData) {
+ continue;
+ }
}
if (!mFramesConfigured) {
@@ -223,7 +234,9 @@
return;
}
- if (portSettingsChanged()) {
+ // H263 doesn't have VOL header, the frame size information is in short header, i.e. the
+ // decoder may detect size change after PVDecodeVideoFrame.
+ if (handlePortSettingsChange()) {
return;
}
@@ -269,7 +282,7 @@
}
}
-bool SoftMPEG4::portSettingsChanged() {
+bool SoftMPEG4::handlePortSettingsChange() {
uint32_t disp_width, disp_height;
PVGetVideoDimensions(mHandle, (int32 *)&disp_width, (int32 *)&disp_height);
@@ -282,25 +295,20 @@
ALOGV("disp_width = %d, disp_height = %d, buf_width = %d, buf_height = %d",
disp_width, disp_height, buf_width, buf_height);
- if (mCropWidth != disp_width
- || mCropHeight != disp_height) {
+ bool cropChanged = false;
+ if (mCropWidth != disp_width || mCropHeight != disp_height) {
mCropLeft = 0;
mCropTop = 0;
mCropWidth = disp_width;
mCropHeight = disp_height;
-
- notify(OMX_EventPortSettingsChanged,
- 1,
- OMX_IndexConfigCommonOutputCrop,
- NULL);
+ cropChanged = true;
}
- if (buf_width != mWidth || buf_height != mHeight) {
- mWidth = buf_width;
- mHeight = buf_height;
-
- updatePortDefinitions();
-
+ bool portWillReset = false;
+ const bool fakeStride = true;
+ SoftVideoDecoderOMXComponent::handlePortSettingsChange(
+ &portWillReset, buf_width, buf_height, cropChanged, fakeStride);
+ if (portWillReset) {
if (mMode == MODE_H263) {
PVCleanUpVideoDecoder(mHandle);
@@ -318,13 +326,9 @@
}
mFramesConfigured = false;
-
- notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
- mOutputPortSettingsChange = AWAITING_DISABLED;
- return true;
}
- return false;
+ return portWillReset;
}
void SoftMPEG4::onPortFlushCompleted(OMX_U32 portIndex) {
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.h b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.h
index de14aaf..8a06a00 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.h
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.h
@@ -67,7 +67,7 @@
status_t initDecoder();
virtual void updatePortDefinitions();
- bool portSettingsChanged();
+ bool handlePortSettingsChange();
DISALLOW_EVIL_CONSTRUCTORS(SoftMPEG4);
};
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
index b3c350f..b03ec8c 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
@@ -1426,7 +1426,7 @@
video->nBitsForMBID = CalcNumBits((uint)video->nTotalMB - 1); /* otherwise calculate above */
}
size = (int32)video->width * video->height;
- if (video->currVop->predictionType == P_VOP && size > video->videoDecControls->size)
+ if (currVop->predictionType == P_VOP && size > video->videoDecControls->size)
{
status = PV_FAIL;
goto return_point;
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index cc98da0..1899b40 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -65,8 +65,8 @@
CHECK(format->findInt32("color-format", &colorFormatNew));
int32_t widthNew, heightNew;
- CHECK(format->findInt32("width", &widthNew));
- CHECK(format->findInt32("height", &heightNew));
+ CHECK(format->findInt32("stride", &widthNew));
+ CHECK(format->findInt32("slice-height", &heightNew));
int32_t cropLeftNew, cropTopNew, cropRightNew, cropBottomNew;
if (!format->findRect(
diff --git a/media/libstagefright/include/SoftVideoDecoderOMXComponent.h b/media/libstagefright/include/SoftVideoDecoderOMXComponent.h
index 4a6ab63..8cb8ed7 100644
--- a/media/libstagefright/include/SoftVideoDecoderOMXComponent.h
+++ b/media/libstagefright/include/SoftVideoDecoderOMXComponent.h
@@ -66,7 +66,8 @@
virtual void updatePortDefinitions(bool updateCrop = true);
void handlePortSettingsChange(
- bool *portWillReset, uint32_t width, uint32_t height, bool cropChanged = false);
+ bool *portWillReset, uint32_t width, uint32_t height,
+ bool cropChanged = false, bool fakeStride = false);
void copyYV12FrameToOutputBuffer(
uint8_t *dst, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
index e533fdd..741ac96 100644
--- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
@@ -151,7 +151,7 @@
}
void SoftVideoDecoderOMXComponent::handlePortSettingsChange(
- bool *portWillReset, uint32_t width, uint32_t height, bool cropChanged) {
+ bool *portWillReset, uint32_t width, uint32_t height, bool cropChanged, bool fakeStride) {
*portWillReset = false;
bool sizeChanged = (width != mWidth || height != mHeight);
@@ -177,6 +177,19 @@
*portWillReset = true;
} else {
updatePortDefinitions(updateCrop);
+
+ if (fakeStride) {
+ // MAJOR HACK that is not pretty, it's just to fool the renderer to read the correct
+ // data.
+ // Some software decoders (e.g. SoftMPEG4) fill decoded frame directly to output
+ // buffer without considering the output buffer stride and slice height. So this is
+ // used to signal how the buffer is arranged. The alternative is to re-arrange the
+ // output buffer in SoftMPEG4, but that results in memcopies.
+ OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kOutputPortIndex)->mDef;
+ def->format.video.nStride = mWidth;
+ def->format.video.nSliceHeight = mHeight;
+ }
+
notify(OMX_EventPortSettingsChanged, kOutputPortIndex,
OMX_IndexConfigCommonOutputCrop, NULL);
}
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index 22c4e04..abdbc5c 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -2294,14 +2294,14 @@
}
sp<DeviceDescriptor> srcDeviceDesc =
mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
+ if (srcDeviceDesc == 0) {
+ return BAD_VALUE;
+ }
//update source and sink with our own data as the data passed in the patch may
// be incomplete.
struct audio_patch newPatch = *patch;
srcDeviceDesc->toAudioPortConfig(&newPatch.sources[0], &patch->sources[0]);
- if (srcDeviceDesc == 0) {
- return BAD_VALUE;
- }
for (size_t i = 0; i < patch->num_sinks; i++) {
if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index 33bdaa3..1a4d9a6 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -122,6 +122,16 @@
mClientPid);
len = (len > SIZE - 1) ? SIZE - 1 : len;
write(fd, buffer, len);
+
+ len = snprintf(buffer, SIZE, "Latest set parameters:\n");
+ len = (len > SIZE - 1) ? SIZE - 1 : len;
+ write(fd, buffer, len);
+
+ mLatestSetParameters.dump(fd, args);
+
+ const char *enddump = "\n\n";
+ write(fd, enddump, strlen(enddump));
+
return mHardware->dump(fd, args);
}
@@ -550,6 +560,7 @@
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
+ mLatestSetParameters = CameraParameters(params);
CameraParameters p(params);
return mHardware->setParameters(p);
}
diff --git a/services/camera/libcameraservice/api1/CameraClient.h b/services/camera/libcameraservice/api1/CameraClient.h
index 6779f5e..63a9d0f 100644
--- a/services/camera/libcameraservice/api1/CameraClient.h
+++ b/services/camera/libcameraservice/api1/CameraClient.h
@@ -142,6 +142,9 @@
// of the original one), we allocate mPreviewBuffer and reuse it if possible.
sp<MemoryHeapBase> mPreviewBuffer;
+ // Debugging information
+ CameraParameters mLatestSetParameters;
+
// We need to avoid the deadlock when the incoming command thread and
// the CameraHardwareInterface callback thread both want to grab mLock.
// An extra flag is used to tell the callback thread that it should stop