staticbool is_valid_img_fmt(aom_img_fmt_t fmt) { switch (fmt) { case AOM_IMG_FMT_YV12: case AOM_IMG_FMT_I420: case AOM_IMG_FMT_I422: case AOM_IMG_FMT_I444: case AOM_IMG_FMT_NV12: case AOM_IMG_FMT_I42016: case AOM_IMG_FMT_YV1216: case AOM_IMG_FMT_I42216: case AOM_IMG_FMT_I44416: returntrue; default: return false;
}
}
static aom_image_t *img_alloc_helper(
aom_image_t *img, aom_img_fmt_t fmt, unsigned int d_w, unsigned int d_h, unsigned int buf_align, unsigned int stride_align, unsigned int size_align, unsigned int border, unsigned char *img_data,
aom_alloc_img_data_cb_fn_t alloc_cb, void *cb_priv) { /* NOTE: In this function, bit_depth is either 8 or 16 (if *AOM_IMG_FMT_HIGHBITDEPTHisset),never10or12.
*/ unsigned int xcs, ycs, bps, bit_depth;
if (img != NULL) memset(img, 0, sizeof(aom_image_t));
if (!is_valid_img_fmt(fmt)) goto fail;
/* Impose maximum values on input parameters so that this function can *performarithmeticoperationswithoutworryingaboutoverflows.
*/
if (d_w > 0x08000000 || d_h > 0x08000000 || buf_align > 65536 ||
stride_align > 65536 || size_align > 65536 || border > 65536) {
goto fail;
}
/* Treat align==0 like align==1 */
if (!buf_align) buf_align = 1;
/* Validate alignment (must be power of 2) */
if (buf_align & (buf_align - 1)) goto fail;
/* Treat align==0 like align==1 */
if (!stride_align) stride_align = 1;
/* Validate alignment (must be power of 2) */
if (stride_align & (stride_align - 1)) goto fail;
/* Treat align==0 like align==1 */
if (!size_align) size_align = 1;
/* Validate alignment (must be power of 2) */
if (size_align & (size_align - 1)) goto fail;
/* Get sample size for this format */ switch (fmt) { case AOM_IMG_FMT_I420: case AOM_IMG_FMT_YV12: case AOM_IMG_FMT_NV12: bps = 12; break; case AOM_IMG_FMT_I422: bps = 16; break; case AOM_IMG_FMT_I444: bps = 24; break; case AOM_IMG_FMT_YV1216: case AOM_IMG_FMT_I42016: bps = 24; break; case AOM_IMG_FMT_I42216: bps = 32; break; case AOM_IMG_FMT_I44416: bps = 48; break; default: bps = 16; break;
}
/* Get chroma shift values for this format */ switch (fmt) { case AOM_IMG_FMT_I420: case AOM_IMG_FMT_YV12: case AOM_IMG_FMT_NV12: case AOM_IMG_FMT_I422: case AOM_IMG_FMT_I42016: case AOM_IMG_FMT_YV1216: case AOM_IMG_FMT_I42216: xcs = 1; break; default: xcs = 0; break;
}
switch (fmt) { case AOM_IMG_FMT_I420: case AOM_IMG_FMT_YV12: case AOM_IMG_FMT_NV12: case AOM_IMG_FMT_YV1216: case AOM_IMG_FMT_I42016: ycs = 1; break; default: ycs = 0; break;
}
/* Calculate storage sizes given the chroma subsampling */ constunsigned int w = align_image_dimension(d_w, xcs, size_align);
assert(d_w <= w); constunsigned int h = align_image_dimension(d_h, ycs, size_align);
assert(d_h <= h);
uint64_t s = (uint64_t)w + 2 * border;
s = (fmt & AOM_IMG_FMT_PLANAR) ? s : s * bps / bit_depth;
s = s * bit_depth / 8;
s = (s + stride_align - 1) & ~((uint64_t)stride_align - 1);
if (s > INT_MAX) goto fail; const int stride_in_bytes = (int)s;
/* Allocate the new image */
if (!img) {
img = (aom_image_t *)calloc(1, sizeof(aom_image_t));
if (fmt == AOM_IMG_FMT_NV12) { // Each row is a row of U and a row of V interleaved, so the stride is twice // as long.
img->stride[AOM_PLANE_U] *= 2;
img->stride[AOM_PLANE_V] = 0;
}
aom_image_t *aom_img_wrap(aom_image_t *img, aom_img_fmt_t fmt, unsigned int d_w, unsigned int d_h, unsigned int stride_align, unsigned char *img_data) { /* Set buf_align = 1. It is ignored by img_alloc_helper because img_data is
* not NULL. */ return img_alloc_helper(img, fmt, d_w, d_h, 1, stride_align, 1, 0, img_data,
NULL, NULL);
}
aom_image_t *aom_img_alloc_with_border(aom_image_t *img, aom_img_fmt_t fmt, unsigned int d_w, unsigned int d_h, unsigned int align, unsigned int size_align, unsigned int border) { return img_alloc_helper(img, fmt, d_w, d_h, align, align, size_align, border,
NULL, NULL, NULL);
}
int aom_img_set_rect(aom_image_t *img, unsigned int x, unsigned int y, unsigned int w, unsigned int h, unsigned int border) {
if (x <= UINT_MAX - w && x + w <= img->w && y <= UINT_MAX - h &&
y + h <= img->h) {
img->d_w = w;
img->d_h = h;
img->planes[AOM_PLANE_Y] =
data + x * bytes_per_sample + y * img->stride[AOM_PLANE_Y];
data += ((size_t)img->h + 2 * border) * img->stride[AOM_PLANE_Y];
unsigned int uv_border_h = border >> img->y_chroma_shift; unsigned int uv_x = x >> img->x_chroma_shift; unsigned int uv_y = y >> img->y_chroma_shift;
if (img->fmt == AOM_IMG_FMT_NV12) {
img->planes[AOM_PLANE_U] = data + uv_x * bytes_per_sample * 2 +
uv_y * img->stride[AOM_PLANE_U];
img->planes[AOM_PLANE_V] = NULL;
} else if (!(img->fmt & AOM_IMG_FMT_UV_FLIP)) {
img->planes[AOM_PLANE_U] =
data + uv_x * bytes_per_sample + uv_y * img->stride[AOM_PLANE_U];
data += ((size_t)(img->h >> img->y_chroma_shift) + 2 * uv_border_h) *
img->stride[AOM_PLANE_U];
img->planes[AOM_PLANE_V] =
data + uv_x * bytes_per_sample + uv_y * img->stride[AOM_PLANE_V];
} else {
img->planes[AOM_PLANE_V] =
data + uv_x * bytes_per_sample + uv_y * img->stride[AOM_PLANE_V];
data += ((size_t)(img->h >> img->y_chroma_shift) + 2 * uv_border_h) *
img->stride[AOM_PLANE_V];
img->planes[AOM_PLANE_U] =
data + uv_x * bytes_per_sample + uv_y * img->stride[AOM_PLANE_U];
}
} return0;
} return -1;
}
void aom_img_flip(aom_image_t *img) { /* Note: In the calculation pointer adjustment calculation, we want the *rhstobepromotedtoasignedtype.Section6.3.1.8oftheISOC99 *standardindicatesthatiftheadjustmentparameterisunsigned,the *strideparameterwillbepromotedtounsigned,causingerrorswhen *thelhsisalargertypethantherhs.
*/
img->planes[AOM_PLANE_Y] += (signed)(img->d_h - 1) * img->stride[AOM_PLANE_Y];
img->stride[AOM_PLANE_Y] = -img->stride[AOM_PLANE_Y];
void aom_img_metadata_array_free(aom_metadata_array_t *arr) {
if (arr) {
if (arr->metadata_array) {
for (size_t i = 0; i < arr->sz; i++) {
aom_img_metadata_free(arr->metadata_array[i]);
}
free(arr->metadata_array);
}
free(arr);
}
}
int aom_img_add_metadata(aom_image_t *img, uint32_t type, const uint8_t *data,
size_t sz, aom_metadata_insert_flags_t insert_flag) {
if (!img) return -1;
if (!img->metadata) {
img->metadata = aom_img_metadata_array_alloc(0);
if (!img->metadata) return -1;
} // Some metadata types are not allowed to be layer specific, according to // the Table in Section 6.7.1 of the AV1 specifiction. // Do not check for OBU_METADATA_TYPE_HDR_CLL or OBU_METADATA_TYPE_HDR_MDCV // because there are plans to alow them to be layer specific.
if ((insert_flag & AOM_MIF_LAYER_SPECIFIC) &&
(type == OBU_METADATA_TYPE_SCALABILITY ||
type == OBU_METADATA_TYPE_TIMECODE)) { return -1;
}
aom_metadata_t *metadata =
aom_img_metadata_alloc(type, data, sz, insert_flag);
if (!metadata) return -1;
aom_metadata_t **metadata_array = (aom_metadata_t **)realloc(
img->metadata->metadata_array,
(img->metadata->sz + 1) * sizeof(*metadata_array));
if (!metadata_array) {
aom_img_metadata_free(metadata); return -1;
}
img->metadata->metadata_array = metadata_array;
img->metadata->metadata_array[img->metadata->sz] = metadata;
img->metadata->sz++; return0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.