[libvpx] Update to v1.12.0

This commit is contained in:
Andrey Volk committed 2026-07-10 19:38:46 +03:00
1 parent 287a71dc66
commit b5046d2a76
572 files changed
+52900 -29493

No files matched your search

+278 -261
View File
@@ -10,6 +10,7 @@
* Based on code from the OggTheora software codec source code,
* Copyright (C) 2002-2010 The Xiph.Org Foundation and contributors.
*/
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -51,15 +52,8 @@ static int file_read(void *buf, size_t size, FILE *file) {
}
static int y4m_parse_tags(y4m_input *_y4m, char *_tags) {
int got_w;
int got_h;
int got_fps;
int got_interlace;
int got_par;
int got_chroma;
char *p;
char *q;
got_w = got_h = got_fps = got_interlace = got_par = got_chroma = 0;
for (p = _tags;; p = q) {
/*Skip any leading spaces.*/
while (*p == ' ') p++;
@@ -72,52 +66,119 @@ static int y4m_parse_tags(y4m_input *_y4m, char *_tags) {
switch (p[0]) {
case 'W': {
if (sscanf(p + 1, "%d", &_y4m->pic_w) != 1) return -1;
got_w = 1;
break;
}
case 'H': {
if (sscanf(p + 1, "%d", &_y4m->pic_h) != 1) return -1;
got_h = 1;
break;
}
case 'F': {
if (sscanf(p + 1, "%d:%d", &_y4m->fps_n, &_y4m->fps_d) != 2) {
return -1;
}
got_fps = 1;
break;
}
case 'I': {
_y4m->interlace = p[1];
got_interlace = 1;
break;
}
case 'A': {
if (sscanf(p + 1, "%d:%d", &_y4m->par_n, &_y4m->par_d) != 2) {
return -1;
}
got_par = 1;
break;
}
case 'C': {
if (q - p > 16) return -1;
memcpy(_y4m->chroma_type, p + 1, q - p - 1);
_y4m->chroma_type[q - p - 1] = '\0';
got_chroma = 1;
break;
}
/*Ignore unknown tags.*/
}
}
if (!got_w || !got_h || !got_fps) return -1;
if (!got_interlace) _y4m->interlace = '?';
if (!got_par) _y4m->par_n = _y4m->par_d = 0;
/*Chroma-type is not specified in older files, e.g., those generated by
mplayer.*/
if (!got_chroma) strcpy(_y4m->chroma_type, "420");
return 0;
}
// Copy a single tag into the buffer, along with a null character.
// Returns 0 if any file IO errors occur.
static int copy_tag(char *buf, size_t buf_len, char *end_tag, FILE *file) {
size_t i;
assert(buf_len >= 1);
// Skip leading space characters.
do {
if (!file_read(buf, 1, file)) {
return 0;
}
} while (buf[0] == ' ');
// If we hit the newline, treat this as the "empty" tag.
if (buf[0] == '\n') {
buf[0] = '\0';
*end_tag = '\n';
return 1;
}
// Copy over characters until a space is hit, or the buffer is exhausted.
for (i = 1; i < buf_len; ++i) {
if (!file_read(buf + i, 1, file)) {
return 0;
}
if (buf[i] == ' ' || buf[i] == '\n') {
break;
}
}
if (i == buf_len) {
fprintf(stderr, "Error: Y4M header tags must be less than %lu characters\n",
(unsigned long)i);
return 0;
}
*end_tag = buf[i];
buf[i] = '\0';
return 1;
}
/* Returns 1 if tags were parsed successfully, 0 otherwise. */
static int parse_tags(y4m_input *y4m_ctx, FILE *file) {
char tag[256];
char end; /* Character denoting the end of the tag, ' ' or '\n'. */
/* Set Y4M tags to defaults, updating them as processing occurs. Mandatory
fields are marked with -1 and will be checked after the tags are parsed. */
y4m_ctx->pic_w = -1;
y4m_ctx->pic_h = -1;
y4m_ctx->fps_n = -1; /* Also serves as marker for fps_d */
y4m_ctx->par_n = 0;
y4m_ctx->par_d = 0;
y4m_ctx->interlace = '?';
snprintf(y4m_ctx->chroma_type, sizeof(y4m_ctx->chroma_type), "420");
/* Find one tag at a time. */
do {
if (!copy_tag(tag, sizeof(tag), &end, file)) {
return 0;
}
/* y4m_parse_tags returns 0 on success. */
if (y4m_parse_tags(y4m_ctx, tag)) {
return 0;
}
} while (end != '\n');
/* Check the mandatory fields. */
if (y4m_ctx->pic_w == -1) {
fprintf(stderr, "Width field missing\n");
return 0;
}
if (y4m_ctx->pic_h == -1) {
fprintf(stderr, "Height field missing\n");
return 0;
}
if (y4m_ctx->fps_n == -1) {
fprintf(stderr, "FPS field missing\n");
return 0;
}
return 1;
}
/*All anti-aliasing filters in the following conversion functions are based on
one of two window functions:
The 6-tap Lanczos window (for down-sampling and shifts):
@@ -224,26 +285,6 @@ static void y4m_42xmpeg2_42xjpeg_helper(unsigned char *_dst,
}
}
/*Handles both 422 and 420mpeg2 to 422jpeg and 420jpeg, respectively.*/
static void y4m_convert_42xmpeg2_42xjpeg(y4m_input *_y4m, unsigned char *_dst,
unsigned char *_aux) {
int c_w;
int c_h;
int c_sz;
int pli;
/*Skip past the luma data.*/
_dst += _y4m->pic_w * _y4m->pic_h;
/*Compute the size of each chroma plane.*/
c_w = (_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h;
c_h = (_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v;
c_sz = c_w * c_h;
for (pli = 1; pli < 3; pli++) {
y4m_42xmpeg2_42xjpeg_helper(_dst, _aux, c_w, c_h);
_dst += c_sz;
_aux += c_sz;
}
}
/*This format is only used for interlaced content, but is included for
completeness.
@@ -784,301 +825,277 @@ static void y4m_convert_null(y4m_input *_y4m, unsigned char *_dst,
(void)_aux;
}
int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip,
int only_420) {
char buffer[80] = { 0 };
int ret;
int i;
/*Read until newline, or 80 cols, whichever happens first.*/
for (i = 0; i < 79; i++) {
if (_nskip > 0) {
buffer[i] = *_skip++;
_nskip--;
} else {
if (!file_read(buffer + i, 1, _fin)) return -1;
}
if (buffer[i] == '\n') break;
static const char TAG[] = "YUV4MPEG2";
int y4m_input_open(y4m_input *y4m_ctx, FILE *file, char *skip_buffer,
int num_skip, int only_420) {
// File must start with |TAG|.
char tag_buffer[9]; // 9 == strlen(TAG)
// Read as much as possible from |skip_buffer|, which were characters
// that were previously read from the file to do input-type detection.
assert(num_skip >= 0 && num_skip <= 8);
if (num_skip > 0) {
memcpy(tag_buffer, skip_buffer, num_skip);
}
/*We skipped too much header data.*/
if (_nskip > 0) return -1;
if (i == 79) {
fprintf(stderr, "Error parsing header; not a YUV2MPEG2 file?\n");
// Start reading from the file now that the |skip_buffer| is depleted.
if (!file_read(tag_buffer + num_skip, 9 - num_skip, file)) {
return -1;
}
buffer[i] = '\0';
if (memcmp(buffer, "YUV4MPEG", 8)) {
fprintf(stderr, "Incomplete magic for YUV4MPEG file.\n");
if (memcmp(TAG, tag_buffer, 9) != 0) {
fprintf(stderr, "Error parsing header: must start with %s\n", TAG);
return -1;
}
if (buffer[8] != '2') {
fprintf(stderr, "Incorrect YUV input file version; YUV4MPEG2 required.\n");
// Next character must be a space.
if (!file_read(tag_buffer, 1, file) || tag_buffer[0] != ' ') {
fprintf(stderr, "Error parsing header: space must follow %s\n", TAG);
return -1;
}
ret = y4m_parse_tags(_y4m, buffer + 5);
if (ret < 0) {
fprintf(stderr, "Error parsing YUV4MPEG2 header.\n");
return ret;
if (!parse_tags(y4m_ctx, file)) {
fprintf(stderr, "Error parsing %s header.\n", TAG);
}
if (_y4m->interlace == '?') {
if (y4m_ctx->interlace == '?') {
fprintf(stderr,
"Warning: Input video interlacing format unknown; "
"assuming progressive scan.\n");
} else if (_y4m->interlace != 'p') {
} else if (y4m_ctx->interlace != 'p') {
fprintf(stderr,
"Input video is interlaced; "
"Only progressive scan handled.\n");
return -1;
}
_y4m->vpx_fmt = VPX_IMG_FMT_I420;
_y4m->bps = 12;
_y4m->bit_depth = 8;
if (strcmp(_y4m->chroma_type, "420") == 0 ||
strcmp(_y4m->chroma_type, "420jpeg") == 0) {
_y4m->src_c_dec_h = _y4m->dst_c_dec_h = _y4m->src_c_dec_v =
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz =
_y4m->pic_w * _y4m->pic_h +
2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2);
y4m_ctx->vpx_fmt = VPX_IMG_FMT_I420;
y4m_ctx->bps = 12;
y4m_ctx->bit_depth = 8;
y4m_ctx->aux_buf = NULL;
y4m_ctx->dst_buf = NULL;
if (strcmp(y4m_ctx->chroma_type, "420") == 0 ||
strcmp(y4m_ctx->chroma_type, "420jpeg") == 0 ||
strcmp(y4m_ctx->chroma_type, "420mpeg2") == 0) {
y4m_ctx->src_c_dec_h = y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_v =
y4m_ctx->dst_c_dec_v = 2;
y4m_ctx->dst_buf_read_sz =
y4m_ctx->pic_w * y4m_ctx->pic_h +
2 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2);
/* Natively supported: no conversion required. */
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
_y4m->convert = y4m_convert_null;
} else if (strcmp(_y4m->chroma_type, "420p10") == 0) {
_y4m->src_c_dec_h = 2;
_y4m->dst_c_dec_h = 2;
_y4m->src_c_dec_v = 2;
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz =
2 * (_y4m->pic_w * _y4m->pic_h +
2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2));
y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0;
y4m_ctx->convert = y4m_convert_null;
} else if (strcmp(y4m_ctx->chroma_type, "420p10") == 0) {
y4m_ctx->src_c_dec_h = 2;
y4m_ctx->dst_c_dec_h = 2;
y4m_ctx->src_c_dec_v = 2;
y4m_ctx->dst_c_dec_v = 2;
y4m_ctx->dst_buf_read_sz =
2 * (y4m_ctx->pic_w * y4m_ctx->pic_h +
2 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2));
/* Natively supported: no conversion required. */
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
_y4m->convert = y4m_convert_null;
_y4m->bit_depth = 10;
_y4m->bps = 15;
_y4m->vpx_fmt = VPX_IMG_FMT_I42016;
y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0;
y4m_ctx->convert = y4m_convert_null;
y4m_ctx->bit_depth = 10;
y4m_ctx->bps = 15;
y4m_ctx->vpx_fmt = VPX_IMG_FMT_I42016;
if (only_420) {
fprintf(stderr, "Unsupported conversion from 420p10 to 420jpeg\n");
return -1;
}
} else if (strcmp(_y4m->chroma_type, "420p12") == 0) {
_y4m->src_c_dec_h = 2;
_y4m->dst_c_dec_h = 2;
_y4m->src_c_dec_v = 2;
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz =
2 * (_y4m->pic_w * _y4m->pic_h +
2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2));
} else if (strcmp(y4m_ctx->chroma_type, "420p12") == 0) {
y4m_ctx->src_c_dec_h = 2;
y4m_ctx->dst_c_dec_h = 2;
y4m_ctx->src_c_dec_v = 2;
y4m_ctx->dst_c_dec_v = 2;
y4m_ctx->dst_buf_read_sz =
2 * (y4m_ctx->pic_w * y4m_ctx->pic_h +
2 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2));
/* Natively supported: no conversion required. */
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
_y4m->convert = y4m_convert_null;
_y4m->bit_depth = 12;
_y4m->bps = 18;
_y4m->vpx_fmt = VPX_IMG_FMT_I42016;
y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0;
y4m_ctx->convert = y4m_convert_null;
y4m_ctx->bit_depth = 12;
y4m_ctx->bps = 18;
y4m_ctx->vpx_fmt = VPX_IMG_FMT_I42016;
if (only_420) {
fprintf(stderr, "Unsupported conversion from 420p12 to 420jpeg\n");
return -1;
}
} else if (strcmp(_y4m->chroma_type, "420mpeg2") == 0) {
_y4m->src_c_dec_h = _y4m->dst_c_dec_h = _y4m->src_c_dec_v =
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
/*Chroma filter required: read into the aux buf first.*/
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz =
2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2);
_y4m->convert = y4m_convert_42xmpeg2_42xjpeg;
} else if (strcmp(_y4m->chroma_type, "420paldv") == 0) {
_y4m->src_c_dec_h = _y4m->dst_c_dec_h = _y4m->src_c_dec_v =
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
} else if (strcmp(y4m_ctx->chroma_type, "420paldv") == 0) {
y4m_ctx->src_c_dec_h = y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_v =
y4m_ctx->dst_c_dec_v = 2;
y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h;
/*Chroma filter required: read into the aux buf first.
We need to make two filter passes, so we need some extra space in the
aux buffer.*/
_y4m->aux_buf_sz = 3 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2);
_y4m->aux_buf_read_sz =
2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2);
_y4m->convert = y4m_convert_42xpaldv_42xjpeg;
} else if (strcmp(_y4m->chroma_type, "422jpeg") == 0) {
_y4m->src_c_dec_h = _y4m->dst_c_dec_h = 2;
_y4m->src_c_dec_v = 1;
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
y4m_ctx->aux_buf_sz =
3 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2);
y4m_ctx->aux_buf_read_sz =
2 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2);
y4m_ctx->convert = y4m_convert_42xpaldv_42xjpeg;
} else if (strcmp(y4m_ctx->chroma_type, "422jpeg") == 0) {
y4m_ctx->src_c_dec_h = y4m_ctx->dst_c_dec_h = 2;
y4m_ctx->src_c_dec_v = 1;
y4m_ctx->dst_c_dec_v = 2;
y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h;
/*Chroma filter required: read into the aux buf first.*/
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz =
2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
_y4m->convert = y4m_convert_422jpeg_420jpeg;
} else if (strcmp(_y4m->chroma_type, "422") == 0) {
_y4m->src_c_dec_h = 2;
_y4m->src_c_dec_v = 1;
y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz =
2 * ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h;
y4m_ctx->convert = y4m_convert_422jpeg_420jpeg;
} else if (strcmp(y4m_ctx->chroma_type, "422") == 0) {
y4m_ctx->src_c_dec_h = 2;
y4m_ctx->src_c_dec_v = 1;
if (only_420) {
_y4m->dst_c_dec_h = 2;
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
y4m_ctx->dst_c_dec_h = 2;
y4m_ctx->dst_c_dec_v = 2;
y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h;
/*Chroma filter required: read into the aux buf first.
We need to make two filter passes, so we need some extra space in the
aux buffer.*/
_y4m->aux_buf_read_sz = 2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
_y4m->aux_buf_sz =
_y4m->aux_buf_read_sz + ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
_y4m->convert = y4m_convert_422_420jpeg;
y4m_ctx->aux_buf_read_sz =
2 * ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h;
y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz +
((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h;
y4m_ctx->convert = y4m_convert_422_420jpeg;
} else {
_y4m->vpx_fmt = VPX_IMG_FMT_I422;
_y4m->bps = 16;
_y4m->dst_c_dec_h = _y4m->src_c_dec_h;
_y4m->dst_c_dec_v = _y4m->src_c_dec_v;
_y4m->dst_buf_read_sz =
_y4m->pic_w * _y4m->pic_h + 2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
y4m_ctx->vpx_fmt = VPX_IMG_FMT_I422;
y4m_ctx->bps = 16;
y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h;
y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v;
y4m_ctx->dst_buf_read_sz =
y4m_ctx->pic_w * y4m_ctx->pic_h +
2 * ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h;
/*Natively supported: no conversion required.*/
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
_y4m->convert = y4m_convert_null;
y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0;
y4m_ctx->convert = y4m_convert_null;
}
} else if (strcmp(_y4m->chroma_type, "422p10") == 0) {
_y4m->src_c_dec_h = 2;
_y4m->src_c_dec_v = 1;
_y4m->vpx_fmt = VPX_IMG_FMT_I42216;
_y4m->bps = 20;
_y4m->bit_depth = 10;
_y4m->dst_c_dec_h = _y4m->src_c_dec_h;
_y4m->dst_c_dec_v = _y4m->src_c_dec_v;
_y4m->dst_buf_read_sz = 2 * (_y4m->pic_w * _y4m->pic_h +
2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h);
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
_y4m->convert = y4m_convert_null;
} else if (strcmp(y4m_ctx->chroma_type, "422p10") == 0) {
y4m_ctx->src_c_dec_h = 2;
y4m_ctx->src_c_dec_v = 1;
y4m_ctx->vpx_fmt = VPX_IMG_FMT_I42216;
y4m_ctx->bps = 20;
y4m_ctx->bit_depth = 10;
y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h;
y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v;
y4m_ctx->dst_buf_read_sz =
2 * (y4m_ctx->pic_w * y4m_ctx->pic_h +
2 * ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h);
y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0;
y4m_ctx->convert = y4m_convert_null;
if (only_420) {
fprintf(stderr, "Unsupported conversion from 422p10 to 420jpeg\n");
return -1;
}
} else if (strcmp(_y4m->chroma_type, "422p12") == 0) {
_y4m->src_c_dec_h = 2;
_y4m->src_c_dec_v = 1;
_y4m->vpx_fmt = VPX_IMG_FMT_I42216;
_y4m->bps = 24;
_y4m->bit_depth = 12;
_y4m->dst_c_dec_h = _y4m->src_c_dec_h;
_y4m->dst_c_dec_v = _y4m->src_c_dec_v;
_y4m->dst_buf_read_sz = 2 * (_y4m->pic_w * _y4m->pic_h +
2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h);
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
_y4m->convert = y4m_convert_null;
} else if (strcmp(y4m_ctx->chroma_type, "422p12") == 0) {
y4m_ctx->src_c_dec_h = 2;
y4m_ctx->src_c_dec_v = 1;
y4m_ctx->vpx_fmt = VPX_IMG_FMT_I42216;
y4m_ctx->bps = 24;
y4m_ctx->bit_depth = 12;
y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h;
y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v;
y4m_ctx->dst_buf_read_sz =
2 * (y4m_ctx->pic_w * y4m_ctx->pic_h +
2 * ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h);
y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0;
y4m_ctx->convert = y4m_convert_null;
if (only_420) {
fprintf(stderr, "Unsupported conversion from 422p12 to 420jpeg\n");
return -1;
}
} else if (strcmp(_y4m->chroma_type, "411") == 0) {
_y4m->src_c_dec_h = 4;
_y4m->dst_c_dec_h = 2;
_y4m->src_c_dec_v = 1;
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
} else if (strcmp(y4m_ctx->chroma_type, "411") == 0) {
y4m_ctx->src_c_dec_h = 4;
y4m_ctx->dst_c_dec_h = 2;
y4m_ctx->src_c_dec_v = 1;
y4m_ctx->dst_c_dec_v = 2;
y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h;
/*Chroma filter required: read into the aux buf first.
We need to make two filter passes, so we need some extra space in the
aux buffer.*/
_y4m->aux_buf_read_sz = 2 * ((_y4m->pic_w + 3) / 4) * _y4m->pic_h;
_y4m->aux_buf_sz =
_y4m->aux_buf_read_sz + ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
_y4m->convert = y4m_convert_411_420jpeg;
y4m_ctx->aux_buf_read_sz = 2 * ((y4m_ctx->pic_w + 3) / 4) * y4m_ctx->pic_h;
y4m_ctx->aux_buf_sz =
y4m_ctx->aux_buf_read_sz + ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h;
y4m_ctx->convert = y4m_convert_411_420jpeg;
fprintf(stderr, "Unsupported conversion from yuv 411\n");
return -1;
} else if (strcmp(_y4m->chroma_type, "444") == 0) {
_y4m->src_c_dec_h = 1;
_y4m->src_c_dec_v = 1;
} else if (strcmp(y4m_ctx->chroma_type, "444") == 0) {
y4m_ctx->src_c_dec_h = 1;
y4m_ctx->src_c_dec_v = 1;
if (only_420) {
_y4m->dst_c_dec_h = 2;
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
y4m_ctx->dst_c_dec_h = 2;
y4m_ctx->dst_c_dec_v = 2;
y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h;
/*Chroma filter required: read into the aux buf first.
We need to make two filter passes, so we need some extra space in the
aux buffer.*/
_y4m->aux_buf_read_sz = 2 * _y4m->pic_w * _y4m->pic_h;
_y4m->aux_buf_sz =
_y4m->aux_buf_read_sz + ((_y4m->pic_w + 1) / 2) * _y4m->pic_h;
_y4m->convert = y4m_convert_444_420jpeg;
y4m_ctx->aux_buf_read_sz = 2 * y4m_ctx->pic_w * y4m_ctx->pic_h;
y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz +
((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h;
y4m_ctx->convert = y4m_convert_444_420jpeg;
} else {
_y4m->vpx_fmt = VPX_IMG_FMT_I444;
_y4m->bps = 24;
_y4m->dst_c_dec_h = _y4m->src_c_dec_h;
_y4m->dst_c_dec_v = _y4m->src_c_dec_v;
_y4m->dst_buf_read_sz = 3 * _y4m->pic_w * _y4m->pic_h;
y4m_ctx->vpx_fmt = VPX_IMG_FMT_I444;
y4m_ctx->bps = 24;
y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h;
y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v;
y4m_ctx->dst_buf_read_sz = 3 * y4m_ctx->pic_w * y4m_ctx->pic_h;
/*Natively supported: no conversion required.*/
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
_y4m->convert = y4m_convert_null;
y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0;
y4m_ctx->convert = y4m_convert_null;
}
} else if (strcmp(_y4m->chroma_type, "444p10") == 0) {
_y4m->src_c_dec_h = 1;
_y4m->src_c_dec_v = 1;
_y4m->vpx_fmt = VPX_IMG_FMT_I44416;
_y4m->bps = 30;
_y4m->bit_depth = 10;
_y4m->dst_c_dec_h = _y4m->src_c_dec_h;
_y4m->dst_c_dec_v = _y4m->src_c_dec_v;
_y4m->dst_buf_read_sz = 2 * 3 * _y4m->pic_w * _y4m->pic_h;
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
_y4m->convert = y4m_convert_null;
} else if (strcmp(y4m_ctx->chroma_type, "444p10") == 0) {
y4m_ctx->src_c_dec_h = 1;
y4m_ctx->src_c_dec_v = 1;
y4m_ctx->vpx_fmt = VPX_IMG_FMT_I44416;
y4m_ctx->bps = 30;
y4m_ctx->bit_depth = 10;
y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h;
y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v;
y4m_ctx->dst_buf_read_sz = 2 * 3 * y4m_ctx->pic_w * y4m_ctx->pic_h;
y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0;
y4m_ctx->convert = y4m_convert_null;
if (only_420) {
fprintf(stderr, "Unsupported conversion from 444p10 to 420jpeg\n");
return -1;
}
} else if (strcmp(_y4m->chroma_type, "444p12") == 0) {
_y4m->src_c_dec_h = 1;
_y4m->src_c_dec_v = 1;
_y4m->vpx_fmt = VPX_IMG_FMT_I44416;
_y4m->bps = 36;
_y4m->bit_depth = 12;
_y4m->dst_c_dec_h = _y4m->src_c_dec_h;
_y4m->dst_c_dec_v = _y4m->src_c_dec_v;
_y4m->dst_buf_read_sz = 2 * 3 * _y4m->pic_w * _y4m->pic_h;
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
_y4m->convert = y4m_convert_null;
} else if (strcmp(y4m_ctx->chroma_type, "444p12") == 0) {
y4m_ctx->src_c_dec_h = 1;
y4m_ctx->src_c_dec_v = 1;
y4m_ctx->vpx_fmt = VPX_IMG_FMT_I44416;
y4m_ctx->bps = 36;
y4m_ctx->bit_depth = 12;
y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h;
y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v;
y4m_ctx->dst_buf_read_sz = 2 * 3 * y4m_ctx->pic_w * y4m_ctx->pic_h;
y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0;
y4m_ctx->convert = y4m_convert_null;
if (only_420) {
fprintf(stderr, "Unsupported conversion from 444p12 to 420jpeg\n");
return -1;
}
} else if (strcmp(_y4m->chroma_type, "444alpha") == 0) {
_y4m->src_c_dec_h = 1;
_y4m->src_c_dec_v = 1;
if (only_420) {
_y4m->dst_c_dec_h = 2;
_y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
/*Chroma filter required: read into the aux buf first.
We need to make two filter passes, so we need some extra space in the
aux buffer.
The extra plane also gets read into the aux buf.
It will be discarded.*/
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 3 * _y4m->pic_w * _y4m->pic_h;
_y4m->convert = y4m_convert_444_420jpeg;
} else {
_y4m->vpx_fmt = VPX_IMG_FMT_444A;
_y4m->bps = 32;
_y4m->dst_c_dec_h = _y4m->src_c_dec_h;
_y4m->dst_c_dec_v = _y4m->src_c_dec_v;
_y4m->dst_buf_read_sz = 4 * _y4m->pic_w * _y4m->pic_h;
/*Natively supported: no conversion required.*/
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
_y4m->convert = y4m_convert_null;
}
} else if (strcmp(_y4m->chroma_type, "mono") == 0) {
_y4m->src_c_dec_h = _y4m->src_c_dec_v = 0;
_y4m->dst_c_dec_h = _y4m->dst_c_dec_v = 2;
_y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h;
} else if (strcmp(y4m_ctx->chroma_type, "mono") == 0) {
y4m_ctx->src_c_dec_h = y4m_ctx->src_c_dec_v = 0;
y4m_ctx->dst_c_dec_h = y4m_ctx->dst_c_dec_v = 2;
y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h;
/*No extra space required, but we need to clear the chroma planes.*/
_y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0;
_y4m->convert = y4m_convert_mono_420jpeg;
y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0;
y4m_ctx->convert = y4m_convert_mono_420jpeg;
} else {
fprintf(stderr, "Unknown chroma sampling type: %s\n", _y4m->chroma_type);
fprintf(stderr, "Unknown chroma sampling type: %s\n", y4m_ctx->chroma_type);
return -1;
}
/*The size of the final frame buffers is always computed from the
destination chroma decimation type.*/
_y4m->dst_buf_sz =
_y4m->pic_w * _y4m->pic_h +
2 * ((_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h) *
((_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v);
if (_y4m->bit_depth == 8)
_y4m->dst_buf = (unsigned char *)malloc(_y4m->dst_buf_sz);
y4m_ctx->dst_buf_sz =
y4m_ctx->pic_w * y4m_ctx->pic_h +
2 * ((y4m_ctx->pic_w + y4m_ctx->dst_c_dec_h - 1) / y4m_ctx->dst_c_dec_h) *
((y4m_ctx->pic_h + y4m_ctx->dst_c_dec_v - 1) / y4m_ctx->dst_c_dec_v);
if (y4m_ctx->bit_depth == 8)
y4m_ctx->dst_buf = (unsigned char *)malloc(y4m_ctx->dst_buf_sz);
else
_y4m->dst_buf = (unsigned char *)malloc(2 * _y4m->dst_buf_sz);
y4m_ctx->dst_buf = (unsigned char *)malloc(2 * y4m_ctx->dst_buf_sz);
if (!y4m_ctx->dst_buf) return -1;
if (_y4m->aux_buf_sz > 0)
_y4m->aux_buf = (unsigned char *)malloc(_y4m->aux_buf_sz);
if (y4m_ctx->aux_buf_sz > 0) {
y4m_ctx->aux_buf = (unsigned char *)malloc(y4m_ctx->aux_buf_sz);
if (!y4m_ctx->aux_buf) {
free(y4m_ctx->dst_buf);
return -1;
}
}
return 0;
}