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

Commit d71f1626 authored by Wonsik Kim's avatar Wonsik Kim Committed by Android (Google) Code Review
Browse files

Merge "MediaCodec refactoring part 2-a: introduce callback"

parents 1f28e57b 79054b1f
Loading
Loading
Loading
Loading
+118 −10
Original line number Diff line number Diff line
@@ -59,6 +59,114 @@ static void mysighandler(int signum) {
    oldhandler(signum);
}

namespace {

enum {
    kWhatFillThisBuffer      = 'fill',
    kWhatDrainThisBuffer     = 'drai',
    kWhatEOS                 = 'eos ',
    kWhatStopCompleted       = 'scom',
    kWhatReleaseCompleted    = 'rcom',
    kWhatFlushCompleted      = 'fcom',
    kWhatError               = 'erro',
};

class Sf2Callback : public CodecBase::Callback {
public:
    explicit Sf2Callback(const sp<AMessage> &notify);
    ~Sf2Callback();

    virtual void fillThisBuffer(IOMX::buffer_id bufferId, const sp<MediaCodecBuffer> &buffer,
            const sp<AMessage> &reply) override;
    virtual void drainThisBuffer(IOMX::buffer_id bufferId, const sp<MediaCodecBuffer> &buffer,
            int32_t flags, const sp<AMessage> &reply) override;
    virtual void onEos(status_t err) override;
    virtual void onStopCompleted() override;
    virtual void onReleaseCompleted() override;
    virtual void onFlushCompleted() override;
    virtual void onError(status_t err, enum ActionCode actionCode) override;
    // Events below are not handled; thus ignore.
    virtual void onComponentAllocated(const char *) override {}
    virtual void onComponentConfigured(const sp<AMessage> &, const sp<AMessage> &) override {}
    virtual void onInputSurfaceCreated(
            const sp<AMessage> &,
            const sp<AMessage> &,
            const sp<BufferProducerWrapper> &) override {}
    virtual void onInputSurfaceCreationFailed(status_t) override {}
    virtual void onInputSurfaceAccepted(const sp<AMessage> &, const sp<AMessage> &) override {}
    virtual void onInputSurfaceDeclined(status_t) override {}
    virtual void onSignaledInputEOS(status_t) override {}
    virtual void onBuffersAllocated(int32_t, const sp<CodecBase::PortDescription> &) override {}
    virtual void onOutputFramesRendered(const std::list<FrameRenderTracker::Info> &) override {}
private:
    const sp<AMessage> mNotify;
};

Sf2Callback::Sf2Callback(const sp<AMessage> &notify) : mNotify(notify) {}

Sf2Callback::~Sf2Callback() {}

void Sf2Callback::fillThisBuffer(
        IOMX::buffer_id bufferId,
        const sp<MediaCodecBuffer> &buffer,
        const sp<AMessage> &reply) {
    sp<AMessage> notify(mNotify->dup());
    notify->setInt32("what", kWhatFillThisBuffer);
    notify->setInt32("buffer-id", bufferId);
    notify->setObject("buffer", buffer);
    notify->setMessage("reply", reply);
    notify->post();
}

void Sf2Callback::drainThisBuffer(
        IOMX::buffer_id bufferId,
        const sp<MediaCodecBuffer> &buffer,
        int32_t flags,
        const sp<AMessage> &reply) {
    sp<AMessage> notify(mNotify->dup());
    notify->setInt32("what", kWhatDrainThisBuffer);
    notify->setInt32("buffer-id", bufferId);
    notify->setObject("buffer", buffer);
    notify->setInt32("flags", flags);
    notify->setMessage("reply", reply);
    notify->post();
}

void Sf2Callback::onEos(status_t err) {
    sp<AMessage> notify(mNotify->dup());
    notify->setInt32("what", kWhatEOS);
    notify->setInt32("err", err);
    notify->post();
}

void Sf2Callback::onStopCompleted() {
    sp<AMessage> notify(mNotify->dup());
    notify->setInt32("what", kWhatStopCompleted);
    notify->post();
}

void Sf2Callback::onReleaseCompleted() {
    sp<AMessage> notify(mNotify->dup());
    notify->setInt32("what", kWhatReleaseCompleted);
    notify->post();
}

void Sf2Callback::onFlushCompleted() {
    sp<AMessage> notify(mNotify->dup());
    notify->setInt32("what", kWhatFlushCompleted);
    notify->post();
}

void Sf2Callback::onError(status_t err, enum ActionCode actionCode) {
    sp<AMessage> notify(mNotify->dup());
    notify->setInt32("what", kWhatError);
    notify->setInt32("err", err);
    notify->setInt32("actionCode", actionCode);
    notify->post();
}

}  // namespace

struct Controller : public AHandler {
    Controller(const char *uri, bool decodeAudio,
               const sp<Surface> &surface, bool renderToSurface)
@@ -148,8 +256,8 @@ protected:

                mDecodeLooper->registerHandler(mCodec);

                mCodec->setNotificationMessage(
                        new AMessage(kWhatCodecNotify, this));
                mCodec->setCallback(
                        std::make_shared<Sf2Callback>(new AMessage(kWhatCodecNotify, this)));

                sp<AMessage> format = makeFormat(mSource->getFormat());

@@ -210,28 +318,28 @@ protected:
                int32_t what;
                CHECK(msg->findInt32("what", &what));

                if (what == CodecBase::kWhatFillThisBuffer) {
                if (what == kWhatFillThisBuffer) {
                    onFillThisBuffer(msg);
                } else if (what == CodecBase::kWhatDrainThisBuffer) {
                } else if (what == kWhatDrainThisBuffer) {
                    if ((mNumOutputBuffersReceived++ % 16) == 0) {
                        printf(".");
                        fflush(stdout);
                    }

                    onDrainThisBuffer(msg);
                } else if (what == CodecBase::kWhatEOS
                        || what == CodecBase::kWhatError) {
                    printf((what == CodecBase::kWhatEOS) ? "$\n" : "E\n");
                } else if (what == kWhatEOS
                        || what == kWhatError) {
                    printf((what == kWhatEOS) ? "$\n" : "E\n");

                    printStatistics();
                    (new AMessage(kWhatStop, this))->post();
                } else if (what == CodecBase::kWhatFlushCompleted) {
                } else if (what == kWhatFlushCompleted) {
                    mSeekState = SEEK_FLUSH_COMPLETED;
                    mCodec->signalResume();

                    (new AMessage(kWhatSeek, this))->post(5000000ll);
                } else if (what == CodecBase::kWhatStopCompleted ||
                        what == CodecBase::kWhatReleaseCompleted) {
                } else if (what == kWhatStopCompleted ||
                        what == kWhatReleaseCompleted) {
                    mDecodeLooper->unregisterHandler(mCodec->id());

                    if (mDecodeLooper != looper()) {
+147 −16
Original line number Diff line number Diff line
@@ -18,12 +18,15 @@

#define CODEC_BASE_H_

#include <memory>

#include <stdint.h>

#define STRINGIFY_ENUMS

#include <media/IOMX.h>
#include <media/MediaCodecInfo.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/foundation/AHandler.h>
#include <media/stagefright/foundation/ColorUtils.h>
#include <media/hardware/HardwareAPI.h>
@@ -34,33 +37,159 @@

namespace android {

class BufferProducerWrapper;
class MediaCodecBuffer;
struct PersistentSurface;
struct RenderedFrameInfo;
class Surface;

struct CodecBase : public AHandler, /* static */ ColorUtils {
    enum {
        kWhatFillThisBuffer      = 'fill',
        kWhatDrainThisBuffer     = 'drai',
        kWhatEOS                 = 'eos ',
        kWhatStopCompleted       = 'scom',
        kWhatReleaseCompleted    = 'rcom',
        kWhatFlushCompleted      = 'fcom',
        kWhatError               = 'erro',
        kWhatComponentAllocated  = 'cAll',
        kWhatComponentConfigured = 'cCon',
        kWhatInputSurfaceCreated = 'isfc',
        kWhatInputSurfaceAccepted = 'isfa',
        kWhatSignaledInputEOS    = 'seos',
        kWhatBuffersAllocated    = 'allc',
        kWhatOutputFramesRendered = 'outR',
    struct PortDescription;

    /**
     * This interface defines events firing from CodecBase back to MediaCodec.
     * All methods must not block.
     */
    class Callback {
    public:
        virtual ~Callback() = default;

        /**
         * Request MediaCodec to fill the specified input buffer.
         *
         * @param bufferId  ID of the buffer, assigned by underlying component.
         * @param buffer    a buffer to be filled.
         * @param reply     a message to post once MediaCodec has filled the
         *                  buffer.
         */
        virtual void fillThisBuffer(
                IOMX::buffer_id bufferId,
                const sp<MediaCodecBuffer> &buffer,
                const sp<AMessage> &reply) = 0;
        /**
         * Request MediaCodec to drain the specified output buffer.
         *
         * @param bufferId  ID of the buffer, assigned by underlying component.
         * @param buffer    a buffer to be filled.
         * @param flags     flags associated with this buffer (e.g. EOS).
         * @param reply     a message to post once MediaCodec has filled the
         *                  buffer.
         */
        virtual void drainThisBuffer(
                IOMX::buffer_id bufferId,
                const sp<MediaCodecBuffer> &buffer,
                int32_t flags,
                const sp<AMessage> &reply) = 0;
        /**
         * Notify MediaCodec for seeing an output EOS.
         *
         * @param err the underlying cause of the EOS. If the value is neither
         *            OK nor ERROR_END_OF_STREAM, the EOS is declared
         *            prematurely for that error.
         */
        virtual void onEos(status_t err) = 0;
        /**
         * Notify MediaCodec that stop operation is complete.
         */
        virtual void onStopCompleted() = 0;
        /**
         * Notify MediaCodec that release operation is complete.
         */
        virtual void onReleaseCompleted() = 0;
        /**
         * Notify MediaCodec that flush operation is complete.
         */
        virtual void onFlushCompleted() = 0;
        /**
         * Notify MediaCodec that an error is occurred.
         *
         * @param err         an error code for the occurred error.
         * @param actionCode  an action code for severity of the error.
         */
        virtual void onError(status_t err, enum ActionCode actionCode) = 0;
        /**
         * Notify MediaCodec that the underlying component is allocated.
         *
         * @param componentName the unique name of the component specified in
         *                      MediaCodecList.
         */
        virtual void onComponentAllocated(const char *componentName) = 0;
        /**
         * Notify MediaCodec that the underlying component is configured.
         *
         * @param inputFormat   an input format at configure time.
         * @param outputFormat  an output format at configure time.
         */
        virtual void onComponentConfigured(
                const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) = 0;
        /**
         * Notify MediaCodec that the input surface is created.
         *
         * @param inputFormat   an input format at surface creation. Formats
         *                      could change from the previous state as a result
         *                      of creating a surface.
         * @param outputFormat  an output format at surface creation.
         * @param inputSurface  the created surface.
         */
        virtual void onInputSurfaceCreated(
                const sp<AMessage> &inputFormat,
                const sp<AMessage> &outputFormat,
                const sp<BufferProducerWrapper> &inputSurface) = 0;
        /**
         * Notify MediaCodec that the input surface creation is failed.
         *
         * @param err an error code of the cause.
         */
        virtual void onInputSurfaceCreationFailed(status_t err) = 0;
        /**
         * Notify MediaCodec that the component accepted the provided input
         * surface.
         *
         * @param inputFormat   an input format at surface assignment. Formats
         *                      could change from the previous state as a result
         *                      of assigning a surface.
         * @param outputFormat  an output format at surface assignment.
         */
        virtual void onInputSurfaceAccepted(
                const sp<AMessage> &inputFormat,
                const sp<AMessage> &outputFormat) = 0;
        /**
         * Notify MediaCodec that the component declined the provided input
         * surface.
         *
         * @param err an error code of the cause.
         */
        virtual void onInputSurfaceDeclined(status_t err) = 0;
        /**
         * Noitfy MediaCodec that the requested input EOS is sent to the input
         * surface.
         *
         * @param err an error code returned from the surface. If there is no
         *            input surface, the value is INVALID_OPERATION.
         */
        virtual void onSignaledInputEOS(status_t err) = 0;
        /**
         * Notify MediaCodec with the allocated buffers.
         *
         * @param portIndex zero for input port, one for output port.
         * @param portDesc  a PortDescription object containing allocated
         *                  buffers.
         */
        virtual void onBuffersAllocated(int32_t portIndex, const sp<PortDescription> &portDesc) = 0;
        /**
         * Notify MediaCodec that output frames are rendered with information on
         * those frames.
         *
         * @param done  a list of rendered frames.
         */
        virtual void onOutputFramesRendered(const std::list<RenderedFrameInfo> &done) = 0;
    };

    enum {
        kMaxCodecBufferSize = 8192 * 4096 * 4, // 8K RGBA
    };

    virtual void setNotificationMessage(const sp<AMessage> &msg) = 0;
    void setCallback(std::shared_ptr<Callback> &&callback);

    virtual void initiateAllocateComponent(const sp<AMessage> &msg) = 0;
    virtual void initiateConfigureComponent(const sp<AMessage> &msg) = 0;
@@ -107,6 +236,8 @@ protected:
    CodecBase();
    virtual ~CodecBase();

    std::shared_ptr<Callback> mCallback;

private:
    DISALLOW_EVIL_CONSTRUCTORS(CodecBase);
};
+54 −51
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ namespace android {
class Fence;
class GraphicBuffer;

struct FrameRenderTracker {
// Tracks the render information about a frame. Frames go through several states while
// the render information is tracked:
//
@@ -47,7 +46,7 @@ struct FrameRenderTracker {
// 3. rendered frame or frame: mFence is cleared, mRenderTimeNs is set.
// Key characteristics: mFence is NULL.
//
    struct Info {
struct RenderedFrameInfo {
    // set by client during onFrameQueued or onFrameRendered
    int64_t getMediaTimeUs() const  { return mMediaTimeUs; }

@@ -58,7 +57,8 @@ struct FrameRenderTracker {
    ssize_t getIndex() const        { return mIndex; }

    // creates information for a queued frame
        Info(int64_t mediaTimeUs, const sp<GraphicBuffer> &graphicBuffer, const sp<Fence> &fence)
    RenderedFrameInfo(int64_t mediaTimeUs, const sp<GraphicBuffer> &graphicBuffer,
            const sp<Fence> &fence)
        : mMediaTimeUs(mediaTimeUs),
          mRenderTimeNs(-1),
          mIndex(-1),
@@ -67,7 +67,7 @@ struct FrameRenderTracker {
    }

    // creates information for a frame rendered on a tunneled surface
        Info(int64_t mediaTimeUs, nsecs_t renderTimeNs)
    RenderedFrameInfo(int64_t mediaTimeUs, nsecs_t renderTimeNs)
        : mMediaTimeUs(mediaTimeUs),
          mRenderTimeNs(renderTimeNs),
          mIndex(-1),
@@ -85,6 +85,9 @@ struct FrameRenderTracker {
    friend class FrameRenderTracker;
};

struct FrameRenderTracker {
    typedef RenderedFrameInfo Info;

    FrameRenderTracker();

    void setComponentName(const AString &componentName);
+0 −3
Original line number Diff line number Diff line
@@ -28,8 +28,6 @@ struct SimpleFilter;
struct MediaFilter : public CodecBase {
    MediaFilter();

    virtual void setNotificationMessage(const sp<AMessage> &msg);

    virtual void initiateAllocateComponent(const sp<AMessage> &msg);
    virtual void initiateConfigureComponent(const sp<AMessage> &msg);
    virtual void initiateCreateInputSurface();
@@ -120,7 +118,6 @@ private:
    int32_t mColorFormatIn, mColorFormatOut;
    size_t mMaxInputSize, mMaxOutputSize;
    int32_t mGeneration;
    sp<AMessage> mNotify;
    sp<AMessage> mInputFormat;
    sp<AMessage> mOutputFormat;

+35 −118

File changed.

Preview size limit exceeded, changes collapsed.

Loading