Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7fc8b4f5 authored by James Dong's avatar James Dong
Browse files

Better organize media recorder error and information event and types

Change-Id: I45f1f953596985494725525c1fabf57eccc19175
parent 6ed6f6d8
Loading
Loading
Loading
Loading
+47 −16
Original line number Diff line number Diff line
@@ -104,35 +104,62 @@ enum video_encoder {
};

/*
 * The state machine of the media_recorder uses a set of different state names.
 * The mapping between the media_recorder and the pvauthorengine is shown below:
 *
 *    mediarecorder                        pvauthorengine
 * ----------------------------------------------------------------
 *    MEDIA_RECORDER_ERROR                 ERROR
 *    MEDIA_RECORDER_IDLE                  IDLE
 *    MEDIA_RECORDER_INITIALIZED           OPENED
 *    MEDIA_RECORDER_DATASOURCE_CONFIGURED
 *    MEDIA_RECORDER_PREPARED              INITIALIZED
 *    MEDIA_RECORDER_RECORDING             RECORDING
 * The state machine of the media_recorder.
 */
enum media_recorder_states {
    // Error state.
    MEDIA_RECORDER_ERROR                 =      0,

    // Recorder was just created.
    MEDIA_RECORDER_IDLE                  = 1 << 0,

    // Recorder has been initialized.
    MEDIA_RECORDER_INITIALIZED           = 1 << 1,

    // Configuration of the recorder has been completed.
    MEDIA_RECORDER_DATASOURCE_CONFIGURED = 1 << 2,

    // Recorder is ready to start.
    MEDIA_RECORDER_PREPARED              = 1 << 3,

    // Recording is in progress.
    MEDIA_RECORDER_RECORDING             = 1 << 4,
};

// The "msg" code passed to the listener in notify.
enum media_recorder_event_type {
    MEDIA_RECORDER_EVENT_LIST_START               = 1,
    MEDIA_RECORDER_EVENT_ERROR                    = 1,
    MEDIA_RECORDER_EVENT_INFO                     = 2
    MEDIA_RECORDER_EVENT_INFO                     = 2,
    MEDIA_RECORDER_EVENT_LIST_END                 = 99,

    // Track related event types
    MEDIA_RECORDER_TRACK_EVENT_LIST_START         = 100,
    MEDIA_RECORDER_TRACK_EVENT_ERROR              = 100,
    MEDIA_RECORDER_TRACK_EVENT_INFO               = 101,
    MEDIA_RECORDER_TRACK_EVENT_LIST_END           = 1000,
};

/*
 * The (part of) "what" code passed to the listener in notify.
 * When the error or info type is track specific, the what has
 * the following layout:
 * the left-most 16-bit is meant for error or info type.
 * the right-most 4-bit is meant for track id.
 * the rest is reserved.
 *
 * | track id | reserved |     error or info type     |
 * 31         28         16                           0
 *
 */
enum media_recorder_error_type {
    MEDIA_RECORDER_ERROR_UNKNOWN                  = 1
    MEDIA_RECORDER_ERROR_UNKNOWN                   = 1,

    // Track related error type
    MEDIA_RECORDER_TRACK_ERROR_LIST_START          = 100,
    MEDIA_RECORDER_TRACK_ERROR_GENERAL             = 100,
    MEDIA_RECORDER_ERROR_VIDEO_NO_SYNC_FRAME       = 200,
    MEDIA_RECORDER_TRACK_ERROR_LIST_END            = 1000,
};

// The codes are distributed as follow:
@@ -141,11 +168,15 @@ enum media_recorder_error_type {
//
enum media_recorder_info_type {
    MEDIA_RECORDER_INFO_UNKNOWN                   = 1,

    MEDIA_RECORDER_INFO_MAX_DURATION_REACHED      = 800,
    MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED      = 801,
    MEDIA_RECORDER_INFO_COMPLETION_STATUS         = 802,
    MEDIA_RECORDER_INFO_PROGRESS_FRAME_STATUS     = 803,
    MEDIA_RECORDER_INFO_PROGRESS_TIME_STATUS      = 804,

    // All track related informtional events start here
    MEDIA_RECORDER_TRACK_INFO_LIST_START           = 1000,
    MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS    = 1000,
    MEDIA_RECORDER_TRACK_INFO_PROGRESS_IN_TIME     = 1001,
    MEDIA_RECORDER_TRACK_INFO_LIST_END             = 2000,
};

// ----------------------------------------------------------------------------
+1 −1
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ private:
    bool use32BitFileOffset() const;
    bool exceedsFileDurationLimit();
    bool isFileStreamable() const;
    void trackProgressStatus(const Track* track, int64_t timeUs, status_t err = OK);
    void trackProgressStatus(size_t trackId, int64_t timeUs, status_t err = OK);
    void writeCompositionMatrix(int32_t degrees);

    MPEG4Writer(const MPEG4Writer &);
+1 −1
Original line number Diff line number Diff line
@@ -269,7 +269,7 @@ status_t AMRWriter::threadFunc() {
    }

    if (stoppedPrematurely) {
        notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_COMPLETION_STATUS, UNKNOWN_ERROR);
        notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS, UNKNOWN_ERROR);
    }

    close(mFd);
+20 −20
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ static const int64_t kVideoMediaTimeAdjustPeriodTimeUs = 600000000LL; // 10 min

class MPEG4Writer::Track {
public:
    Track(MPEG4Writer *owner, const sp<MediaSource> &source);
    Track(MPEG4Writer *owner, const sp<MediaSource> &source, size_t trackId);

    ~Track();

@@ -82,6 +82,7 @@ private:
    bool mIsAvc;
    bool mIsAudio;
    bool mIsMPEG4;
    int32_t mTrackId;
    int64_t mTrackDurationUs;

    // For realtime applications, we need to adjust the media clock
@@ -295,7 +296,12 @@ status_t MPEG4Writer::Track::dump(
}

status_t MPEG4Writer::addSource(const sp<MediaSource> &source) {
    Track *track = new Track(this, source);
    Mutex::Autolock l(mLock);
    if (mStarted) {
        LOGE("Attempt to add source AFTER recording is started");
        return UNKNOWN_ERROR;
    }
    Track *track = new Track(this, source, mTracks.size());
    mTracks.push_back(track);

    return OK;
@@ -945,7 +951,7 @@ size_t MPEG4Writer::numTracks() {
////////////////////////////////////////////////////////////////////////////////

MPEG4Writer::Track::Track(
        MPEG4Writer *owner, const sp<MediaSource> &source)
        MPEG4Writer *owner, const sp<MediaSource> &source, size_t trackId)
    : mOwner(owner),
      mMeta(source->getFormat()),
      mSource(source),
@@ -953,6 +959,7 @@ MPEG4Writer::Track::Track(
      mPaused(false),
      mResumed(false),
      mStarted(false),
      mTrackId(trackId),
      mTrackDurationUs(0),
      mEstimatedTrackSizeBytes(0),
      mSamplesHaveSameSize(true),
@@ -2030,7 +2037,7 @@ status_t MPEG4Writer::Track::threadEntry() {
        (OK != checkCodecSpecificData())) {          // no codec specific data
        err = ERROR_MALFORMED;
    }
    mOwner->trackProgressStatus(this, -1, err);
    mOwner->trackProgressStatus(mTrackId, -1, err);

    // Last chunk
    if (mOwner->numTracks() == 1) {
@@ -2077,41 +2084,34 @@ void MPEG4Writer::Track::trackProgressStatus(int64_t timeUs, status_t err) {
    if (mTrackEveryTimeDurationUs > 0 &&
        timeUs - mPreviousTrackTimeUs >= mTrackEveryTimeDurationUs) {
        LOGV("Fire time tracking progress status at %lld us", timeUs);
        mOwner->trackProgressStatus(this, timeUs - mPreviousTrackTimeUs, err);
        mOwner->trackProgressStatus(mTrackId, timeUs - mPreviousTrackTimeUs, err);
        mPreviousTrackTimeUs = timeUs;
    }
}

void MPEG4Writer::trackProgressStatus(
        const MPEG4Writer::Track* track, int64_t timeUs, status_t err) {
        size_t trackId, int64_t timeUs, status_t err) {
    Mutex::Autolock lock(mLock);
    int32_t nTracks = mTracks.size();
    CHECK(nTracks >= 1);
    CHECK(nTracks < 64);  // Arbitrary number

    int32_t trackNum = 0;
    CHECK(trackNum < nTracks);
    trackNum <<= 16;
    int32_t trackNum = (trackId << 28);

    // Error notification
    // Do not consider ERROR_END_OF_STREAM an error
    if (err != OK && err != ERROR_END_OF_STREAM) {
        notify(MEDIA_RECORDER_EVENT_ERROR,
               trackNum | MEDIA_RECORDER_ERROR_UNKNOWN,
        notify(MEDIA_RECORDER_TRACK_EVENT_ERROR,
               trackNum | MEDIA_RECORDER_TRACK_ERROR_GENERAL,
               err);
        return;
    }

    if (timeUs == -1) {
        // Send completion notification
        notify(MEDIA_RECORDER_EVENT_INFO,
               trackNum | MEDIA_RECORDER_INFO_COMPLETION_STATUS,
        notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
               trackNum | MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS,
               err);
        return;
    } else {
        // Send progress status
        notify(MEDIA_RECORDER_EVENT_INFO,
               trackNum | MEDIA_RECORDER_INFO_PROGRESS_TIME_STATUS,
        notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
               trackNum | MEDIA_RECORDER_TRACK_INFO_PROGRESS_IN_TIME,
               timeUs / 1000);
    }
}