summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/libmedia/AudioTrack.cpp3
-rw-r--r--media/libstagefright/ACodec.cpp41
-rw-r--r--media/libstagefright/MediaCodec.cpp12
-rwxr-xr-xmedia/libstagefright/OMXCodec.cpp36
-rw-r--r--media/libstagefright/StagefrightMetadataRetriever.cpp37
-rw-r--r--media/libstagefright/wifi-display/source/Converter.cpp21
-rw-r--r--media/libstagefright/wifi-display/source/Converter.h6
-rw-r--r--media/libstagefright/wifi-display/source/PlaybackSession.cpp8
-rw-r--r--media/libstagefright/wifi-display/source/PlaybackSession.h2
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.cpp3
10 files changed, 158 insertions, 11 deletions
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index d9d8aee..362d022 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -279,8 +279,7 @@ status_t AudioTrack::set(
mCbf = cbf;
if (cbf != NULL) {
- //FIXME ignoring threadCanCallJava to work around track recreation issue
- mAudioTrackThread = new AudioTrackThread(*this, true /*threadCanCallJava*/);
+ mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava);
mAudioTrackThread->run("AudioTrack", ANDROID_PRIORITY_AUDIO, 0 /*stack*/);
}
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 3dd5d60..8190498 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -34,6 +34,8 @@
#include <OMX_Component.h>
+#include "include/avc_utils.h"
+
namespace android {
template<class T>
@@ -401,6 +403,10 @@ void ACodec::initiateShutdown(bool keepComponentAllocated) {
msg->post();
}
+void ACodec::signalRequestIDRFrame() {
+ (new AMessage(kWhatRequestIDRFrame, id()))->post();
+}
+
status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
@@ -2284,6 +2290,24 @@ error:
ACodec::PortDescription::PortDescription() {
}
+status_t ACodec::requestIDRFrame() {
+ if (!mIsEncoder) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ OMX_CONFIG_INTRAREFRESHVOPTYPE params;
+ InitOMXParams(&params);
+
+ params.nPortIndex = kPortIndexOutput;
+ params.IntraRefreshVOP = OMX_TRUE;
+
+ return mOMX->setConfig(
+ mNode,
+ OMX_IndexConfigVideoIntraVOPRefresh,
+ &params,
+ sizeof(params));
+}
+
void ACodec::PortDescription::addBuffer(
IOMX::buffer_id id, const sp<ABuffer> &buffer) {
mBufferIDs.push_back(id);
@@ -2737,6 +2761,12 @@ bool ACodec::BaseState::onOMXFillBufferDone(
if (mCodec->mNativeWindow == NULL) {
info->mData->setRange(rangeOffset, rangeLength);
+
+#if 0
+ if (IsIDR(info->mData)) {
+ ALOGI("IDR frame");
+ }
+#endif
}
if (mCodec->mSkipCutBuffer != NULL) {
@@ -3400,6 +3430,17 @@ bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ case kWhatRequestIDRFrame:
+ {
+ status_t err = mCodec->requestIDRFrame();
+ if (err != OK) {
+ ALOGW("Requesting an IDR frame failed.");
+ }
+
+ handled = true;
+ break;
+ }
+
default:
handled = BaseState::onMessageReceived(msg);
break;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 2060699..7f97430 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -327,6 +327,12 @@ status_t MediaCodec::flush() {
return PostAndAwaitResponse(msg, &response);
}
+status_t MediaCodec::requestIDRFrame() {
+ (new AMessage(kWhatRequestIDRFrame, id()))->post();
+
+ return OK;
+}
+
////////////////////////////////////////////////////////////////////////////////
void MediaCodec::cancelPendingDequeueOperations() {
@@ -1133,6 +1139,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ case kWhatRequestIDRFrame:
+ {
+ mCodec->signalRequestIDRFrame();
+ break;
+ }
+
default:
TRESPASS();
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index d0e306c..07f92c7 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -546,12 +546,8 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
if (mIsEncoder) {
setVideoInputFormat(mMIME, meta);
} else {
- int32_t width, height;
- bool success = meta->findInt32(kKeyWidth, &width);
- success = success && meta->findInt32(kKeyHeight, &height);
- CHECK(success);
status_t err = setVideoOutputFormat(
- mMIME, width, height);
+ mMIME, meta);
if (err != OK) {
return err;
@@ -894,7 +890,7 @@ static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
} else if (iFramesInterval == 0) {
return 0;
}
- OMX_U32 ret = frameRate * iFramesInterval;
+ OMX_U32 ret = frameRate * iFramesInterval - 1;
CHECK(ret > 1);
return ret;
}
@@ -1172,7 +1168,13 @@ status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) {
}
status_t OMXCodec::setVideoOutputFormat(
- const char *mime, OMX_U32 width, OMX_U32 height) {
+ const char *mime, const sp<MetaData>& meta) {
+
+ int32_t width, height;
+ bool success = meta->findInt32(kKeyWidth, &width);
+ success = success && meta->findInt32(kKeyHeight, &height);
+ CHECK(success);
+
CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height);
OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
@@ -1218,6 +1220,26 @@ status_t OMXCodec::setVideoOutputFormat(
|| format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar
|| format.eColorFormat == OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka);
+ int32_t colorFormat;
+ if (meta->findInt32(kKeyColorFormat, &colorFormat)
+ && colorFormat != OMX_COLOR_FormatUnused
+ && colorFormat != format.eColorFormat) {
+
+ while (OMX_ErrorNoMore != err) {
+ format.nIndex++;
+ err = mOMX->getParameter(
+ mNode, OMX_IndexParamVideoPortFormat,
+ &format, sizeof(format));
+ if (format.eColorFormat == colorFormat) {
+ break;
+ }
+ }
+ if (format.eColorFormat != colorFormat) {
+ CODEC_LOGE("Color format %d is not supported", colorFormat);
+ return ERROR_UNSUPPORTED;
+ }
+ }
+
err = mOMX->setParameter(
mNode, OMX_IndexParamVideoPortFormat,
&format, sizeof(format));
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index c9ef4d9..a2f3f13 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -110,6 +110,31 @@ status_t StagefrightMetadataRetriever::setDataSource(
return OK;
}
+static bool isYUV420PlanarSupported(
+ OMXClient *client,
+ const sp<MetaData> &trackMeta) {
+
+ const char *mime;
+ CHECK(trackMeta->findCString(kKeyMIMEType, &mime));
+
+ Vector<CodecCapabilities> caps;
+ if (QueryCodecs(client->interface(), mime,
+ true, /* queryDecoders */
+ true, /* hwCodecOnly */
+ &caps) == OK) {
+
+ for (size_t j = 0; j < caps.size(); ++j) {
+ CodecCapabilities cap = caps[j];
+ for (size_t i = 0; i < cap.mColorFormats.size(); ++i) {
+ if (cap.mColorFormats[i] == OMX_COLOR_FormatYUV420Planar) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
static VideoFrame *extractVideoFrameWithCodecFlags(
OMXClient *client,
const sp<MetaData> &trackMeta,
@@ -117,9 +142,19 @@ static VideoFrame *extractVideoFrameWithCodecFlags(
uint32_t flags,
int64_t frameTimeUs,
int seekMode) {
+
+ sp<MetaData> format = source->getFormat();
+
+ // XXX:
+ // Once all vendors support OMX_COLOR_FormatYUV420Planar, we can
+ // remove this check and always set the decoder output color format
+ if (isYUV420PlanarSupported(client, trackMeta)) {
+ format->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar);
+ }
+
sp<MediaSource> decoder =
OMXCodec::Create(
- client->interface(), source->getFormat(), false, source,
+ client->interface(), format, false, source,
NULL, flags | OMXCodec::kClientNeedsFramebuffer);
if (decoder.get() == NULL) {
diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp
index c4845e3..390b2e2 100644
--- a/media/libstagefright/wifi-display/source/Converter.cpp
+++ b/media/libstagefright/wifi-display/source/Converter.cpp
@@ -40,7 +40,15 @@ Converter::Converter(
mNotify(notify),
mCodecLooper(codecLooper),
mInputFormat(format),
+ mIsVideo(false),
mDoMoreWorkPending(false) {
+ AString mime;
+ CHECK(mInputFormat->findString("mime", &mime));
+
+ if (!strncasecmp("video/", mime.c_str(), 6)) {
+ mIsVideo = true;
+ }
+
mInitCheck = initEncoder();
}
@@ -202,6 +210,15 @@ void Converter::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ case kWhatRequestIDRFrame:
+ {
+ if (mIsVideo) {
+ ALOGI("requesting IDR frame");
+ mEncoder->requestIDRFrame();
+ }
+ break;
+ }
+
default:
TRESPASS();
}
@@ -306,5 +323,9 @@ status_t Converter::doMoreWork() {
return err;
}
+void Converter::requestIDRFrame() {
+ (new AMessage(kWhatRequestIDRFrame, id()))->post();
+}
+
} // namespace android
diff --git a/media/libstagefright/wifi-display/source/Converter.h b/media/libstagefright/wifi-display/source/Converter.h
index 67471c7..901ae2e 100644
--- a/media/libstagefright/wifi-display/source/Converter.h
+++ b/media/libstagefright/wifi-display/source/Converter.h
@@ -43,6 +43,8 @@ struct Converter : public AHandler {
void feedAccessUnit(const sp<ABuffer> &accessUnit);
void signalEOS();
+ void requestIDRFrame();
+
enum {
kWhatAccessUnit,
kWhatEOS,
@@ -57,13 +59,15 @@ private:
enum {
kWhatFeedAccessUnit,
kWhatInputEOS,
- kWhatDoMoreWork
+ kWhatDoMoreWork,
+ kWhatRequestIDRFrame,
};
status_t mInitCheck;
sp<AMessage> mNotify;
sp<ALooper> mCodecLooper;
sp<AMessage> mInputFormat;
+ bool mIsVideo;
sp<AMessage> mOutputFormat;
sp<MediaCodec> mEncoder;
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
index c38a300..f6f7030 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -1164,5 +1164,13 @@ status_t WifiDisplaySource::PlaybackSession::parseTSFB(
return OK;
}
+void WifiDisplaySource::PlaybackSession::requestIDRFrame() {
+ for (size_t i = 0; i < mTracks.size(); ++i) {
+ const sp<Track> &track = mTracks.valueAt(i);
+
+ track->converter()->requestIDRFrame();
+ }
+}
+
} // namespace android
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.h b/media/libstagefright/wifi-display/source/PlaybackSession.h
index 88f6ea9..8b6ddee 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.h
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.h
@@ -58,6 +58,8 @@ struct WifiDisplaySource::PlaybackSession : public AHandler {
int32_t width() const;
int32_t height() const;
+ void requestIDRFrame();
+
enum {
kWhatSessionDead,
kWhatBinaryData,
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index aeefcf3..53adb87 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -984,6 +984,9 @@ void WifiDisplaySource::onSetParameterRequest(
}
#endif
+ // XXX check that the parameter is about that.
+ playbackSession->requestIDRFrame();
+
playbackSession->updateLiveness();
AString response = "RTSP/1.0 200 OK\r\n";