aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-13 13:04:21 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-13 13:04:21 -0700
commit2c918c82a1735eeaba8cf84d1985b1b1c2ba0018 (patch)
treea79f7706ca4faa2273d4efcb6cc61a8da83d2044
parent9a3f021d759ae484998ddabc3dc94a39496da4a5 (diff)
downloadopencore-2c918c82a1735eeaba8cf84d1985b1b1c2ba0018.tar.gz
auto import from //branches/cupcake_rel/...@138607
-rw-r--r--android/author/PVMediaRecorder.cpp14
-rw-r--r--android/author/authordriver.cpp172
-rw-r--r--android/author/authordriver.h24
-rw-r--r--android/playerdriver.cpp43
-rw-r--r--engines/player/src/pv_player_engine.cpp25
-rw-r--r--nodes/pvmp4ffparsernode/src/pvmf_mp4ffparser_node.cpp44
-rw-r--r--pvmi/pvmf/include/pvmf_return_codes.h4
-rw-r--r--pvmi/pvmf/src/pvmf_return_codes.cpp1
8 files changed, 278 insertions, 49 deletions
diff --git a/android/author/PVMediaRecorder.cpp b/android/author/PVMediaRecorder.cpp
index bea78ef1b..9464053cc 100644
--- a/android/author/PVMediaRecorder.cpp
+++ b/android/author/PVMediaRecorder.cpp
@@ -135,6 +135,19 @@ status_t PVMediaRecorder::setOutputFile(int fd, int64_t offset, int64_t length)
return mAuthorDriverWrapper->enqueueCommand(ac, 0, 0);
}
+status_t PVMediaRecorder::setParameters(const String8& params) {
+ LOGV("setParameters(%s)", params.string());
+ set_parameters_command *command = new set_parameters_command(params);
+ if (command == NULL) {
+ LOGE("failed to construct an author command");
+
+ return NO_MEMORY;
+ }
+
+ return mAuthorDriverWrapper->enqueueCommand(
+ command, NULL /* completion_func */, NULL /* completion_cookie */);
+}
+
status_t PVMediaRecorder::setAudioEncoder(audio_encoder ae)
{
LOGV("setAudioEncoder(%d)", ae);
@@ -278,6 +291,7 @@ status_t PVMediaRecorder::start()
LOGE("failed to construct an author command");
return UNKNOWN_ERROR;
}
+
return mAuthorDriverWrapper->enqueueCommand(ac, 0, 0);
}
diff --git a/android/author/authordriver.cpp b/android/author/authordriver.cpp
index 417f6b94a..37d3c7ef1 100644
--- a/android/author/authordriver.cpp
+++ b/android/author/authordriver.cpp
@@ -24,6 +24,7 @@
#include <ui/ICamera.h>
#include "pv_omxmastercore.h"
#include "authordriver.h"
+#include "pvmf_composer_size_and_duration.h"
using namespace android;
@@ -249,6 +250,10 @@ void AuthorDriver::Run()
handleSetOutputFile((set_output_file_command *)ac);
return;
+ case AUTHOR_SET_PARAMETERS:
+ handleSetParameters((set_parameters_command *)ac);
+ return;
+
case AUTHOR_REMOVE_VIDEO_SOURCE:
handleRemoveVideoSource(ac);
return;
@@ -553,6 +558,149 @@ exit:
}
}
+PVMFStatus AuthorDriver::setMaxDuration(int64_t max_duration_ms) {
+ PVInterface *interface;
+ PvmfComposerSizeAndDurationInterface *durationConfig;
+
+ if (max_duration_ms > 0xffffffff) {
+ // PV API expects this to fit in a uint32.
+ return PVMFErrArgument;
+ }
+
+ if (!mComposerConfig) {
+ return PVMFFailure;
+ }
+
+ mComposerConfig->queryInterface(
+ PvmfComposerSizeAndDurationUuid, interface);
+
+ durationConfig =
+ OSCL_DYNAMIC_CAST(PvmfComposerSizeAndDurationInterface *, interface);
+
+ if (!durationConfig) {
+ return PVMFFailure;
+ }
+
+ // SetMaxDuration's first parameter is a boolean "enable", we enable
+ // enforcement of the maximum duration if it's (strictly) positive,
+ // otherwise we take it to imply disabling.
+ PVMFStatus ret = durationConfig->SetMaxDuration(
+ max_duration_ms > 0, static_cast<uint32>(max_duration_ms));
+
+ durationConfig->removeRef();
+ durationConfig = NULL;
+
+ return ret;
+}
+
+// Attempt to parse an int64 literal optionally surrounded by whitespace,
+// returns true on success, false otherwise.
+static bool safe_strtoi64(const char *s, int64 *val) {
+ char *end;
+ *val = strtoll(s, &end, 10);
+
+ if (end == s || errno == ERANGE) {
+ return false;
+ }
+
+ // Skip trailing whitespace
+ while (isspace(*end)) {
+ ++end;
+ }
+
+ // For a successful return, the string must contain nothing but a valid
+ // int64 literal optionally surrounded by whitespace.
+
+ return *end == '\0';
+}
+
+// Trim both leading and trailing whitespace from the given string.
+static void TrimString(String8 *s) {
+ size_t num_bytes = s->bytes();
+ const char *data = s->string();
+
+ size_t leading_space = 0;
+ while (leading_space < num_bytes && isspace(data[leading_space])) {
+ ++leading_space;
+ }
+
+ size_t i = num_bytes;
+ while (i > leading_space && isspace(data[i - 1])) {
+ --i;
+ }
+
+ s->setTo(String8(&data[leading_space], i - leading_space));
+}
+
+PVMFStatus AuthorDriver::setParameter(
+ const String8& key, const String8& value) {
+ if (key == "max-duration") {
+ int64_t max_duration_ms;
+ if (safe_strtoi64(value.string(), &max_duration_ms)) {
+ return setMaxDuration(max_duration_ms);
+ }
+ }
+
+ return PVMFErrArgument;
+}
+
+// Applies the requested parameters, completes either successfully or stops
+// application of parameters upon encountering the first error, finishing the
+// transaction with the failure result of that initial failure.
+void AuthorDriver::handleSetParameters(set_parameters_command *ac) {
+ PVMFStatus ret = PVMFSuccess;
+
+ const char *params = ac->params().string();
+ const char *key_start = params;
+ for (;;) {
+ const char *equal_pos = strchr(key_start, '=');
+ if (equal_pos == NULL) {
+ // This key is missing a value.
+
+ ret = PVMFErrArgument;
+ break;
+ }
+
+ String8 key(key_start, equal_pos - key_start);
+ TrimString(&key);
+
+ if (key.length() == 0) {
+ ret = PVMFErrArgument;
+ break;
+ }
+
+ const char *value_start = equal_pos + 1;
+ const char *semicolon_pos = strchr(value_start, ';');
+ String8 value;
+ if (semicolon_pos == NULL) {
+ value.setTo(value_start);
+ } else {
+ value.setTo(value_start, semicolon_pos - value_start);
+ }
+
+ ret = setParameter(key, value);
+
+ if (ret != NO_ERROR) {
+ LOGE("setParameter(%s = %s) failed with result %d",
+ key.string(), value.string(), ret);
+ break;
+ }
+
+ if (semicolon_pos == NULL) {
+ break;
+ }
+
+ key_start = semicolon_pos + 1;
+ }
+
+ if (ret == PVMFSuccess) {
+ FinishNonAsyncCommand(ac);
+ } else {
+ LOGE("Ln %d handleSetParameters(%s) error", __LINE__, params);
+ commandFailed(ac);
+ }
+}
+
void AuthorDriver::handlePrepare(author_command *ac)
{
int error = 0;
@@ -836,9 +984,31 @@ void AuthorDriver::HandleErrorEvent(const PVAsyncErrorEvent& aEvent)
}
}
+static int GetMediaRecorderInfoCode(const PVAsyncInformationalEvent& aEvent) {
+ switch (aEvent.GetEventType()) {
+ case PVMF_COMPOSER_MAXDURATION_REACHED:
+ return MEDIA_RECORDER_INFO_MAX_DURATION_REACHED;
+
+ default:
+ return MEDIA_RECORDER_INFO_UNKNOWN;
+ }
+}
+
void AuthorDriver::HandleInformationalEvent(const PVAsyncInformationalEvent& aEvent)
{
- LOGV("HandleInformationalEvent(%d)", aEvent.GetEventType());
+ const PVEventType event_type = aEvent.GetEventType();
+ assert(!IsPVMFErrCode(event_type));
+ if (IsPVMFInfoCode(event_type)) {
+ LOGV("HandleInformationalEvent(%d:%s)",
+ event_type, PVMFStatusToString(event_type));
+ } else {
+ LOGV("HandleInformationalEvent(%d)", event_type);
+ }
+
+ mListener->notify(
+ MEDIA_RECORDER_EVENT_INFO,
+ GetMediaRecorderInfoCode(aEvent),
+ aEvent.GetEventType());
}
status_t AuthorDriver::getMaxAmplitude(int *max)
diff --git a/android/author/authordriver.h b/android/author/authordriver.h
index 0e0d50b08..aeada4111 100644
--- a/android/author/authordriver.h
+++ b/android/author/authordriver.h
@@ -92,6 +92,7 @@ enum author_command_type {
AUTHOR_SET_VIDEO_FRAME_RATE,
AUTHOR_SET_PREVIEW_SURFACE,
AUTHOR_SET_OUTPUT_FILE,
+ AUTHOR_SET_PARAMETERS,
AUTHOR_PREPARE,
AUTHOR_START,
AUTHOR_STOP,
@@ -108,6 +109,8 @@ struct author_command
this->which = which;
}
+ virtual ~author_command() {}
+
author_command_type which;
media_completion_f comp;
void *cookie;
@@ -176,6 +179,23 @@ struct set_camera_command : author_command
sp<ICamera> camera;
};
+struct set_parameters_command : author_command
+{
+ set_parameters_command(const String8& params)
+ : author_command(AUTHOR_SET_PARAMETERS),
+ mParams(params) {
+ }
+
+ const String8& params() const { return mParams; }
+
+private:
+ String8 mParams;
+
+ // Disallow copying and assignment.
+ set_parameters_command(const set_parameters_command&);
+ set_parameters_command& operator=(const set_parameters_command&);
+};
+
class AuthorDriver :
public OsclActiveObject,
public PVCommandStatusObserver,
@@ -205,6 +225,7 @@ public:
void handleSetVideoFrameRate(set_video_frame_rate_command *ac);
void handleSetPreviewSurface(set_preview_surface_command *ac);
void handleSetOutputFile(set_output_file_command *ac);
+ void handleSetParameters(set_parameters_command *ac);
void handlePrepare(author_command *ac);
void handleStart(author_command *ac);
void handleStop(author_command *ac);
@@ -248,6 +269,9 @@ private:
// Callback for synchronous commands.
static void syncCompletion(status_t s, void *cookie);
+ PVMFStatus setMaxDuration(int64_t max_duration_ms);
+ PVMFStatus setParameter(const String8 &key, const String8 &value);
+
PVAuthorEngineInterface *mAuthor;
PvmiMIOControl *mVideoInputMIO;
diff --git a/android/playerdriver.cpp b/android/playerdriver.cpp
index a355510fe..859fab7b5 100644
--- a/android/playerdriver.cpp
+++ b/android/playerdriver.cpp
@@ -180,6 +180,34 @@ const char *PlayerCommandCodeToString(PlayerCommand::Code code) {
}
#undef CONSIDER_CODE
+// Map a PV status code to a message type (error/info/nop)
+// @param status PacketVideo status code as defined in pvmf_return_codes.h
+// @return the corresponding android message type. MEDIA_NOP is used as a default.
+::android::media_event_type MapStatusToEventType(const PVMFStatus status) {
+ if (status <= PVMFErrFirst) {
+ return ::android::MEDIA_ERROR;
+ } else if (status >= PVMFInfoFirst) {
+ return ::android::MEDIA_INFO;
+ } else {
+ return ::android::MEDIA_NOP;
+ }
+}
+
+// Map a PV status to an error/info code.
+// @param status PacketVideo status code as defined in pvmf_return_codes.h
+// @return the corresponding android error/info code.
+int MapStatusToEventCode(const PVMFStatus status) {
+ switch (status) {
+ case PVMFErrContentInvalidForProgressivePlayback:
+ return ::android::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK;
+ default:
+ // Takes advantage that both error and info codes are mapped to the
+ // same value.
+ assert(::android::MEDIA_ERROR_UNKNOWN == ::android::MEDIA_INFO_UNKNOWN);
+ return ::android::MEDIA_ERROR_UNKNOWN;
+ }
+}
+
} // anonymous namespace
class PlayerDriver :
@@ -1146,12 +1174,12 @@ void PlayerDriver::CommandCompleted(const PVCmdResponse& aResponse)
status = PVMFSuccess;
command->complete(NO_ERROR, true);
} else {
- // error occurred
- LOGE("CommandCompleted with an error or info %s", PVMFStatusToString(status));
- if (status <= PVMFErrFirst) {
- mPvPlayer->sendEvent(MEDIA_ERROR, ::android::MEDIA_ERROR_UNKNOWN, status);
- } else if (status >= PVMFInfoFirst) {
- mPvPlayer->sendEvent(MEDIA_INFO, ::android::MEDIA_INFO_UNKNOWN, status);
+ // Try to map the PV error code to an Android one.
+ LOGE("Command %s completed with an error or info %s", command->toString(), PVMFStatusToString(status));
+ const media_event_type event_type = MapStatusToEventType(status);
+
+ if (MEDIA_NOP != event_type) {
+ mPvPlayer->sendEvent(event_type, MapStatusToEventCode(status), status);
} else {
LOGE("Ignoring: %d", status);
}
@@ -1169,6 +1197,7 @@ void PlayerDriver::HandleErrorEvent(const PVAsyncErrorEvent& aEvent)
if (status > PVMFErrFirst) {
LOGE("HandleErrorEvent called with an non-error event [%d]!!", status);
}
+
LOGE("HandleErrorEvent: %s", PVMFStatusToString(status));
// TODO: Map more of the PV error code into the Android Media Player ones.
mPvPlayer->sendEvent(MEDIA_ERROR, ::android::MEDIA_ERROR_UNKNOWN, status);
@@ -1289,7 +1318,7 @@ void PlayerDriver::HandleInformationalEvent(const PVAsyncInformationalEvent& aEv
break;
default:
- LOGV("HandleInformationalEvent: type=%d UNHANDLED", status);
+ LOGE("HandleInformationalEvent: type=%d UNHANDLED", status);
break;
}
}
diff --git a/engines/player/src/pv_player_engine.cpp b/engines/player/src/pv_player_engine.cpp
index 43ac44b3e..f7f82cccd 100644
--- a/engines/player/src/pv_player_engine.cpp
+++ b/engines/player/src/pv_player_engine.cpp
@@ -3897,6 +3897,7 @@ PVMFStatus PVPlayerEngine::DoSetupSourceNode(PVCommandId aCmdId, OsclAny* aCmdCo
return PVMFErrNotSupported;
}
+
int32 leavecode = 0;
OSCL_TRY(leavecode, iSourceNode = iPlayerNodeRegistry.CreateNode(foundUuids[0]));
OSCL_FIRST_CATCH_ANY(leavecode,
@@ -11970,6 +11971,8 @@ void PVPlayerEngine::HandleSourceNodeInit(PVPlayerEngineContext& aNodeContext, c
iCommandCompleteInEngineAOPending = false;
PVMFStatus cmdstatus;
+ PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::HandleSourceNodeInit() Status= %s", PVMFStatusToString(aNodeResp.GetCmdStatus())));
+
switch (aNodeResp.GetCmdStatus())
{
case PVMFSuccess:
@@ -12019,7 +12022,25 @@ void PVPlayerEngine::HandleSourceNodeInit(PVPlayerEngineContext& aNodeContext, c
}
break;
- ;
+ case PVMFErrContentInvalidForProgressivePlayback:
+ {
+ SetEngineState(PVP_ENGINE_STATE_ERROR);
+ AddCommandToQueue(PVP_ENGINE_COMMAND_STOP_DUE_TO_ERROR, NULL, NULL, NULL, false);
+
+ cmdstatus = aNodeResp.GetCmdStatus();
+
+ PVMFErrorInfoMessageInterface* nextmsg = NULL;
+ if (aNodeResp.GetEventExtensionInterface())
+ {
+ nextmsg = GetErrorInfoMessageInterface(*(aNodeResp.GetEventExtensionInterface()));
+ }
+
+ PVUuid puuid = PVPlayerErrorInfoEventTypesUUID;
+ PVMFBasicErrorInfoMessage* errmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (PVPlayerErrSourceInit, puuid, nextmsg));
+ EngineCommandCompleted(aNodeContext.iCmdId, aNodeContext.iCmdContext, cmdstatus, OSCL_STATIC_CAST(PVInterface*, errmsg), aNodeResp.GetEventData());
+ errmsg->removeRef();
+ }
+ break;
default:
{
@@ -17013,5 +17034,3 @@ void PVPlayerEngine::DepopulateAllRegistries()
DepopulateRecognizerRegistry();
}
#endif
-
-
diff --git a/nodes/pvmp4ffparsernode/src/pvmf_mp4ffparser_node.cpp b/nodes/pvmp4ffparsernode/src/pvmf_mp4ffparser_node.cpp
index c09414df1..57193f3c3 100644
--- a/nodes/pvmp4ffparsernode/src/pvmf_mp4ffparser_node.cpp
+++ b/nodes/pvmp4ffparsernode/src/pvmf_mp4ffparser_node.cpp
@@ -7211,6 +7211,7 @@ PVMFStatus PVMFMP4FFParserNode::CheckForMP4HeaderAvailability()
isProgressiveDownloadable,
iMP4HeaderSize);
+ PVMFStatus retcode = PVMFFailure;
if (retCode == EVERYTHING_FINE)
{
if (isProgressiveDownloadable == true)
@@ -7227,11 +7228,11 @@ PVMFStatus PVMFMP4FFParserNode::CheckForMP4HeaderAvailability()
*this,
iMP4HeaderSize);
iDataStreamRequestPending = true;
- return PVMFPending;
+ retcode = PVMFPending;
}
else
{
- return PVMFSuccess;
+ retcode = PVMFSuccess;
}
}
else
@@ -7260,7 +7261,7 @@ PVMFStatus PVMFMP4FFParserNode::CheckForMP4HeaderAvailability()
download_progress_interface->requestResumeNotification(nptTsinMS, iDownloadComplete);
}
PVMF_MP4FFPARSERNODE_LOGDATATRAFFIC((0, "PVMFMP4FFParserNode::CheckForMP4HeaderAvailability() - Auto Pause Triggered, TS = %d", nptTsinMS));
- return PVMFPending;
+ retcode = PVMFPending;
}
else
{
@@ -7272,13 +7273,14 @@ PVMFStatus PVMFMP4FFParserNode::CheckForMP4HeaderAvailability()
{
// progressive playback and no movie atom found
PVMF_MP4FFPARSERNODE_LOGERROR((0, "PVMFMP4FFParserNode::CheckForMP4HeaderAvailability() - Moov atom not found, needed for progressive playback"));
+ retcode = PVMFErrContentInvalidForProgressivePlayback;
}
else
{
PVMF_MP4FFPARSERNODE_LOGERROR((0, "PVMFMP4FFParserNode::CheckForMP4HeaderAvailability() - GetMetaDataSize Failed %d", retCode));
}
- return PVMFFailure;
+ return retcode;
}
return PVMFSuccess;
}
@@ -8411,37 +8413,3 @@ bool PVMFMP4FFParserNode::SendBeginOfMediaStreamCommand(PVMP4FFNodeTrackPortInfo
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFMP4FFParserNode::SendBeginOfMediaStreamCommand() BOS sent StreamId=%d ", iStreamID));
return true;
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/pvmi/pvmf/include/pvmf_return_codes.h b/pvmi/pvmf/include/pvmf_return_codes.h
index 5aaaefe0e..46a175bdf 100644
--- a/pvmi/pvmf/include/pvmf_return_codes.h
+++ b/pvmi/pvmf/include/pvmf_return_codes.h
@@ -161,6 +161,10 @@ const PVMFStatus PVMFLowDiskSpace = (-25);
Error due to the requirement of user-id and password input from app for HTTP basic/digest authentication
*/
const PVMFStatus PVMFErrHTTPAuthenticationRequired = (-26);
+/*
+ Error: the video container is not valid for progressive playback.
+ */
+const PVMFStatus PVMFErrContentInvalidForProgressivePlayback = (-27);
/*
Placeholder for last event in range.
diff --git a/pvmi/pvmf/src/pvmf_return_codes.cpp b/pvmi/pvmf/src/pvmf_return_codes.cpp
index a07a28968..6673706b6 100644
--- a/pvmi/pvmf/src/pvmf_return_codes.cpp
+++ b/pvmi/pvmf/src/pvmf_return_codes.cpp
@@ -53,6 +53,7 @@ const char *PVMFStatusToString(const PVMFStatus status) {
CONSIDER(PVMFErrMaxReached);
CONSIDER(PVMFLowDiskSpace);
CONSIDER(PVMFErrHTTPAuthenticationRequired);
+ CONSIDER(PVMFErrContentInvalidForProgressivePlayback);
CONSIDER(PVMFInfoPortCreated);
CONSIDER(PVMFInfoPortDeleted);
CONSIDER(PVMFInfoPortConnected);