Merge "transcoding: fix timeout value"
diff --git a/media/codec2/components/base/SimpleC2Interface.cpp b/media/codec2/components/base/SimpleC2Interface.cpp
index 5c019f3..29740d1 100644
--- a/media/codec2/components/base/SimpleC2Interface.cpp
+++ b/media/codec2/components/base/SimpleC2Interface.cpp
@@ -39,6 +39,16 @@
setDerivedInstance(this);
addParameter(
+ DefineParam(mApiFeatures, C2_PARAMKEY_API_FEATURES)
+ .withConstValue(new C2ApiFeaturesSetting(C2Config::api_feature_t(
+ API_REFLECTION |
+ API_VALUES |
+ API_CURRENT_VALUES |
+ API_DEPENDENCY |
+ API_SAME_INPUT_BUFFER)))
+ .build());
+
+ addParameter(
DefineParam(mName, C2_PARAMKEY_COMPONENT_NAME)
.withConstValue(AllocSharedString<C2ComponentNameSetting>(name.c_str()))
.build());
@@ -305,7 +315,6 @@
Clients need to handle the following base params due to custom dependency.
std::shared_ptr<C2ApiLevelSetting> mApiLevel;
- std::shared_ptr<C2ApiFeaturesSetting> mApiFeatures;
std::shared_ptr<C2ComponentAttributesSetting> mAttrib;
std::shared_ptr<C2PortSuggestedBufferCountTuning::input> mSuggestedInputBufferCount;
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.cpp b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
index 74e105e..7e9090f 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
@@ -460,8 +460,8 @@
const C2ConstGraphicBlock inBuffer =
inputBuffer->data().graphicBlocks().front();
- if (inBuffer.width() != mSize->width ||
- inBuffer.height() != mSize->height) {
+ if (inBuffer.width() < mSize->width ||
+ inBuffer.height() < mSize->height) {
ALOGE("unexpected Input buffer attributes %d(%d) x %d(%d)",
inBuffer.width(), mSize->width, inBuffer.height(),
mSize->height);
@@ -472,8 +472,8 @@
bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
vpx_image_t raw_frame;
const C2PlanarLayout &layout = rView->layout();
- uint32_t width = rView->width();
- uint32_t height = rView->height();
+ uint32_t width = mSize->width;
+ uint32_t height = mSize->height;
if (width > 0x8000 || height > 0x8000) {
ALOGE("Image too big: %u x %u", width, height);
work->result = C2_BAD_VALUE;
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 05e086f..70171fd 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1958,11 +1958,98 @@
inputSurface->getHalInterface()));
}
-static void MaybeLogUnrecognizedName(const char *func, const std::string &name) {
- thread_local std::set<std::string> sLogged{};
- if (sLogged.insert(name).second) {
- ALOGW("%s: Unrecognized interface name: %s", func, name.c_str());
+class IntfCache {
+public:
+ IntfCache() = default;
+
+ status_t init(const std::string &name) {
+ std::shared_ptr<Codec2Client::Interface> intf{
+ Codec2Client::CreateInterfaceByName(name.c_str())};
+ if (!intf) {
+ ALOGW("IntfCache [%s]: Unrecognized interface name", name.c_str());
+ mInitStatus = NO_INIT;
+ return NO_INIT;
+ }
+ const static C2StreamUsageTuning::input sUsage{0u /* stream id */};
+ mFields.push_back(C2FieldSupportedValuesQuery::Possible(
+ C2ParamField{&sUsage, &sUsage.value}));
+ c2_status_t err = intf->querySupportedValues(mFields, C2_MAY_BLOCK);
+ if (err != C2_OK) {
+ ALOGW("IntfCache [%s]: failed to query usage supported value (err=%d)",
+ name.c_str(), err);
+ mFields[0].status = err;
+ }
+ std::vector<std::unique_ptr<C2Param>> params;
+ err = intf->query(
+ {&mApiFeatures},
+ {C2PortAllocatorsTuning::input::PARAM_TYPE},
+ C2_MAY_BLOCK,
+ ¶ms);
+ if (err != C2_OK && err != C2_BAD_INDEX) {
+ ALOGW("IntfCache [%s]: failed to query api features (err=%d)",
+ name.c_str(), err);
+ }
+ while (!params.empty()) {
+ C2Param *param = params.back().release();
+ params.pop_back();
+ if (!param) {
+ continue;
+ }
+ if (param->type() == C2PortAllocatorsTuning::input::PARAM_TYPE) {
+ mInputAllocators.reset(
+ C2PortAllocatorsTuning::input::From(params[0].get()));
+ }
+ }
+ mInitStatus = OK;
+ return OK;
}
+
+ status_t initCheck() const { return mInitStatus; }
+
+ const C2FieldSupportedValuesQuery &getUsageSupportedValues() const {
+ CHECK_EQ(1u, mFields.size());
+ return mFields[0];
+ }
+
+ const C2ApiFeaturesSetting &getApiFeatures() const {
+ return mApiFeatures;
+ }
+
+ const C2PortAllocatorsTuning::input &getInputAllocators() const {
+ static std::unique_ptr<C2PortAllocatorsTuning::input> sInvalidated = []{
+ std::unique_ptr<C2PortAllocatorsTuning::input> param =
+ C2PortAllocatorsTuning::input::AllocUnique(0);
+ param->invalidate();
+ return param;
+ }();
+ return mInputAllocators ? *mInputAllocators : *sInvalidated;
+ }
+
+private:
+ status_t mInitStatus{NO_INIT};
+
+ std::vector<C2FieldSupportedValuesQuery> mFields;
+ C2ApiFeaturesSetting mApiFeatures;
+ std::unique_ptr<C2PortAllocatorsTuning::input> mInputAllocators;
+};
+
+static const IntfCache &GetIntfCache(const std::string &name) {
+ static IntfCache sNullIntfCache;
+ static std::mutex sMutex;
+ static std::map<std::string, IntfCache> sCache;
+ std::unique_lock<std::mutex> lock{sMutex};
+ auto it = sCache.find(name);
+ if (it == sCache.end()) {
+ lock.unlock();
+ IntfCache intfCache;
+ status_t err = intfCache.init(name);
+ if (err != OK) {
+ return sNullIntfCache;
+ }
+ lock.lock();
+ it = sCache.insert({name, std::move(intfCache)}).first;
+ }
+ return it->second;
}
static status_t GetCommonAllocatorIds(
@@ -1980,24 +2067,16 @@
}
bool firstIteration = true;
for (const std::string &name : names) {
- std::shared_ptr<Codec2Client::Interface> intf{
- Codec2Client::CreateInterfaceByName(name.c_str())};
- if (!intf) {
- MaybeLogUnrecognizedName(__FUNCTION__, name);
+ const IntfCache &intfCache = GetIntfCache(name);
+ if (intfCache.initCheck() != OK) {
continue;
}
- std::vector<std::unique_ptr<C2Param>> params;
- c2_status_t err = intf->query(
- {}, {C2PortAllocatorsTuning::input::PARAM_TYPE}, C2_MAY_BLOCK, ¶ms);
+ const C2PortAllocatorsTuning::input &allocators = intfCache.getInputAllocators();
if (firstIteration) {
firstIteration = false;
- if (err == C2_OK && params.size() == 1u) {
- C2PortAllocatorsTuning::input *allocators =
- C2PortAllocatorsTuning::input::From(params[0].get());
- if (allocators && allocators->flexCount() > 0) {
- ids->insert(allocators->m.values,
- allocators->m.values + allocators->flexCount());
- }
+ if (allocators && allocators.flexCount() > 0) {
+ ids->insert(allocators.m.values,
+ allocators.m.values + allocators.flexCount());
}
if (ids->empty()) {
// The component does not advertise allocators. Use default.
@@ -2006,24 +2085,20 @@
continue;
}
bool filtered = false;
- if (err == C2_OK && params.size() == 1u) {
- C2PortAllocatorsTuning::input *allocators =
- C2PortAllocatorsTuning::input::From(params[0].get());
- if (allocators && allocators->flexCount() > 0) {
- filtered = true;
- for (auto it = ids->begin(); it != ids->end(); ) {
- bool found = false;
- for (size_t j = 0; j < allocators->flexCount(); ++j) {
- if (allocators->m.values[j] == *it) {
- found = true;
- break;
- }
+ if (allocators && allocators.flexCount() > 0) {
+ filtered = true;
+ for (auto it = ids->begin(); it != ids->end(); ) {
+ bool found = false;
+ for (size_t j = 0; j < allocators.flexCount(); ++j) {
+ if (allocators.m.values[j] == *it) {
+ found = true;
+ break;
}
- if (found) {
- ++it;
- } else {
- it = ids->erase(it);
- }
+ }
+ if (found) {
+ ++it;
+ } else {
+ it = ids->erase(it);
}
}
}
@@ -2055,23 +2130,16 @@
*minUsage = 0;
*maxUsage = ~0ull;
for (const std::string &name : names) {
- std::shared_ptr<Codec2Client::Interface> intf{
- Codec2Client::CreateInterfaceByName(name.c_str())};
- if (!intf) {
- MaybeLogUnrecognizedName(__FUNCTION__, name);
+ const IntfCache &intfCache = GetIntfCache(name);
+ if (intfCache.initCheck() != OK) {
continue;
}
- std::vector<C2FieldSupportedValuesQuery> fields;
- fields.push_back(C2FieldSupportedValuesQuery::Possible(
- C2ParamField{&sUsage, &sUsage.value}));
- c2_status_t err = intf->querySupportedValues(fields, C2_MAY_BLOCK);
- if (err != C2_OK) {
+ const C2FieldSupportedValuesQuery &usageSupportedValues =
+ intfCache.getUsageSupportedValues();
+ if (usageSupportedValues.status != C2_OK) {
continue;
}
- if (fields[0].status != C2_OK) {
- continue;
- }
- const C2FieldSupportedValues &supported = fields[0].values;
+ const C2FieldSupportedValues &supported = usageSupportedValues.values;
if (supported.type != C2FieldSupportedValues::FLAGS) {
continue;
}
@@ -2092,6 +2160,17 @@
// static
status_t CCodec::CanFetchLinearBlock(
const std::vector<std::string> &names, const C2MemoryUsage &usage, bool *isCompatible) {
+ for (const std::string &name : names) {
+ const IntfCache &intfCache = GetIntfCache(name);
+ if (intfCache.initCheck() != OK) {
+ continue;
+ }
+ const C2ApiFeaturesSetting &features = intfCache.getApiFeatures();
+ if (features && !(features.value & API_SAME_INPUT_BUFFER)) {
+ *isCompatible = false;
+ return OK;
+ }
+ }
uint64_t minUsage = usage.expected;
uint64_t maxUsage = ~0ull;
std::set<C2Allocator::id_t> allocators;
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 4345a9f..c07f3dc 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -916,6 +916,12 @@
if (inputFormat != nullptr) {
bool graphic = (iStreamFormat.value == C2BufferData::GRAPHIC);
+ C2Config::api_feature_t apiFeatures = C2Config::api_feature_t(
+ API_REFLECTION |
+ API_VALUES |
+ API_CURRENT_VALUES |
+ API_DEPENDENCY |
+ API_SAME_INPUT_BUFFER);
std::shared_ptr<C2BlockPool> pool;
{
Mutexed<BlockPools>::Locked pools(mBlockPools);
@@ -927,14 +933,15 @@
// query C2PortAllocatorsTuning::input from component. If an allocator ID is obtained
// from component, create the input block pool with given ID. Otherwise, use default IDs.
std::vector<std::unique_ptr<C2Param>> params;
- err = mComponent->query({ },
+ C2ApiFeaturesSetting featuresSetting{apiFeatures};
+ err = mComponent->query({ &featuresSetting },
{ C2PortAllocatorsTuning::input::PARAM_TYPE },
C2_DONT_BLOCK,
¶ms);
if ((err != C2_OK && err != C2_BAD_INDEX) || params.size() != 1) {
ALOGD("[%s] Query input allocators returned %zu params => %s (%u)",
mName, params.size(), asString(err), err);
- } else if (err == C2_OK && params.size() == 1) {
+ } else if (params.size() == 1) {
C2PortAllocatorsTuning::input *inputAllocators =
C2PortAllocatorsTuning::input::From(params[0].get());
if (inputAllocators && inputAllocators->flexCount() > 0) {
@@ -949,6 +956,9 @@
}
}
}
+ if (featuresSetting) {
+ apiFeatures = featuresSetting.value;
+ }
// TODO: use C2Component wrapper to associate this pool with ourselves
if ((poolMask >> pools->inputAllocatorId) & 1) {
@@ -982,7 +992,10 @@
input->numSlots = numInputSlots;
input->extraBuffers.flush();
input->numExtraSlots = 0u;
- if (!buffersBoundToCodec) {
+ bool conforming = (apiFeatures & API_SAME_INPUT_BUFFER);
+ // For encrypted content, framework decrypts source buffer (ashmem) into
+ // C2Buffers. Thus non-conforming codecs can process these.
+ if (!buffersBoundToCodec && (hasCryptoOrDescrambler() || conforming)) {
input->buffers.reset(new SlotInputBuffers(mName));
} else if (graphic) {
if (mInputSurface) {
diff --git a/media/libmediatranscoding/transcoder/MediaTrackTranscoder.cpp b/media/libmediatranscoding/transcoder/MediaTrackTranscoder.cpp
index 10c0c6c..3a281ba 100644
--- a/media/libmediatranscoding/transcoder/MediaTrackTranscoder.cpp
+++ b/media/libmediatranscoding/transcoder/MediaTrackTranscoder.cpp
@@ -19,6 +19,7 @@
#include <android-base/logging.h>
#include <media/MediaTrackTranscoder.h>
+#include <media/MediaTrackTranscoderCallback.h>
namespace android {
diff --git a/media/libmediatranscoding/transcoder/MediaTranscoder.cpp b/media/libmediatranscoding/transcoder/MediaTranscoder.cpp
index f2f7810..3db7455 100644
--- a/media/libmediatranscoding/transcoder/MediaTranscoder.cpp
+++ b/media/libmediatranscoding/transcoder/MediaTranscoder.cpp
@@ -20,6 +20,7 @@
#include <android-base/logging.h>
#include <fcntl.h>
#include <media/MediaSampleReaderNDK.h>
+#include <media/MediaSampleWriter.h>
#include <media/MediaTranscoder.h>
#include <media/PassthroughTrackTranscoder.h>
#include <media/VideoTrackTranscoder.h>
@@ -92,11 +93,10 @@
}
// Transcoding is done and the callback to the client has been sent, so tear down the
- // pipeline but do it asynchronously to avoid deadlocks. If an error occurred then
- // automatically delete the output file.
- const bool deleteOutputFile = status != AMEDIA_OK;
+ // pipeline but do it asynchronously to avoid deadlocks. If an error occurred, client
+ // should clean up the file.
std::thread asyncCancelThread{
- [self = shared_from_this(), deleteOutputFile] { self->cancel(deleteOutputFile); }};
+ [self = shared_from_this()] { self->cancel(); }};
asyncCancelThread.detach();
}
}
@@ -115,6 +115,9 @@
sendCallback(status);
}
+MediaTranscoder::MediaTranscoder(const std::shared_ptr<CallbackInterface>& callbacks)
+ : mCallbacks(callbacks) {}
+
std::shared_ptr<MediaTranscoder> MediaTranscoder::create(
const std::shared_ptr<CallbackInterface>& callbacks,
const std::shared_ptr<Parcel>& pausedState) {
@@ -129,15 +132,9 @@
return std::shared_ptr<MediaTranscoder>(new MediaTranscoder(callbacks));
}
-media_status_t MediaTranscoder::configureSource(const char* path) {
- if (path == nullptr) {
- LOG(ERROR) << "Source path cannot be null";
- return AMEDIA_ERROR_INVALID_PARAMETER;
- }
-
- const int fd = open(path, O_RDONLY);
- if (fd <= 0) {
- LOG(ERROR) << "Unable to open source path: " << path;
+media_status_t MediaTranscoder::configureSource(int fd) {
+ if (fd < 0) {
+ LOG(ERROR) << "Invalid source fd: " << fd;
return AMEDIA_ERROR_INVALID_PARAMETER;
}
@@ -145,10 +142,9 @@
lseek(fd, 0, SEEK_SET);
mSampleReader = MediaSampleReaderNDK::createFromFd(fd, 0 /* offset */, fileSize);
- close(fd);
if (mSampleReader == nullptr) {
- LOG(ERROR) << "Unable to parse source file: " << path;
+ LOG(ERROR) << "Unable to parse source fd: " << fd;
return AMEDIA_ERROR_UNSUPPORTED;
}
@@ -239,35 +235,23 @@
return AMEDIA_OK;
}
-media_status_t MediaTranscoder::configureDestination(const char* path) {
- if (path == nullptr || strlen(path) < 1) {
- LOG(ERROR) << "Invalid destination path: " << path;
+media_status_t MediaTranscoder::configureDestination(int fd) {
+ if (fd < 0) {
+ LOG(ERROR) << "Invalid destination fd: " << fd;
return AMEDIA_ERROR_INVALID_PARAMETER;
- } else if (mSampleWriter != nullptr) {
+ }
+
+ if (mSampleWriter != nullptr) {
LOG(ERROR) << "Destination is already configured.";
return AMEDIA_ERROR_INVALID_OPERATION;
}
- // Write-only, create file if non-existent, don't overwrite existing file.
- static constexpr int kOpenFlags = O_WRONLY | O_CREAT | O_EXCL;
- // User R+W permission.
- static constexpr int kFileMode = S_IRUSR | S_IWUSR;
-
- const int fd = open(path, kOpenFlags, kFileMode);
- if (fd < 0) {
- LOG(ERROR) << "Unable to open destination file \"" << path << "\" for writing: " << fd;
- return AMEDIA_ERROR_INVALID_PARAMETER;
- }
-
- mDestinationPath = std::string(path);
-
mSampleWriter = std::make_unique<MediaSampleWriter>();
const bool initOk = mSampleWriter->init(
fd, std::bind(&MediaTranscoder::onSampleWriterFinished, this, std::placeholders::_1));
- close(fd);
if (!initOk) {
- LOG(ERROR) << "Unable to initialize sample writer with destination path " << path;
+ LOG(ERROR) << "Unable to initialize sample writer with destination fd: " << fd;
mSampleWriter.reset();
return AMEDIA_ERROR_UNKNOWN;
}
@@ -305,7 +289,7 @@
started = transcoder->start();
if (!started) {
LOG(ERROR) << "Unable to start track transcoder.";
- cancel(true);
+ cancel();
return AMEDIA_ERROR_UNKNOWN;
}
}
@@ -323,7 +307,7 @@
return AMEDIA_ERROR_UNSUPPORTED;
}
-media_status_t MediaTranscoder::cancel(bool deleteDestinationFile) {
+media_status_t MediaTranscoder::cancel() {
bool expected = false;
if (!mCancelled.compare_exchange_strong(expected, true)) {
// Already cancelled.
@@ -335,15 +319,6 @@
transcoder->stop();
}
- // TODO(chz): file deletion should be done by upper level from the content URI.
- if (deleteDestinationFile && !mDestinationPath.empty()) {
- int error = unlink(mDestinationPath.c_str());
- if (error) {
- LOG(ERROR) << "Unable to delete destination file " << mDestinationPath.c_str() << ": "
- << error;
- return AMEDIA_ERROR_IO;
- }
- }
return AMEDIA_OK;
}
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaTrackTranscoder.h b/media/libmediatranscoding/transcoder/include/media/MediaTrackTranscoder.h
index a71db67..0a35a57 100644
--- a/media/libmediatranscoding/transcoder/include/media/MediaTrackTranscoder.h
+++ b/media/libmediatranscoding/transcoder/include/media/MediaTrackTranscoder.h
@@ -30,28 +30,7 @@
namespace android {
-class MediaTrackTranscoder;
-
-/** Callback interface for MediaTrackTranscoder. */
-class MediaTrackTranscoderCallback {
-public:
- /**
- * Called when the MediaTrackTranscoder instance have finished transcoding all media samples
- * successfully.
- * @param transcoder The MediaTrackTranscoder that finished the transcoding.
- */
- virtual void onTrackFinished(const MediaTrackTranscoder* transcoder);
-
- /**
- * Called when the MediaTrackTranscoder instance encountered an error it could not recover from.
- * @param transcoder The MediaTrackTranscoder that encountered the error.
- * @param status The non-zero error code describing the encountered error.
- */
- virtual void onTrackError(const MediaTrackTranscoder* transcoder, media_status_t status);
-
-protected:
- virtual ~MediaTrackTranscoderCallback() = default;
-};
+class MediaTrackTranscoderCallback;
/**
* Base class for all track transcoders. MediaTrackTranscoder operates asynchronously on an internal
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaTrackTranscoderCallback.h b/media/libmediatranscoding/transcoder/include/media/MediaTrackTranscoderCallback.h
new file mode 100644
index 0000000..d535ada
--- /dev/null
+++ b/media/libmediatranscoding/transcoder/include/media/MediaTrackTranscoderCallback.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIA_TRACK_TRANSCODER_CALLBACK_H
+#define ANDROID_MEDIA_TRACK_TRANSCODER_CALLBACK_H
+
+#include <media/NdkMediaError.h>
+
+namespace android {
+
+class MediaTrackTranscoder;
+
+/** Callback interface for MediaTrackTranscoder. */
+class MediaTrackTranscoderCallback {
+public:
+ /**
+ * Called when the MediaTrackTranscoder instance have finished transcoding all media samples
+ * successfully.
+ * @param transcoder The MediaTrackTranscoder that finished the transcoding.
+ */
+ virtual void onTrackFinished(const MediaTrackTranscoder* transcoder);
+
+ /**
+ * Called when the MediaTrackTranscoder instance encountered an error it could not recover from.
+ * @param transcoder The MediaTrackTranscoder that encountered the error.
+ * @param status The non-zero error code describing the encountered error.
+ */
+ virtual void onTrackError(const MediaTrackTranscoder* transcoder, media_status_t status);
+
+protected:
+ virtual ~MediaTrackTranscoderCallback() = default;
+};
+
+} // namespace android
+#endif // ANDROID_MEDIA_TRACK_TRANSCODER_CALLBACK_H
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h b/media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h
index 2d18eea..72a5559 100644
--- a/media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h
+++ b/media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h
@@ -19,9 +19,7 @@
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
-#include <media/MediaSampleReader.h>
-#include <media/MediaSampleWriter.h>
-#include <media/MediaTrackTranscoder.h>
+#include <media/MediaTrackTranscoderCallback.h>
#include <media/NdkMediaError.h>
#include <media/NdkMediaFormat.h>
@@ -31,6 +29,9 @@
namespace android {
+class MediaSampleReader;
+class MediaSampleWriter;
+
class MediaTranscoder : public std::enable_shared_from_this<MediaTranscoder>,
public MediaTrackTranscoderCallback {
public:
@@ -68,8 +69,8 @@
const std::shared_ptr<CallbackInterface>& callbacks,
const std::shared_ptr<Parcel>& pausedState = nullptr);
- /** Configures source from path. */
- media_status_t configureSource(const char* path);
+ /** Configures source from path fd. */
+ media_status_t configureSource(int fd);
/** Gets the media formats of all tracks in the file. */
std::vector<std::shared_ptr<AMediaFormat>> getTrackFormats() const;
@@ -83,8 +84,8 @@
*/
media_status_t configureTrackFormat(size_t trackIndex, AMediaFormat* trackFormat);
- /** Configures destination from path. */
- media_status_t configureDestination(const char* path);
+ /** Configures destination from fd. */
+ media_status_t configureDestination(int fd);
/** Starts transcoding. No configurations can be made once the transcoder has started. */
media_status_t start();
@@ -105,19 +106,14 @@
/** Resumes a paused transcoding. */
media_status_t resume();
- /** Cancels the transcoding. Once canceled the transcoding can not be restarted. returns error
- * if file could not be deleted. */
- media_status_t cancel(bool deleteDestinationFile = true);
+ /** Cancels the transcoding. Once canceled the transcoding can not be restarted. Client
+ * will be responsible for cleaning up the abandoned file. */
+ media_status_t cancel();
virtual ~MediaTranscoder() = default;
private:
- MediaTranscoder(const std::shared_ptr<CallbackInterface>& callbacks)
- : mCallbacks(callbacks),
- mSampleReader(nullptr),
- mSampleWriter(nullptr),
- mSourceTrackFormats(),
- mTrackTranscoders() {}
+ MediaTranscoder(const std::shared_ptr<CallbackInterface>& callbacks);
// MediaTrackTranscoderCallback
virtual void onTrackFinished(const MediaTrackTranscoder* transcoder) override;
@@ -133,7 +129,6 @@
std::vector<std::shared_ptr<AMediaFormat>> mSourceTrackFormats;
std::vector<std::unique_ptr<MediaTrackTranscoder>> mTrackTranscoders;
- std::string mDestinationPath;
std::atomic_bool mCallbackSent = false;
std::atomic_bool mCancelled = false;
};
diff --git a/media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp b/media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp
index c4a67bb..09c24b5 100644
--- a/media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp
+++ b/media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp
@@ -68,6 +68,10 @@
static const char* SOURCE_PATH =
"/data/local/tmp/TranscoderTestAssets/cubicle_avc_480x240_aac_24KHz.mp4";
+// Write-only, create file if non-existent, don't overwrite existing file.
+static constexpr int kOpenFlags = O_WRONLY | O_CREAT | O_EXCL;
+// User R+W permission.
+static constexpr int kFileMode = S_IRUSR | S_IWUSR;
class MediaTranscoderTests : public ::testing::Test {
public:
@@ -92,7 +96,8 @@
auto transcoder = MediaTranscoder::create(mCallbacks, nullptr);
EXPECT_NE(transcoder, nullptr);
- EXPECT_EQ(transcoder->configureSource(SOURCE_PATH), AMEDIA_OK);
+ const int srcFd = open(SOURCE_PATH, O_RDONLY);
+ EXPECT_EQ(transcoder->configureSource(srcFd), AMEDIA_OK);
std::vector<std::shared_ptr<AMediaFormat>> trackFormats = transcoder->getTrackFormats();
EXPECT_GT(trackFormats.size(), 0);
@@ -105,13 +110,16 @@
}
}
deleteFile(destPath);
- EXPECT_EQ(transcoder->configureDestination(destPath), AMEDIA_OK);
+ const int dstFd = open(destPath, kOpenFlags, kFileMode);
+ EXPECT_EQ(transcoder->configureDestination(dstFd), AMEDIA_OK);
media_status_t startStatus = transcoder->start();
EXPECT_EQ(startStatus, AMEDIA_OK);
if (startStatus == AMEDIA_OK) {
mCallbacks->waitForTranscodingFinished();
}
+ close(srcFd);
+ close(dstFd);
return mCallbacks->mStatus;
}
diff --git a/media/libmediatranscoding/transcoder/tests/TrackTranscoderTestUtils.h b/media/libmediatranscoding/transcoder/tests/TrackTranscoderTestUtils.h
index 79c227b..32a1a0a 100644
--- a/media/libmediatranscoding/transcoder/tests/TrackTranscoderTestUtils.h
+++ b/media/libmediatranscoding/transcoder/tests/TrackTranscoderTestUtils.h
@@ -15,6 +15,7 @@
*/
#include <media/MediaTrackTranscoder.h>
+#include <media/MediaTrackTranscoderCallback.h>
#include <condition_variable>
#include <memory>
diff --git a/media/libstagefright/flac/dec/FLACDecoder.cpp b/media/libstagefright/flac/dec/FLACDecoder.cpp
index cef0bc6..f5e9532 100644
--- a/media/libstagefright/flac/dec/FLACDecoder.cpp
+++ b/media/libstagefright/flac/dec/FLACDecoder.cpp
@@ -433,7 +433,7 @@
if (mBuffer == nullptr) {
mBufferDataSize = 0;
mBufferLen = 0;
- ALOGE("decodeOneFrame: failed to allocate memory for input buffer");
+ ALOGE("addDataToBuffer: failed to allocate memory for input buffer");
return NO_MEMORY;
}
mBufferLen = mBufferDataSize + inBufferLen;