Home | History | Annotate | Download | only in enc
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef SOFT_VPX_ENCODER_H_
     18 
     19 #define SOFT_VPX_ENCODER_H_
     20 
     21 #include "SimpleSoftOMXComponent.h"
     22 
     23 #include <OMX_VideoExt.h>
     24 #include <OMX_IndexExt.h>
     25 
     26 #include "vpx/vpx_encoder.h"
     27 #include "vpx/vpx_codec.h"
     28 #include "vpx/vp8cx.h"
     29 
     30 namespace android {
     31 
     32 // Exposes a vpx encoder as an OMX Component
     33 //
     34 // Boilerplate for callback bindings are taken care
     35 // by the base class SimpleSoftOMXComponent and its
     36 // parent SoftOMXComponent.
     37 //
     38 // Only following encoder settings are available
     39 //    - target bitrate
     40 //    - rate control (constant / variable)
     41 //    - frame rate
     42 //    - error resilience
     43 //    - token partitioning
     44 //    - reconstruction & loop filters (g_profile)
     45 //
     46 // Only following color formats are recognized
     47 //    - YUV420Planar
     48 //    - YUV420SemiPlanar
     49 //    - AndroidOpaque
     50 //
     51 // Following settings are not configurable by the client
     52 //    - encoding deadline is realtime
     53 //    - multithreaded encoding utilizes a number of threads equal
     54 // to online cpu's available
     55 //    - the algorithm interface for encoder is vp8
     56 //    - fractional bits of frame rate is discarded
     57 //    - OMX timestamps are in microseconds, therefore
     58 // encoder timebase is fixed to 1/1000000
     59 
     60 class SoftVPXEncoder : public SimpleSoftOMXComponent {
     61  public:
     62     SoftVPXEncoder(const char *name,
     63                    const OMX_CALLBACKTYPE *callbacks,
     64                    OMX_PTR appData,
     65                    OMX_COMPONENTTYPE **component);
     66 
     67  protected:
     68     virtual ~SoftVPXEncoder();
     69 
     70     // Returns current values for requested OMX
     71     // parameters
     72     virtual OMX_ERRORTYPE internalGetParameter(
     73             OMX_INDEXTYPE index, OMX_PTR param);
     74 
     75     // Validates, extracts and stores relevant OMX
     76     // parameters
     77     virtual OMX_ERRORTYPE internalSetParameter(
     78             OMX_INDEXTYPE index, const OMX_PTR param);
     79 
     80     // OMX callback when buffers available
     81     // Note that both an input and output buffer
     82     // is expected to be available to carry out
     83     // encoding of the frame
     84     virtual void onQueueFilled(OMX_U32 portIndex);
     85 
     86  private:
     87     // number of buffers allocated per port
     88     static const uint32_t kNumBuffers = 4;
     89 
     90     // OMX port indexes that refer to input and
     91     // output ports respectively
     92     static const uint32_t kInputPortIndex = 0;
     93     static const uint32_t kOutputPortIndex = 1;
     94 
     95     // Byte-alignment required for buffers
     96     static const uint32_t kInputBufferAlignment = 1;
     97     static const uint32_t kOutputBufferAlignment = 2;
     98 
     99     // Max value supported for DCT partitions
    100     static const uint32_t kMaxDCTPartitions = 3;
    101 
    102     // Number of supported input color formats
    103     static const uint32_t kNumberOfSupportedColorFormats = 3;
    104 
    105     // vpx specific opaque data structure that
    106     // stores encoder state
    107     vpx_codec_ctx_t* mCodecContext;
    108 
    109     // vpx specific data structure that
    110     // stores encoder configuration
    111     vpx_codec_enc_cfg_t* mCodecConfiguration;
    112 
    113     // vpx specific read-only data structure
    114     // that specifies algorithm interface (e.g. vp8)
    115     vpx_codec_iface_t* mCodecInterface;
    116 
    117     // Width of the input frames
    118     int32_t mWidth;
    119 
    120     // Height of the input frames
    121     int32_t mHeight;
    122 
    123     // Target bitrate set for the encoder, in bits per second.
    124     int32_t mBitrate;
    125 
    126     // Bitrate control mode, either constant or variable
    127     vpx_rc_mode mBitrateControlMode;
    128 
    129     // Frame duration is the reciprocal of framerate, denoted
    130     // in microseconds
    131     uint64_t mFrameDurationUs;
    132 
    133     // vp8 specific configuration parameter
    134     // that enables token partitioning of
    135     // the stream into substreams
    136     int32_t mDCTPartitions;
    137 
    138     // Parameter that denotes whether error resilience
    139     // is enabled in encoder
    140     OMX_BOOL mErrorResilience;
    141 
    142     // Color format for the input port
    143     OMX_COLOR_FORMATTYPE mColorFormat;
    144 
    145     // Encoder profile corresponding to OMX level parameter
    146     //
    147     // The inconsistency in the naming is caused by
    148     // OMX spec referring vpx profiles (g_profile)
    149     // as "levels" whereas using the name "profile" for
    150     // something else.
    151     OMX_VIDEO_VP8LEVELTYPE mLevel;
    152 
    153     // Conversion buffer is needed to convert semi
    154     // planar yuv420 to planar format
    155     // It is only allocated if input format is
    156     // indeed YUV420SemiPlanar.
    157     uint8_t* mConversionBuffer;
    158 
    159     // Initializes input and output OMX ports with sensible
    160     // default values.
    161     void initPorts();
    162 
    163     // Initializes vpx encoder with available settings.
    164     status_t initEncoder();
    165 
    166     // Releases vpx encoder instance, with it's associated
    167     // data structures.
    168     //
    169     // Unless called earlier, this is handled by the
    170     // dtor.
    171     status_t releaseEncoder();
    172 
    173     // Handles port changes with respect to color formats
    174     OMX_ERRORTYPE internalSetFormatParams(
    175         const OMX_VIDEO_PARAM_PORTFORMATTYPE* format);
    176 
    177     // Verifies the component role tried to be set to this OMX component is
    178     // strictly video_encoder.vpx
    179     OMX_ERRORTYPE internalSetRoleParams(
    180         const OMX_PARAM_COMPONENTROLETYPE* role);
    181 
    182     // Updates bitrate to reflect port settings.
    183     OMX_ERRORTYPE internalSetBitrateParams(
    184         const OMX_VIDEO_PARAM_BITRATETYPE* bitrate);
    185 
    186     // Handles port definition changes.
    187     OMX_ERRORTYPE internalSetPortParams(
    188         const OMX_PARAM_PORTDEFINITIONTYPE* port);
    189 
    190     // Handles vp8 specific parameters.
    191     OMX_ERRORTYPE internalSetVp8Params(
    192         const OMX_VIDEO_PARAM_VP8TYPE* vp8Params);
    193 
    194     // Updates encoder profile
    195     OMX_ERRORTYPE internalSetProfileLevel(
    196         const OMX_VIDEO_PARAM_PROFILELEVELTYPE* profileAndLevel);
    197 
    198     DISALLOW_EVIL_CONSTRUCTORS(SoftVPXEncoder);
    199 };
    200 
    201 }  // namespace android
    202 
    203 #endif  // SOFT_VPX_ENCODER_H_
    204