Merge "refactor AudioTrack and AudioFlinger createTrack()"
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 629d75a..1793877 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -471,10 +471,6 @@
* Otherwise will always be present.</p>
* <p>The maximum number of regions supported by the device is determined by the value
* of android.control.maxRegionsAe.</p>
- * <p>The data representation is int[5 * area_count].
- * Every five elements represent a metering region of (xmin, ymin, xmax, ymax, weight).
- * The rectangle is defined to be inclusive on xmin and ymin, but exclusive on xmax and
- * ymax.</p>
* <p>The coordinate system is based on the active pixel array,
* with (0,0) being the top-left pixel in the active pixel array, and
* (ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE.width - 1,
@@ -495,6 +491,10 @@
* region and output only the intersection rectangle as the metering region in the result
* metadata. If the region is entirely outside the crop region, it will be ignored and
* not reported in the result metadata.</p>
+ * <p>The data representation is <code>int[5 * area_count]</code>.
+ * Every five elements represent a metering region of <code>(xmin, ymin, xmax, ymax, weight)</code>.
+ * The rectangle is defined to be inclusive on xmin and ymin, but exclusive on xmax and
+ * ymax.</p>
*
* @see ACAMERA_SCALER_CROP_REGION
* @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -633,10 +633,6 @@
* Otherwise will always be present.</p>
* <p>The maximum number of focus areas supported by the device is determined by the value
* of android.control.maxRegionsAf.</p>
- * <p>The data representation is int[5 * area_count].
- * Every five elements represent a metering region of (xmin, ymin, xmax, ymax, weight).
- * The rectangle is defined to be inclusive on xmin and ymin, but exclusive on xmax and
- * ymax.</p>
* <p>The coordinate system is based on the active pixel array,
* with (0,0) being the top-left pixel in the active pixel array, and
* (ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE.width - 1,
@@ -657,6 +653,10 @@
* region and output only the intersection rectangle as the metering region in the result
* metadata. If the region is entirely outside the crop region, it will be ignored and
* not reported in the result metadata.</p>
+ * <p>The data representation is <code>int[5 * area_count]</code>.
+ * Every five elements represent a metering region of <code>(xmin, ymin, xmax, ymax, weight)</code>.
+ * The rectangle is defined to be inclusive on xmin and ymin, but exclusive on xmax and
+ * ymax.</p>
*
* @see ACAMERA_SCALER_CROP_REGION
* @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -791,10 +791,6 @@
* Otherwise will always be present.</p>
* <p>The maximum number of regions supported by the device is determined by the value
* of android.control.maxRegionsAwb.</p>
- * <p>The data representation is int[5 * area_count].
- * Every five elements represent a metering region of (xmin, ymin, xmax, ymax, weight).
- * The rectangle is defined to be inclusive on xmin and ymin, but exclusive on xmax and
- * ymax.</p>
* <p>The coordinate system is based on the active pixel array,
* with (0,0) being the top-left pixel in the active pixel array, and
* (ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE.width - 1,
@@ -815,6 +811,10 @@
* region and output only the intersection rectangle as the metering region in the result
* metadata. If the region is entirely outside the crop region, it will be ignored and
* not reported in the result metadata.</p>
+ * <p>The data representation is <code>int[5 * area_count]</code>.
+ * Every five elements represent a metering region of <code>(xmin, ymin, xmax, ymax, weight)</code>.
+ * The rectangle is defined to be inclusive on xmin and ymin, but exclusive on xmax and
+ * ymax.</p>
*
* @see ACAMERA_SCALER_CROP_REGION
* @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -885,11 +885,10 @@
* <p>When set to AUTO, the individual algorithm controls in
* ACAMERA_CONTROL_* are in effect, such as ACAMERA_CONTROL_AF_MODE.</p>
* <p>When set to USE_SCENE_MODE, the individual controls in
- * ACAMERA_CONTROL_* are mostly disabled, and the camera device implements
- * one of the scene mode settings (such as ACTION, SUNSET, or PARTY)
- * as it wishes. The camera device scene mode 3A settings are provided by
- * capture results {@link ACameraMetadata} from
- * {@link ACameraCaptureSession_captureCallback_result}.</p>
+ * ACAMERA_CONTROL_* are mostly disabled, and the camera device
+ * implements one of the scene mode settings (such as ACTION,
+ * SUNSET, or PARTY) as it wishes. The camera device scene mode
+ * 3A settings are provided by {@link ACameraCaptureSession_captureCallback_result capture results}.</p>
* <p>When set to OFF_KEEP_STATE, it is similar to OFF mode, the only difference
* is that this frame will not be used by camera device background 3A statistics
* update, as if this frame is never captured. This mode can be used in the scenario
@@ -1043,20 +1042,18 @@
* <p>For constant-framerate recording, for each normal
* <a href="https://developer.android.com/reference/android/media/CamcorderProfile.html">CamcorderProfile</a>, that is, a
* <a href="https://developer.android.com/reference/android/media/CamcorderProfile.html">CamcorderProfile</a> that has
- * <a href="https://developer.android.com/reference/android/media/CamcorderProfile.html#quality">quality</a>
- * in the range [
- * <a href="https://developer.android.com/reference/android/media/CamcorderProfile.html#QUALITY_LOW">QUALITY_LOW</a>,
- * <a href="https://developer.android.com/reference/android/media/CamcorderProfile.html#QUALITY_2160P">QUALITY_2160P</a>],
- * if the profile is supported by the device and has
- * <a href="https://developer.android.com/reference/android/media/CamcorderProfile.html#videoFrameRate">videoFrameRate</a>
- * <code>x</code>, this list will always include (<code>x</code>,<code>x</code>).</p>
+ * <a href="https://developer.android.com/reference/android/media/CamcorderProfile.html#quality">quality</a> in
+ * the range [<a href="https://developer.android.com/reference/android/media/CamcorderProfile.html#QUALITY_LOW">QUALITY_LOW</a>,
+ * <a href="https://developer.android.com/reference/android/media/CamcorderProfile.html#QUALITY_2160P">QUALITY_2160P</a>], if the profile is
+ * supported by the device and has
+ * <a href="https://developer.android.com/reference/android/media/CamcorderProfile.html#videoFrameRate">videoFrameRate</a> <code>x</code>, this list will
+ * always include (<code>x</code>,<code>x</code>).</p>
* </li>
* <li>
* <p>Also, a camera device must either not support any
* <a href="https://developer.android.com/reference/android/media/CamcorderProfile.html">CamcorderProfile</a>,
* or support at least one
- * normal <a href="https://developer.android.com/reference/android/media/CamcorderProfile.html">CamcorderProfile</a>
- * that has
+ * normal <a href="https://developer.android.com/reference/android/media/CamcorderProfile.html">CamcorderProfile</a> that has
* <a href="https://developer.android.com/reference/android/media/CamcorderProfile.html#videoFrameRate">videoFrameRate</a> <code>x</code> >= 24.</p>
* </li>
* </ul>
@@ -1619,13 +1616,13 @@
* compared to previous regular requests. enableZsl does not affect requests with other
* capture intents.</p>
* <p>For example, when requests are submitted in the following order:
- * Request A: enableZsl is <code>true</code>, ACAMERA_CONTROL_CAPTURE_INTENT is PREVIEW
- * Request B: enableZsl is <code>true</code>, ACAMERA_CONTROL_CAPTURE_INTENT is STILL_CAPTURE</p>
+ * Request A: enableZsl is ON, ACAMERA_CONTROL_CAPTURE_INTENT is PREVIEW
+ * Request B: enableZsl is ON, ACAMERA_CONTROL_CAPTURE_INTENT is STILL_CAPTURE</p>
* <p>The output images for request B may have contents captured before the output images for
* request A, and the result metadata for request B may be older than the result metadata for
* request A.</p>
- * <p>Note that when enableZsl is <code>true</code>, it is not guaranteed to get output images captured in the
- * past for requests with STILL_CAPTURE capture intent.</p>
+ * <p>Note that when enableZsl is <code>true</code>, it is not guaranteed to get output images captured in
+ * the past for requests with STILL_CAPTURE capture intent.</p>
* <p>For applications targeting SDK versions O and newer, the value of enableZsl in
* TEMPLATE_STILL_CAPTURE template may be <code>true</code>. The value in other templates is always
* <code>false</code> if present.</p>
@@ -1959,14 +1956,14 @@
* <p>When an ACAMERA_JPEG_ORIENTATION of non-zero degree is requested,
* the camera device will handle thumbnail rotation in one of the following ways:</p>
* <ul>
- * <li>Set the
- * <a href="https://developer.android.com/reference/android/media/ExifInterface.html#TAG_ORIENTATION">EXIF orientation flag</a>
+ * <li>Set the <a href="https://developer.android.com/reference/android/media/ExifInterface.html#TAG_ORIENTATION">EXIF orientation flag</a>
* and keep jpeg and thumbnail image data unrotated.</li>
* <li>Rotate the jpeg and thumbnail image data and not set
- * <a href="https://developer.android.com/reference/android/media/ExifInterface.html#TAG_ORIENTATION">EXIF orientation flag</a>.
- * In this case, LIMITED or FULL hardware level devices will report rotated thumnail size
- * in capture result, so the width and height will be interchanged if 90 or 270 degree
- * orientation is requested. LEGACY device will always report unrotated thumbnail size.</li>
+ * <a href="https://developer.android.com/reference/android/media/ExifInterface.html#TAG_ORIENTATION">EXIF orientation flag</a>. In this
+ * case, LIMITED or FULL hardware level devices will report rotated thumnail size in
+ * capture result, so the width and height will be interchanged if 90 or 270 degree
+ * orientation is requested. LEGACY device will always report unrotated thumbnail
+ * size.</li>
* </ul>
*
* @see ACAMERA_JPEG_ORIENTATION
@@ -2218,9 +2215,8 @@
* <p>The position of the camera device's lens optical center,
* as a three-dimensional vector <code>(x,y,z)</code>, relative to the
* optical center of the largest camera device facing in the
- * same direction as this camera, in the
- * <a href="https://developer.android.com/reference/android/hardware/SensorEvent.html">Android sensor coordinate axes</a>.
- * Note that only the axis definitions are shared with
+ * same direction as this camera, in the <a href="https://developer.android.com/reference/android/hardware/SensorEvent.html">Android sensor coordinate
+ * axes</a>. Note that only the axis definitions are shared with
* the sensor coordinate system, but not the origin.</p>
* <p>If this device is the largest or only camera device with a
* given facing, then this position will be <code>(0, 0, 0)</code>; a
@@ -2662,11 +2658,12 @@
* into the 3 stream types as below:</p>
* <ul>
* <li>Processed (but stalling): any non-RAW format with a stallDurations > 0.
- * Typically {@link AIMAGE_FORMAT_JPEG} format.</li>
- * <li>Raw formats: {@link AIMAGE_FORMAT_RAW16}, {@link AIMAGE_FORMAT_RAW10}, or
- * {@link AIMAGE_FORMAT_RAW12}.</li>
- * <li>Processed (but not-stalling): any non-RAW format without a stall duration.
- * Typically {@link AIMAGE_FORMAT_YUV_420_888}.</li>
+ * Typically {@link AIMAGE_FORMAT_JPEG JPEG format}.</li>
+ * <li>Raw formats: {@link AIMAGE_FORMAT_RAW16 RAW_SENSOR}, {@link AIMAGE_FORMAT_RAW10 RAW10}, or
+ * {@link AIMAGE_FORMAT_RAW12 RAW12}.</li>
+ * <li>Processed (but not-stalling): any non-RAW format without a stall duration. Typically
+ * {@link AIMAGE_FORMAT_YUV_420_888 YUV_420_888},
+ * <a href="https://developer.android.com/reference/android/graphics/ImageFormat.html#NV21">NV21</a>, or <a href="https://developer.android.com/reference/android/graphics/ImageFormat.html#YV12">YV12</a>.</li>
* </ul>
*
* @see ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
@@ -2787,7 +2784,7 @@
ACAMERA_REQUEST_START + 12,
/**
* <p>A list of all keys that the camera device has available
- * to use with {@link ACaptureRequest}.</p>
+ * to use with {@link ACaptureRequest }.</p>
*
* <p>Type: int32[n]</p>
*
@@ -2809,9 +2806,7 @@
ACAMERA_REQUEST_AVAILABLE_REQUEST_KEYS = // int32[n]
ACAMERA_REQUEST_START + 13,
/**
- * <p>A list of all keys that the camera device has available
- * to query with {@link ACameraMetadata} from
- * {@link ACameraCaptureSession_captureCallback_result}.</p>
+ * <p>A list of all keys that the camera device has available to use with {@link ACameraCaptureSession_captureCallback_result }.</p>
*
* <p>Type: int32[n]</p>
*
@@ -2842,9 +2837,7 @@
ACAMERA_REQUEST_AVAILABLE_RESULT_KEYS = // int32[n]
ACAMERA_REQUEST_START + 14,
/**
- * <p>A list of all keys that the camera device has available
- * to query with {@link ACameraMetadata} from
- * {@link ACameraManager_getCameraCharacteristics}.</p>
+ * <p>A list of all keys that the camera device has available to use with {@link ACameraManager_getCameraCharacteristics }.</p>
*
* <p>Type: int32[n]</p>
*
@@ -2876,7 +2869,6 @@
* </ul></p>
*
* <p>This control can be used to implement digital zoom.</p>
- * <p>The data representation is int[4], which maps to (left, top, width, height).</p>
* <p>The crop region coordinate system is based off
* ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE, with <code>(0, 0)</code> being the
* top-left corner of the sensor active array.</p>
@@ -2906,6 +2898,7 @@
* for rounding and other hardware requirements; the final
* crop region used will be included in the output capture
* result.</p>
+ * <p>The data representation is int[4], which maps to (left, top, width, height).</p>
*
* @see ACAMERA_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
* @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -3061,13 +3054,14 @@
* ignored).</p>
* <p>The following formats may always have a stall duration:</p>
* <ul>
- * <li>{@link AIMAGE_FORMAT_JPEG}</li>
- * <li>{@link AIMAGE_FORMAT_RAW16}</li>
+ * <li>{@link AIMAGE_FORMAT_JPEG }</li>
+ * <li>{@link AIMAGE_FORMAT_RAW16 }</li>
* </ul>
* <p>The following formats will never have a stall duration:</p>
* <ul>
- * <li>{@link AIMAGE_FORMAT_YUV_420_888}</li>
- * <li>{@link AIMAGE_FORMAT_RAW10}</li>
+ * <li>{@link AIMAGE_FORMAT_YUV_420_888 }</li>
+ * <li>{@link AIMAGE_FORMAT_RAW10 }</li>
+ * <li>{@link AIMAGE_FORMAT_RAW12 }</li>
* </ul>
* <p>All other formats may or may not have an allowed stall duration on
* a per-capability basis; refer to ACAMERA_REQUEST_AVAILABLE_CAPABILITIES
@@ -3177,39 +3171,29 @@
* can run concurrently to the rest of the camera pipeline, but
* cannot process more than 1 capture at a time.</li>
* </ul>
- * <p>The necessary information for the application, given the model above,
- * is provided via
- * {@link ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS}.
- * These are used to determine the maximum frame rate / minimum frame
- * duration that is possible for a given stream configuration.</p>
+ * <p>The necessary information for the application, given the model above, is provided via
+ * {@link ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS }.
+ * These are used to determine the maximum frame rate / minimum frame duration that is
+ * possible for a given stream configuration.</p>
* <p>Specifically, the application can use the following rules to
* determine the minimum frame duration it can request from the camera
* device:</p>
* <ol>
- * <li>Let the set of currently configured input/output streams
- * be called <code>S</code>.</li>
- * <li>Find the minimum frame durations for each stream in <code>S</code>, by looking
- * it up in {@link ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS}
- * (with its respective size/format). Let this set of frame durations be
- * called <code>F</code>.</li>
- * <li>For any given request <code>R</code>, the minimum frame duration allowed
- * for <code>R</code> is the maximum out of all values in <code>F</code>. Let the streams
- * used in <code>R</code> be called <code>S_r</code>.</li>
+ * <li>Let the set of currently configured input/output streams be called <code>S</code>.</li>
+ * <li>Find the minimum frame durations for each stream in <code>S</code>, by looking it up in {@link ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS }
+ * (with its respective size/format). Let this set of frame durations be called <code>F</code>.</li>
+ * <li>For any given request <code>R</code>, the minimum frame duration allowed for <code>R</code> is the maximum
+ * out of all values in <code>F</code>. Let the streams used in <code>R</code> be called <code>S_r</code>.</li>
* </ol>
- * <p>If none of the streams in <code>S_r</code> have a stall time (listed in {@link
- * ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS}
- * using its respective size/format), then the frame duration in <code>F</code>
- * determines the steady state frame rate that the application will get
- * if it uses <code>R</code> as a repeating request. Let this special kind of
- * request be called <code>Rsimple</code>.</p>
- * <p>A repeating request <code>Rsimple</code> can be <em>occasionally</em> interleaved
- * by a single capture of a new request <code>Rstall</code> (which has at least
- * one in-use stream with a non-0 stall time) and if <code>Rstall</code> has the
- * same minimum frame duration this will not cause a frame rate loss
- * if all buffers from the previous <code>Rstall</code> have already been
- * delivered.</p>
- * <p>For more details about stalling, see
- * {@link ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS}.</p>
+ * <p>If none of the streams in <code>S_r</code> have a stall time (listed in {@link ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS }
+ * using its respective size/format), then the frame duration in <code>F</code> determines the steady
+ * state frame rate that the application will get if it uses <code>R</code> as a repeating request. Let
+ * this special kind of request be called <code>Rsimple</code>.</p>
+ * <p>A repeating request <code>Rsimple</code> can be <em>occasionally</em> interleaved by a single capture of a
+ * new request <code>Rstall</code> (which has at least one in-use stream with a non-0 stall time) and if
+ * <code>Rstall</code> has the same minimum frame duration this will not cause a frame rate loss if all
+ * buffers from the previous <code>Rstall</code> have already been delivered.</p>
+ * <p>For more details about stalling, see {@link ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS }.</p>
* <p>This control is only effective if ACAMERA_CONTROL_AE_MODE or ACAMERA_CONTROL_MODE is set to
* OFF; otherwise the auto-exposure algorithm will override this value.</p>
*
@@ -3567,14 +3551,12 @@
* timestamps for other captures from the same camera device, but are
* not guaranteed to be comparable to any other time source.</p>
* <p>When ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE <code>==</code> REALTIME, the
- * timestamps measure time in the same timebase as
- * <a href="https://developer.android.com/reference/android/os/SystemClock.html#elapsedRealtimeNanos">elapsedRealtimeNanos</a>
- * (or CLOCK_BOOTTIME), and they can
+ * timestamps measure time in the same timebase as <a href="https://developer.android.com/reference/android/os/SystemClock.html#elapsedRealtimeNanos">SystemClock#elapsedRealtimeNanos</a>, and they can
* be compared to other timestamps from other subsystems that
* are using that base.</p>
* <p>For reprocessing, the timestamp will match the start of exposure of
- * the input image, i.e. {@link CaptureResult#SENSOR_TIMESTAMP the
- * timestamp} in the TotalCaptureResult that was used to create the
+ * the input image, i.e. <a href="https://developer.android.com/reference/CaptureResult.html#SENSOR_TIMESTAMP">the
+ * timestamp</a> in the TotalCaptureResult that was used to create the
* reprocess capture request.</p>
*
* @see ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE
@@ -3775,7 +3757,6 @@
* optically shielded pixel areas. By blocking light, these pixels
* provides a reliable black reference for black level compensation
* in active array region.</p>
- * <p>The data representation is int[4], which maps to (left, top, width, height).</p>
* <p>This key provides a list of disjoint rectangles specifying the
* regions of optically shielded (with metal shield) black pixel
* regions if the camera device is capable of reading out these black
@@ -3785,6 +3766,7 @@
* black level of each captured raw images.</p>
* <p>When this key is reported, the ACAMERA_SENSOR_DYNAMIC_BLACK_LEVEL and
* ACAMERA_SENSOR_DYNAMIC_WHITE_LEVEL will also be reported.</p>
+ * <p>The data representation is <code>int[4]</code>, which maps to <code>(left, top, width, height)</code>.</p>
*
* @see ACAMERA_SENSOR_BLACK_LEVEL_PATTERN
* @see ACAMERA_SENSOR_DYNAMIC_BLACK_LEVEL
@@ -3825,9 +3807,8 @@
* layout key (see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT), i.e. the
* nth value given corresponds to the black level offset for the nth
* color channel listed in the CFA.</p>
- * <p>This key will be available if ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS is
- * available or the camera device advertises this key via
- * {@link ACAMERA_REQUEST_AVAILABLE_RESULT_KEYS}.</p>
+ * <p>This key will be available if ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS is available or the
+ * camera device advertises this key via {@link ACAMERA_REQUEST_AVAILABLE_RESULT_KEYS }.</p>
*
* @see ACAMERA_SENSOR_BLACK_LEVEL_PATTERN
* @see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
@@ -3853,7 +3834,7 @@
* estimated white level for each frame.</p>
* <p>This key will be available if ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS is
* available or the camera device advertises this key via
- * {@link ACAMERA_REQUEST_AVAILABLE_RESULT_KEYS}.</p>
+ * {@link ACAMERA_REQUEST_AVAILABLE_RESULT_KEYS }.</p>
*
* @see ACAMERA_SENSOR_BLACK_LEVEL_PATTERN
* @see ACAMERA_SENSOR_INFO_WHITE_LEVEL
@@ -3882,13 +3863,13 @@
* <p>This rectangle is defined relative to the full pixel array; (0,0) is the top-left of
* the full pixel array, and the size of the full pixel array is given by
* ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE.</p>
- * <p>The data representation is int[4], which maps to (left, top, width, height).</p>
* <p>The coordinate system for most other keys that list pixel coordinates, including
* ACAMERA_SCALER_CROP_REGION, is defined relative to the active array rectangle given in
* this field, with <code>(0, 0)</code> being the top-left of this rectangle.</p>
* <p>The active array may be smaller than the full pixel array, since the full array may
* include black calibration pixels or other inactive regions, and geometric correction
* resulting in scaling or cropping may have been applied.</p>
+ * <p>The data representation is <code>int[4]</code>, which maps to <code>(left, top, width, height)</code>.</p>
*
* @see ACAMERA_SCALER_CROP_REGION
* @see ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE
@@ -3960,8 +3941,7 @@
* <p>Attempting to use frame durations beyond the maximum will result in the frame
* duration being clipped to the maximum. See that control for a full definition of frame
* durations.</p>
- * <p>Refer to {@link
- * ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS}
+ * <p>Refer to {@link ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS }
* for the minimum frame duration values.</p>
*/
ACAMERA_SENSOR_INFO_MAX_FRAME_DURATION = // int64
@@ -4000,9 +3980,9 @@
* the raw buffers produced by this sensor.</p>
* <p>If a camera device supports raw sensor formats, either this or
* ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE is the maximum dimensions for the raw
- * output formats listed in ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS (this depends on
- * whether or not the image sensor returns buffers containing pixels that are not
- * part of the active array region for blacklevel calibration or other purposes).</p>
+ * output formats listed in {@link ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS }
+ * (this depends on whether or not the image sensor returns buffers containing pixels that
+ * are not part of the active array region for blacklevel calibration or other purposes).</p>
* <p>Some parts of the full pixel array may not receive light from the scene,
* or be otherwise inactive. The ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE key
* defines the rectangle of active pixels that will be included in processed image
@@ -4092,7 +4072,6 @@
* <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
* </ul></p>
*
- * <p>The data representation is int[4], which maps to (left, top, width, height).</p>
* <p>This is the rectangle representing the size of the active region of the sensor (i.e.
* the region that actually receives light from the scene) before any geometric correction
* has been applied, and should be treated as the active region rectangle for any of the
@@ -4143,6 +4122,7 @@
* ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE.</p>
* <p>The pre-correction active array may be smaller than the full pixel array, since the
* full array may include black calibration pixels or other inactive regions.</p>
+ * <p>The data representation is <code>int[4]</code>, which maps to <code>(left, top, width, height)</code>.</p>
*
* @see ACAMERA_LENS_RADIAL_DISTORTION
* @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -4302,10 +4282,10 @@
* <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
* </ul></p>
*
- * <p>The data representation is int[4], which maps to (left, top, width, height).</p>
* <p>The coordinate system is that of ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE, with
* <code>(0, 0)</code> being the top-left pixel of the active array.</p>
- * <p>Only available if ACAMERA_STATISTICS_FACE_DETECT_MODE != OFF</p>
+ * <p>Only available if ACAMERA_STATISTICS_FACE_DETECT_MODE != OFF
+ * The data representation is <code>int[4]</code>, which maps to <code>(left, top, width, height)</code>.</p>
*
* @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
* @see ACAMERA_STATISTICS_FACE_DETECT_MODE
@@ -4832,7 +4812,7 @@
* <p>See the individual level enums for full descriptions of the supported capabilities. The
* ACAMERA_REQUEST_AVAILABLE_CAPABILITIES entry describes the device's capabilities at a
* finer-grain level, if needed. In addition, many controls have their available settings or
- * ranges defined in individual metadata tag entries in this document.</p>
+ * ranges defined in individual entries from {@link ACameraManager_getCameraCharacteristics }.</p>
* <p>Some features are not part of any particular hardware level or capability and must be
* queried separately. These include:</p>
* <ul>
@@ -6157,13 +6137,13 @@
ACAMERA_EDGE_MODE_HIGH_QUALITY = 2,
/**
- * <p>Edge enhancement is applied at different levels for different output streams,
- * based on resolution. Streams at maximum recording resolution (see {@link
- * ACameraDevice_createCaptureSession}) or below have
- * edge enhancement applied, while higher-resolution streams have no edge enhancement
- * applied. The level of edge enhancement for low-resolution streams is tuned so that
- * frame rate is not impacted, and the quality is equal to or better than FAST (since it
- * is only applied to lower-resolution outputs, quality may improve from FAST).</p>
+ * <p>Edge enhancement is applied at different
+ * levels for different output streams, based on resolution. Streams at maximum recording
+ * resolution (see {@link ACameraDevice_createCaptureSession })
+ * or below have edge enhancement applied, while higher-resolution streams have no edge
+ * enhancement applied. The level of edge enhancement for low-resolution streams is tuned
+ * so that frame rate is not impacted, and the quality is equal to or better than FAST
+ * (since it is only applied to lower-resolution outputs, quality may improve from FAST).</p>
* <p>This mode is intended to be used by applications operating in a zero-shutter-lag mode
* with YUV or PRIVATE reprocessing, where the application continuously captures
* high-resolution intermediate buffers into a circular buffer, from which a final image is
@@ -6412,13 +6392,12 @@
/**
* <p>Noise reduction is applied at different levels for different output streams,
- * based on resolution. Streams at maximum recording resolution (see {@link
- * ACameraDevice_createCaptureSession}) or below have noise
- * reduction applied, while higher-resolution streams have MINIMAL (if supported) or no
- * noise reduction applied (if MINIMAL is not supported.) The degree of noise reduction
- * for low-resolution streams is tuned so that frame rate is not impacted, and the quality
- * is equal to or better than FAST (since it is only applied to lower-resolution outputs,
- * quality may improve from FAST).</p>
+ * based on resolution. Streams at maximum recording resolution (see {@link ACameraDevice_createCaptureSession })
+ * or below have noise reduction applied, while higher-resolution streams have MINIMAL (if
+ * supported) or no noise reduction applied (if MINIMAL is not supported.) The degree of
+ * noise reduction for low-resolution streams is tuned so that frame rate is not impacted,
+ * and the quality is equal to or better than FAST (since it is only applied to
+ * lower-resolution outputs, quality may improve from FAST).</p>
* <p>This mode is intended to be used by applications operating in a zero-shutter-lag mode
* with YUV or PRIVATE reprocessing, where the application continuously captures
* high-resolution intermediate buffers into a circular buffer, from which a final image is
@@ -6635,18 +6614,16 @@
* to FAST. Additionally, maximum-resolution images can be captured at >= 10 frames
* per second. Here, 'high resolution' means at least 8 megapixels, or the maximum
* resolution of the device, whichever is smaller.</p>
- * <p>More specifically, this means that at least one output {@link
- * AIMAGE_FORMAT_YUV_420_888} size listed in
- * {@link ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS} is larger or equal to the
- * 'high resolution' defined above, and can be captured at at least 20 fps.
- * For the largest {@link AIMAGE_FORMAT_YUV_420_888} size listed in
- * {@link ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS}, camera device can capture this
- * size for at least 10 frames per second.
- * Also the ACAMERA_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES entry lists at least one FPS range
- * where the minimum FPS is >= 1 / minimumFrameDuration for the largest YUV_420_888 size.</p>
- * <p>If the device supports the {@link AIMAGE_FORMAT_RAW10}, {@link
- * AIMAGE_FORMAT_RAW12}, then those can also be captured at the same rate
- * as the maximum-size YUV_420_888 resolution is.</p>
+ * <p>More specifically, this means that at least one output {@link AIMAGE_FORMAT_YUV_420_888 } size listed in
+ * {@link ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS }
+ * is larger or equal to the 'high resolution' defined above, and can be captured at at
+ * least 20 fps. For the largest {@link AIMAGE_FORMAT_YUV_420_888 } size listed in
+ * {@link ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS },
+ * camera device can capture this size for at least 10 frames per second. Also the
+ * ACAMERA_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES entry lists at least one FPS range where
+ * the minimum FPS is >= 1 / minimumFrameDuration for the largest YUV_420_888 size.</p>
+ * <p>If the device supports the {@link AIMAGE_FORMAT_RAW10 }, {@link AIMAGE_FORMAT_RAW12 }, then those can also be
+ * captured at the same rate as the maximum-size YUV_420_888 resolution is.</p>
* <p>In addition, the ACAMERA_SYNC_MAX_LATENCY field is guaranted to have a value between 0
* and 4, inclusive. ACAMERA_CONTROL_AE_LOCK_AVAILABLE and ACAMERA_CONTROL_AWB_LOCK_AVAILABLE
* are also guaranteed to be <code>true</code> so burst capture with these two locks ON yields
@@ -6663,13 +6640,13 @@
* <p>The camera device can produce depth measurements from its field of view.</p>
* <p>This capability requires the camera device to support the following:</p>
* <ul>
- * <li>{@link AIMAGE_FORMAT_DEPTH16} is supported as an output format.</li>
- * <li>{@link AIMAGE_FORMAT_DEPTH_POINT_CLOUD} is optionally supported as an
- * output format.</li>
- * <li>This camera device, and all camera devices with the same ACAMERA_LENS_FACING,
- * will list the following calibration entries in {@link ACameraMetadata} from both
- * {@link ACameraManager_getCameraCharacteristics} and
- * {@link ACameraCaptureSession_captureCallback_result}:<ul>
+ * <li>{@link AIMAGE_FORMAT_DEPTH16 } is supported as
+ * an output format.</li>
+ * <li>{@link AIMAGE_FORMAT_DEPTH_POINT_CLOUD } is
+ * optionally supported as an output format.</li>
+ * <li>This camera device, and all camera devices with the same ACAMERA_LENS_FACING, will
+ * list the following calibration metadata entries in both {@link ACameraManager_getCameraCharacteristics }
+ * and {@link ACameraCaptureSession_captureCallback_result }:<ul>
* <li>ACAMERA_LENS_POSE_TRANSLATION</li>
* <li>ACAMERA_LENS_POSE_ROTATION</li>
* <li>ACAMERA_LENS_INTRINSIC_CALIBRATION</li>
@@ -6683,8 +6660,7 @@
* </ul>
* <p>Generally, depth output operates at a slower frame rate than standard color capture,
* so the DEPTH16 and DEPTH_POINT_CLOUD formats will commonly have a stall duration that
- * should be accounted for (see
- * {@link ACAMERA_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS}).
+ * should be accounted for (see {@link ACAMERA_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS }).
* On a device that supports both depth and color-based output, to enable smooth preview,
* using a repeating burst is recommended, where a depth-output target is only included
* once every N frames, where N is the ratio between preview output rate and depth output
@@ -6918,8 +6894,8 @@
/**
* <p>Timestamps from ACAMERA_SENSOR_TIMESTAMP are in the same timebase as
- * <a href="https://developer.android.com/reference/android/os/SystemClock.html#elapsedRealtimeNanos">elapsedRealtimeNanos</a>
- * (or CLOCK_BOOTTIME), and they can be compared to other timestamps using that base.</p>
+ * <a href="https://developer.android.com/reference/android/os/SystemClock.html#elapsedRealtimeNanos">SystemClock#elapsedRealtimeNanos</a>,
+ * and they can be compared to other timestamps using that base.</p>
*
* @see ACAMERA_SENSOR_TIMESTAMP
*/
@@ -7104,7 +7080,7 @@
* <p>This camera device does not have enough capabilities to qualify as a <code>FULL</code> device or
* better.</p>
* <p>Only the stream configurations listed in the <code>LEGACY</code> and <code>LIMITED</code> tables in the
- * {@link ACameraDevice_createCaptureSession} documentation are guaranteed to be supported.</p>
+ * {@link ACameraDevice_createCaptureSession createCaptureSession} documentation are guaranteed to be supported.</p>
* <p>All <code>LIMITED</code> devices support the <code>BACKWARDS_COMPATIBLE</code> capability, indicating basic
* support for color image capture. The only exception is that the device may
* alternatively support only the <code>DEPTH_OUTPUT</code> capability, if it can only output depth
@@ -7130,7 +7106,7 @@
/**
* <p>This camera device is capable of supporting advanced imaging applications.</p>
* <p>The stream configurations listed in the <code>FULL</code>, <code>LEGACY</code> and <code>LIMITED</code> tables in the
- * {@link ACameraDevice_createCaptureSession} documentation are guaranteed to be supported.</p>
+ * {@link ACameraDevice_createCaptureSession createCaptureSession} documentation are guaranteed to be supported.</p>
* <p>A <code>FULL</code> device will support below capabilities:</p>
* <ul>
* <li><code>BURST_CAPTURE</code> capability (ACAMERA_REQUEST_AVAILABLE_CAPABILITIES contains
@@ -7157,8 +7133,7 @@
/**
* <p>This camera device is running in backward compatibility mode.</p>
- * <p>Only the stream configurations listed in the <code>LEGACY</code> table in the {@link
- * ACameraDevice_createCaptureSession} documentation are supported.</p>
+ * <p>Only the stream configurations listed in the <code>LEGACY</code> table in the {@link ACameraDevice_createCaptureSession createCaptureSession} documentation are supported.</p>
* <p>A <code>LEGACY</code> device does not support per-frame control, manual sensor control, manual
* post-processing, arbitrary cropping regions, and has relaxed performance constraints.
* No additional capabilities beyond <code>BACKWARD_COMPATIBLE</code> will ever be listed by a
@@ -7179,9 +7154,7 @@
* <p>This camera device is capable of YUV reprocessing and RAW data capture, in addition to
* FULL-level capabilities.</p>
* <p>The stream configurations listed in the <code>LEVEL_3</code>, <code>RAW</code>, <code>FULL</code>, <code>LEGACY</code> and
- * <code>LIMITED</code> tables in the {@link
- * ACameraDevice_createCaptureSession}
- * documentation are guaranteed to be supported.</p>
+ * <code>LIMITED</code> tables in the {@link ACameraDevice_createCaptureSession createCaptureSession} documentation are guaranteed to be supported.</p>
* <p>The following additional capabilities are guaranteed to be supported:</p>
* <ul>
* <li><code>YUV_REPROCESSING</code> capability (ACAMERA_REQUEST_AVAILABLE_CAPABILITIES contains
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 283bcb4..c62833d 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -7,9 +7,6 @@
jpeg.cpp \
SineSource.cpp
-LOCAL_HEADER_LIBRARIES := \
- media_plugin_headers \
-
LOCAL_SHARED_LIBRARIES := \
libstagefright libmedia libmedia_omx libmediaextractor libutils libbinder \
libstagefright_foundation libjpeg libui libgui libcutils liblog \
@@ -17,6 +14,9 @@
android.hardware.media.omx@1.0 \
LOCAL_C_INCLUDES:= \
+ frameworks/av/media/libstagefright \
+ frameworks/av/media/libstagefright/include \
+ frameworks/native/include/media/openmax \
external/jpeg \
LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
@@ -35,13 +35,15 @@
SineSource.cpp \
record.cpp
-LOCAL_HEADER_LIBRARIES := \
- media_plugin_headers \
-
LOCAL_SHARED_LIBRARIES := \
libstagefright libmedia libmediaextractor liblog libutils libbinder \
libstagefright_foundation
+LOCAL_C_INCLUDES:= \
+ frameworks/av/media/libstagefright \
+ frameworks/native/include/media/openmax \
+ frameworks/native/include/media/hardware
+
LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
LOCAL_MODULE_TAGS := optional
@@ -58,13 +60,15 @@
SineSource.cpp \
recordvideo.cpp
-LOCAL_HEADER_LIBRARIES := \
- media_plugin_headers \
-
LOCAL_SHARED_LIBRARIES := \
libstagefright libmedia libmediaextractor liblog libutils libbinder \
libstagefright_foundation
+LOCAL_C_INCLUDES:= \
+ frameworks/av/media/libstagefright \
+ frameworks/native/include/media/openmax \
+ frameworks/native/include/media/hardware
+
LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
LOCAL_MODULE_TAGS := optional
@@ -82,13 +86,14 @@
SineSource.cpp \
audioloop.cpp
-LOCAL_HEADER_LIBRARIES := \
- media_plugin_headers \
-
LOCAL_SHARED_LIBRARIES := \
libstagefright libmedia libmediaextractor liblog libutils libbinder \
libstagefright_foundation
+LOCAL_C_INCLUDES:= \
+ frameworks/av/media/libstagefright \
+ frameworks/native/include/media/openmax
+
LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
LOCAL_MODULE_TAGS := optional
@@ -104,13 +109,14 @@
LOCAL_SRC_FILES:= \
stream.cpp \
-LOCAL_HEADER_LIBRARIES := \
- media_plugin_headers \
-
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libui libgui \
libstagefright_foundation libmedia libcutils
+LOCAL_C_INCLUDES:= \
+ frameworks/av/media/libstagefright \
+ frameworks/native/include/media/openmax
+
LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
LOCAL_MODULE_TAGS := optional
@@ -127,13 +133,14 @@
codec.cpp \
SimplePlayer.cpp \
-LOCAL_HEADER_LIBRARIES := \
- media_plugin_headers \
-
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libstagefright_foundation \
libmedia libmedia_omx libaudioclient libui libgui libcutils
+LOCAL_C_INCLUDES:= \
+ frameworks/av/media/libstagefright \
+ frameworks/native/include/media/openmax
+
LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
LOCAL_MODULE_TAGS := optional
@@ -152,9 +159,6 @@
filters/saturation.rs \
mediafilter.cpp \
-LOCAL_HEADER_LIBRARIES := \
- media_plugin_headers \
-
LOCAL_SHARED_LIBRARIES := \
libstagefright \
liblog \
@@ -168,9 +172,14 @@
libcutils \
libRScpp \
+LOCAL_C_INCLUDES:= \
+ frameworks/av/media/libstagefright \
+ frameworks/native/include/media/openmax \
+ frameworks/rs/cpp \
+ frameworks/rs \
+
intermediates := $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,)
LOCAL_C_INCLUDES += $(intermediates)
-LOCAL_C_INCLUDES += frameworks/av/media/libstagefright/filters
LOCAL_STATIC_LIBRARIES:= \
libstagefright_mediafilter
@@ -193,13 +202,14 @@
LOCAL_SRC_FILES:= \
muxer.cpp \
-LOCAL_HEADER_LIBRARIES := \
- media_plugin_headers \
-
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libstagefright_foundation \
libcutils libc
+LOCAL_C_INCLUDES:= \
+ frameworks/av/media/libstagefright \
+ frameworks/native/include/media/openmax
+
LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
LOCAL_MODULE_TAGS := optional
diff --git a/cmds/stagefright/mediafilter.cpp b/cmds/stagefright/mediafilter.cpp
index c90a2e4..f24d2dd 100644
--- a/cmds/stagefright/mediafilter.cpp
+++ b/cmds/stagefright/mediafilter.cpp
@@ -20,7 +20,7 @@
#include <inttypes.h>
#include <binder/ProcessState.h>
-#include <ColorConvert.h>
+#include <filters/ColorConvert.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/Surface.h>
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index f873ba5..ddc4b16 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -41,7 +41,7 @@
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/AUtils.h>
-#include <NuCachedSource2.h>
+#include "include/NuCachedSource2.h"
#include <media/stagefright/AudioPlayer.h>
#include <media/stagefright/DataSourceFactory.h>
#include <media/stagefright/JPEGSource.h>
diff --git a/media/audioserver/Android.mk b/media/audioserver/Android.mk
index 0777890..ee87751 100644
--- a/media/audioserver/Android.mk
+++ b/media/audioserver/Android.mk
@@ -13,11 +13,12 @@
libbinder \
libcutils \
liblog \
+ libhidltransport \
+ libhwbinder \
libmedialogservice \
libnbaio \
libsoundtriggerservice \
- libutils \
- libhwbinder
+ libutils
# TODO oboeservice is the old folder name for aaudioservice. It will be changed.
LOCAL_C_INCLUDES := \
diff --git a/media/audioserver/main_audioserver.cpp b/media/audioserver/main_audioserver.cpp
index 474ef97..5a9d1bb 100644
--- a/media/audioserver/main_audioserver.cpp
+++ b/media/audioserver/main_audioserver.cpp
@@ -25,12 +25,9 @@
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
+#include <hidl/HidlTransportSupport.h>
#include <utils/Log.h>
-// FIXME: remove when BUG 31748996 is fixed
-#include <hwbinder/IPCThreadState.h>
-#include <hwbinder/ProcessState.h>
-
// from LOCAL_C_INCLUDES
#include "aaudio/AAudioTesting.h"
#include "AudioFlinger.h"
@@ -128,6 +125,7 @@
prctl(PR_SET_PDEATHSIG, SIGKILL); // if parent media.log dies before me, kill me also
setpgid(0, 0); // but if I die first, don't kill my parent
}
+ android::hardware::configureRpcThreadpool(4, false /*callerWillJoin*/);
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
@@ -145,10 +143,6 @@
SoundTriggerHwService::instantiate();
ProcessState::self()->startThreadPool();
-
-// FIXME: remove when BUG 31748996 is fixed
- android::hardware::ProcessState::self()->startThreadPool();
-
IPCThreadState::self()->joinThreadPool();
}
}
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index 1cf2c72..8d7a01e 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -219,8 +219,7 @@
// Data conversion.
float levelFrom;
float levelTo;
- bool ramping = mVolumeRamp.nextSegment(framesToWrite * getSamplesPerFrame(),
- &levelFrom, &levelTo);
+ bool ramping = mVolumeRamp.nextSegment(framesToWrite, &levelFrom, &levelTo);
// The formats are validated when the stream is opened so we do not have to
// check for illegal combinations here.
// TODO factor this out into a utility function
diff --git a/media/libaaudio/src/utility/LinearRamp.h b/media/libaaudio/src/utility/LinearRamp.h
index ff09dce..2b1b8e0 100644
--- a/media/libaaudio/src/utility/LinearRamp.h
+++ b/media/libaaudio/src/utility/LinearRamp.h
@@ -87,7 +87,7 @@
std::atomic<float> mTarget;
- int32_t mLengthInFrames = 48000 / 50; // 20 msec at 48000 Hz
+ int32_t mLengthInFrames = 48000 / 100; // 10 msec at 48000 Hz
int32_t mRemaining = 0;
float mLevelFrom = 0.0f;
float mLevelTo = 0.0f;
diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
index fa1d253..cfb5be6 100644
--- a/media/libaudioclient/ToneGenerator.cpp
+++ b/media/libaudioclient/ToneGenerator.cpp
@@ -811,6 +811,20 @@
{ .duration = 0 , .waveFreq = { 0 }, 0, 0}},
.repeatCnt = ToneGenerator::TONEGEN_INF,
.repeatSegment = 0 }, // TONE_HK_RINGTONE
+ { .segments = { { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 },
+ { .duration = 200, .waveFreq = { 0 }, 0, 0 },
+ { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 },
+ { .duration = 2000, .waveFreq = { 0 }, 0, 0},
+ { .duration = 0, .waveFreq = { 0 }, 0, 0}},
+ .repeatCnt = ToneGenerator::TONEGEN_INF,
+ .repeatSegment = 0 }, // TONE_IE_RINGTONE
+ { .segments = { { .duration = 180, .waveFreq = { 425, 0 }, 0, 0 },
+ { .duration = 200, .waveFreq = { 0 }, 0, 0 },
+ { .duration = 200, .waveFreq = { 425, 0 }, 0, 0 },
+ { .duration = 4500, .waveFreq = { 0 }, 0, 0 },
+ { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
+ .repeatCnt = ToneGenerator::TONEGEN_INF,
+ .repeatSegment = 0 }, // TONE_IE_CALL_WAITING
};
// Used by ToneGenerator::getToneForRegion() to convert user specified supervisory tone type
@@ -875,6 +889,16 @@
TONE_SUP_ERROR, // TONE_SUP_ERROR
TONE_SUP_CALL_WAITING, // TONE_SUP_CALL_WAITING
TONE_HK_RINGTONE // TONE_SUP_RINGTONE
+ },
+ { // IRELAND
+ TONE_SUP_DIAL, // TONE_SUP_DIAL
+ TONE_SUP_BUSY, // TONE_SUP_BUSY
+ TONE_SUP_CONGESTION, // TONE_SUP_CONGESTION
+ TONE_SUP_RADIO_ACK, // TONE_SUP_RADIO_ACK
+ TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL
+ TONE_SUP_ERROR, // TONE_SUP_ERROR
+ TONE_IE_CALL_WAITING, // TONE_SUP_CALL_WAITING
+ TONE_IE_RINGTONE // TONE_SUP_RINGTONE
}
};
@@ -944,6 +968,8 @@
mRegion = SINGAPORE;
} else if (strstr(value, "hk") != NULL) {
mRegion = HONGKONG;
+ } else if (strstr(value, "ie") != NULL) {
+ mRegion = IRELAND;
} else {
mRegion = CEPT;
}
diff --git a/media/libaudioclient/include/media/ToneGenerator.h b/media/libaudioclient/include/media/ToneGenerator.h
index 97bc825..247703f 100644
--- a/media/libaudioclient/include/media/ToneGenerator.h
+++ b/media/libaudioclient/include/media/ToneGenerator.h
@@ -209,6 +209,9 @@
// HONG KONG Supervisory tones
TONE_HK_BUSY, // Busy tone: 480 Hz + 620 Hz, 500ms ON, 500ms OFF...
TONE_HK_RINGTONE, // Ring Tone: 440 Hz + 480 Hz repeated with pattern 0,4s on, 0,2s off, 0,4s on and 3s off.
+ // IRELAND Supervisory tones
+ TONE_IE_RINGTONE, // Ring Tone: A 400Hz + 450Hz tone repeated in a 0.4s on, 0.2s off, 0.4s on, 2.0s off pattern.
+ TONE_IE_CALL_WAITING, // Call waiting tone: 425Hz tone repeated in a 0.18s on, 0.2s off, 0.2s on, 4.5s off pattern.
NUM_ALTERNATE_TONES
};
@@ -219,6 +222,7 @@
AUSTRALIA,
SINGAPORE,
HONGKONG,
+ IRELAND,
CEPT,
NUM_REGIONS
};
diff --git a/media/libaudiohal/DevicesFactoryHalHidl.cpp b/media/libaudiohal/DevicesFactoryHalHidl.cpp
index 31da263..5b33592 100644
--- a/media/libaudiohal/DevicesFactoryHalHidl.cpp
+++ b/media/libaudiohal/DevicesFactoryHalHidl.cpp
@@ -43,6 +43,9 @@
ALOGE("Failed to obtain IDevicesFactory service, terminating process.");
exit(1);
}
+ // The MSD factory is optional
+ mDevicesFactoryMsd = IDevicesFactory::getService(AUDIO_HAL_SERVICE_NAME_MSD);
+ // TODO: Register death handler, and add 'restart' directive to audioserver.rc
}
DevicesFactoryHalHidl::~DevicesFactoryHalHidl() {
diff --git a/media/libaudiohal/DevicesFactoryHalHidl.h b/media/libaudiohal/DevicesFactoryHalHidl.h
index e2f1ad1..0748849 100644
--- a/media/libaudiohal/DevicesFactoryHalHidl.h
+++ b/media/libaudiohal/DevicesFactoryHalHidl.h
@@ -39,6 +39,7 @@
friend class DevicesFactoryHalHybrid;
sp<IDevicesFactory> mDevicesFactory;
+ sp<IDevicesFactory> mDevicesFactoryMsd;
static status_t nameFromHal(const char *name, IDevicesFactory::Device *device);
diff --git a/media/libaudiohal/HalDeathHandlerHidl.cpp b/media/libaudiohal/HalDeathHandlerHidl.cpp
index a742671..1e3ab58 100644
--- a/media/libaudiohal/HalDeathHandlerHidl.cpp
+++ b/media/libaudiohal/HalDeathHandlerHidl.cpp
@@ -48,12 +48,13 @@
void HalDeathHandler::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
// No matter which of the service objects has died,
- // we need to run all the registered handlers and crash our process.
+ // we need to run all the registered handlers and exit.
std::lock_guard<std::mutex> guard(mHandlersLock);
for (const auto& handler : mHandlers) {
handler.second();
}
- LOG_ALWAYS_FATAL("HAL server crashed, need to restart");
+ ALOGE("HAL server crashed, audio server is restarting");
+ exit(1);
}
} // namespace android
diff --git a/media/libaudioprocessing/AudioMixer.cpp b/media/libaudioprocessing/AudioMixer.cpp
index 238925d..3e72c89 100644
--- a/media/libaudioprocessing/AudioMixer.cpp
+++ b/media/libaudioprocessing/AudioMixer.cpp
@@ -813,7 +813,7 @@
mMixerInFormat, sampleRate, playbackRate);
reconfigureBufferProviders();
} else {
- reinterpret_cast<TimestretchBufferProvider*>(mTimestretchBufferProvider)
+ static_cast<TimestretchBufferProvider*>(mTimestretchBufferProvider)
->setPlaybackRate(playbackRate);
}
return true;
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 98a47c4..495c418 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1622,6 +1622,7 @@
mFlags(AUDIO_OUTPUT_FLAG_NONE),
mVolumeHandler(new media::VolumeHandler()),
mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
+ mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE),
mDeviceCallbackEnabled(false),
mDeviceCallback(deviceCallback)
{
@@ -2368,10 +2369,10 @@
ALOGV("getRoutedDeviceId");
Mutex::Autolock lock(mLock);
if (mTrack != 0) {
- *deviceId = mTrack->getRoutedDeviceId();
- return NO_ERROR;
+ mRoutedDeviceId = mTrack->getRoutedDeviceId();
}
- return NO_INIT;
+ *deviceId = mRoutedDeviceId;
+ return NO_ERROR;
}
status_t MediaPlayerService::AudioOutput::enableAudioDeviceCallback(bool enabled)
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 71e87a0..eefdd7d 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -176,6 +176,7 @@
audio_output_flags_t mFlags;
sp<media::VolumeHandler> mVolumeHandler;
audio_port_handle_t mSelectedDeviceId;
+ audio_port_handle_t mRoutedDeviceId;
bool mDeviceCallbackEnabled;
wp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
mutable Mutex mLock;
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index c3127ae..a3f4efb 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -677,6 +677,12 @@
break;
}
+ case kWhatSeek:
+ {
+ onSeek(msg);
+ break;
+ }
+
case kWhatReadBuffer:
{
onReadBuffer(msg);
@@ -1097,8 +1103,39 @@
}
status_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs, MediaPlayerSeekMode mode) {
- Mutex::Autolock _l(mLock);
ALOGV("seekTo: %lld, %d", (long long)seekTimeUs, mode);
+ sp<AMessage> msg = new AMessage(kWhatSeek, this);
+ msg->setInt64("seekTimeUs", seekTimeUs);
+ msg->setInt32("mode", mode);
+
+ // Need to call readBuffer on |mLooper| to ensure the calls to
+ // IMediaSource::read* are serialized. Note that IMediaSource::read*
+ // is called without |mLock| acquired and MediaSource is not thread safe.
+ sp<AMessage> response;
+ status_t err = msg->postAndAwaitResponse(&response);
+ if (err == OK && response != NULL) {
+ CHECK(response->findInt32("err", &err));
+ }
+
+ return err;
+}
+
+void NuPlayer::GenericSource::onSeek(const sp<AMessage>& msg) {
+ int64_t seekTimeUs;
+ int32_t mode;
+ CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
+ CHECK(msg->findInt32("mode", &mode));
+
+ sp<AMessage> response = new AMessage;
+ status_t err = doSeek(seekTimeUs, (MediaPlayerSeekMode)mode);
+ response->setInt32("err", err);
+
+ sp<AReplyToken> replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+ response->postReply(replyID);
+}
+
+status_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs, MediaPlayerSeekMode mode) {
if (mVideoTrack.mSource != NULL) {
++mVideoDataGeneration;
@@ -1321,13 +1358,14 @@
Vector<MediaBuffer *> mediaBuffers;
status_t err = NO_ERROR;
+ sp<IMediaSource> source = track->mSource;
mLock.unlock();
if (couldReadMultiple) {
- err = track->mSource->readMultiple(
+ err = source->readMultiple(
&mediaBuffers, maxBuffers - numBuffers, &options);
} else {
MediaBuffer *mbuf = NULL;
- err = track->mSource->read(&mbuf, &options);
+ err = source->read(&mbuf, &options);
if (err == OK && mbuf != NULL) {
mediaBuffers.push_back(mbuf);
}
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index 16c0224..cb9c27f 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -112,6 +112,7 @@
kWhatSendTimedTextData,
kWhatChangeAVSource,
kWhatPollBuffering,
+ kWhatSeek,
kWhatReadBuffer,
kWhatStart,
kWhatResume,
@@ -183,6 +184,9 @@
void finishPrepareAsync();
status_t startSources();
+ void onSeek(const sp<AMessage>& msg);
+ status_t doSeek(int64_t seekTimeUs, MediaPlayerSeekMode mode);
+
void onPrepareAsync();
void fetchTextData(
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index a26d525..6c4b823 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -182,6 +182,7 @@
mAudioDecoderGeneration(0),
mVideoDecoderGeneration(0),
mRendererGeneration(0),
+ mLastStartedPlayingTimeNs(0),
mPreviousSeekTimeUs(0),
mAudioEOS(false),
mVideoEOS(false),
@@ -1309,6 +1310,7 @@
ALOGV("kWhatReset");
mResetting = true;
+ stopPlaybackTimer("kWhatReset");
mDeferredActions.push_back(
new FlushDecoderAction(
@@ -1449,7 +1451,7 @@
ALOGW("resume called when renderer is gone or not set");
}
- mLastStartedPlayingTimeNs = systemTime();
+ startPlaybackTimer("onresume");
}
status_t NuPlayer::onInstantiateSecureDecoders() {
@@ -1569,12 +1571,43 @@
mAudioDecoder->setRenderer(mRenderer);
}
- mLastStartedPlayingTimeNs = systemTime();
+ startPlaybackTimer("onstart");
postScanSources();
}
+void NuPlayer::startPlaybackTimer(const char *where) {
+ Mutex::Autolock autoLock(mPlayingTimeLock);
+ if (mLastStartedPlayingTimeNs == 0) {
+ mLastStartedPlayingTimeNs = systemTime();
+ ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
+ }
+}
+
+void NuPlayer::stopPlaybackTimer(const char *where) {
+ Mutex::Autolock autoLock(mPlayingTimeLock);
+
+ ALOGV("stopPlaybackTimer() time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
+
+ if (mLastStartedPlayingTimeNs != 0) {
+ sp<NuPlayerDriver> driver = mDriver.promote();
+ if (driver != NULL) {
+ int64_t now = systemTime();
+ int64_t played = now - mLastStartedPlayingTimeNs;
+ ALOGV("stopPlaybackTimer() log %20" PRId64 "", played);
+
+ if (played > 0) {
+ driver->notifyMorePlayingTimeUs((played+500)/1000);
+ }
+ }
+ mLastStartedPlayingTimeNs = 0;
+ }
+}
+
void NuPlayer::onPause() {
+
+ stopPlaybackTimer("onPause");
+
if (mPaused) {
return;
}
@@ -1590,13 +1623,6 @@
ALOGW("pause called when renderer is gone or not set");
}
- sp<NuPlayerDriver> driver = mDriver.promote();
- if (driver != NULL) {
- int64_t now = systemTime();
- int64_t played = now - mLastStartedPlayingTimeNs;
-
- driver->notifyMorePlayingTimeUs((played+500)/1000);
- }
}
bool NuPlayer::audioDecoderStillNeeded() {
@@ -2223,6 +2249,8 @@
CHECK(mAudioDecoder == NULL);
CHECK(mVideoDecoder == NULL);
+ stopPlaybackTimer("performReset");
+
cancelPollDuration();
++mScanSourcesGeneration;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 747dc47..492b8d4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -178,7 +178,10 @@
int32_t mVideoDecoderGeneration;
int32_t mRendererGeneration;
+ Mutex mPlayingTimeLock;
int64_t mLastStartedPlayingTimeNs;
+ void stopPlaybackTimer(const char *where);
+ void startPlaybackTimer(const char *where);
int64_t mPreviousSeekTimeUs;
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 7ba4b7d..0c71487 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -100,8 +100,10 @@
"libui",
"libutils",
"libmedia_helper",
- "libstagefright_omx_utils",
"libstagefright_foundation",
+ "libstagefright_omx",
+ "libstagefright_omx_utils",
+ "libstagefright_xmlparser",
"libdl",
"libRScpp",
"libhidlbase",
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index cd07262..9375de1 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -36,6 +36,10 @@
OMXClient::OMXClient() {
}
+status_t OMXClient::connect() {
+ return connect("default");
+}
+
status_t OMXClient::connect(const char* name) {
using namespace ::android::hardware::media::omx::V1_0;
if (name == nullptr) {
diff --git a/media/libstagefright/OmxInfoBuilder.cpp b/media/libstagefright/OmxInfoBuilder.cpp
index c174371..a6ebadd 100644
--- a/media/libstagefright/OmxInfoBuilder.cpp
+++ b/media/libstagefright/OmxInfoBuilder.cpp
@@ -35,6 +35,7 @@
#include <media/IOMX.h>
#include <media/omx/1.0/WOmx.h>
+#include <media/stagefright/omx/1.0/OmxStore.h>
#include <media/openmax/OMX_Index.h>
#include <media/openmax/OMX_IndexExt.h>
@@ -89,8 +90,6 @@
}
status_t OmxInfoBuilder::buildMediaCodecList(MediaCodecListWriter* writer) {
- hidl_vec<IOmxStore::RoleInfo> roles;
-
// Obtain IOmxStore
sp<IOmxStore> omxStore = IOmxStore::getService();
if (omxStore == nullptr) {
@@ -100,8 +99,37 @@
// List service attributes (global settings)
Status status;
+ hidl_vec<IOmxStore::RoleInfo> roles;
+ auto transStatus = omxStore->listRoles(
+ [&roles] (
+ const hidl_vec<IOmxStore::RoleInfo>& inRoleList) {
+ roles = inRoleList;
+ });
+ if (!transStatus.isOk()) {
+ ALOGE("Fail to obtain codec roles from IOmxStore.");
+ return NO_INIT;
+ } else if (roles.size() == 0) {
+ ALOGW("IOmxStore has empty implementation. "
+ "Creating a local default instance...");
+ omxStore = new implementation::OmxStore();
+ if (omxStore == nullptr) {
+ ALOGE("Cannot create a local default instance.");
+ return NO_INIT;
+ }
+ ALOGI("IOmxStore local default instance created.");
+ transStatus = omxStore->listRoles(
+ [&roles] (
+ const hidl_vec<IOmxStore::RoleInfo>& inRoleList) {
+ roles = inRoleList;
+ });
+ if (!transStatus.isOk()) {
+ ALOGE("Fail to obtain codec roles from local IOmxStore.");
+ return NO_INIT;
+ }
+ }
+
hidl_vec<IOmxStore::ServiceAttribute> serviceAttributes;
- auto transStatus = omxStore->listServiceAttributes(
+ transStatus = omxStore->listServiceAttributes(
[&status, &serviceAttributes] (
Status inStatus,
const hidl_vec<IOmxStore::ServiceAttribute>& inAttributes) {
@@ -121,16 +149,6 @@
p.key.c_str(), p.value.c_str());
}
- transStatus = omxStore->listRoles(
- [&roles] (
- const hidl_vec<IOmxStore::RoleInfo>& inRoleList) {
- roles = inRoleList;
- });
- if (!transStatus.isOk()) {
- ALOGE("Fail to obtain codec roles from IOmxStore.");
- return NO_INIT;
- }
-
// Convert roles to lists of codecs
// codec name -> index into swCodecs/hwCodecs
diff --git a/media/libstagefright/codec2/Android.bp b/media/libstagefright/codec2/Android.bp
index f79e058..311a20b 100644
--- a/media/libstagefright/codec2/Android.bp
+++ b/media/libstagefright/codec2/Android.bp
@@ -17,9 +17,9 @@
"unsigned-integer-overflow",
"signed-integer-overflow",
],
- cfi: true,
+ cfi: false, // true,
diag: {
- cfi: true,
+ cfi: false, // true,
},
},
diff --git a/media/libstagefright/codec2/include/C2.h b/media/libstagefright/codec2/include/C2.h
index 7d00a03..bd563ff 100644
--- a/media/libstagefright/codec2/include/C2.h
+++ b/media/libstagefright/codec2/include/C2.h
@@ -66,8 +66,8 @@
* mitigate binary breaks by adhering to the following conventions:
*
* - at most one vtable with placeholder virtual methods
- * - all optional/placeholder virtual methods returning a status_t, with C2_NOT_IMPLEMENTED not
- * requiring any update to input/output arguments.
+ * - all optional/placeholder virtual methods returning a C2Status, with C2_OMITTED not requiring
+ * any update to input/output arguments.
* - limiting symbol export of inline methods
* - use of pimpl (or shared-pimpl)
*
@@ -98,49 +98,62 @@
* C2String: basic string implementation
*/
typedef std::string C2String;
+
+/**
+ * C2StringLiteral: basic string literal implementation.
+ * \note these are never owned by any object, and can only refer to C string literals.
+ */
typedef const char *C2StringLiteral;
/**
- * C2Error: status codes used.
+ * C2Status: status codes used.
*/
-typedef int32_t C2Error;
-enum {
+enum C2Status : int32_t {
+
+/*
+ * Use android status constants if available. Otherwise, define the android status constants as
+ * additional enum values using POSIX errno constants.
+ */
#ifndef __ANDROID__
- OK = 0,
+ ALREADY_EXISTS = -EEXIST,
BAD_VALUE = -EINVAL,
BAD_INDEX = -EOVERFLOW,
- UNKNOWN_TRANSACTION = -EBADMSG,
- ALREADY_EXISTS = -EEXIST,
- NAME_NOT_FOUND = -ENOENT,
+ FAILED_TRANSACTION = -ENOTSUP,
INVALID_OPERATION = -ENOSYS,
+ NAME_NOT_FOUND = -ENOENT,
NO_MEMORY = -ENOMEM,
+ NO_INIT = -ENODEV,
+ OK = 0,
PERMISSION_DENIED = -EPERM,
TIMED_OUT = -ETIMEDOUT,
- UNKNOWN_ERROR = -EINVAL,
+ UNKNOWN_ERROR = -EFAULT,
+ UNKNOWN_TRANSACTION = -EBADMSG,
#endif
- C2_OK = OK, ///< operation completed successfully
+ C2_OK = OK, ///< operation completed successfully
// bad input
- C2_BAD_VALUE = BAD_VALUE, ///< argument has invalid value (user error)
- C2_BAD_INDEX = BAD_INDEX, ///< argument uses invalid index (user error)
- C2_UNSUPPORTED = UNKNOWN_TRANSACTION, ///< argument/index is value but not supported \todo is this really BAD_INDEX/VALUE?
+ C2_BAD_VALUE = BAD_VALUE, ///< argument has invalid value (user error)
+ C2_BAD_INDEX = BAD_INDEX, ///< argument uses invalid index (user error)
+ C2_CANNOT_DO = FAILED_TRANSACTION, ///< argument/index is valid but not possible
// bad sequencing of events
- C2_DUPLICATE = ALREADY_EXISTS, ///< object already exists
- C2_NOT_FOUND = NAME_NOT_FOUND, ///< object not found
- C2_BAD_STATE = INVALID_OPERATION, ///< operation is not permitted in the current state
+ C2_DUPLICATE = ALREADY_EXISTS, ///< object already exists
+ C2_NOT_FOUND = NAME_NOT_FOUND, ///< object not found
+ C2_BAD_STATE = INVALID_OPERATION, ///< operation is not permitted in the current state
// bad environment
- C2_NO_MEMORY = NO_MEMORY, ///< not enough memory to complete operation
- C2_NO_PERMISSION = PERMISSION_DENIED, ///< missing permission to complete operation
- C2_TIMED_OUT = TIMED_OUT, ///< operation did not complete within timeout
+ C2_NO_MEMORY = NO_MEMORY, ///< not enough memory to complete operation
+ C2_REFUSED = PERMISSION_DENIED, ///< missing permission to complete operation
+
+ C2_TIMED_OUT = TIMED_OUT, ///< operation did not complete within timeout
// bad versioning
- C2_NOT_IMPLEMENTED = UNKNOWN_TRANSACTION, ///< operation is not implemented (optional only) \todo for now reuse error code
+ C2_OMITTED = UNKNOWN_TRANSACTION, ///< operation is not implemented/supported (optional only)
// unknown fatal
- C2_CORRUPTED = UNKNOWN_ERROR, ///< some unexpected error prevented the operation
+ C2_CORRUPTED = UNKNOWN_ERROR, ///< some unexpected error prevented the operation
+ C2_NO_INIT = NO_INIT, ///< status has not been initialized
};
/// @}
diff --git a/media/libstagefright/codec2/include/C2Buffer.h b/media/libstagefright/codec2/include/C2Buffer.h
index 9580449..22e4360 100644
--- a/media/libstagefright/codec2/include/C2Buffer.h
+++ b/media/libstagefright/codec2/include/C2Buffer.h
@@ -88,10 +88,10 @@
* \retval C2_TIMED_OUT the fence has not been signaled within the timeout
* \retval C2_BAD_STATE the fence has been abandoned without being signaled (it will never
* be signaled)
- * \retval C2_NO_PERMISSION no permission to wait for the fence (unexpected - system)
+ * \retval C2_REFUSED no permission to wait for the fence (unexpected - system)
* \retval C2_CORRUPTED some unknown error prevented waiting for the fence (unexpected)
*/
- C2Error wait(nsecs_t timeoutNs);
+ C2Status wait(nsecs_t timeoutNs);
/**
* Used to check if this fence is valid (if there is a chance for it to be signaled.)
@@ -155,10 +155,10 @@
* \retval C2_OK the fence(s) were successfully signaled
* \retval C2_BAD_STATE the fence(s) have already been abandoned or merged (caller error)
* \retval C2_DUPLICATE the fence(s) have already been signaled (caller error)
- * \retval C2_NO_PERMISSION no permission to signal the fence (unexpected - system)
+ * \retval C2_REFUSED no permission to signal the fence (unexpected - system)
* \retval C2_CORRUPTED some unknown error prevented signaling the fence(s) (unexpected)
*/
- C2Error fire();
+ C2Status fire();
/**
* Trigger this event from the merging of the supplied fences. This means that it will be
@@ -169,10 +169,10 @@
* \retval C2_NO_MEMORY not enough memory to perform the merging
* \retval C2_DUPLICATE the fence have already been merged (caller error)
* \retval C2_BAD_STATE the fence have already been signaled or abandoned (caller error)
- * \retval C2_NO_PERMISSION no permission to merge the fence (unexpected - system)
+ * \retval C2_REFUSED no permission to merge the fence (unexpected - system)
* \retval C2_CORRUPTED some unknown error prevented merging the fence(s) (unexpected)
*/
- C2Error merge(std::vector<C2Fence> fences);
+ C2Status merge(std::vector<C2Fence> fences);
/**
* Abandons the event and any associated fence(s).
@@ -183,10 +183,10 @@
* \retval C2_OK the fence(s) were successfully signaled
* \retval C2_BAD_STATE the fence(s) have already been signaled or merged (caller error)
* \retval C2_DUPLICATE the fence(s) have already been abandoned (caller error)
- * \retval C2_NO_PERMISSION no permission to abandon the fence (unexpected - system)
+ * \retval C2_REFUSED no permission to abandon the fence (unexpected - system)
* \retval C2_CORRUPTED some unknown error prevented signaling the fence(s) (unexpected)
*/
- C2Error abandon();
+ C2Status abandon();
private:
class Impl;
@@ -197,15 +197,15 @@
/// @{
/**
- * Interface for objects that encapsulate an updatable error value.
+ * Interface for objects that encapsulate an updatable status value.
*/
-struct _C2InnateError {
- inline C2Error error() const { return mError; }
+struct _C2InnateStatus {
+ inline C2Status status() const { return mStatus; }
protected:
- _C2InnateError(C2Error error) : mError(error) { }
+ _C2InnateStatus(C2Status status) : mStatus(status) { }
- C2Error mError; // this error is updatable by the object
+ C2Status mStatus; // this status is updatable by the object
};
/// @}
@@ -230,10 +230,10 @@
}
protected:
- C2Acquirable(C2Error error, C2Fence fence, T t) : C2Fence(fence), mInitialError(error), mT(t) { }
+ C2Acquirable(C2Status error, C2Fence fence, T t) : C2Fence(fence), mInitialError(error), mT(t) { }
private:
- C2Error mInitialError;
+ C2Status mInitialError;
T mT; // TODO: move instead of copy
};
@@ -449,11 +449,11 @@
/**
* \return error during the creation/mapping of this view.
*/
- C2Error error();
+ C2Status error() const;
protected:
C2ReadView(const _C2LinearCapacityAspect *parent, const uint8_t *data);
- explicit C2ReadView(C2Error error);
+ explicit C2ReadView(C2Status error);
private:
class Impl;
@@ -482,11 +482,11 @@
/**
* \return error during the creation/mapping of this view.
*/
- C2Error error();
+ C2Status error() const;
protected:
C2WriteView(const _C2LinearRangeAspect *parent, uint8_t *base);
- explicit C2WriteView(C2Error error);
+ explicit C2WriteView(C2Status error);
private:
class Impl;
@@ -631,7 +631,7 @@
* \retval C2_TIMED_OUT the reservation timed out \todo when?
* \retval C2_CORRUPTED some unknown error prevented reserving space. (unexpected)
*/
- C2Error reserve(size_t size, C2Fence *fence /* nullable */);
+ C2Status reserve(size_t size, C2Fence *fence /* nullable */);
/**
* Abandons a portion of this segment. This will move to the beginning of this segment.
@@ -644,7 +644,7 @@
* \retval C2_TIMED_OUT the operation timed out (unexpected)
* \retval C2_CORRUPTED some unknown error prevented abandoning the data (unexpected)
*/
- C2Error abandon(size_t size);
+ C2Status abandon(size_t size);
/**
* Share a portion as block(s) with consumers (these are moved to the used section).
@@ -661,7 +661,7 @@
* \retval C2_TIMED_OUT the operation timed out (unexpected)
* \retval C2_CORRUPTED some unknown error prevented sharing the data (unexpected)
*/
- C2Error share(size_t size, C2Fence fence, std::list<C2ConstLinearBlock> &blocks);
+ C2Status share(size_t size, C2Fence fence, std::list<C2ConstLinearBlock> &blocks);
/**
* Returns the beginning offset of this segment from the start of this circular block.
@@ -695,7 +695,7 @@
/**
* \return error during the creation/mapping of this view.
*/
- C2Error error();
+ C2Status error() const;
};
/**
@@ -716,7 +716,7 @@
* \param size number of bytes to commit to the next segment
* \param fence fence used for the commit (the fence must signal before the data is committed)
*/
- C2Error commit(size_t size, C2Fence fence);
+ C2Status commit(size_t size, C2Fence fence);
/**
* Maps this block into memory and returns a write view for it.
@@ -1016,14 +1016,14 @@
/**
* \return error during the creation/mapping of this view.
*/
- C2Error error() const;
+ C2Status error() const;
protected:
C2GraphicView(
const _C2PlanarCapacityAspect *parent,
uint8_t *const *data,
const C2PlaneLayout& layout);
- explicit C2GraphicView(C2Error error);
+ explicit C2GraphicView(C2Status error);
private:
class Impl;
@@ -1224,7 +1224,7 @@
* \retval C2_NO_MEMORY not enough memory to register for this callback
* \retval C2_CORRUPTED an unknown error prevented the registration (unexpected)
*/
- C2Error registerOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg = nullptr);
+ C2Status registerOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg = nullptr);
/**
* Unregisters a previously registered pre-destroy notification.
@@ -1236,7 +1236,7 @@
* \retval C2_NOT_FOUND the notification was not found
* \retval C2_CORRUPTED an unknown error prevented the registration (unexpected)
*/
- C2Error unregisterOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg = nullptr);
+ C2Status unregisterOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg = nullptr);
///@}
@@ -1262,7 +1262,7 @@
* \retval C2_NO_MEMORY not enough memory to attach the metadata (this return value is not
* used if the same kind of metadata is already attached to the buffer).
*/
- C2Error setInfo(const std::shared_ptr<C2Info> &info);
+ C2Status setInfo(const std::shared_ptr<C2Info> &info);
/**
* Checks if there is a certain type of metadata attached to this buffer.
@@ -1377,7 +1377,7 @@
* \todo Do we need to support sync operation as we could just wait for the fence?
*
* \retval C2_OK the operation was successful
- * \retval C2_NO_PERMISSION no permission to map the portion
+ * \retval C2_REFUSED no permission to map the portion
* \retval C2_TIMED_OUT the operation timed out
* \retval C2_DUPLICATE if the allocation is already mapped.
* \retval C2_NO_MEMORY not enough memory to complete the operation
@@ -1385,7 +1385,7 @@
* the usage flags are invalid (caller error)
* \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected)
*/
- virtual C2Error map(
+ virtual C2Status map(
size_t offset, size_t size, C2MemoryUsage usage, int *fenceFd /* nullable */,
void **addr /* nonnull */) = 0;
@@ -1407,9 +1407,9 @@
* \retval C2_BAD_VALUE the parameters (addr/size) do not correspond to previously mapped
* regions (caller error)
* \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected)
- * \retval C2_NO_PERMISSION no permission to unmap the portion (unexpected - system)
+ * \retval C2_REFUSED no permission to unmap the portion (unexpected - system)
*/
- virtual C2Error unmap(void *addr, size_t size, int *fenceFd /* nullable */) = 0;
+ virtual C2Status unmap(void *addr, size_t size, int *fenceFd /* nullable */) = 0;
/**
* Returns true if this is a valid allocation.
@@ -1463,7 +1463,7 @@
* \todo Do we need to support sync operation as we could just wait for the fence?
*
* \retval C2_OK the operation was successful
- * \retval C2_NO_PERMISSION no permission to map the section
+ * \retval C2_REFUSED no permission to map the section
* \retval C2_DUPLICATE there is already a mapped region (caller error)
* \retval C2_TIMED_OUT the operation timed out
* \retval C2_NO_MEMORY not enough memory to complete the operation
@@ -1472,7 +1472,7 @@
* \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected)
*/
- virtual C2Error map(
+ virtual C2Status map(
C2Rect rect, C2MemoryUsage usage, int *fenceFd,
// TODO: return <addr, size> buffers with plane sizes
C2PlaneLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) = 0;
@@ -1490,9 +1490,9 @@
* \retval C2_TIMED_OUT the operation timed out
* \retval C2_NOT_FOUND there is no mapped region (caller error)
* \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected)
- * \retval C2_NO_PERMISSION no permission to unmap the section (unexpected - system)
+ * \retval C2_REFUSED no permission to unmap the section (unexpected - system)
*/
- virtual C2Error unmap(C2Fence *fenceFd /* nullable */) = 0;
+ virtual C2Status unmap(C2Fence *fenceFd /* nullable */) = 0;
/**
* Returns true if this is a valid allocation.
@@ -1529,32 +1529,86 @@
class C2Allocator {
public:
/**
+ * Allocator ID type.
+ */
+ typedef uint32_t id_t;
+
+ /**
+ * Allocation types. This is a bitmask and is used in C2Allocator::Info
+ * to list the supported allocation types of an allocator.
+ */
+ enum type_t : uint32_t {
+ LINEAR = 1 << 0, //
+ GRAPHIC = 1 << 1,
+ };
+
+ /**
+ * Information about an allocator.
+ */
+ struct Info {
+ C2String name; ///< allocator name
+ id_t id; ///< allocator ID
+ type_t supportedTypes; ///< supported allocation types
+ C2MemoryUsage minimumUsage; ///< usage that is minimally required for allocations
+ C2MemoryUsage maximumUsage; ///< usage that is maximally allowed for allocations
+ };
+
+ /**
+ * Returns the unique name of this allocator.
+ *
+ * This method MUST be "non-blocking" and return within 1ms.
+ *
+ * \return the name of this allocator.
+ * \retval an empty string if there was not enough memory to allocate the actual name.
+ */
+ virtual C2String getName() const = 0;
+
+ /**
+ * Returns a unique ID for this allocator. This ID is used to get this allocator from the
+ * allocator store, and to identify this allocator across all processes.
+ *
+ * This method MUST be "non-blocking" and return within 1ms.
+ *
+ * \return a unique ID for this allocator.
+ */
+ virtual id_t getId() const = 0;
+
+ /**
+ * Returns the allocator information.
+ *
+ * This method MUST be "non-blocking" and return within 1ms.
+ *
+ * \return allocator information
+ */
+ virtual std::shared_ptr<const Info> getInfo() const = 0;
+
+ /**
* Allocates a 1D allocation of given |capacity| and |usage|. If successful, the allocation is
* stored in |allocation|. Otherwise, |allocation| is set to 'nullptr'.
*
- * \param capacity the size of requested allocation (the allocation could be slightly
+ * \param capacity the size of requested allocation (the allocation could be slightly
* larger, e.g. to account for any system-required alignment)
- * \param usage the memory usage info for the requested allocation. \note that the
+ * \param usage the memory usage info for the requested allocation. \note that the
* returned allocation may be later used/mapped with different usage.
* The allocator should layout the buffer to be optimized for this usage,
* but must support any usage. One exception: protected buffers can
* only be used in a protected scenario.
- * \param allocation pointer to where the allocation shall be stored on success. nullptr
+ * \param allocation pointer to where the allocation shall be stored on success. nullptr
* will be stored here on failure
*
* \retval C2_OK the allocation was successful
* \retval C2_NO_MEMORY not enough memory to complete the allocation
* \retval C2_TIMED_OUT the allocation timed out
- * \retval C2_NO_PERMISSION no permission to complete the allocation
+ * \retval C2_REFUSED no permission to complete the allocation
* \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
- * \retval C2_UNSUPPORTED this allocator does not support 1D allocations
+ * \retval C2_OMITTED this allocator does not support 1D allocations
* \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected)
*/
- virtual C2Error allocateLinearBuffer(
+ virtual C2Status newLinearAllocation(
uint32_t capacity __unused, C2MemoryUsage usage __unused,
std::shared_ptr<C2LinearAllocation> *allocation /* nonnull */) {
*allocation = nullptr;
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
/**
@@ -1563,55 +1617,55 @@
*
* \param handle the handle for the existing allocation
* \param allocation pointer to where the allocation shall be stored on success. nullptr
- * will be stored here on failure
+ * will be stored here on failure
*
* \retval C2_OK the allocation was recreated successfully
* \retval C2_NO_MEMORY not enough memory to recreate the allocation
* \retval C2_TIMED_OUT the recreation timed out (unexpected)
- * \retval C2_NO_PERMISSION no permission to recreate the allocation
+ * \retval C2_REFUSED no permission to recreate the allocation
* \retval C2_BAD_VALUE invalid handle (caller error)
- * \retval C2_UNSUPPORTED this allocator does not support 1D allocations
+ * \retval C2_OMITTED this allocator does not support 1D allocations
* \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected)
*/
- virtual C2Error recreateLinearBuffer(
+ virtual C2Status priorLinearAllocation(
const C2Handle *handle __unused,
std::shared_ptr<C2LinearAllocation> *allocation /* nonnull */) {
*allocation = nullptr;
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
/**
* Allocates a 2D allocation of given |width|, |height|, |format| and |usage|. If successful,
* the allocation is stored in |allocation|. Otherwise, |allocation| is set to 'nullptr'.
*
- * \param width the width of requested allocation (the allocation could be slightly
+ * \param width the width of requested allocation (the allocation could be slightly
* larger, e.g. to account for any system-required alignment)
- * \param height the height of requested allocation (the allocation could be slightly
+ * \param height the height of requested allocation (the allocation could be slightly
* larger, e.g. to account for any system-required alignment)
- * \param format the pixel format of requested allocation. This could be a vendor
+ * \param format the pixel format of requested allocation. This could be a vendor
* specific format.
- * \param usage the memory usage info for the requested allocation. \note that the
+ * \param usage the memory usage info for the requested allocation. \note that the
* returned allocation may be later used/mapped with different usage.
* The allocator should layout the buffer to be optimized for this usage,
* but must support any usage. One exception: protected buffers can
* only be used in a protected scenario.
- * \param allocation pointer to where the allocation shall be stored on success. nullptr
+ * \param allocation pointer to where the allocation shall be stored on success. nullptr
* will be stored here on failure
*
* \retval C2_OK the allocation was successful
* \retval C2_NO_MEMORY not enough memory to complete the allocation
* \retval C2_TIMED_OUT the allocation timed out
- * \retval C2_NO_PERMISSION no permission to complete the allocation
+ * \retval C2_REFUSED no permission to complete the allocation
* \retval C2_BAD_VALUE width, height, format or usage are not supported (invalid) (caller error)
- * \retval C2_UNSUPPORTED this allocator does not support 2D allocations
+ * \retval C2_OMITTED this allocator does not support 2D allocations
* \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected)
*/
- virtual C2Error allocateGraphicBuffer(
+ virtual C2Status newGraphicAllocation(
uint32_t width __unused, uint32_t height __unused, uint32_t format __unused,
C2MemoryUsage usage __unused,
std::shared_ptr<C2GraphicAllocation> *allocation /* nonnull */) {
*allocation = nullptr;
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
/**
@@ -1620,21 +1674,21 @@
*
* \param handle the handle for the existing allocation
* \param allocation pointer to where the allocation shall be stored on success. nullptr
- * will be stored here on failure
+ * will be stored here on failure
*
* \retval C2_OK the allocation was recreated successfully
* \retval C2_NO_MEMORY not enough memory to recreate the allocation
* \retval C2_TIMED_OUT the recreation timed out (unexpected)
- * \retval C2_NO_PERMISSION no permission to recreate the allocation
+ * \retval C2_REFUSED no permission to recreate the allocation
* \retval C2_BAD_VALUE invalid handle (caller error)
- * \retval C2_UNSUPPORTED this allocator does not support 2D allocations
+ * \retval C2_OMITTED this allocator does not support 2D allocations
* \retval C2_CORRUPTED some unknown, unrecoverable error occured during recreation (unexpected)
*/
- virtual C2Error recreateGraphicBuffer(
+ virtual C2Status priorGraphicAllocation(
const C2Handle *handle __unused,
std::shared_ptr<C2GraphicAllocation> *allocation /* nonnull */) {
*allocation = nullptr;
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
protected:
@@ -1644,110 +1698,143 @@
};
/**
- * Block allocators are used by components to allocate memory for output buffers. They can
- * support either linear (1D), circular (1D) or graphic (2D) allocations.
+ * Block pools are used by components to obtain output buffers in an efficient way. They can
+ * support either linear (1D), circular (1D) or graphic (2D) blocks.
+ *
+ * Block pools decouple the recycling of memory/allocations from the components. They are meant to
+ * be an opaque service (there are no public APIs other than obtaining blocks) provided by the
+ * platform. Block pools are also meant to decouple allocations from memory used by buffers. This
+ * is accomplished by allowing pools to allot multiple memory 'blocks' on a single allocation. As
+ * their name suggest, block pools maintain a pool of memory blocks. When a component asks for
+ * a memory block, pools will try to return a free memory block already in the pool. If no such
+ * block exists, they will allocate memory using the backing allocator and allot a block on that
+ * allocation. When blocks are no longer used in the system, they are recycled back to the block
+ * pool and are available as free blocks.
*
* Never constructed on stack.
- *
- * Block allocators are provided by the framework.
*/
-class C2BlockAllocator {
+class C2BlockPool {
public:
/**
- * Allocates a linear writeable block of given |capacity| and |usage|. If successful, the
+ * Block pool ID type.
+ */
+ typedef uint64_t local_id_t;
+
+ enum : local_id_t {
+ BASIC_LINEAR = 0, ///< ID of basic (unoptimized) block pool for fetching 1D blocks
+ BASIC_GRAPHIC = 1, ///< ID of basic (unoptimized) block pool for fetching 2D blocks
+ PLATFORM_START = 0x10,
+ };
+
+ /**
+ * Returns the ID for this block pool. This ID is used to get this block pool from the platform.
+ * It is only valid in the current process.
+ *
+ * This method MUST be "non-blocking" and return within 1ms.
+ *
+ * \return a local ID for this block pool.
+ */
+ virtual local_id_t getLocalId() const = 0;
+
+ /**
+ * Returns the ID of the backing allocator of this block pool.
+ *
+ * This method MUST be "non-blocking" and return within 1ms.
+ *
+ * \return the ID of the backing allocator of this block pool.
+ */
+ virtual C2Allocator::id_t getAllocatorId() const = 0;
+
+ /**
+ * Obtains a linear writeable block of given |capacity| and |usage|. If successful, the
* block is stored in |block|. Otherwise, |block| is set to 'nullptr'.
*
- * \param capacity the size of requested block.
- * \param usage the memory usage info for the requested allocation. \note that the
- * returned allocation may be later used/mapped with different usage.
- * The allocator shall lay out the buffer to be optimized for this usage,
- * but must support any usage. One exception: protected buffers can
- * only be used in a protected scenario.
- * \param block pointer to where the allocated block shall be stored on success. nullptr
- * will be stored here on failure
+ * \param capacity the size of requested block.
+ * \param usage the memory usage info for the requested block. Returned blocks will be
+ * optimized for this usage, but may be used with any usage. One exception:
+ * protected blocks/buffers can only be used in a protected scenario.
+ * \param block pointer to where the obtained block shall be stored on success. nullptr will
+ * be stored here on failure
*
- * \retval C2_OK the allocation was successful
- * \retval C2_NO_MEMORY not enough memory to complete the allocation
- * \retval C2_TIMED_OUT the allocation timed out
- * \retval C2_NO_PERMISSION no permission to complete the allocation
+ * \retval C2_OK the operation was successful
+ * \retval C2_NO_MEMORY not enough memory to complete any required allocation
+ * \retval C2_TIMED_OUT the operation timed out
+ * \retval C2_REFUSED no permission to complete any required allocation
* \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
- * \retval C2_UNSUPPORTED this allocator does not support linear allocations
- * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected)
+ * \retval C2_OMITTED this pool does not support linear blocks
+ * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected)
*/
- virtual C2Error allocateLinearBlock(
+ virtual C2Status fetchLinearBlock(
uint32_t capacity __unused, C2MemoryUsage usage __unused,
std::shared_ptr<C2LinearBlock> *block /* nonnull */) {
*block = nullptr;
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
/**
- * Allocates a circular writeable block of given |capacity| and |usage|. If successful, the
+ * Obtains a circular writeable block of given |capacity| and |usage|. If successful, the
* block is stored in |block|. Otherwise, |block| is set to 'nullptr'.
*
- * \param capacity the size of requested circular block. (the allocation could be slightly
- * larger, e.g. to account for any system-required alignment)
- * \param usage the memory usage info for the requested allocation. \note that the
- * returned allocation may be later used/mapped with different usage.
- * The allocator shall lay out the buffer to be optimized for this usage,
- * but must support any usage. One exception: protected buffers can
- * only be used in a protected scenario.
- * \param block pointer to where the allocated block shall be stored on success. nullptr
- * will be stored here on failure
+ * \param capacity the size of requested circular block. (note: the size of the obtained
+ * block could be slightly larger, e.g. to accommodate any system-required
+ * alignment)
+ * \param usage the memory usage info for the requested block. Returned blocks will be
+ * optimized for this usage, but may be used with any usage. One exception:
+ * protected blocks/buffers can only be used in a protected scenario.
+ * \param block pointer to where the obtained block shall be stored on success. nullptr
+ * will be stored here on failure
*
- * \retval C2_OK the allocation was successful
- * \retval C2_NO_MEMORY not enough memory to complete the allocation
- * \retval C2_TIMED_OUT the allocation timed out
- * \retval C2_NO_PERMISSION no permission to complete the allocation
- * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
- * \retval C2_UNSUPPORTED this allocator does not support circular allocations
- * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected)
+ * \retval C2_OK the operation was successful
+ * \retval C2_NO_MEMORY not enough memory to complete any required allocation
+ * \retval C2_TIMED_OUT the operation timed out
+ * \retval C2_REFUSED no permission to complete any required allocation
+ * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
+ * \retval C2_OMITTED this pool does not support circular blocks
+ * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected)
*/
- virtual C2Error allocateCircularBlock(
+ virtual C2Status fetchCircularBlock(
uint32_t capacity __unused, C2MemoryUsage usage __unused,
std::shared_ptr<C2CircularBlock> *block /* nonnull */) {
*block = nullptr;
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
/**
- * Allocates a 2D graphic block of given |width|, |height|, |format| and |usage|. If successful,
- * the allocation is stored in |block|. Otherwise, |block| is set to 'nullptr'.
+ * Obtains a 2D graphic block of given |width|, |height|, |format| and |usage|. If successful,
+ * the block is stored in |block|. Otherwise, |block| is set to 'nullptr'.
*
- * \param width the width of requested allocation (the allocation could be slightly
- * larger, e.g. to account for any system-required alignment)
- * \param height the height of requested allocation (the allocation could be slightly
- * larger, e.g. to account for any system-required alignment)
- * \param format the pixel format of requested allocation. This could be a vendor
- * specific format.
- * \param usage the memory usage info for the requested allocation. \note that the
- * returned allocation may be later used/mapped with different usage.
- * The allocator should layout the buffer to be optimized for this usage,
- * but must support any usage. One exception: protected buffers can
- * only be used in a protected scenario.
- * \param block pointer to where the allocation shall be stored on success. nullptr
- * will be stored here on failure
+ * \param width the width of requested block (the obtained block could be slightly larger, e.g.
+ * to accommodate any system-required alignment)
+ * \param height the height of requested block (the obtained block could be slightly larger,
+ * e.g. to accommodate any system-required alignment)
+ * \param format the pixel format of requested block. This could be a vendor specific format.
+ * \param usage the memory usage info for the requested block. Returned blocks will be
+ * optimized for this usage, but may be used with any usage. One exception:
+ * protected blocks/buffers can only be used in a protected scenario.
+ * \param block pointer to where the obtained block shall be stored on success. nullptr
+ * will be stored here on failure
*
- * \retval C2_OK the allocation was successful
- * \retval C2_NO_MEMORY not enough memory to complete the allocation
- * \retval C2_TIMED_OUT the allocation timed out
- * \retval C2_NO_PERMISSION no permission to complete the allocation
- * \retval C2_BAD_VALUE width, height, format or usage are not supported (invalid) (caller error)
- * \retval C2_UNSUPPORTED this allocator does not support 2D allocations
- * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected)
+ * \retval C2_OK the operation was successful
+ * \retval C2_NO_MEMORY not enough memory to complete any required allocation
+ * \retval C2_TIMED_OUT the operation timed out
+ * \retval C2_REFUSED no permission to complete any required allocation
+ * \retval C2_BAD_VALUE width, height, format or usage are not supported (invalid) (caller
+ * error)
+ * \retval C2_OMITTED this pool does not support 2D blocks
+ * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected)
*/
- virtual C2Error allocateGraphicBlock(
+ virtual C2Status fetchGraphicBlock(
uint32_t width __unused, uint32_t height __unused, uint32_t format __unused,
C2MemoryUsage usage __unused,
std::shared_ptr<C2GraphicBlock> *block /* nonnull */) {
*block = nullptr;
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
protected:
- C2BlockAllocator() = default;
+ C2BlockPool() = default;
- virtual ~C2BlockAllocator() = default;
+ virtual ~C2BlockPool() = default;
};
/// @}
diff --git a/media/libstagefright/codec2/include/C2Component.h b/media/libstagefright/codec2/include/C2Component.h
index a9b1702..c88de62 100644
--- a/media/libstagefright/codec2/include/C2Component.h
+++ b/media/libstagefright/codec2/include/C2Component.h
@@ -55,6 +55,31 @@
virtual ~C2ComponentListener() = default;
};
+struct C2FieldSupportedValuesQuery {
+ enum Type : uint32_t {
+ POSSIBLE, ///< query all possible values regardless of other settings
+ CURRENT, ///< query currently possible values given dependent settings
+ };
+
+ const C2ParamField field;
+ const Type type;
+ C2Status status;
+ C2FieldSupportedValues values;
+
+ C2FieldSupportedValuesQuery(const C2ParamField &field_, Type type_)
+ : field(field_), type(type_), status(C2_NO_INIT) { }
+
+ static C2FieldSupportedValuesQuery&&
+ Current(const C2ParamField &field_) {
+ return std::move(C2FieldSupportedValuesQuery(field_, CURRENT));
+ }
+
+ static C2FieldSupportedValuesQuery&&
+ Possible(const C2ParamField &field_) {
+ return std::move(C2FieldSupportedValuesQuery(field_, POSSIBLE));
+ }
+};
+
/**
* Component interface object. This object contains all of the configuration of a potential or
* actual component. It can be created and used independently of an actual C2Component instance to
@@ -129,7 +154,7 @@
* \retval C2_CORRUPTED some unknown error prevented the querying of the parameters
* (unexpected)
*/
- virtual status_t query_nb(
+ virtual C2Status query_nb(
const std::vector<C2Param* const> &stackParams,
const std::vector<C2Param::Index> &heapParamIndices,
std::vector<std::unique_ptr<C2Param>>* const heapParams) const = 0;
@@ -166,7 +191,7 @@
* \retval C2_CORRUPTED some unknown error prevented the update of the parameters
* (unexpected)
*/
- virtual status_t config_nb(
+ virtual C2Status config_nb(
const std::vector<C2Param* const> ¶ms,
std::vector<std::unique_ptr<C2SettingResult>>* const failures) = 0;
@@ -205,7 +230,7 @@
* \retval C2_CORRUPTED some unknown error prevented the update of the parameters
* (unexpected)
*/
- virtual status_t commit_sm(
+ virtual C2Status commit_sm(
const std::vector<C2Param* const> ¶ms,
std::vector<std::unique_ptr<C2SettingResult>>* const failures) = 0;
@@ -225,12 +250,13 @@
* \retval C2_OK the tunnel was successfully created
* \retval C2_BAD_INDEX the target component does not exist
* \retval C2_DUPLICATE the tunnel already exists
- * \retval C2_UNSUPPORTED the tunnel is not supported
+ * \retval C2_OMITTED tunneling is not supported by this component
+ * \retval C2_CANNOT_DO the specific tunnel is not supported
*
* \retval C2_TIMED_OUT could not create the tunnel within the time limit (unexpected)
* \retval C2_CORRUPTED some unknown error prevented the creation of the tunnel (unexpected)
*/
- virtual status_t createTunnel_sm(node_id targetComponent) = 0;
+ virtual C2Status createTunnel_sm(node_id targetComponent) = 0;
/**
* Releases a tunnel from this component to the target component.
@@ -246,11 +272,12 @@
* \retval C2_OK the tunnel was marked for release successfully
* \retval C2_BAD_INDEX the target component does not exist
* \retval C2_NOT_FOUND the tunnel does not exist
+ * \retval C2_OMITTED tunneling is not supported by this component
*
* \retval C2_TIMED_OUT could not mark the tunnel for release within the time limit (unexpected)
* \retval C2_CORRUPTED some unknown error prevented the release of the tunnel (unexpected)
*/
- virtual status_t releaseTunnel_sm(node_id targetComponent) = 0;
+ virtual C2Status releaseTunnel_sm(node_id targetComponent) = 0;
// REFLECTION MECHANISM (USED FOR EXTENSION)
@@ -273,7 +300,7 @@
* \retval C2_OK the operation completed successfully.
* \retval C2_NO_MEMORY not enough memory to complete this method.
*/
- virtual status_t getSupportedParams(
+ virtual C2Status getSupportedParams(
std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const = 0;
/**
@@ -281,9 +308,8 @@
* \todo should this take a list considering that setting some fields may further limit other
* fields in the same list?
*/
- virtual status_t getSupportedValues(
- const std::vector<const C2ParamField> &fields,
- std::vector<C2FieldSupportedValues>* const values) const = 0;
+ virtual C2Status getSupportedValues(
+ std::vector<C2FieldSupportedValuesQuery> &fields) const = 0;
virtual ~C2ComponentInterface() = default;
};
@@ -305,12 +331,12 @@
*
* \retval C2_OK the work was successfully queued
* \retval C2_BAD_INDEX some component(s) in the work do(es) not exist
- * \retval C2_UNSUPPORTED the components are not tunneled
+ * \retval C2_CANNOT_DO the components are not tunneled
*
* \retval C2_NO_MEMORY not enough memory to queue the work
* \retval C2_CORRUPTED some unknown error prevented queuing the work (unexpected)
*/
- virtual status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) = 0;
+ virtual C2Status queue_nb(std::list<std::unique_ptr<C2Work>>* const items) = 0;
/**
* Announces a work to be queued later for the component. This reserves a slot for the queue
@@ -322,14 +348,14 @@
*
* \retval C2_OK the work announcement has been successfully recorded
* \retval C2_BAD_INDEX some component(s) in the work outline do(es) not exist
- * \retval C2_UNSUPPORTED the componentes are not tunneled
+ * \retval C2_CANNOT_DO the componentes are not tunneled
*
* \retval C2_NO_MEMORY not enough memory to record the work announcement
* \retval C2_CORRUPTED some unknown error prevented recording the announcement (unexpected)
*
* \todo Can this be rolled into queue_nb?
*/
- virtual status_t announce_nb(const std::vector<C2WorkOutline> &items) = 0;
+ virtual C2Status announce_nb(const std::vector<C2WorkOutline> &items) = 0;
/**
* Discards and abandons any pending work for the component, and optionally any component
@@ -361,7 +387,7 @@
* \retval C2_TIMED_OUT the flush could not be completed within the time limit (unexpected)
* \retval C2_CORRUPTED some unknown error prevented flushing from completion (unexpected)
*/
- virtual status_t flush_sm(bool flushThrough, std::list<std::unique_ptr<C2Work>>* const flushedWork) = 0;
+ virtual C2Status flush_sm(bool flushThrough, std::list<std::unique_ptr<C2Work>>* const flushedWork) = 0;
/**
* Drains the component, and optionally downstream components
@@ -390,7 +416,7 @@
* \retval C2_TIMED_OUT the flush could not be completed within the time limit (unexpected)
* \retval C2_CORRUPTED some unknown error prevented flushing from completion (unexpected)
*/
- virtual status_t drain_nb(bool drainThrough) = 0;
+ virtual C2Status drain_nb(bool drainThrough) = 0;
// STATE CHANGE METHODS
// =============================================================================================
@@ -411,7 +437,7 @@
* \retval C2_TIMED_OUT the component could not be started within the time limit (unexpected)
* \retval C2_CORRUPTED some unknown error prevented starting the component (unexpected)
*/
- virtual status_t start() = 0;
+ virtual C2Status start() = 0;
/**
* Stops the component.
@@ -428,7 +454,7 @@
* This does not alter any settings and tunings that may have resulted in a tripped state.
* (Is this material given the definition? Perhaps in case we want to start again.)
*/
- virtual status_t stop() = 0;
+ virtual C2Status stop() = 0;
/**
* Resets the component.
@@ -502,9 +528,9 @@
* \retval C2_TIMED_OUT could not reset the parser within the time limit (unexpected)
* \retval C2_CORRUPTED some unknown error prevented the resetting of the parser (unexpected)
*/
- virtual status_t reset() { return C2_OK; }
+ virtual C2Status reset() { return C2_OK; }
- virtual status_t parseFrame(C2BufferPack &frame);
+ virtual C2Status parseFrame(C2BufferPack &frame);
virtual ~C2FrameInfoParser() = default;
};
@@ -516,11 +542,9 @@
class C2AllocatorStore {
public:
- // TBD
+ typedef C2Allocator::id_t id_t;
- typedef uint32_t ID;
-
- enum ID_ : uint32_t {
+ enum : C2Allocator::id_t {
DEFAULT_LINEAR, ///< basic linear allocator type
DEFAULT_GRAPHIC, ///< basic graphic allocator type
PLATFORM_START = 0x10,
@@ -528,7 +552,30 @@
};
/**
- * Creates an allocator.
+ * Returns the unique name of this allocator store.
+ *
+ * This method MUST be "non-blocking" and return within 1ms.
+ *
+ * \return the name of this allocator store.
+ * \retval an empty string if there was not enough memory to allocate the actual name.
+ */
+ virtual C2String getName() const = 0;
+
+ /**
+ * Returns the set of allocators supported by this allocator store.
+ *
+ * This method SHALL return within 1ms.
+ *
+ * \retval vector of allocator information (as shared pointers)
+ * \retval an empty vector if there was not enough memory to allocate the whole vector.
+ */
+ virtual std::vector<std::shared_ptr<const C2Allocator::Info>> listAllocators() const = 0;
+
+ /**
+ * Retrieves/creates a shared allocator object.
+ *
+ * The allocator is created on first use, and the same allocator is returned on subsequent
+ * concurrent uses in the same process. The allocator is freed when it is no longer referenced.
*
* \param id the ID of the allocator to create. This is defined by the store, but
* the ID of the default linear and graphic allocators is formalized.
@@ -542,7 +589,7 @@
* \retval C2_NOT_FOUND no such allocator
* \retval C2_NO_MEMORY not enough memory to create the allocator
*/
- virtual status_t createAllocator(ID id, std::shared_ptr<C2Allocator>* const allocator) = 0;
+ virtual C2Status getAllocator(id_t id, std::shared_ptr<C2Allocator>* const allocator) = 0;
virtual ~C2AllocatorStore() = default;
};
@@ -565,7 +612,7 @@
* \retval C2_NOT_FOUND no such component
* \retval C2_NO_MEMORY not enough memory to create the component
*/
- virtual status_t createComponent(C2String name, std::shared_ptr<C2Component>* const component);
+ virtual C2Status createComponent(C2String name, std::shared_ptr<C2Component>* const component);
/**
* Creates a component interface.
@@ -586,7 +633,7 @@
*
* \todo Do we need an interface, or could this just be a component that is never started?
*/
- virtual status_t createInterface(C2String name, std::shared_ptr<C2ComponentInterface>* const interface);
+ virtual C2Status createInterface(C2String name, std::shared_ptr<C2ComponentInterface>* const interface);
/**
* Returns the list of components supported by this component store.
@@ -600,9 +647,9 @@
// -------------------------------------- UTILITY METHODS --------------------------------------
// on-demand buffer layout conversion (swizzling)
- virtual status_t copyBuffer(std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst);
+ virtual C2Status copyBuffer(std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst);
- // status_t selectPreferredColor(formats<A>, formats<B>);
+ // C2Status selectPreferredColor(formats<A>, formats<B>);
// GLOBAL SETTINGS
// system-wide stride & slice-height (???)
@@ -636,7 +683,7 @@
* \retval C2_CORRUPTED some unknown error prevented the querying of the parameters
* (unexpected)
*/
- virtual status_t query_sm(
+ virtual C2Status query_sm(
const std::vector<C2Param* const> &stackParams,
const std::vector<C2Param::Index> &heapParamIndices,
std::vector<std::unique_ptr<C2Param>>* const heapParams) const = 0;
@@ -675,7 +722,7 @@
* \retval C2_CORRUPTED some unknown error prevented the update of the parameters
* (unexpected)
*/
- virtual status_t config_nb(
+ virtual C2Status config_nb(
const std::vector<C2Param* const> ¶ms,
std::list<std::unique_ptr<C2SettingResult>>* const failures) = 0;
diff --git a/media/libstagefright/codec2/include/C2Config.h b/media/libstagefright/codec2/include/C2Config.h
index d4294c4..0568432 100644
--- a/media/libstagefright/codec2/include/C2Config.h
+++ b/media/libstagefright/codec2/include/C2Config.h
@@ -61,13 +61,15 @@
kParamIndexMime,
kParamIndexStreamCount,
kParamIndexFormat,
+ kParamIndexBlockPools,
+
+ kParamIndexMaxVideoSizeHint,
+ kParamIndexVideoSizeTuning,
// video info
kParamIndexStructStart = 0x1,
kParamIndexVideoSize,
- kParamIndexMaxVideoSizeHint,
- kParamIndexVideoSizeTuning,
kParamIndexParamStart = 0x800,
};
@@ -125,6 +127,8 @@
typedef C2StreamParam<C2Tuning, C2Uint32Value, kParamIndexFormat> C2StreamFormatConfig;
+typedef C2PortParam<C2Tuning, C2Uint64Array, kParamIndexBlockPools> C2PortBlockPoolsTuning;
+
/*
Component description fields:
diff --git a/media/libstagefright/codec2/include/C2Param.h b/media/libstagefright/codec2/include/C2Param.h
index 02403c5..f0b92a3 100644
--- a/media/libstagefright/codec2/include/C2Param.h
+++ b/media/libstagefright/codec2/include/C2Param.h
@@ -344,6 +344,10 @@
/// returns the parameter type: the parameter index without the stream ID
inline uint32_t type() const { return _mIndex.type(); }
+ /// returns the index of this parameter
+ /// \todo: should we restrict this to C2ParamField?
+ inline uint32_t index() const { return (uint32_t)_mIndex; }
+
/// returns the kind of this parameter
inline Kind kind() const { return _mIndex.kind(); }
@@ -562,7 +566,6 @@
/**
* Constructor used to identify a field in an object.
*
- * \param U[type] pointer to the object that contains this field
* \param pm[im] member pointer to the field
*/
template<typename R, typename T, typename B=typename std::remove_extent<R>::type>
@@ -597,23 +600,93 @@
};
/**
- * Structure uniquely specifying a field in a configuration
+ * Structure uniquely specifying a 'field' in a configuration. The field
+ * can be a field of a configuration, a subfield of a field of a configuration,
+ * and even the whole configuration. Moreover, if the field can point to an
+ * element in a array field, or to the entire array field.
+ *
+ * This structure is used for querying supported values for a field, as well
+ * as communicating configuration failures and conflicts when trying to change
+ * a configuration for a component/interface or a store.
*/
struct C2ParamField {
//public:
- // TODO: fix what this is for T[] (for now size becomes T[1])
+ /**
+ * Create a field identifier using a configuration parameter (variable),
+ * and a pointer to member.
+ *
+ * ~~~~~~~~~~~~~ (.cpp)
+ *
+ * struct C2SomeParam {
+ * uint32_t mField;
+ * uint32_t mArray[2];
+ * C2OtherStruct mStruct;
+ * uint32_t mFlexArray[];
+ * } *mParam;
+ *
+ * C2ParamField(mParam, &mParam->mField);
+ * C2ParamField(mParam, &mParam->mArray);
+ * C2ParamField(mParam, &mParam->mArray[0]);
+ * C2ParamField(mParam, &mParam->mStruct.mSubField);
+ * C2ParamField(mParam, &mParam->mFlexArray);
+ * C2ParamField(mParam, &mParam->mFlexArray[2]);
+ *
+ * ~~~~~~~~~~~~~
+ *
+ * \todo fix what this is for T[] (for now size becomes T[1])
+ *
+ * \param param pointer to parameter
+ * \param offset member pointer
+ */
template<typename S, typename T>
inline C2ParamField(S* param, T* offset)
: _mIndex(param->index()),
_mFieldId(offset) {}
+ /**
+ * Create a field identifier using a configuration parameter (variable),
+ * and a member pointer. This method cannot be used to refer to an
+ * array element or a subfield.
+ *
+ * ~~~~~~~~~~~~~ (.cpp)
+ *
+ * C2SomeParam mParam;
+ * C2ParamField(&mParam, &C2SomeParam::mMemberField);
+ *
+ * ~~~~~~~~~~~~~
+ *
+ * \param p pointer to parameter
+ * \param T member pointer to the field member
+ */
template<typename R, typename T, typename U>
- inline C2ParamField(U *p, R T::* pm) : _mIndex(p->type()), _mFieldId(p, pm) { }
+ inline C2ParamField(U *p, R T::* pm) : _mIndex(p->index()), _mFieldId(p, pm) { }
+ /**
+ * Create a field identifier to a configuration parameter (variable).
+ *
+ * ~~~~~~~~~~~~~ (.cpp)
+ *
+ * C2SomeParam mParam;
+ * C2ParamField(&mParam);
+ *
+ * ~~~~~~~~~~~~~
+ *
+ * \param param pointer to parameter
+ */
+ template<typename S>
+ inline C2ParamField(S* param)
+ : _mIndex(param->index()), _mFieldId(0u, param->size()) {}
+
+ /**
+ * Equality operator.
+ */
inline bool operator==(const C2ParamField &other) const {
return _mIndex == other._mIndex && _mFieldId == other._mFieldId;
}
+ /**
+ * Ordering operator.
+ */
inline bool operator<(const C2ParamField &other) const {
return _mIndex < other._mIndex ||
(_mIndex == other._mIndex && _mFieldId < other._mFieldId);
@@ -622,8 +695,8 @@
DEFINE_OTHER_COMPARISON_OPERATORS(C2ParamField)
private:
- C2Param::Index _mIndex;
- _C2FieldId _mFieldId;
+ C2Param::Index _mIndex; ///< parameter index
+ _C2FieldId _mFieldId; ///< field identifier
};
/**
@@ -1153,6 +1226,7 @@
struct C2FieldSupportedValues {
//public:
enum Type {
+ EMPTY, ///< no supported values
RANGE, ///< a numeric range that can be continuous or discrete
VALUES, ///< a list of values
FLAGS ///< a list of flags that can be OR-ed
@@ -1171,6 +1245,10 @@
} range;
std::vector<Primitive> values;
+ C2FieldSupportedValues()
+ : type(EMPTY) {
+ }
+
template<typename T>
C2FieldSupportedValues(T min, T max, T step = T(std::is_floating_point<T>::value ? 0 : 1))
: type(RANGE),
@@ -1199,6 +1277,9 @@
}
}
+ /// \internal
+ /// \todo: create separate values vs. flags initializer as for flags we want
+ /// to list both allowed and disallowed flags
template<typename T, typename E=decltype(C2FieldDescriptor::namedValuesFor(*(T*)0))>
C2FieldSupportedValues(bool flags, const T*)
: type(flags ? FLAGS : VALUES),
@@ -1210,6 +1291,21 @@
}
};
+/**
+ * Spported values for a specific field.
+ *
+ * This is a pair of the field specifier together with an optional supported values object.
+ * This structure is used when reporting parameter configuration failures and conflicts.
+ */
+struct C2ParamFieldValues {
+ C2ParamField paramOrField; ///< the field or parameter
+ /// optional supported values for the field if paramOrField specifies an actual field that is
+ /// numeric (non struct, blob or string). Supported values for arrays (including string and
+ /// blobs) describe the supported values for each element (character for string, and bytes for
+ /// blobs). It is optional for read-only strings and blobs.
+ std::unique_ptr<C2FieldSupportedValues> values;
+};
+
/// @}
} // namespace android
diff --git a/media/libstagefright/codec2/include/C2Work.h b/media/libstagefright/codec2/include/C2Work.h
index a378623..52c00d5 100644
--- a/media/libstagefright/codec2/include/C2Work.h
+++ b/media/libstagefright/codec2/include/C2Work.h
@@ -28,28 +28,47 @@
#include <list>
#include <vector>
-typedef int status_t;
-
namespace android {
/// \defgroup work Work and data processing
/// @{
+/**
+ * Information describing the reason a parameter settings may fail, or
+ * may be overriden.
+ */
struct C2SettingResult {
- enum Failure {
+ enum Failure : uint32_t {
READ_ONLY, ///< parameter is read-only and cannot be set
MISMATCH, ///< parameter mismatches input data
BAD_VALUE, ///< parameter does not accept value
BAD_TYPE, ///< parameter is not supported
BAD_PORT, ///< parameter is not supported on the specific port
BAD_INDEX, ///< parameter is not supported on the specific stream
- CONFLICT, ///< parameter is in conflict with another setting
+ CONFLICT, ///< parameter is in conflict with an/other setting(s)
+ /// parameter is out of range due to other settings (this failure mode
+ /// can only be used for strict parameters)
+ UNSUPPORTED,
+
+
+ /// requested parameter value is in conflict with an/other setting(s)
+ /// and has been corrected to the closest supported value. This failure
+ /// mode is given to provide suggestion to the client as to how to
+ /// enable the requested parameter value.
+ INFO_CONFLICT,
};
- C2ParamField field;
- Failure failure;
- std::unique_ptr<C2FieldSupportedValues> supportedValues; //< if different from normal (e.g. in conflict w/another param or input data)
- std::list<C2ParamField> conflictingFields;
+ Failure failure; ///< failure code
+
+ /// Failing (or corrected) field. Currently supported values for the field. This is set if
+ /// different from the globally supported values (e.g. due to restrictions by another param or
+ /// input data)
+ /// \todo need to define suggestions for masks to be set and unset.
+ C2ParamFieldValues field;
+
+ /// Conflicting parameters or fields with optional suggestions with (optional) suggested values
+ /// for any conflicting fields to avoid the conflict.
+ std::list<C2ParamFieldValues> conflicts;
};
// ================================================================================================
@@ -99,8 +118,8 @@
std::list<std::unique_ptr<C2Param>> tunings; //< tunings to be applied before processing this
// worklet
std::list<C2Param::Type> requestedInfos;
- std::vector<std::shared_ptr<C2BlockAllocator>> allocators; //< This vector shall be the same size as
- //< output.buffers.
+ std::vector<std::shared_ptr<C2BlockPool>> allocators; //< This vector shall be the same size as
+ //< output.buffers. \deprecated
// OUT
C2BufferPack output;
@@ -146,7 +165,7 @@
std::list<std::unique_ptr<C2Worklet>> worklets;
uint32_t worklets_processed;
- status_t result;
+ C2Status result;
};
struct C2WorkOutline {
diff --git a/media/libstagefright/codec2/tests/C2ComponentInterface_test.cpp b/media/libstagefright/codec2/tests/C2ComponentInterface_test.cpp
index 0c8ca3e..b725d76 100644
--- a/media/libstagefright/codec2/tests/C2ComponentInterface_test.cpp
+++ b/media/libstagefright/codec2/tests/C2ComponentInterface_test.cpp
@@ -112,11 +112,11 @@
// check if a component has a parameter whose type is |T|.
// If a component has, the value should be copied into an argument, that is
// |p| in queryOnStack() and |heapParams| in queryOnHeap().
- // The return value is status_t (e.g. C2_OK).
- template <typename T> status_t queryOnStack(T *const p);
+ // The return value is C2Status (e.g. C2_OK).
+ template <typename T> C2Status queryOnStack(T *const p);
template <typename T>
- status_t queryOnHeap(const T &p,
+ C2Status queryOnHeap(const T &p,
std::vector<std::unique_ptr<C2Param>> *const heapParams);
// Get a value whose type is |T| in a component. The value is copied to |param|.
@@ -139,7 +139,7 @@
// Execute an interface's config_nb(). |T| is a single parameter type, not std::vector.
// config() creates std::vector<C2Param *const> {p} and passes it to config_nb().
template <typename T>
- status_t
+ C2Status
config(T *const p,
std::vector<std::unique_ptr<C2SettingResult>> *const failures);
@@ -150,7 +150,7 @@
// Test if config works correctly for writable parameters.
// This changes the parameter's value to |newParam|.
// |stConfig| is a return value of config().
- template <typename T> void configWritableParamValidValue(const T &newParam, status_t *stConfig);
+ template <typename T> void configWritableParamValidValue(const T &newParam, C2Status *stConfig);
// Test if config works correctly in the case an invalid value |newParam| is tried to write
// to an writable parameter.
@@ -162,7 +162,7 @@
// config() should be failed if these values are used as new values.
// This function should be called only for writable and supported parameters.
template <typename TField>
- void getTestValues(const std::vector<C2FieldSupportedValues> &validValueInfos,
+ void getTestValues(const C2FieldSupportedValues &validValueInfos,
std::vector<TField> *const validValues,
std::vector<TField> *const invalidValues);
@@ -194,13 +194,13 @@
} \
} while (false)
-template <typename T> status_t C2CompIntfTest::queryOnStack(T *const p) {
+template <typename T> C2Status C2CompIntfTest::queryOnStack(T *const p) {
std::vector<C2Param *const> stackParams{p};
return mIntf->query_nb(stackParams, {}, nullptr);
}
template <typename T>
-status_t C2CompIntfTest::queryOnHeap(
+C2Status C2CompIntfTest::queryOnHeap(
const T &p, std::vector<std::unique_ptr<C2Param>> *const heapParams) {
uint32_t index = p.type();
if (p.forStream()) {
@@ -258,7 +258,7 @@
}
template <typename T>
-status_t C2CompIntfTest::config(
+C2Status C2CompIntfTest::config(
T *const p, std::vector<std::unique_ptr<C2SettingResult>> *const failures) {
std::vector<C2Param *const> params{p};
return mIntf->config_nb(params, failures);
@@ -286,7 +286,7 @@
}
template <typename T>
-void C2CompIntfTest::configWritableParamValidValue(const T &newParam, status_t *configResult) {
+void C2CompIntfTest::configWritableParamValidValue(const T &newParam, C2Status *configResult) {
std::unique_ptr<T> p = makeParamFrom(newParam);
std::vector<C2Param *const> params{p.get()};
@@ -297,7 +297,7 @@
// because there may be dependent limitations between fields or between parameters.
// TODO(hiroh): I have to fill the return value. Comments in C2Component.h doesn't mention
// about the return value when conflict happens. I set C2_BAD_VALUE to it temporarily now.
- status_t stConfig = mIntf->config_nb(params, &failures);
+ C2Status stConfig = mIntf->config_nb(params, &failures);
if (stConfig == C2_OK) {
EXPECT_EQ(0u, failures.size());
} else {
@@ -325,7 +325,7 @@
// If another field type is added, it is necessary to add function for that.
template <>
void C2CompIntfTest::getTestValues(
- const std::vector<C2FieldSupportedValues> &validValueInfos,
+ const C2FieldSupportedValues &validValueInfos,
std::vector<C2DomainKind> *const validValues,
std::vector<C2DomainKind> *const invalidValues) {
UNUSED(validValueInfos);
@@ -339,7 +339,7 @@
template <typename TField>
void C2CompIntfTest::getTestValues(
- const std::vector<C2FieldSupportedValues> &validValueInfos,
+ const C2FieldSupportedValues &validValueInfos,
std::vector<TField> *const validValues,
std::vector<TField> *const invalidValues) {
@@ -366,9 +366,14 @@
};
// The size of validValueInfos is one.
- const auto &c2FSV = validValueInfos[0];
+ const auto &c2FSV = validValueInfos;
switch (c2FSV.type) {
+ case C2FieldSupportedValues::Type::EMPTY: {
+ invalidValues->emplace_back(TField(0));
+ // TODO(hiroh) : Should other invalid values be tested?
+ break;
+ }
case C2FieldSupportedValues::Type::RANGE: {
const auto &range = c2FSV.range;
auto rmin = prim2Value(range.min);
@@ -476,7 +481,7 @@
TParam *const param, TRealField *const writableField,
const std::vector<TField> &validValues,
const std::vector<TField> &invalidValues) {
- status_t stConfig;
+ C2Status stConfig;
// Get the parameter's value in the beginning in order to reset the value at the end.
TRACED_FAILURE(getValue(param));
@@ -550,7 +555,7 @@
std::vector<std::unique_ptr<C2SettingResult>> failures;
// Config does not change the parameter, because param is the present param.
// This config is executed to find out if a parameter is read-only or writable.
- status_t stStack = config(param.get(), &failures);
+ C2Status stStack = config(param.get(), &failures);
if (stStack == C2_BAD_VALUE) {
// Read-only
std::unique_ptr<T> newParam = makeParam<T>();
@@ -584,15 +589,16 @@
#define TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, field_name_) \
do { \
std::unique_ptr<TParam_> param = makeParam<TParam_>(); \
- std::vector<C2FieldSupportedValues> validValueInfos; \
+ std::vector<C2FieldSupportedValuesQuery> validValueInfos = { \
+ C2FieldSupportedValuesQuery::Current( \
+ C2ParamField(param.get(), &field_type_name_::field_name_)) \
+ }; \
ASSERT_EQ(C2_OK, \
- mIntf->getSupportedValues( \
- {C2ParamField(param.get(), &field_type_name_::field_name_)}, \
- &validValueInfos)); \
+ mIntf->getSupportedValues(validValueInfos)); \
ASSERT_EQ(1u, validValueInfos.size()); \
std::vector<decltype(param->field_name_)> validValues; \
std::vector<decltype(param->field_name_)> invalidValues; \
- getTestValues(validValueInfos, &validValues, &invalidValues); \
+ getTestValues(validValueInfos[0].values, &validValues, &invalidValues); \
testWritableParam(param.get(), ¶m->field_name_, validValues,\
invalidValues); \
} while (0)
diff --git a/media/libstagefright/codec2/tests/C2Param_test.cpp b/media/libstagefright/codec2/tests/C2Param_test.cpp
index 0e71b2a..97c5f91 100644
--- a/media/libstagefright/codec2/tests/C2Param_test.cpp
+++ b/media/libstagefright/codec2/tests/C2Param_test.cpp
@@ -2403,28 +2403,28 @@
return 0;
}
- virtual status_t commit_sm(
+ virtual C2Status commit_sm(
const std::vector<C2Param* const> ¶ms,
std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
(void)params;
(void)failures;
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
- virtual status_t config_nb(
+ virtual C2Status config_nb(
const std::vector<C2Param* const> ¶ms,
std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
(void)params;
(void)failures;
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
- virtual status_t createTunnel_sm(node_id targetComponent) {
+ virtual C2Status createTunnel_sm(node_id targetComponent) {
(void)targetComponent;
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
- virtual status_t query_nb(
+ virtual C2Status query_nb(
const std::vector<C2Param* const> &stackParams,
const std::vector<C2Param::Index> &heapParamIndices,
std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
@@ -2466,9 +2466,9 @@
mMyParams.insert({mDomainInfo.type(), mDomainInfo});
}
- virtual status_t releaseTunnel_sm(node_id targetComponent) {
+ virtual C2Status releaseTunnel_sm(node_id targetComponent) {
(void)targetComponent;
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
class MyParamReflector : public C2ParamReflector {
@@ -2490,17 +2490,19 @@
}
};
- virtual status_t getSupportedValues(
- const std::vector<const C2ParamField> &fields,
- std::vector<C2FieldSupportedValues>* const values) const {
- for (const C2ParamField &field : fields) {
- if (field == C2ParamField(&mDomainInfo, &C2ComponentDomainInfo::mValue)) {
- values->push_back(C2FieldSupportedValues(
+ virtual C2Status getSupportedValues(
+ std::vector<C2FieldSupportedValuesQuery> &fields) const {
+ for (C2FieldSupportedValuesQuery &query : fields) {
+ if (query.field == C2ParamField(&mDomainInfo, &C2ComponentDomainInfo::mValue)) {
+ query.values = C2FieldSupportedValues(
false /* flag */,
&mDomainInfo.mValue
//,
//{(int32_t)C2DomainVideo}
- ));
+ );
+ query.status = C2_OK;
+ } else {
+ query.status = C2_BAD_INDEX;
}
}
return C2_OK;
@@ -2510,13 +2512,13 @@
return std::shared_ptr<C2ParamReflector>(new MyParamReflector(this));
}
- virtual status_t getSupportedParams(std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const {
+ virtual C2Status getSupportedParams(std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const {
params->push_back(std::make_shared<C2ParamDescriptor>(
true /* required */, "_domain", &mDomainInfo));
return C2_OK;
}
- status_t getSupportedParams2(std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) {
+ C2Status getSupportedParams2(std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) {
params->push_back(std::shared_ptr<C2ParamDescriptor>(
new C2ParamDescriptor(true /* required */, "_domain", &mDomainInfo)));
return C2_OK;
@@ -2699,21 +2701,23 @@
TEST_F(C2ParamTest, ReflectorTest) {
C2ComponentDomainInfo domainInfo;
std::shared_ptr<C2ComponentInterface> comp(new MyComponentInstance);
- std::vector<C2FieldSupportedValues> values;
std::unique_ptr<C2StructDescriptor> desc{
comp->getParamReflector()->describe(C2ComponentDomainInfo::indexFlags)};
dumpStruct(*desc);
- EXPECT_EQ(
- C2_OK,
- comp->getSupportedValues(
- { C2ParamField(&domainInfo, &C2ComponentDomainInfo::mValue) },
- &values)
- );
+ std::vector<C2FieldSupportedValuesQuery> query = {
+ { C2ParamField(&domainInfo, &C2ComponentDomainInfo::mValue),
+ C2FieldSupportedValuesQuery::CURRENT },
+ C2FieldSupportedValuesQuery(C2ParamField(&domainInfo, &C2ComponentDomainInfo::mValue),
+ C2FieldSupportedValuesQuery::CURRENT),
+ C2FieldSupportedValuesQuery::Current(C2ParamField(&domainInfo, &C2ComponentDomainInfo::mValue)),
+ };
- for (const C2FieldSupportedValues &sv : values) {
- dumpFSV(sv, &domainInfo.mValue);
+ EXPECT_EQ(C2_OK, comp->getSupportedValues(query));
+
+ for (const C2FieldSupportedValuesQuery &q : query) {
+ dumpFSV(q.values, &domainInfo.mValue);
}
}
diff --git a/media/libstagefright/codec2/tests/vndk/C2BufferTest.cpp b/media/libstagefright/codec2/tests/vndk/C2BufferTest.cpp
index a185880..3d23c23 100644
--- a/media/libstagefright/codec2/tests/vndk/C2BufferTest.cpp
+++ b/media/libstagefright/codec2/tests/vndk/C2BufferTest.cpp
@@ -38,19 +38,19 @@
~C2BufferTest() = default;
void allocateLinear(size_t capacity) {
- C2Error err = mLinearAllocator->allocateLinearBuffer(
+ C2Status err = mLinearAllocator->newLinearAllocation(
capacity,
{ C2MemoryUsage::kSoftwareRead, C2MemoryUsage::kSoftwareWrite },
&mLinearAllocation);
if (err != C2_OK) {
mLinearAllocation.reset();
- FAIL() << "C2Allocator::allocateLinearBuffer() failed: " << err;
+ FAIL() << "C2Allocator::newLinearAllocation() failed: " << err;
}
}
void mapLinear(size_t offset, size_t size, uint8_t **addr) {
ASSERT_TRUE(mLinearAllocation);
- C2Error err = mLinearAllocation->map(
+ C2Status err = mLinearAllocation->map(
offset,
size,
{ C2MemoryUsage::kSoftwareRead, C2MemoryUsage::kSoftwareWrite },
@@ -77,12 +77,12 @@
mAddr = nullptr;
}
- std::shared_ptr<C2BlockAllocator> makeLinearBlockAllocator() {
- return std::make_shared<C2DefaultBlockAllocator>(mLinearAllocator);
+ std::shared_ptr<C2BlockPool> makeLinearBlockPool() {
+ return std::make_shared<C2BasicLinearBlockPool>(mLinearAllocator);
}
void allocateGraphic(uint32_t width, uint32_t height) {
- C2Error err = mGraphicAllocator->allocateGraphicBuffer(
+ C2Status err = mGraphicAllocator->newGraphicAllocation(
width,
height,
HAL_PIXEL_FORMAT_YCBCR_420_888,
@@ -90,13 +90,13 @@
&mGraphicAllocation);
if (err != C2_OK) {
mGraphicAllocation.reset();
- FAIL() << "C2Allocator::allocateLinearBuffer() failed: " << err;
+ FAIL() << "C2Allocator::newGraphicAllocation() failed: " << err;
}
}
void mapGraphic(C2Rect rect, C2PlaneLayout *layout, uint8_t **addr) {
ASSERT_TRUE(mGraphicAllocation);
- C2Error err = mGraphicAllocation->map(
+ C2Status err = mGraphicAllocation->map(
rect,
{ C2MemoryUsage::kSoftwareRead, C2MemoryUsage::kSoftwareWrite },
// TODO: fence
@@ -118,8 +118,8 @@
ASSERT_EQ(C2_OK, mGraphicAllocation->unmap(nullptr));
}
- std::shared_ptr<C2BlockAllocator> makeGraphicBlockAllocator() {
- return std::make_shared<C2DefaultGraphicBlockAllocator>(mGraphicAllocator);
+ std::shared_ptr<C2BlockPool> makeGraphicBlockPool() {
+ return std::make_shared<C2BasicGraphicBlockPool>(mGraphicAllocator);
}
private:
@@ -155,13 +155,13 @@
}
}
-TEST_F(C2BufferTest, BlockAllocatorTest) {
+TEST_F(C2BufferTest, BlockPoolTest) {
constexpr size_t kCapacity = 1024u * 1024u;
- std::shared_ptr<C2BlockAllocator> blockAllocator(makeLinearBlockAllocator());
+ std::shared_ptr<C2BlockPool> blockPool(makeLinearBlockPool());
std::shared_ptr<C2LinearBlock> block;
- ASSERT_EQ(C2_OK, blockAllocator->allocateLinearBlock(
+ ASSERT_EQ(C2_OK, blockPool->fetchLinearBlock(
kCapacity,
{ C2MemoryUsage::kSoftwareRead, C2MemoryUsage::kSoftwareWrite },
&block));
@@ -285,14 +285,14 @@
ASSERT_TRUE(verifyPlane({ 0, 0, kWidth / 4, kHeight }, vInfo, v, 0));
}
-TEST_F(C2BufferTest, GraphicBlockAllocatorTest) {
+TEST_F(C2BufferTest, GraphicBlockPoolTest) {
constexpr uint32_t kWidth = 320;
constexpr uint32_t kHeight = 240;
- std::shared_ptr<C2BlockAllocator> blockAllocator(makeGraphicBlockAllocator());
+ std::shared_ptr<C2BlockPool> blockPool(makeGraphicBlockPool());
std::shared_ptr<C2GraphicBlock> block;
- ASSERT_EQ(C2_OK, blockAllocator->allocateGraphicBlock(
+ ASSERT_EQ(C2_OK, blockPool->fetchGraphicBlock(
kWidth,
kHeight,
HAL_PIXEL_FORMAT_YCBCR_420_888,
@@ -370,8 +370,8 @@
};
TEST_F(C2BufferTest, BufferDataTest) {
- std::shared_ptr<C2BlockAllocator> linearBlockAllocator(makeLinearBlockAllocator());
- std::shared_ptr<C2BlockAllocator> graphicBlockAllocator(makeGraphicBlockAllocator());
+ std::shared_ptr<C2BlockPool> linearBlockPool(makeLinearBlockPool());
+ std::shared_ptr<C2BlockPool> graphicBlockPool(makeGraphicBlockPool());
constexpr uint32_t kWidth1 = 320;
constexpr uint32_t kHeight1 = 240;
@@ -384,23 +384,23 @@
std::shared_ptr<C2LinearBlock> linearBlock1;
std::shared_ptr<C2LinearBlock> linearBlock2;
- ASSERT_EQ(C2_OK, linearBlockAllocator->allocateLinearBlock(
+ ASSERT_EQ(C2_OK, linearBlockPool->fetchLinearBlock(
kCapacity1,
{ C2MemoryUsage::kSoftwareRead, C2MemoryUsage::kSoftwareWrite },
&linearBlock1));
- ASSERT_EQ(C2_OK, linearBlockAllocator->allocateLinearBlock(
+ ASSERT_EQ(C2_OK, linearBlockPool->fetchLinearBlock(
kCapacity2,
{ C2MemoryUsage::kSoftwareRead, C2MemoryUsage::kSoftwareWrite },
&linearBlock2));
std::shared_ptr<C2GraphicBlock> graphicBlock1;
std::shared_ptr<C2GraphicBlock> graphicBlock2;
- ASSERT_EQ(C2_OK, graphicBlockAllocator->allocateGraphicBlock(
+ ASSERT_EQ(C2_OK, graphicBlockPool->fetchGraphicBlock(
kWidth1,
kHeight1,
HAL_PIXEL_FORMAT_YCBCR_420_888,
{ C2MemoryUsage::kSoftwareRead, C2MemoryUsage::kSoftwareWrite },
&graphicBlock1));
- ASSERT_EQ(C2_OK, graphicBlockAllocator->allocateGraphicBlock(
+ ASSERT_EQ(C2_OK, graphicBlockPool->fetchGraphicBlock(
kWidth2,
kHeight2,
HAL_PIXEL_FORMAT_YCBCR_420_888,
@@ -454,11 +454,11 @@
typedef C2GlobalParam<C2Info, C2Int32Value, kParamIndexNumber2> C2Number2Info;
TEST_F(C2BufferTest, BufferTest) {
- std::shared_ptr<C2BlockAllocator> alloc(makeLinearBlockAllocator());
+ std::shared_ptr<C2BlockPool> alloc(makeLinearBlockPool());
constexpr size_t kCapacity = 1024u;
std::shared_ptr<C2LinearBlock> block;
- ASSERT_EQ(C2_OK, alloc->allocateLinearBlock(
+ ASSERT_EQ(C2_OK, alloc->fetchLinearBlock(
kCapacity,
{ C2MemoryUsage::kSoftwareRead, C2MemoryUsage::kSoftwareWrite },
&block));
diff --git a/media/libstagefright/codec2/vndk/C2AllocatorGralloc.cpp b/media/libstagefright/codec2/vndk/C2AllocatorGralloc.cpp
index baa6637..3e2242b 100644
--- a/media/libstagefright/codec2/vndk/C2AllocatorGralloc.cpp
+++ b/media/libstagefright/codec2/vndk/C2AllocatorGralloc.cpp
@@ -38,14 +38,14 @@
using ::android::hardware::hidl_vec;
/* ===================================== GRALLOC ALLOCATION ==================================== */
-static C2Error maperr2error(Error maperr) {
+static C2Status maperr2error(Error maperr) {
switch (maperr) {
case Error::NONE: return C2_OK;
case Error::BAD_DESCRIPTOR: return C2_BAD_VALUE;
case Error::BAD_BUFFER: return C2_BAD_VALUE;
case Error::BAD_VALUE: return C2_BAD_VALUE;
case Error::NO_RESOURCES: return C2_NO_MEMORY;
- case Error::UNSUPPORTED: return C2_UNSUPPORTED;
+ case Error::UNSUPPORTED: return C2_CANNOT_DO;
}
return C2_CORRUPTED;
}
@@ -54,10 +54,10 @@
public:
virtual ~C2AllocationGralloc();
- virtual C2Error map(
+ virtual C2Status map(
C2Rect rect, C2MemoryUsage usage, int *fenceFd,
C2PlaneLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
- virtual C2Error unmap(C2Fence *fenceFd /* nullable */) override;
+ virtual C2Status unmap(C2Fence *fenceFd /* nullable */) override;
virtual bool isValid() const override { return true; }
virtual const C2Handle *handle() const override { return mHandle; }
virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
@@ -69,7 +69,7 @@
const sp<IMapper> &mapper,
hidl_handle &handle);
int dup() const;
- C2Error status() const;
+ C2Status status() const;
private:
const IMapper::BufferDescriptorInfo mInfo;
@@ -100,7 +100,7 @@
mMapper->freeBuffer(const_cast<native_handle_t *>(mBuffer));
}
-C2Error C2AllocationGralloc::map(
+C2Status C2AllocationGralloc::map(
C2Rect rect, C2MemoryUsage usage, int *fenceFd,
C2PlaneLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
// TODO
@@ -114,7 +114,7 @@
return C2_BAD_VALUE;
}
- C2Error err = C2_OK;
+ C2Status err = C2_OK;
if (!mBuffer) {
mMapper->importBuffer(
mHandle, [&err, this](const auto &maperr, const auto &buffer) {
@@ -195,16 +195,16 @@
return err;
}
// TODO
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
mLocked = true;
return C2_OK;
}
-C2Error C2AllocationGralloc::unmap(C2Fence *fenceFd /* nullable */) {
+C2Status C2AllocationGralloc::unmap(C2Fence *fenceFd /* nullable */) {
// TODO: fence
- C2Error err = C2_OK;
+ C2Status err = C2_OK;
mMapper->unlock(
const_cast<native_handle_t *>(mBuffer),
[&err, &fenceFd](const auto &maperr, const auto &releaseFence) {
@@ -231,18 +231,22 @@
public:
Impl();
- C2Error allocateGraphicBuffer(
+ id_t getId() const;
+
+ C2String getName() const;
+
+ C2Status newGraphicAllocation(
uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
std::shared_ptr<C2GraphicAllocation> *allocation);
- C2Error recreateGraphicBuffer(
+ C2Status priorGraphicAllocation(
const C2Handle *handle,
std::shared_ptr<C2GraphicAllocation> *allocation);
- C2Error status() const { return mInit; }
+ C2Status status() const { return mInit; }
private:
- C2Error mInit;
+ C2Status mInit;
sp<IAllocator> mAllocator;
sp<IMapper> mMapper;
};
@@ -256,7 +260,15 @@
}
}
-C2Error C2AllocatorGralloc::Impl::allocateGraphicBuffer(
+C2Allocator::id_t C2AllocatorGralloc::Impl::getId() const {
+ return 1; /// \todo implement ID
+}
+
+C2String C2AllocatorGralloc::Impl::getName() const {
+ return "android.allocator.gralloc";
+}
+
+C2Status C2AllocatorGralloc::Impl::newGraphicAllocation(
uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
std::shared_ptr<C2GraphicAllocation> *allocation) {
// TODO: buffer usage should be determined according to |usage|
@@ -269,7 +281,7 @@
(PixelFormat)format,
BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN,
};
- C2Error err = C2_OK;
+ C2Status err = C2_OK;
BufferDescriptor desc;
mMapper->createDescriptor(
info, [&err, &desc](const auto &maperr, const auto &descriptor) {
@@ -307,33 +319,41 @@
return C2_OK;
}
-C2Error C2AllocatorGralloc::Impl::recreateGraphicBuffer(
+C2Status C2AllocatorGralloc::Impl::priorGraphicAllocation(
const C2Handle *handle,
std::shared_ptr<C2GraphicAllocation> *allocation) {
(void) handle;
// TODO: need to figure out BufferDescriptorInfo from the handle.
allocation->reset();
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
C2AllocatorGralloc::C2AllocatorGralloc() : mImpl(new Impl) {}
C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
-C2Error C2AllocatorGralloc::allocateGraphicBuffer(
+C2Allocator::id_t C2AllocatorGralloc::getId() const {
+ return mImpl->getId();
+}
+
+C2String C2AllocatorGralloc::getName() const {
+ return mImpl->getName();
+}
+
+C2Status C2AllocatorGralloc::newGraphicAllocation(
uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
std::shared_ptr<C2GraphicAllocation> *allocation) {
- return mImpl->allocateGraphicBuffer(width, height, format, usage, allocation);
+ return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
}
-C2Error C2AllocatorGralloc::recreateGraphicBuffer(
+C2Status C2AllocatorGralloc::priorGraphicAllocation(
const C2Handle *handle,
std::shared_ptr<C2GraphicAllocation> *allocation) {
- return mImpl->recreateGraphicBuffer(handle, allocation);
+ return mImpl->priorGraphicAllocation(handle, allocation);
}
-C2Error C2AllocatorGralloc::status() const {
+C2Status C2AllocatorGralloc::status() const {
return mImpl->status();
}
diff --git a/media/libstagefright/codec2/vndk/C2AllocatorIon.cpp b/media/libstagefright/codec2/vndk/C2AllocatorIon.cpp
index 7aa7769..09df502 100644
--- a/media/libstagefright/codec2/vndk/C2AllocatorIon.cpp
+++ b/media/libstagefright/codec2/vndk/C2AllocatorIon.cpp
@@ -82,10 +82,10 @@
/* ======================================= ION ALLOCATION ====================================== */
class C2AllocationIon : public C2LinearAllocation {
public:
- virtual C2Error map(
+ virtual C2Status map(
size_t offset, size_t size, C2MemoryUsage usage, int *fence,
void **addr /* nonnull */);
- virtual C2Error unmap(void *addr, size_t size, int *fenceFd);
+ virtual C2Status unmap(void *addr, size_t size, int *fenceFd);
virtual bool isValid() const;
virtual ~C2AllocationIon();
virtual const C2Handle *handle() const;
@@ -95,7 +95,7 @@
C2AllocationIon(int ionFd, size_t size, size_t align, unsigned heapMask, unsigned flags);
C2AllocationIon(int ionFd, size_t size, int shareFd);
int dup() const;
- C2Error status() const;
+ C2Status status() const;
protected:
class Impl;
@@ -121,18 +121,28 @@
}
Impl(int ionFd, size_t capacity, int shareFd)
- : mHandle(ionFd, -1),
+ : mInit(C2_OK),
+ mHandle(ionFd, -1),
mMapFd(-1),
mCapacity(capacity) {
ion_user_handle_t buffer;
- mInit = ion_import(mHandle.ionFd(), shareFd, &buffer);
- if (mInit == 0) {
+ int ret = ion_import(mHandle.ionFd(), shareFd, &buffer);
+ switch (-ret) {
+ case 0:
mHandle.setBuffer(buffer);
+ break;
+ case EBADF: // bad ion handle - should not happen
+ case ENOTTY: // bad ion driver
+ mInit = C2_CORRUPTED;
+ break;
+ default:
+ mInit = c2_map_errno<ENOMEM, EACCES, EINVAL>(-ret);
+ break;
}
(void)mCapacity; // TODO
}
- C2Error map(size_t offset, size_t size, C2MemoryUsage usage, int *fenceFd, void **addr) {
+ C2Status map(size_t offset, size_t size, C2MemoryUsage usage, int *fenceFd, void **addr) {
(void)fenceFd; // TODO: wait for fence
*addr = nullptr;
int prot = PROT_NONE;
@@ -149,7 +159,7 @@
size_t mapOffset = offset - alignmentBytes;
size_t mapSize = size + alignmentBytes;
- C2Error err = C2_OK;
+ C2Status err = C2_OK;
if (mMapFd == -1) {
int ret = ion_map(mHandle.ionFd(), mHandle.buffer(), mapSize, prot,
flags, mapOffset, (unsigned char**)&mMapAddr, &mMapFd);
@@ -176,7 +186,7 @@
return err;
}
- C2Error unmap(void *addr, size_t size, int *fenceFd) {
+ C2Status unmap(void *addr, size_t size, int *fenceFd) {
if (addr != (uint8_t *)mMapAddr + mMapAlignmentBytes ||
size + mMapAlignmentBytes != mMapSize) {
return C2_BAD_VALUE;
@@ -200,7 +210,7 @@
(void)ion_free(mHandle.ionFd(), mHandle.buffer());
}
- C2Error status() const {
+ C2Status status() const {
return mInit;
}
@@ -217,7 +227,7 @@
}
private:
- C2Error mInit;
+ C2Status mInit;
C2HandleIon mHandle;
int mMapFd; // only one for now
void *mMapAddr;
@@ -226,12 +236,12 @@
size_t mCapacity;
};
-C2Error C2AllocationIon::map(
+C2Status C2AllocationIon::map(
size_t offset, size_t size, C2MemoryUsage usage, int *fenceFd, void **addr) {
return mImpl->map(offset, size, usage, fenceFd, addr);
}
-C2Error C2AllocationIon::unmap(void *addr, size_t size, int *fenceFd) {
+C2Status C2AllocationIon::unmap(void *addr, size_t size, int *fenceFd) {
return mImpl->unmap(addr, size, fenceFd);
}
@@ -239,7 +249,7 @@
return mImpl->status() == C2_OK;
}
-C2Error C2AllocationIon::status() const {
+C2Status C2AllocationIon::status() const {
return mImpl->status();
}
@@ -272,7 +282,7 @@
C2AllocatorIon::C2AllocatorIon() : mInit(C2_OK), mIonFd(ion_open()) {
if (mIonFd < 0) {
switch (errno) {
- case ENOENT: mInit = C2_UNSUPPORTED; break;
+ case ENOENT: mInit = C2_OMITTED; break;
default: mInit = c2_map_errno<EACCES>(errno); break;
}
}
@@ -284,7 +294,15 @@
}
}
-C2Error C2AllocatorIon::allocateLinearBuffer(
+C2Allocator::id_t C2AllocatorIon::getId() const {
+ return 0; /// \todo implement ID
+}
+
+C2String C2AllocatorIon::getName() const {
+ return "android.allocator.ion";
+}
+
+C2Status C2AllocatorIon::newLinearAllocation(
uint32_t capacity, C2MemoryUsage usage, std::shared_ptr<C2LinearAllocation> *allocation) {
if (allocation == nullptr) {
return C2_BAD_VALUE;
@@ -292,7 +310,7 @@
allocation->reset();
if (mInit != C2_OK) {
- return C2_UNSUPPORTED;
+ return mInit;
}
// get align, heapMask and flags
@@ -311,18 +329,18 @@
std::shared_ptr<C2AllocationIon> alloc
= std::make_shared<C2AllocationIon>(mIonFd, capacity, align, heapMask, flags);
- C2Error ret = alloc->status();
+ C2Status ret = alloc->status();
if (ret == C2_OK) {
*allocation = alloc;
}
return ret;
}
-C2Error C2AllocatorIon::recreateLinearBuffer(
+C2Status C2AllocatorIon::priorLinearAllocation(
const C2Handle *handle, std::shared_ptr<C2LinearAllocation> *allocation) {
*allocation = nullptr;
if (mInit != C2_OK) {
- return C2_UNSUPPORTED;
+ return mInit;
}
if (!C2HandleIon::isValid(handle)) {
@@ -333,7 +351,7 @@
const C2HandleIon *h = static_cast<const C2HandleIon*>(handle);
std::shared_ptr<C2AllocationIon> alloc
= std::make_shared<C2AllocationIon>(mIonFd, 0 /* capacity */, h->buffer());
- C2Error ret = alloc->status();
+ C2Status ret = alloc->status();
if (ret == C2_OK) {
*allocation = alloc;
}
diff --git a/media/libstagefright/codec2/vndk/C2Buffer.cpp b/media/libstagefright/codec2/vndk/C2Buffer.cpp
index 1ffbf49..02e2dd9 100644
--- a/media/libstagefright/codec2/vndk/C2Buffer.cpp
+++ b/media/libstagefright/codec2/vndk/C2Buffer.cpp
@@ -61,7 +61,7 @@
class C2DefaultLinearBlock : public C2LinearBlock {
using C2LinearBlock::C2LinearBlock;
- friend class ::android::C2DefaultBlockAllocator;
+ friend class ::android::C2BasicLinearBlockPool;
};
class C2DefaultGraphicView : public C2GraphicView {
@@ -87,7 +87,7 @@
class C2DefaultGraphicBlock : public C2GraphicBlock {
using C2GraphicBlock::C2GraphicBlock;
- friend class ::android::C2DefaultGraphicBlockAllocator;
+ friend class ::android::C2BasicGraphicBlockPool;
};
class C2DefaultBufferData : public C2BufferData {
@@ -129,26 +129,26 @@
explicit Impl(const uint8_t *data)
: mData(data), mError(C2_OK) {}
- explicit Impl(C2Error error)
+ explicit Impl(C2Status error)
: mData(nullptr), mError(error) {}
const uint8_t *data() const {
return mData;
}
- C2Error error() const {
+ C2Status error() const {
return mError;
}
private:
const uint8_t *mData;
- C2Error mError;
+ C2Status mError;
};
C2ReadView::C2ReadView(const _C2LinearCapacityAspect *parent, const uint8_t *data)
: _C2LinearCapacityAspect(parent), mImpl(std::make_shared<Impl>(data)) {}
-C2ReadView::C2ReadView(C2Error error)
+C2ReadView::C2ReadView(C2Status error)
: _C2LinearCapacityAspect(0u), mImpl(std::make_shared<Impl>(error)) {}
const uint8_t *C2ReadView::data() const {
@@ -167,7 +167,7 @@
return C2ReadView(&newCapacity, data() + offset);
}
-C2Error C2ReadView::error() {
+C2Status C2ReadView::error() const {
return mImpl->error();
}
@@ -176,33 +176,33 @@
explicit Impl(uint8_t *base)
: mBase(base), mError(C2_OK) {}
- explicit Impl(C2Error error)
+ explicit Impl(C2Status error)
: mBase(nullptr), mError(error) {}
uint8_t *base() const {
return mBase;
}
- C2Error error() const {
+ C2Status error() const {
return mError;
}
private:
uint8_t *mBase;
- C2Error mError;
+ C2Status mError;
};
C2WriteView::C2WriteView(const _C2LinearRangeAspect *parent, uint8_t *base)
: _C2EditableLinearRange(parent), mImpl(std::make_shared<Impl>(base)) {}
-C2WriteView::C2WriteView(C2Error error)
+C2WriteView::C2WriteView(C2Status error)
: _C2EditableLinearRange(nullptr), mImpl(std::make_shared<Impl>(error)) {}
uint8_t *C2WriteView::base() { return mImpl->base(); }
uint8_t *C2WriteView::data() { return mImpl->base() + offset(); }
-C2Error C2WriteView::error() { return mImpl->error(); }
+C2Status C2WriteView::error() const { return mImpl->error(); }
class C2ConstLinearBlock::Impl {
public:
@@ -212,7 +212,7 @@
~Impl() {
if (mBase != nullptr) {
// TODO: fence
- C2Error err = mAllocation->unmap(mBase, mSize, nullptr);
+ C2Status err = mAllocation->unmap(mBase, mSize, nullptr);
if (err != C2_OK) {
// TODO: Log?
}
@@ -238,13 +238,13 @@
const uint8_t *base() const { return mBase; }
- C2Error error() const { return mError; }
+ C2Status error() const { return mError; }
private:
std::shared_ptr<C2LinearAllocation> mAllocation;
uint8_t *mBase;
size_t mSize;
- C2Error mError;
+ C2Status mError;
};
C2ConstLinearBlock::C2ConstLinearBlock(std::shared_ptr<C2LinearAllocation> alloc)
@@ -277,7 +277,7 @@
~Impl() {
if (mBase != nullptr) {
// TODO: fence
- C2Error err = mAllocation->unmap(mBase, mSize, nullptr);
+ C2Status err = mAllocation->unmap(mBase, mSize, nullptr);
if (err != C2_OK) {
// TODO: Log?
}
@@ -309,7 +309,7 @@
uint8_t *base() const { return mBase; }
- C2Error error() const { return mError; }
+ C2Status error() const { return mError; }
C2Fence fence() const { return mFence; }
@@ -317,7 +317,7 @@
std::shared_ptr<C2LinearAllocation> mAllocation;
uint8_t *mBase;
size_t mSize;
- C2Error mError;
+ C2Status mError;
C2Fence mFence;
};
@@ -345,18 +345,18 @@
return mImpl->share(offset, size, fence);
}
-C2DefaultBlockAllocator::C2DefaultBlockAllocator(
+C2BasicLinearBlockPool::C2BasicLinearBlockPool(
const std::shared_ptr<C2Allocator> &allocator)
: mAllocator(allocator) {}
-C2Error C2DefaultBlockAllocator::allocateLinearBlock(
+C2Status C2BasicLinearBlockPool::fetchLinearBlock(
uint32_t capacity,
C2MemoryUsage usage,
std::shared_ptr<C2LinearBlock> *block /* nonnull */) {
block->reset();
std::shared_ptr<C2LinearAllocation> alloc;
- C2Error err = mAllocator->allocateLinearBuffer(capacity, usage, &alloc);
+ C2Status err = mAllocator->newLinearAllocation(capacity, usage, &alloc);
if (err != C2_OK) {
return err;
}
@@ -392,16 +392,16 @@
public:
Impl(uint8_t *const *data, const C2PlaneLayout &layout)
: mData(data), mLayout(layout), mError(C2_OK) {}
- explicit Impl(C2Error error) : mData(nullptr), mError(error) {}
+ explicit Impl(C2Status error) : mData(nullptr), mError(error) {}
uint8_t *const *data() const { return mData; }
const C2PlaneLayout &layout() const { return mLayout; }
- C2Error error() const { return mError; }
+ C2Status error() const { return mError; }
private:
uint8_t *const *mData;
C2PlaneLayout mLayout;
- C2Error mError;
+ C2Status mError;
};
C2GraphicView::C2GraphicView(
@@ -410,7 +410,7 @@
const C2PlaneLayout& layout)
: _C2PlanarSection(parent), mImpl(new Impl(data, layout)) {}
-C2GraphicView::C2GraphicView(C2Error error)
+C2GraphicView::C2GraphicView(C2Status error)
: _C2PlanarSection(nullptr), mImpl(new Impl(error)) {}
const uint8_t *const *C2GraphicView::data() const {
@@ -437,7 +437,7 @@
return view;
}
-C2Error C2GraphicView::error() const {
+C2Status C2GraphicView::error() const {
return mImpl->error();
}
@@ -453,12 +453,12 @@
}
}
- C2Error map(C2Rect rect) {
+ C2Status map(C2Rect rect) {
if (mData[0] != nullptr) {
// Already mapped.
return C2_OK;
}
- C2Error err = mAllocation->map(
+ C2Status err = mAllocation->map(
rect,
{ C2MemoryUsage::kSoftwareRead, 0 },
nullptr,
@@ -493,7 +493,7 @@
: C2Block2D(alloc), mImpl(new Impl(alloc)), mFence(fence) {}
C2Acquirable<const C2GraphicView> C2ConstGraphicBlock::map() const {
- C2Error err = mImpl->map(crop());
+ C2Status err = mImpl->map(crop());
if (err != C2_OK) {
C2DefaultGraphicView view(err);
return C2AcquirableConstGraphicView(err, mFence, view);
@@ -518,13 +518,13 @@
}
}
- C2Error map(C2Rect rect) {
+ C2Status map(C2Rect rect) {
if (mData[0] != nullptr) {
// Already mapped.
return C2_OK;
}
uint8_t *data[C2PlaneLayout::MAX_NUM_PLANES];
- C2Error err = mAllocation->map(
+ C2Status err = mAllocation->map(
rect,
{ C2MemoryUsage::kSoftwareRead, C2MemoryUsage::kSoftwareWrite },
nullptr,
@@ -560,7 +560,7 @@
: C2Block2D(alloc), mImpl(new Impl(alloc)) {}
C2Acquirable<C2GraphicView> C2GraphicBlock::map() {
- C2Error err = mImpl->map(crop());
+ C2Status err = mImpl->map(crop());
if (err != C2_OK) {
C2DefaultGraphicView view(err);
// TODO: fence
@@ -575,11 +575,11 @@
return mImpl->share(crop, fence);
}
-C2DefaultGraphicBlockAllocator::C2DefaultGraphicBlockAllocator(
+C2BasicGraphicBlockPool::C2BasicGraphicBlockPool(
const std::shared_ptr<C2Allocator> &allocator)
: mAllocator(allocator) {}
-C2Error C2DefaultGraphicBlockAllocator::allocateGraphicBlock(
+C2Status C2BasicGraphicBlockPool::fetchGraphicBlock(
uint32_t width,
uint32_t height,
uint32_t format,
@@ -588,7 +588,7 @@
block->reset();
std::shared_ptr<C2GraphicAllocation> alloc;
- C2Error err = mAllocator->allocateGraphicBuffer(width, height, format, usage, &alloc);
+ C2Status err = mAllocator->newGraphicAllocation(width, height, format, usage, &alloc);
if (err != C2_OK) {
return err;
}
@@ -650,7 +650,7 @@
const C2BufferData &data() const { return mData; }
- C2Error registerOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
+ C2Status registerOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
auto it = std::find_if(
mNotify.begin(), mNotify.end(),
[onDestroyNotify, arg] (const auto &pair) {
@@ -663,7 +663,7 @@
return C2_OK;
}
- C2Error unregisterOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
+ C2Status unregisterOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
auto it = std::find_if(
mNotify.begin(), mNotify.end(),
[onDestroyNotify, arg] (const auto &pair) {
@@ -684,7 +684,7 @@
return result;
}
- C2Error setInfo(const std::shared_ptr<C2Info> &info) {
+ C2Status setInfo(const std::shared_ptr<C2Info> &info) {
// To "update" you need to erase the existing one if any, and then insert.
(void) mInfos.erase(info->type());
(void) mInfos.insert({ info->type(), info });
@@ -720,11 +720,11 @@
const C2BufferData C2Buffer::data() const { return mImpl->data(); }
-C2Error C2Buffer::registerOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
+C2Status C2Buffer::registerOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
return mImpl->registerOnDestroyNotify(onDestroyNotify, arg);
}
-C2Error C2Buffer::unregisterOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
+C2Status C2Buffer::unregisterOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
return mImpl->unregisterOnDestroyNotify(onDestroyNotify, arg);
}
@@ -732,7 +732,7 @@
return mImpl->infos();
}
-C2Error C2Buffer::setInfo(const std::shared_ptr<C2Info> &info) {
+C2Status C2Buffer::setInfo(const std::shared_ptr<C2Info> &info) {
return mImpl->setInfo(info);
}
diff --git a/media/libstagefright/codec2/vndk/C2Store.cpp b/media/libstagefright/codec2/vndk/C2Store.cpp
index f21a3f0..f8ddfef 100644
--- a/media/libstagefright/codec2/vndk/C2Store.cpp
+++ b/media/libstagefright/codec2/vndk/C2Store.cpp
@@ -16,6 +16,7 @@
#include <C2AllocatorGralloc.h>
#include <C2AllocatorIon.h>
+#include <C2BufferPriv.h>
#include <C2Component.h>
#include <C2PlatformSupport.h>
@@ -27,7 +28,7 @@
class C2PlatformAllocatorStore : public C2AllocatorStore {
public:
- enum ID_ : uint32_t {
+ enum : id_t {
ION = PLATFORM_START,
GRALLOC,
};
@@ -35,7 +36,16 @@
C2PlatformAllocatorStore(
/* ionmapper */
);
- virtual status_t createAllocator(ID id, std::shared_ptr<C2Allocator> *const allocator);
+
+ virtual C2Status getAllocator(id_t id, std::shared_ptr<C2Allocator> *const allocator);
+
+ virtual std::vector<std::shared_ptr<const C2Allocator::Info>> listAllocators() const {
+ return std::vector<std::shared_ptr<const C2Allocator::Info>>(); /// \todo
+ }
+
+ virtual C2String getName() const {
+ return "android.allocator-store";
+ }
private:
// returns a shared-singleton ion allocator
@@ -48,8 +58,8 @@
C2PlatformAllocatorStore::C2PlatformAllocatorStore() {
}
-status_t C2PlatformAllocatorStore::createAllocator(
- ID id, std::shared_ptr<C2Allocator> *const allocator) {
+C2Status C2PlatformAllocatorStore::getAllocator(
+ id_t id, std::shared_ptr<C2Allocator> *const allocator) {
allocator->reset();
switch (id) {
// TODO: should we implement a generic registry for all, and use that?
@@ -100,4 +110,35 @@
return std::make_shared<C2PlatformAllocatorStore>();
}
+C2Status GetCodec2BlockPool(
+ C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
+ std::shared_ptr<C2BlockPool> *pool) {
+ pool->reset();
+ if (!component) {
+ return C2_BAD_VALUE;
+ }
+ // TODO support pre-registered block pools
+ std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
+ std::shared_ptr<C2Allocator> allocator;
+ C2Status res = C2_NOT_FOUND;
+
+ switch (id) {
+ case C2BlockPool::BASIC_LINEAR:
+ res = allocatorStore->getAllocator(C2AllocatorStore::DEFAULT_LINEAR, &allocator);
+ if (res == OK) {
+ *pool = std::make_shared<C2BasicLinearBlockPool>(allocator);
+ }
+ break;
+ case C2BlockPool::BASIC_GRAPHIC:
+ res = allocatorStore->getAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &allocator);
+ if (res == OK) {
+ *pool = std::make_shared<C2BasicGraphicBlockPool>(allocator);
+ }
+ break;
+ default:
+ break;
+ }
+ return res;
+}
+
} // namespace android
\ No newline at end of file
diff --git a/media/libstagefright/codec2/vndk/include/C2AllocatorGralloc.h b/media/libstagefright/codec2/vndk/include/C2AllocatorGralloc.h
index 94f74c8..78d41c4 100644
--- a/media/libstagefright/codec2/vndk/include/C2AllocatorGralloc.h
+++ b/media/libstagefright/codec2/vndk/include/C2AllocatorGralloc.h
@@ -30,17 +30,25 @@
typedef std::function<int (C2MemoryUsage, size_t,
/* => */ size_t*, unsigned*, unsigned*)> usage_mapper_fn;
- virtual C2Error allocateGraphicBuffer(
+ virtual id_t getId() const override;
+
+ virtual C2String getName() const override;
+
+ virtual std::shared_ptr<const Info> getInfo() const override {
+ return nullptr; // \todo
+ }
+
+ virtual C2Status newGraphicAllocation(
uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
std::shared_ptr<C2GraphicAllocation> *allocation) override;
- virtual C2Error recreateGraphicBuffer(
+ virtual C2Status priorGraphicAllocation(
const C2Handle *handle,
std::shared_ptr<C2GraphicAllocation> *allocation) override;
C2AllocatorGralloc();
- C2Error status() const;
+ C2Status status() const;
virtual ~C2AllocatorGralloc();
@@ -49,20 +57,6 @@
Impl *mImpl;
};
-#if 0
-class C2Allocation::Impl {
-public:
- Impl() : mMapped(false), mBase(nullptr) { }
- uint8_t* base() { return mMapped ? mBase : nullptr; }
-
- // TODO: call map...
-
-private:
- bool mMapped;
- uint8_t *mBase;
-};
-#endif
-
} // namespace android
#endif // STAGEFRIGHT_CODEC2_ALLOCATOR_GRALLOC_H_
diff --git a/media/libstagefright/codec2/vndk/include/C2AllocatorIon.h b/media/libstagefright/codec2/vndk/include/C2AllocatorIon.h
index a453a7d..2fff91f 100644
--- a/media/libstagefright/codec2/vndk/include/C2AllocatorIon.h
+++ b/media/libstagefright/codec2/vndk/include/C2AllocatorIon.h
@@ -29,22 +29,30 @@
typedef std::function<int (C2MemoryUsage, size_t,
/* => */ size_t*, unsigned*, unsigned*)> usage_mapper_fn;
- virtual C2Error allocateLinearBuffer(
+ virtual id_t getId() const override;
+
+ virtual C2String getName() const override;
+
+ virtual std::shared_ptr<const Info> getInfo() const override {
+ return nullptr; // \todo
+ }
+
+ virtual C2Status newLinearAllocation(
uint32_t capacity, C2MemoryUsage usage,
std::shared_ptr<C2LinearAllocation> *allocation) override;
- virtual C2Error recreateLinearBuffer(
+ virtual C2Status priorLinearAllocation(
const C2Handle *handle,
std::shared_ptr<C2LinearAllocation> *allocation) override;
C2AllocatorIon();
- C2Error status() const { return mInit; }
+ C2Status status() const { return mInit; }
virtual ~C2AllocatorIon();
private:
- C2Error mInit;
+ C2Status mInit;
int mIonFd;
usage_mapper_fn mUsageMapper;
};
diff --git a/media/libstagefright/codec2/vndk/include/C2BufferPriv.h b/media/libstagefright/codec2/vndk/include/C2BufferPriv.h
index 6a8f94e..56b0123 100644
--- a/media/libstagefright/codec2/vndk/include/C2BufferPriv.h
+++ b/media/libstagefright/codec2/vndk/include/C2BufferPriv.h
@@ -23,29 +23,46 @@
namespace android {
-class C2DefaultBlockAllocator : public C2BlockAllocator {
+class C2BasicLinearBlockPool : public C2BlockPool {
public:
- explicit C2DefaultBlockAllocator(const std::shared_ptr<C2Allocator> &allocator);
+ explicit C2BasicLinearBlockPool(const std::shared_ptr<C2Allocator> &allocator);
- virtual ~C2DefaultBlockAllocator() = default;
+ virtual ~C2BasicLinearBlockPool() = default;
- virtual C2Error allocateLinearBlock(
+ virtual C2Allocator::id_t getAllocatorId() const override {
+ return mAllocator->getId();
+ }
+
+ virtual local_id_t getLocalId() const override {
+ return BASIC_LINEAR;
+ }
+
+ virtual C2Status fetchLinearBlock(
uint32_t capacity,
C2MemoryUsage usage,
std::shared_ptr<C2LinearBlock> *block /* nonnull */) override;
- // TODO:
+ // TODO: fetchCircularBlock
+
private:
const std::shared_ptr<C2Allocator> mAllocator;
};
-class C2DefaultGraphicBlockAllocator : public C2BlockAllocator {
+class C2BasicGraphicBlockPool : public C2BlockPool {
public:
- explicit C2DefaultGraphicBlockAllocator(const std::shared_ptr<C2Allocator> &allocator);
+ explicit C2BasicGraphicBlockPool(const std::shared_ptr<C2Allocator> &allocator);
- virtual ~C2DefaultGraphicBlockAllocator() = default;
+ virtual ~C2BasicGraphicBlockPool() = default;
- virtual C2Error allocateGraphicBlock(
+ virtual C2Allocator::id_t getAllocatorId() const override {
+ return mAllocator->getId();
+ }
+
+ virtual local_id_t getLocalId() const override {
+ return BASIC_GRAPHIC;
+ }
+
+ virtual C2Status fetchGraphicBlock(
uint32_t width,
uint32_t height,
uint32_t format,
@@ -56,21 +73,6 @@
const std::shared_ptr<C2Allocator> mAllocator;
};
-
-#if 0
-class C2Allocation::Impl {
-public:
- Impl() : mMapped(false), mBase(nullptr) { }
- uint8_t* base() { return mMapped ? mBase : nullptr; }
-
- // TODO: call map...
-
-private:
- bool mMapped;
- uint8_t *mBase;
-};
-#endif
-
} // namespace android
#endif // STAGEFRIGHT_CODEC2_BUFFER_PRIV_H_
diff --git a/media/libstagefright/codec2/vndk/include/C2ErrnoUtils.h b/media/libstagefright/codec2/vndk/include/C2ErrnoUtils.h
index f834cdb..aea3a6f 100644
--- a/media/libstagefright/codec2/vndk/include/C2ErrnoUtils.h
+++ b/media/libstagefright/codec2/vndk/include/C2ErrnoUtils.h
@@ -23,32 +23,32 @@
namespace android {
// standard ERRNO mappings
-template<int N> constexpr C2Error _c2_errno2error_impl();
-template<> constexpr C2Error _c2_errno2error_impl<0>() { return C2_OK; }
-template<> constexpr C2Error _c2_errno2error_impl<EINVAL>() { return C2_BAD_VALUE; }
-template<> constexpr C2Error _c2_errno2error_impl<EACCES>() { return C2_NO_PERMISSION; }
-template<> constexpr C2Error _c2_errno2error_impl<EPERM>() { return C2_NO_PERMISSION; }
-template<> constexpr C2Error _c2_errno2error_impl<ENOMEM>() { return C2_NO_MEMORY; }
+template<int N> constexpr C2Status _c2_errno2status_impl();
+template<> constexpr C2Status _c2_errno2status_impl<0>() { return C2_OK; }
+template<> constexpr C2Status _c2_errno2status_impl<EINVAL>() { return C2_BAD_VALUE; }
+template<> constexpr C2Status _c2_errno2status_impl<EACCES>() { return C2_REFUSED; }
+template<> constexpr C2Status _c2_errno2status_impl<EPERM>() { return C2_REFUSED; }
+template<> constexpr C2Status _c2_errno2status_impl<ENOMEM>() { return C2_NO_MEMORY; }
-// map standard errno-s to the equivalent C2Error
+// map standard errno-s to the equivalent C2Status
template<int... N> struct _c2_map_errno_impl;
template<int E, int ... N> struct _c2_map_errno_impl<E, N...> {
- static C2Error map(int result) {
+ static C2Status map(int result) {
if (result == E) {
- return _c2_errno2error_impl<E>();
+ return _c2_errno2status_impl <E>();
} else {
return _c2_map_errno_impl<N...>::map(result);
}
}
};
template<> struct _c2_map_errno_impl<> {
- static C2Error map(int result) {
+ static C2Status map(int result) {
return result == 0 ? C2_OK : C2_CORRUPTED;
}
};
template<int... N>
-C2Error c2_map_errno(int result) {
+C2Status c2_map_errno(int result) {
return _c2_map_errno_impl<N...>::map(result);
}
diff --git a/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h b/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h
index 9402050..40bb548 100644
--- a/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h
+++ b/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h
@@ -25,9 +25,33 @@
/**
* Returns the platform allocator store.
+ * \retval nullptr if the platform allocator store could not be obtained
*/
std::shared_ptr<C2AllocatorStore> GetCodec2PlatformAllocatorStore();
+/**
+ * Retrieves a block pool for a component.
+ *
+ * \param id the local ID of the block pool
+ * \param component the component using the block pool (must be non-null)
+ * \param pool pointer to where the obtained block pool shall be stored on success. nullptr
+ * will be stored here on failure
+ *
+ * \retval C2_OK the operation was successful
+ * \retval C2_BAD_VALUE the component is null
+ * \retval C2_NOT_FOUND if the block pool does not exist
+ * \retval C2_NO_MEMORY not enough memory to fetch the block pool (this return value is only
+ * possible for basic pools)
+ * \retval C2_TIMED_OUT the operation timed out (this return value is only possible for basic pools)
+ * \retval C2_REFUSED no permission to complete any required allocation (this return value is only
+ * possible for basic pools)
+ * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected,
+ * this return value is only possible for basic pools)
+ */
+C2Status GetCodec2BlockPool(
+ C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
+ std::shared_ptr<C2BlockPool> *pool);
+
} // namespace android
#endif // STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
diff --git a/media/libstagefright/codecs/avcdec/Android.bp b/media/libstagefright/codecs/avcdec/Android.bp
index 3b2602d..5dcffd5 100644
--- a/media/libstagefright/codecs/avcdec/Android.bp
+++ b/media/libstagefright/codecs/avcdec/Android.bp
@@ -74,9 +74,9 @@
misc_undefined: [
"signed-integer-overflow",
],
- cfi: true,
+ cfi: false, // true,
diag: {
- cfi: true,
+ cfi: false, // true,
},
},
diff --git a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
index 5f55e1e..12eaff5 100644
--- a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
+++ b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
@@ -27,6 +27,8 @@
#include "ih264d.h"
#include "C2SoftAvcDec.h"
+#include <C2PlatformSupport.h>
+
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaDefs.h>
#include <utils/misc.h>
@@ -94,11 +96,15 @@
bool validateField(
const C2FieldSupportedValues &supportedValues, const T &value) {
switch (supportedValues.type) {
+ case C2FieldSupportedValues::EMPTY:
+ {
+ return false;
+ }
case C2FieldSupportedValues::RANGE:
{
// TODO: handle step, nom, denom
- return Getter<T>::get(supportedValues.range.min) < value
- && value < Getter<T>::get(supportedValues.range.max);
+ return Getter<T>::get(supportedValues.range.min) <= value
+ && value <= Getter<T>::get(supportedValues.range.max);
}
case C2FieldSupportedValues::VALUES:
{
@@ -153,7 +159,7 @@
const C2FieldSupportedValues &supportedValues = mSupportedValues.at(field).supported;
if (!validateField(supportedValues, param->mValue)) {
return std::unique_ptr<C2SettingResult>(
- new C2SettingResult {field, C2SettingResult::BAD_VALUE, nullptr, {}});
+ new C2SettingResult {C2SettingResult::BAD_VALUE, {field, nullptr}, {}});
}
return nullptr;
}
@@ -171,13 +177,13 @@
const C2FieldSupportedValues &supportedWidth = mSupportedValues.at(field).supported;
if (!validateField(supportedWidth, param->mWidth)) {
return std::unique_ptr<C2SettingResult>(
- new C2SettingResult {field, C2SettingResult::BAD_VALUE, nullptr, {}});
+ new C2SettingResult {C2SettingResult::BAD_VALUE, {field, nullptr}, {}});
}
field = C2ParamField(param, &T::mHeight);
const C2FieldSupportedValues &supportedHeight = mSupportedValues.at(field).supported;
if (!validateField(supportedHeight, param->mHeight)) {
return std::unique_ptr<C2SettingResult>(
- new C2SettingResult {field, C2SettingResult::BAD_VALUE, nullptr, {}});
+ new C2SettingResult {C2SettingResult::BAD_VALUE, {field, nullptr}, {}});
}
return nullptr;
}
@@ -191,7 +197,7 @@
T* param = (T*)c2param;
if (strncmp(param->m.mValue, mExpected, param->flexCount()) != 0) {
return std::unique_ptr<C2SettingResult>(
- new C2SettingResult {C2ParamField(param, &T::m), C2SettingResult::BAD_VALUE, nullptr, {}});
+ new C2SettingResult {C2SettingResult::BAD_VALUE, {C2ParamField(param, &T::m), nullptr}, {}});
}
return nullptr;
}
@@ -271,6 +277,8 @@
mMaxVideoSizeHint.mWidth = H264_MAX_FRAME_WIDTH;
mMaxVideoSizeHint.mHeight = H264_MAX_FRAME_HEIGHT;
+ mOutputBlockPools = C2PortBlockPoolsTuning::output::alloc_unique({});
+
auto insertParam = [¶ms = mParams] (C2Param *param) {
params[restoreIndex(param)] = param;
};
@@ -418,6 +426,8 @@
false, "_video_size", &mVideoSize));
mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
false, "_max_video_size_hint", &mMaxVideoSizeHint));
+ mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
+ false, "_output_block_pools", mOutputBlockPools.get()));
}
C2String C2SoftAvcDecIntf::getName() const {
@@ -428,7 +438,7 @@
return mId;
}
-status_t C2SoftAvcDecIntf::query_nb(
+C2Status C2SoftAvcDecIntf::query_nb(
const std::vector<C2Param* const> & stackParams,
const std::vector<C2Param::Index> & heapParamIndices,
std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
@@ -439,6 +449,8 @@
uint32_t index = restoreIndex(param);
if (!mParams.count(index)) {
+ // TODO: add support for output-block-pools (this will be done when we move all
+ // config to shared ptr)
continue;
}
@@ -461,12 +473,19 @@
return C2_OK;
}
-status_t C2SoftAvcDecIntf::config_nb(
+C2Status C2SoftAvcDecIntf::config_nb(
const std::vector<C2Param* const> ¶ms,
std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
- status_t err = C2_OK;
+ C2Status err = C2_OK;
for (C2Param *param : params) {
uint32_t index = restoreIndex(param);
+ if (param->index() == mOutputBlockPools.get()->index()) {
+ // setting output block pools
+ mOutputBlockPools.reset(
+ (C2PortBlockPoolsTuning::output *)C2Param::Copy(*param).release());
+ continue;
+ }
+
if (mParams.count(index) == 0) {
// We can't create C2SettingResult with no field, so just skipping in this case.
err = C2_BAD_INDEX;
@@ -485,45 +504,48 @@
return err;
}
-status_t C2SoftAvcDecIntf::commit_sm(
+C2Status C2SoftAvcDecIntf::commit_sm(
const std::vector<C2Param* const> ¶ms,
std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
// TODO
return config_nb(params, failures);
}
-status_t C2SoftAvcDecIntf::createTunnel_sm(node_id targetComponent) {
+C2Status C2SoftAvcDecIntf::createTunnel_sm(node_id targetComponent) {
// Tunneling is not supported
(void) targetComponent;
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
-status_t C2SoftAvcDecIntf::releaseTunnel_sm(node_id targetComponent) {
+C2Status C2SoftAvcDecIntf::releaseTunnel_sm(node_id targetComponent) {
// Tunneling is not supported
(void) targetComponent;
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
std::shared_ptr<C2ParamReflector> C2SoftAvcDecIntf::getParamReflector() const {
return mParamReflector;
}
-status_t C2SoftAvcDecIntf::getSupportedParams(
+C2Status C2SoftAvcDecIntf::getSupportedParams(
std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const {
params->insert(params->begin(), mParamDescs.begin(), mParamDescs.end());
return C2_OK;
}
-status_t C2SoftAvcDecIntf::getSupportedValues(
- const std::vector<const C2ParamField> &fields,
- std::vector<C2FieldSupportedValues>* const values) const {
- for (const auto &field : fields) {
- if (mSupportedValues.count(field) == 0) {
- return BAD_VALUE;
+C2Status C2SoftAvcDecIntf::getSupportedValues(
+ std::vector<C2FieldSupportedValuesQuery> &fields) const {
+ C2Status res = C2_OK;
+ for (C2FieldSupportedValuesQuery &query : fields) {
+ if (mSupportedValues.count(query.field) == 0) {
+ query.status = C2_BAD_INDEX;
+ res = C2_BAD_INDEX;
+ } else {
+ query.status = C2_OK;
+ query.values = mSupportedValues.at(query.field).supported;
}
- values->push_back(mSupportedValues.at(field).supported);
}
- return C2_OK;
+ return res;
}
void C2SoftAvcDecIntf::updateSupportedValues() {
@@ -644,7 +666,7 @@
CHECK_EQ(deInitDecoder(), (status_t)OK);
}
-status_t C2SoftAvcDec::queue_nb(
+C2Status C2SoftAvcDec::queue_nb(
std::list<std::unique_ptr<C2Work>>* const items) {
if (!mThread->isRunning()) {
return C2_CORRUPTED;
@@ -659,13 +681,13 @@
return C2_OK;
}
-status_t C2SoftAvcDec::announce_nb(const std::vector<C2WorkOutline> &items) {
+C2Status C2SoftAvcDec::announce_nb(const std::vector<C2WorkOutline> &items) {
// Tunneling is not supported
(void) items;
- return C2_UNSUPPORTED;
+ return C2_OMITTED;
}
-status_t C2SoftAvcDec::flush_sm(
+C2Status C2SoftAvcDec::flush_sm(
bool flushThrough, std::list<std::unique_ptr<C2Work>>* const flushedWork) {
// Tunneling is not supported
(void) flushThrough;
@@ -691,7 +713,7 @@
return C2_OK;
}
-status_t C2SoftAvcDec::drain_nb(bool drainThrough) {
+C2Status C2SoftAvcDec::drain_nb(bool drainThrough) {
// Tunneling is not supported
(void) drainThrough;
@@ -707,14 +729,14 @@
return C2_OK;
}
-status_t C2SoftAvcDec::start() {
+C2Status C2SoftAvcDec::start() {
if (!mThread->isRunning()) {
mThread->start(shared_from_this());
}
return C2_OK;
}
-status_t C2SoftAvcDec::stop() {
+C2Status C2SoftAvcDec::stop() {
ALOGV("stop");
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::chrono::system_clock::time_point deadline = now + std::chrono::milliseconds(500);
@@ -1204,7 +1226,19 @@
// TODO: format & usage
uint32_t format = HAL_PIXEL_FORMAT_YV12;
C2MemoryUsage usage = { C2MemoryUsage::kSoftwareRead, C2MemoryUsage::kSoftwareWrite };
- (void) work->worklets.front()->allocators[0]->allocateGraphicBlock(
+ // TODO: lock access to interface
+ C2BlockPool::local_id_t poolId =
+ mIntf->mOutputBlockPools->flexCount() ?
+ mIntf->mOutputBlockPools->m.mValues[0] : C2BlockPool::BASIC_GRAPHIC;
+ if (!mOutputBlockPool || mOutputBlockPool->getLocalId() != poolId) {
+ C2Status err = GetCodec2BlockPool(poolId, shared_from_this(), &mOutputBlockPool);
+ if (err != C2_OK) {
+ // TODO: trip
+ }
+ }
+ ALOGE("using allocator %u", mOutputBlockPool->getAllocatorId());
+
+ (void)mOutputBlockPool->fetchGraphicBlock(
mWidth, mHeight, format, usage, &mAllocatedBlock);
ALOGE("provided (%dx%d) required (%dx%d)", mAllocatedBlock->width(), mAllocatedBlock->height(), mWidth, mHeight);
}
diff --git a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h
index 6a83d1d..41ccf39 100644
--- a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h
+++ b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h
@@ -85,24 +85,23 @@
// From C2ComponentInterface
virtual C2String getName() const override;
virtual node_id getId() const override;
- virtual status_t query_nb(
+ virtual C2Status query_nb(
const std::vector<C2Param* const> &stackParams,
const std::vector<C2Param::Index> &heapParamIndices,
std::vector<std::unique_ptr<C2Param>>* const heapParams) const override;
- virtual status_t config_nb(
+ virtual C2Status config_nb(
const std::vector<C2Param* const> ¶ms,
std::vector<std::unique_ptr<C2SettingResult>>* const failures) override;
- virtual status_t commit_sm(
+ virtual C2Status commit_sm(
const std::vector<C2Param* const> ¶ms,
std::vector<std::unique_ptr<C2SettingResult>>* const failures) override;
- virtual status_t createTunnel_sm(node_id targetComponent) override;
- virtual status_t releaseTunnel_sm(node_id targetComponent) override;
+ virtual C2Status createTunnel_sm(node_id targetComponent) override;
+ virtual C2Status releaseTunnel_sm(node_id targetComponent) override;
virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override;
- virtual status_t getSupportedParams(
+ virtual C2Status getSupportedParams(
std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const override;
- virtual status_t getSupportedValues(
- const std::vector<const C2ParamField> &fields,
- std::vector<C2FieldSupportedValues>* const values) const override;
+ virtual C2Status getSupportedValues(
+ std::vector<C2FieldSupportedValuesQuery> &fields) const override;
private:
class ParamReflector;
@@ -119,6 +118,7 @@
// TODO: C2StreamMimeConfig mInputStreamMime;
// TODO: C2StreamMimeConfig mOutputStreamMime;
C2StreamFormatConfig::input mInputStreamFormat;
+ std::unique_ptr<C2PortBlockPoolsTuning::output> mOutputBlockPools;
C2StreamFormatConfig::output mOutputStreamFormat;
C2VideoSizeStreamInfo::output mVideoSize;
C2MaxVideoSizeHintPortSetting::input mMaxVideoSizeHint;
@@ -139,6 +139,7 @@
std::vector<std::shared_ptr<C2ParamDescriptor>> mParamDescs;
void updateSupportedValues();
+ friend class C2SoftAvcDec;
};
class C2SoftAvcDec
@@ -150,13 +151,13 @@
virtual ~C2SoftAvcDec();
// From C2Component
- virtual status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) override;
- virtual status_t announce_nb(const std::vector<C2WorkOutline> &items) override;
- virtual status_t flush_sm(
+ virtual C2Status queue_nb(std::list<std::unique_ptr<C2Work>>* const items) override;
+ virtual C2Status announce_nb(const std::vector<C2WorkOutline> &items) override;
+ virtual C2Status flush_sm(
bool flushThrough, std::list<std::unique_ptr<C2Work>>* const flushedWork) override;
- virtual status_t drain_nb(bool drainThrough) override;
- virtual status_t start() override;
- virtual status_t stop() override;
+ virtual C2Status drain_nb(bool drainThrough) override;
+ virtual C2Status start() override;
+ virtual C2Status stop() override;
virtual void reset() override;
virtual void release() override;
virtual std::shared_ptr<C2ComponentInterface> intf() override;
@@ -192,6 +193,7 @@
const std::shared_ptr<C2SoftAvcDecIntf> mIntf;
const std::shared_ptr<C2ComponentListener> mListener;
+ std::shared_ptr<C2BlockPool> mOutputBlockPool;
std::mutex mQueueLock;
std::condition_variable mQueueCond;
@@ -228,9 +230,9 @@
bool mChangingResolution;
bool mFlushNeeded;
bool mSignalledError;
- int32_t mWidth;
- int32_t mHeight;
- int32_t mStride;
+ uint32_t mWidth;
+ uint32_t mHeight;
+ uint32_t mStride;
size_t mInputOffset;
void processQueue();
diff --git a/media/libstagefright/codecs/cmds/codec2.cpp b/media/libstagefright/codecs/cmds/codec2.cpp
index 29669aa..c7e1c82 100644
--- a/media/libstagefright/codecs/cmds/codec2.cpp
+++ b/media/libstagefright/codecs/cmds/codec2.cpp
@@ -95,9 +95,7 @@
sp<IProducerListener> mProducerListener;
std::shared_ptr<C2Allocator> mAllocIon;
- std::shared_ptr<C2Allocator> mAllocGralloc;
- std::shared_ptr<C2BlockAllocator> mLinearAlloc;
- std::shared_ptr<C2BlockAllocator> mGraphicAlloc;
+ std::shared_ptr<C2BlockPool> mLinearPool;
std::mutex mQueueLock;
std::condition_variable mQueueCondition;
@@ -144,11 +142,8 @@
CHECK_EQ(mComposerClient->initCheck(), (status_t)OK);
std::shared_ptr<C2AllocatorStore> store = GetCodec2PlatformAllocatorStore();
- CHECK_EQ(store->createAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mAllocIon), C2_OK);
- CHECK_EQ(store->createAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &mAllocGralloc), C2_OK);
-
- mLinearAlloc = std::make_shared<C2DefaultBlockAllocator>(mAllocIon);
- mGraphicAlloc = std::make_shared<C2DefaultGraphicBlockAllocator>(mAllocGralloc);
+ CHECK_EQ(store->getAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mAllocIon), C2_OK);
+ mLinearPool = std::make_shared<C2BasicLinearBlockPool>(mAllocIon);
mControl = mComposerClient->createSurface(
String8("A Surface"),
@@ -214,6 +209,10 @@
}
std::shared_ptr<C2Component> component(std::make_shared<C2SoftAvcDec>("avc", 0, mListener));
+ std::unique_ptr<C2PortBlockPoolsTuning::output> pools =
+ C2PortBlockPoolsTuning::output::alloc_unique({ (uint64_t)C2BlockPool::BASIC_GRAPHIC });
+ std::vector<std::unique_ptr<C2SettingResult>> result;
+ (void)component->intf()->config_nb({pools.get()}, &result);
component->start();
for (int i = 0; i < 8; ++i) {
@@ -274,7 +273,7 @@
});
long numFrames = 0;
- mLinearAlloc.reset(new C2DefaultBlockAllocator(mAllocIon));
+ mLinearPool.reset(new C2BasicLinearBlockPool(mAllocIon));
for (;;) {
size_t size = 0u;
@@ -328,7 +327,7 @@
work->input.ordinal.frame_index = numFrames;
std::shared_ptr<C2LinearBlock> block;
- mLinearAlloc->allocateLinearBlock(
+ mLinearPool->fetchLinearBlock(
size,
{ C2MemoryUsage::kSoftwareRead, C2MemoryUsage::kSoftwareWrite },
&block);
@@ -343,7 +342,6 @@
work->input.buffers.emplace_back(new LinearBuffer(block));
work->worklets.clear();
work->worklets.emplace_back(new C2Worklet);
- work->worklets.front()->allocators.emplace_back(mGraphicAlloc);
std::list<std::unique_ptr<C2Work>> items;
items.push_back(std::move(work));
diff --git a/media/libstagefright/filters/Android.bp b/media/libstagefright/filters/Android.bp
index a0af4f6..e944224 100644
--- a/media/libstagefright/filters/Android.bp
+++ b/media/libstagefright/filters/Android.bp
@@ -13,12 +13,8 @@
"ZeroFilter.cpp",
],
- header_libs: [
- "media_plugin_headers",
- ],
-
- export_header_lib_headers: [
- "media_plugin_headers",
+ include_dirs: [
+ "frameworks/native/include/media/openmax",
],
cflags: [
diff --git a/media/libstagefright/include/media/stagefright/OMXClient.h b/media/libstagefright/include/media/stagefright/OMXClient.h
index e7b9be5..bb133d3 100644
--- a/media/libstagefright/include/media/stagefright/OMXClient.h
+++ b/media/libstagefright/include/media/stagefright/OMXClient.h
@@ -26,8 +26,8 @@
public:
OMXClient();
- status_t connect(const char* name = "default");
-
+ status_t connect();
+ status_t connect(const char* name);
void disconnect();
sp<IOMX> interface();
diff --git a/media/ndk/NdkImage.cpp b/media/ndk/NdkImage.cpp
index c4ff537..20b1667 100644
--- a/media/ndk/NdkImage.cpp
+++ b/media/ndk/NdkImage.cpp
@@ -37,8 +37,8 @@
mTimestamp(timestamp), mWidth(width), mHeight(height), mNumPlanes(numPlanes) {
}
-// Can only be called by free() with mLock hold
AImage::~AImage() {
+ Mutex::Autolock _l(mLock);
if (!mIsClosed) {
LOG_ALWAYS_FATAL(
"Error: AImage %p is deleted before returning buffer to AImageReader!", this);
@@ -78,7 +78,6 @@
ALOGE("Cannot free AImage before close!");
return;
}
- Mutex::Autolock _l(mLock);
delete this;
}
diff --git a/media/ndk/OWNERS b/media/ndk/OWNERS
index 43e4bb3..11e8340 100644
--- a/media/ndk/OWNERS
+++ b/media/ndk/OWNERS
@@ -1 +1,5 @@
marcone@google.com
+# For AImage/AImageReader
+etalvala@google.com
+yinchiayeh@google.com
+zhijunhe@google.com
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index 31f0550..9bd68e1 100644
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -35,7 +35,8 @@
* A device mask for all audio input devices that are considered "virtual" when evaluating
* active inputs in getActiveInputs()
*/
-#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX)
+#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX|\
+ AUDIO_DEVICE_IN_BUS|AUDIO_DEVICE_IN_FM_TUNER)
/**
diff --git a/services/mediaanalytics/MediaAnalyticsService.cpp b/services/mediaanalytics/MediaAnalyticsService.cpp
index f08be50..83992aa 100644
--- a/services/mediaanalytics/MediaAnalyticsService.cpp
+++ b/services/mediaanalytics/MediaAnalyticsService.cpp
@@ -318,6 +318,7 @@
saveItem(mFinalized, oitem, 0);
}
// new record could itself be marked finalized...
+ id = item->getSessionID();
if (finalizing) {
summarize(item);
saveItem(mFinalized, item, 0);
@@ -325,16 +326,15 @@
} else {
saveItem(mOpen, item, 1);
}
- id = item->getSessionID();
} else {
// combine the records, send it to finalized if appropriate
oitem->merge(item);
+ id = oitem->getSessionID();
if (finalizing) {
summarize(oitem);
saveItem(mFinalized, oitem, 0);
mItemsFinalized++;
}
- id = oitem->getSessionID();
// we're responsible for disposing of the dead record
delete item;
@@ -614,17 +614,28 @@
// caller should hold mLock
void MediaAnalyticsService::saveItem(List<MediaAnalyticsItem *> *l, MediaAnalyticsItem * item, int front) {
- // adding at back of queue (fifo order)
if (front) {
+ // for non-finalized stuff, since we expect to reference it again soon,
+ // make it quicker to find (nearer the front of our list)
l->push_front(item);
} else {
+ // for finalized records, which we want to dump 'in sequence order'
l->push_back(item);
}
+ // our reclaim process is for oldest-first queues
+ if (front) {
+ return;
+ }
+
+
// keep removing old records the front until we're in-bounds (count)
if (mMaxRecords > 0) {
while (l->size() > (size_t) mMaxRecords) {
MediaAnalyticsItem * oitem = *(l->begin());
+ if (oitem == item) {
+ break;
+ }
l->erase(l->begin());
delete oitem;
mItemsDiscarded++;
@@ -638,6 +649,9 @@
while (l->size() > 0) {
MediaAnalyticsItem * oitem = *(l->begin());
nsecs_t when = oitem->getTimestamp();
+ if (oitem == item) {
+ break;
+ }
// careful about timejumps too
if ((now > when) && (now-when) <= mMaxRecordAgeNs) {
// this (and the rest) are recent enough to keep
diff --git a/services/mediacodec/main_codecservice.cpp b/services/mediacodec/main_codecservice.cpp
index 6bb3fa2..6f14a42 100644
--- a/services/mediacodec/main_codecservice.cpp
+++ b/services/mediacodec/main_codecservice.cpp
@@ -35,18 +35,16 @@
int main(int argc __unused, char** argv)
{
+ strcpy(argv[0], "media.codec");
LOG(INFO) << "mediacodecservice starting";
+ signal(SIGPIPE, SIG_IGN);
+ SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);
#ifdef USE_VNDBINDER
android::ProcessState::initWithDriver("/dev/vndbinder");
android::ProcessState::self()->startThreadPool();
#endif // USE_VNDBINDER
- signal(SIGPIPE, SIG_IGN);
- SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);
-
- strcpy(argv[0], "media.codec");
-
::android::hardware::configureRpcThreadpool(64, false);
using namespace ::android::hardware::media::omx::V1_0;
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 6d833aa..a7d6e83 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -313,7 +313,7 @@
}
-sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent_l(sound_trigger_service_state_t state)
+sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent(sound_trigger_service_state_t state)
{
AutoMutex lock(mMemoryDealerLock);
sp<IMemory> eventMemory;
@@ -328,34 +328,23 @@
return eventMemory;
}
-// call with mServiceLock held
-void SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state,
+void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
Module *module)
{
- sp<IMemory> eventMemory = prepareServiceStateEvent_l(state);
+ sp<IMemory> eventMemory = prepareServiceStateEvent(state);
if (eventMemory == 0) {
return;
}
- sp<Module> strongModule;
- for (size_t i = 0; i < mModules.size(); i++) {
- if (mModules.valueAt(i).get() == module) {
- strongModule = mModules.valueAt(i);
- break;
- }
- }
- if (strongModule == 0) {
- return;
- }
sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
eventMemory);
- callbackEvent->setModule(strongModule);
+ callbackEvent->setModule(module);
sendCallbackEvent(callbackEvent);
}
-void SoundTriggerHwService::sendServiceStateEvent_l(sound_trigger_service_state_t state,
- ModuleClient *moduleClient)
+void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
+ ModuleClient *moduleClient)
{
- sp<IMemory> eventMemory = prepareServiceStateEvent_l(state);
+ sp<IMemory> eventMemory = prepareServiceStateEvent(state);
if (eventMemory == 0) {
return;
}
@@ -906,7 +895,7 @@
}
exit:
- service->sendServiceStateEvent_l(state, this);
+ service->sendServiceStateEvent(state, this);
}
@@ -1051,7 +1040,7 @@
return;
}
}
- service->sendServiceStateEvent_l(state, this);
+ service->sendServiceStateEvent(state, this);
}
void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
diff --git a/services/soundtrigger/SoundTriggerHwService.h b/services/soundtrigger/SoundTriggerHwService.h
index a955f40..708fc98 100644
--- a/services/soundtrigger/SoundTriggerHwService.h
+++ b/services/soundtrigger/SoundTriggerHwService.h
@@ -221,10 +221,10 @@
sp<IMemory> prepareSoundModelEvent(struct sound_trigger_model_event *event);
void sendSoundModelEvent(struct sound_trigger_model_event *event, Module *module);
- sp<IMemory> prepareServiceStateEvent_l(sound_trigger_service_state_t state);
- void sendServiceStateEvent_l(sound_trigger_service_state_t state, Module *module);
- void sendServiceStateEvent_l(sound_trigger_service_state_t state,
- ModuleClient *moduleClient);
+ sp<IMemory> prepareServiceStateEvent(sound_trigger_service_state_t state);
+ void sendServiceStateEvent(sound_trigger_service_state_t state, Module *module);
+ void sendServiceStateEvent(sound_trigger_service_state_t state,
+ ModuleClient *moduleClient);
void sendCallbackEvent(const sp<CallbackEvent>& event);
void onCallbackEvent(const sp<CallbackEvent>& event);