Merge "add trunksize as restriction for function parseClearEncryptedSizes()" into rvc-dev
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
index 19ccbf9..c2d2540 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -628,6 +628,7 @@
mComplexity = mIntf->getComplexity_l();
mQuality = mIntf->getQuality_l();
mGop = mIntf->getGop_l();
+ mRequestSync = mIntf->getRequestSync_l();
}
c2_status_t status = initEncParams();
@@ -956,7 +957,7 @@
}
}
- // handle dynamic config parameters
+ // handle dynamic bitrate change
{
IntfImpl::Lock lock = mIntf->lock();
std::shared_ptr<C2StreamBitrateInfo::output> bitrate = mIntf->getBitrate_l();
@@ -983,6 +984,26 @@
work->workletsProcessed = 1u;
return;
}
+ // handle request key frame
+ {
+ IntfImpl::Lock lock = mIntf->lock();
+ std::shared_ptr<C2StreamRequestSyncFrameTuning::output> requestSync;
+ requestSync = mIntf->getRequestSync_l();
+ lock.unlock();
+ if (requestSync != mRequestSync) {
+ // we can handle IDR immediately
+ if (requestSync->value) {
+ // unset request
+ C2StreamRequestSyncFrameTuning::output clearSync(0u, C2_FALSE);
+ std::vector<std::unique_ptr<C2SettingResult>> failures;
+ mIntf->config({ &clearSync }, C2_MAY_BLOCK, &failures);
+ ALOGV("Got sync request");
+ //Force this as an IDR frame
+ s_encode_ip.i4_force_idr_flag = 1;
+ }
+ mRequestSync = requestSync;
+ }
+ }
uint64_t timeDelay = 0;
uint64_t timeTaken = 0;
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.h b/media/codec2/components/hevc/C2SoftHevcEnc.h
index 140b4a9..5ea4602 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.h
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.h
@@ -88,6 +88,7 @@
std::shared_ptr<C2StreamComplexityTuning::output> mComplexity;
std::shared_ptr<C2StreamQualityTuning::output> mQuality;
std::shared_ptr<C2StreamGopTuning::output> mGop;
+ std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
#ifdef FILE_DUMP_ENABLE
char mInFile[200];
char mOutFile[200];
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.cpp b/media/codec2/components/vpx/C2SoftVpxDec.cpp
index c7d73f4..3eef1e3 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxDec.cpp
@@ -784,7 +784,13 @@
}
}
- CHECK(img->fmt == VPX_IMG_FMT_I420 || img->fmt == VPX_IMG_FMT_I42016);
+ if(img->fmt != VPX_IMG_FMT_I420 && img->fmt != VPX_IMG_FMT_I42016) {
+ ALOGE("img->fmt %d not supported", img->fmt);
+ mSignalledError = true;
+ work->workletsProcessed = 1u;
+ work->result = C2_CORRUPTED;
+ return false;
+ }
std::shared_ptr<C2GraphicBlock> block;
uint32_t format = HAL_PIXEL_FORMAT_YV12;
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 35978e3..c493594 100755
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -19,6 +19,7 @@
#include <ctype.h>
#include <inttypes.h>
+#include <algorithm>
#include <memory>
#include <stdint.h>
#include <stdlib.h>
@@ -149,9 +150,13 @@
bool mIsAudio;
sp<ItemTable> mItemTable;
- // Start offset from composition time to presentation time.
- // Support shift only for video tracks through mElstShiftStartTicks for now.
+ /* Shift start offset (move to earlier time) when media_time > 0,
+ * in media time scale.
+ */
uint64_t mElstShiftStartTicks;
+ /* Initial start offset (move to later time), empty edit list entry
+ * in media time scale.
+ */
uint64_t mElstInitialEmptyEditTicks;
size_t parseNALSize(const uint8_t *data) const;
@@ -1216,7 +1221,6 @@
off64_t entriesoffset = data_offset + 8;
uint64_t segment_duration;
int64_t media_time;
- uint64_t empty_edit_ticks = 0;
bool empty_edit_present = false;
for (int i = 0; i < entry_count; ++i) {
switch (version) {
@@ -1248,45 +1252,37 @@
}
// Empty edit entry would have to be first entry.
if (media_time == -1 && i == 0) {
- int64_t durationUs;
- if (AMediaFormat_getInt64(mFileMetaData, AMEDIAFORMAT_KEY_DURATION,
- &durationUs)) {
- empty_edit_ticks = segment_duration;
- ALOGV("initial empty edit ticks: %" PRIu64, empty_edit_ticks);
- empty_edit_present = true;
- }
- }
- // Process second entry only when the first entry was an empty edit entry.
- if (empty_edit_present && i == 1) {
- int64_t durationUs;
- if (AMediaFormat_getInt64(mLastTrack->meta, AMEDIAFORMAT_KEY_DURATION,
- &durationUs) &&
- mHeaderTimescale != 0) {
- // Support only segment_duration<=track_duration and media_time==0 case.
- uint64_t segmentDurationUs =
- segment_duration * 1000000 / mHeaderTimescale;
- if (segmentDurationUs == 0 || segmentDurationUs > durationUs ||
- media_time != 0) {
- ALOGW("for now, unsupported second entry in empty edit list");
- }
- }
+ empty_edit_present = true;
+ ALOGV("initial empty edit ticks: %" PRIu64, segment_duration);
+ /* In movie header timescale, and needs to be converted to media timescale
+ * after we get that from a track's 'mdhd' atom,
+ * which at times come after 'elst'.
+ */
+ mLastTrack->elst_initial_empty_edit_ticks = segment_duration;
+ } else if (media_time >= 0 && i == 0) {
+ ALOGV("first edit list entry");
+ mLastTrack->elst_media_time = media_time;
+ mLastTrack->elst_segment_duration = segment_duration;
+ ALOGV("segment_duration: %" PRIu64 " media_time: %" PRId64,
+ segment_duration, media_time);
+ // media_time is in media timescale as are STTS/CTTS entries.
+ mLastTrack->elst_shift_start_ticks = media_time;
+ } else if (empty_edit_present && i == 1) {
+ // Process second entry only when the first entry was an empty edit entry.
+ ALOGV("second edit list entry");
+ mLastTrack->elst_media_time = media_time;
+ mLastTrack->elst_segment_duration = segment_duration;
+ ALOGV("segment_duration: %" PRIu64 " media_time: %" PRId64,
+ segment_duration, media_time);
+ mLastTrack->elst_shift_start_ticks = media_time;
+ } else {
+ ALOGW("for now, unsupported entry in edit list %" PRIu32, entry_count);
}
}
// save these for later, because the elst atom might precede
// the atoms that actually gives us the duration and sample rate
// needed to calculate the padding and delay values
mLastTrack->elst_needs_processing = true;
- if (empty_edit_present) {
- /* In movie header timescale, and needs to be converted to media timescale once
- * we get that from a track's 'mdhd' atom, which at times come after 'elst'.
- */
- mLastTrack->elst_initial_empty_edit_ticks = empty_edit_ticks;
- } else {
- mLastTrack->elst_media_time = media_time;
- mLastTrack->elst_segment_duration = segment_duration;
- ALOGV("segment_duration: %" PRIu64 " media_time: %" PRId64, segment_duration,
- media_time);
- }
}
break;
}
@@ -4325,9 +4321,9 @@
}
}
- // media_time is in media timescale as are STTS/CTTS entries.
- track->elst_shift_start_ticks = track->elst_media_time;
ALOGV("track->elst_shift_start_ticks :%" PRIu64, track->elst_shift_start_ticks);
+
+ uint64_t elst_initial_empty_edit_ticks = 0;
if (mHeaderTimescale != 0) {
// Convert empty_edit_ticks from movie timescale to media timescale.
uint64_t elst_initial_empty_edit_ticks_mul = 0, elst_initial_empty_edit_ticks_add = 0;
@@ -4338,15 +4334,15 @@
ALOGE("track->elst_initial_empty_edit_ticks overflow");
return nullptr;
}
- track->elst_initial_empty_edit_ticks = elst_initial_empty_edit_ticks_add / mHeaderTimescale;
- ALOGV("track->elst_initial_empty_edit_ticks :%" PRIu64,
- track->elst_initial_empty_edit_ticks);
+ elst_initial_empty_edit_ticks = elst_initial_empty_edit_ticks_add / mHeaderTimescale;
}
+ ALOGV("elst_initial_empty_edit_ticks in MediaTimeScale :%" PRIu64,
+ elst_initial_empty_edit_ticks);
MPEG4Source* source =
new MPEG4Source(track->meta, mDataSource, track->timescale, track->sampleTable,
mSidxEntries, trex, mMoofOffset, itemTable,
- track->elst_shift_start_ticks, track->elst_initial_empty_edit_ticks);
+ track->elst_shift_start_ticks, elst_initial_empty_edit_ticks);
if (source->init() != OK) {
delete source;
return NULL;
@@ -5906,9 +5902,22 @@
break;
}
if( mode != ReadOptions::SEEK_FRAME_INDEX) {
- seekTimeUs += ((long double)mElstShiftStartTicks * 1000000) / mTimescale;
- ALOGV("shifted seekTimeUs :%" PRId64 ", mElstShiftStartTicks:%" PRIu64, seekTimeUs,
- mElstShiftStartTicks);
+ int64_t elstInitialEmptyEditUs = 0, elstShiftStartUs = 0;
+ if (mElstInitialEmptyEditTicks > 0) {
+ elstInitialEmptyEditUs = ((long double)mElstInitialEmptyEditTicks * 1000000) /
+ mTimescale;
+ /* Sample's composition time from ctts/stts entries are non-negative(>=0).
+ * Hence, lower bound on seekTimeUs is 0.
+ */
+ seekTimeUs = std::max(seekTimeUs - elstInitialEmptyEditUs, (int64_t)0);
+ }
+ if (mElstShiftStartTicks > 0) {
+ elstShiftStartUs = ((long double)mElstShiftStartTicks * 1000000) / mTimescale;
+ seekTimeUs += elstShiftStartUs;
+ }
+ ALOGV("shifted seekTimeUs:%" PRId64 ", elstInitialEmptyEditUs:%" PRIu64
+ ", elstShiftStartUs:%" PRIu64, seekTimeUs, elstInitialEmptyEditUs,
+ elstShiftStartUs);
}
uint32_t sampleIndex;
@@ -5954,7 +5963,12 @@
if (mode == ReadOptions::SEEK_CLOSEST
|| mode == ReadOptions::SEEK_FRAME_INDEX) {
- sampleTime -= mElstShiftStartTicks;
+ if (mElstInitialEmptyEditTicks > 0) {
+ sampleTime += mElstInitialEmptyEditTicks;
+ }
+ if (mElstShiftStartTicks > 0){
+ sampleTime -= mElstShiftStartTicks;
+ }
targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
}
@@ -5997,12 +6011,12 @@
if(err == OK) {
if (mElstInitialEmptyEditTicks > 0) {
cts += mElstInitialEmptyEditTicks;
- } else {
+ }
+ if (mElstShiftStartTicks > 0) {
// cts can be negative. for example, initial audio samples for gapless playback.
cts -= (int64_t)mElstShiftStartTicks;
}
}
-
} else {
err = mItemTable->getImageOffsetAndSize(
options && options->getSeekTo(&seekTimeUs, &mode) ?
@@ -6282,10 +6296,22 @@
int64_t seekTimeUs;
ReadOptions::SeekMode mode;
if (options && options->getSeekTo(&seekTimeUs, &mode)) {
-
- seekTimeUs += ((long double)mElstShiftStartTicks * 1000000) / mTimescale;
- ALOGV("shifted seekTimeUs :%" PRId64 ", mElstShiftStartTicks:%" PRIu64, seekTimeUs,
- mElstShiftStartTicks);
+ int64_t elstInitialEmptyEditUs = 0, elstShiftStartUs = 0;
+ if (mElstInitialEmptyEditTicks > 0) {
+ elstInitialEmptyEditUs = ((long double)mElstInitialEmptyEditTicks * 1000000) /
+ mTimescale;
+ /* Sample's composition time from ctts/stts entries are non-negative(>=0).
+ * Hence, lower bound on seekTimeUs is 0.
+ */
+ seekTimeUs = std::max(seekTimeUs - elstInitialEmptyEditUs, (int64_t)0);
+ }
+ if (mElstShiftStartTicks > 0){
+ elstShiftStartUs = ((long double)mElstShiftStartTicks * 1000000) / mTimescale;
+ seekTimeUs += elstShiftStartUs;
+ }
+ ALOGV("shifted seekTimeUs:%" PRId64 ", elstInitialEmptyEditUs:%" PRIu64
+ ", elstShiftStartUs:%" PRIu64, seekTimeUs, elstInitialEmptyEditUs,
+ elstShiftStartUs);
int numSidxEntries = mSegments.size();
if (numSidxEntries != 0) {
@@ -6376,7 +6402,8 @@
if (mElstInitialEmptyEditTicks > 0) {
cts += mElstInitialEmptyEditTicks;
- } else {
+ }
+ if (mElstShiftStartTicks > 0) {
// cts can be negative. for example, initial audio samples for gapless playback.
cts -= (int64_t)mElstShiftStartTicks;
}
diff --git a/media/extractors/mp4/MPEG4Extractor.h b/media/extractors/mp4/MPEG4Extractor.h
index 53ec6bc..3af432d 100644
--- a/media/extractors/mp4/MPEG4Extractor.h
+++ b/media/extractors/mp4/MPEG4Extractor.h
@@ -88,9 +88,9 @@
*/
int64_t elst_media_time;
uint64_t elst_segment_duration;
- // Shift start offset only when media_time > 0.
+ // Shift start offset (move to earlier time) when media_time > 0.
uint64_t elst_shift_start_ticks;
- // Initial start offset, empty edit list entry.
+ // Initial start offset (move to later time), from empty edit list entry.
uint64_t elst_initial_empty_edit_ticks;
bool subsample_encryption;
diff --git a/media/libstagefright/ACodecBufferChannel.cpp b/media/libstagefright/ACodecBufferChannel.cpp
index e5115d9..fa13f32 100644
--- a/media/libstagefright/ACodecBufferChannel.cpp
+++ b/media/libstagefright/ACodecBufferChannel.cpp
@@ -134,7 +134,12 @@
}
ssize_t result = -1;
ssize_t codecDataOffset = 0;
- if (mCrypto != NULL) {
+ if (numSubSamples == 1
+ && subSamples[0].mNumBytesOfClearData == 0
+ && subSamples[0].mNumBytesOfEncryptedData == 0) {
+ // We don't need to go through crypto or descrambler if the input is empty.
+ result = 0;
+ } else if (mCrypto != NULL) {
hardware::drm::V1_0::DestinationBuffer destination;
if (secure) {
destination.type = DrmBufferType::NATIVE_HANDLE;
diff --git a/services/mediacodec/registrant/CodecServiceRegistrant.cpp b/services/mediacodec/registrant/CodecServiceRegistrant.cpp
index 83d233e..184251a 100644
--- a/services/mediacodec/registrant/CodecServiceRegistrant.cpp
+++ b/services/mediacodec/registrant/CodecServiceRegistrant.cpp
@@ -17,11 +17,13 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "CodecServiceRegistrant"
+#include <android-base/properties.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <C2Component.h>
#include <C2PlatformSupport.h>
+#include <codec2/hidl/1.0/ComponentStore.h>
#include <codec2/hidl/1.1/ComponentStore.h>
#include <codec2/hidl/1.1/Configurable.h>
#include <codec2/hidl/1.1/types.h>
@@ -43,6 +45,10 @@
// Converter from IComponentStore to C2ComponentStore.
class H2C2ComponentStore : public C2ComponentStore {
protected:
+ using IComponentStore =
+ ::android::hardware::media::c2::V1_0::IComponentStore;
+ using IConfigurable =
+ ::android::hardware::media::c2::V1_0::IConfigurable;
sp<IComponentStore> mStore;
sp<IConfigurable> mConfigurable;
public:
@@ -399,36 +405,67 @@
} // unnamed namespace
extern "C" void RegisterCodecServices() {
- using namespace ::android::hardware::media::c2::V1_1;
LOG(INFO) << "Creating software Codec2 service...";
- sp<ComponentStore> store =
- new ComponentStore(::android::GetCodec2PlatformComponentStore());
- if (store == nullptr) {
- LOG(ERROR) <<
- "Cannot create software Codec2 service.";
- } else {
- if (!ionPropertiesDefined()) {
- std::string preferredStoreName = "default";
- sp<IComponentStore> preferredStore =
- IComponentStore::getService(preferredStoreName.c_str());
- if (preferredStore) {
- ::android::SetPreferredCodec2ComponentStore(
- std::make_shared<H2C2ComponentStore>(preferredStore));
- LOG(INFO) <<
- "Preferred Codec2 store is set to \"" <<
- preferredStoreName << "\".";
- } else {
- LOG(INFO) <<
- "Preferred Codec2 store is defaulted to \"software\".";
+ std::shared_ptr<C2ComponentStore> store =
+ android::GetCodec2PlatformComponentStore();
+ if (!store) {
+ LOG(ERROR) << "Failed to create Codec2 service.";
+ return;
+ }
+
+ using namespace ::android::hardware::media::c2;
+
+ int platformVersion =
+ android::base::GetIntProperty("ro.build.version.sdk", int32_t(29));
+ // STOPSHIP: Remove code name checking once platform version bumps up to 30.
+ std::string codeName =
+ android::base::GetProperty("ro.build.version.codename", "");
+ if (codeName == "R") {
+ platformVersion = 30;
+ }
+
+ switch (platformVersion) {
+ case 30: {
+ android::sp<V1_1::IComponentStore> storeV1_1 =
+ new V1_1::utils::ComponentStore(store);
+ if (storeV1_1->registerAsService("software") != android::OK) {
+ LOG(ERROR) << "Cannot register software Codec2 v1.1 service.";
+ return;
}
+ break;
}
- if (store->registerAsService("software") != android::OK) {
- LOG(ERROR) <<
- "Cannot register software Codec2 service.";
- } else {
- LOG(INFO) <<
- "Software Codec2 service created.";
+ case 29: {
+ android::sp<V1_0::IComponentStore> storeV1_0 =
+ new V1_0::utils::ComponentStore(store);
+ if (storeV1_0->registerAsService("software") != android::OK) {
+ LOG(ERROR) << "Cannot register software Codec2 v1.0 service.";
+ return;
+ }
+ break;
+ }
+ default: {
+ LOG(ERROR) << "The platform version " << platformVersion <<
+ " is not supported.";
+ return;
}
}
+ if (!ionPropertiesDefined()) {
+ using IComponentStore =
+ ::android::hardware::media::c2::V1_0::IComponentStore;
+ std::string const preferredStoreName = "default";
+ sp<IComponentStore> preferredStore =
+ IComponentStore::getService(preferredStoreName.c_str());
+ if (preferredStore) {
+ ::android::SetPreferredCodec2ComponentStore(
+ std::make_shared<H2C2ComponentStore>(preferredStore));
+ LOG(INFO) <<
+ "Preferred Codec2 store is set to \"" <<
+ preferredStoreName << "\".";
+ } else {
+ LOG(INFO) <<
+ "Preferred Codec2 store is defaulted to \"software\".";
+ }
+ }
+ LOG(INFO) << "Software Codec2 service created and registered.";
}