mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-24 12:09:55 +00:00
vp9: profile 1 header decoding.
This commit is contained in:
parent
02001ada5c
commit
a03b057ede
@ -112,8 +112,7 @@ typedef struct VP9Context {
|
||||
uint8_t invisible;
|
||||
uint8_t use_last_frame_mvs;
|
||||
uint8_t errorres;
|
||||
uint8_t colorspace;
|
||||
uint8_t fullrange;
|
||||
uint8_t ss_h, ss_v;
|
||||
uint8_t intraonly;
|
||||
uint8_t resetctx;
|
||||
uint8_t refreshrefmask;
|
||||
@ -463,11 +462,56 @@ static int update_prob(VP56RangeCoder *c, int p)
|
||||
255 - inv_recenter_nonneg(inv_map_table[d], 255 - p);
|
||||
}
|
||||
|
||||
static enum AVPixelFormat read_colorspace_details(AVCodecContext *ctx)
|
||||
{
|
||||
static const enum AVColorSpace colorspaces[8] = {
|
||||
AVCOL_SPC_UNSPECIFIED, AVCOL_SPC_BT470BG, AVCOL_SPC_BT709, AVCOL_SPC_SMPTE170M,
|
||||
AVCOL_SPC_SMPTE240M, AVCOL_SPC_BT2020_NCL, AVCOL_SPC_RESERVED, AVCOL_SPC_RGB,
|
||||
};
|
||||
VP9Context *s = ctx->priv_data;
|
||||
enum AVPixelFormat res;
|
||||
|
||||
ctx->colorspace = colorspaces[get_bits(&s->gb, 3)];
|
||||
if (ctx->colorspace == AVCOL_SPC_RGB) { // RGB = profile 1
|
||||
if (s->profile == 1) {
|
||||
s->ss_h = s->ss_v = 1;
|
||||
res = AV_PIX_FMT_GBRP;
|
||||
ctx->color_range = AVCOL_RANGE_JPEG;
|
||||
} else {
|
||||
av_log(ctx, AV_LOG_ERROR, "RGB not supported in profile 0\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
} else {
|
||||
static const enum AVPixelFormat pix_fmt_for_ss[2 /* v */][2 /* h */] = {
|
||||
{ AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P },
|
||||
{ AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV420P },
|
||||
};
|
||||
ctx->color_range = get_bits1(&s->gb) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
|
||||
if (s->profile == 1) {
|
||||
s->ss_h = get_bits1(&s->gb);
|
||||
s->ss_v = get_bits1(&s->gb);
|
||||
if ((res = pix_fmt_for_ss[s->ss_v][s->ss_h]) == AV_PIX_FMT_YUV420P) {
|
||||
av_log(ctx, AV_LOG_ERROR, "YUV 4:2:0 not supported in profile 1\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
} else if (get_bits1(&s->gb)) {
|
||||
av_log(ctx, AV_LOG_ERROR, "Profile 1 color details reserved bit set\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
} else {
|
||||
s->ss_h = s->ss_v = 1;
|
||||
res = AV_PIX_FMT_YUV420P;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int decode_frame_header(AVCodecContext *ctx,
|
||||
const uint8_t *data, int size, int *ref)
|
||||
{
|
||||
VP9Context *s = ctx->priv_data;
|
||||
int c, i, j, k, l, m, n, w, h, max, size2, res, sharp;
|
||||
enum AVPixelFormat fmt = ctx->pix_fmt;
|
||||
int last_invisible;
|
||||
const uint8_t *data2;
|
||||
|
||||
@ -481,8 +525,9 @@ static int decode_frame_header(AVCodecContext *ctx,
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
s->profile = get_bits1(&s->gb);
|
||||
if (get_bits1(&s->gb)) { // reserved bit
|
||||
av_log(ctx, AV_LOG_ERROR, "Reserved bit should be zero\n");
|
||||
s->profile |= get_bits1(&s->gb) << 1;
|
||||
if (s->profile > 1) {
|
||||
av_log(ctx, AV_LOG_ERROR, "Profile %d is not yet supported\n", s->profile);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
if (get_bits1(&s->gb)) {
|
||||
@ -500,12 +545,8 @@ static int decode_frame_header(AVCodecContext *ctx,
|
||||
av_log(ctx, AV_LOG_ERROR, "Invalid sync code\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
s->colorspace = get_bits(&s->gb, 3);
|
||||
if (s->colorspace == 7) { // RGB = profile 1
|
||||
av_log(ctx, AV_LOG_ERROR, "RGB not supported in profile 0\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
s->fullrange = get_bits1(&s->gb);
|
||||
if ((fmt = read_colorspace_details(ctx)) < 0)
|
||||
return fmt;
|
||||
// for profile 1, here follows the subsampling bits
|
||||
s->refreshrefmask = 0xff;
|
||||
w = get_bits(&s->gb, 16) + 1;
|
||||
@ -520,6 +561,15 @@ static int decode_frame_header(AVCodecContext *ctx,
|
||||
av_log(ctx, AV_LOG_ERROR, "Invalid sync code\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
if (s->profile == 1) {
|
||||
if ((fmt = read_colorspace_details(ctx)) < 0)
|
||||
return fmt;
|
||||
} else {
|
||||
s->ss_h = s->ss_v = 1;
|
||||
fmt = AV_PIX_FMT_YUV420P;
|
||||
ctx->colorspace = AVCOL_SPC_BT470BG;
|
||||
ctx->color_range = AVCOL_RANGE_JPEG;
|
||||
}
|
||||
s->refreshrefmask = get_bits(&s->gb, 8);
|
||||
w = get_bits(&s->gb, 16) + 1;
|
||||
h = get_bits(&s->gb, 16) + 1;
|
||||
@ -3815,18 +3865,6 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
|
||||
return res;
|
||||
}
|
||||
|
||||
if (s->fullrange)
|
||||
ctx->color_range = AVCOL_RANGE_JPEG;
|
||||
else
|
||||
ctx->color_range = AVCOL_RANGE_MPEG;
|
||||
|
||||
switch (s->colorspace) {
|
||||
case 1: ctx->colorspace = AVCOL_SPC_BT470BG; break;
|
||||
case 2: ctx->colorspace = AVCOL_SPC_BT709; break;
|
||||
case 3: ctx->colorspace = AVCOL_SPC_SMPTE170M; break;
|
||||
case 4: ctx->colorspace = AVCOL_SPC_SMPTE240M; break;
|
||||
}
|
||||
|
||||
// main tile decode loop
|
||||
memset(s->above_partition_ctx, 0, s->cols);
|
||||
memset(s->above_skip_ctx, 0, s->cols);
|
||||
@ -3836,8 +3874,8 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
|
||||
memset(s->above_mode_ctx, NEARESTMV, s->cols);
|
||||
}
|
||||
memset(s->above_y_nnz_ctx, 0, s->sb_cols * 16);
|
||||
memset(s->above_uv_nnz_ctx[0], 0, s->sb_cols * 8);
|
||||
memset(s->above_uv_nnz_ctx[1], 0, s->sb_cols * 8);
|
||||
memset(s->above_uv_nnz_ctx[0], 0, s->sb_cols * 16 >> s->ss_h);
|
||||
memset(s->above_uv_nnz_ctx[1], 0, s->sb_cols * 16 >> s->ss_h);
|
||||
memset(s->above_segpred_ctx, 0, s->cols);
|
||||
s->pass = s->frames[CUR_FRAME].uses_2pass =
|
||||
ctx->active_thread_type == FF_THREAD_FRAME && s->refreshctx && !s->parallelmode;
|
||||
@ -4094,6 +4132,8 @@ static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo
|
||||
|
||||
s->invisible = ssrc->invisible;
|
||||
s->keyframe = ssrc->keyframe;
|
||||
s->ss_v = ssrc->ss_v;
|
||||
s->ss_h = ssrc->ss_h;
|
||||
s->segmentation.enabled = ssrc->segmentation.enabled;
|
||||
s->segmentation.update_map = ssrc->segmentation.update_map;
|
||||
memcpy(&s->prob_ctx, &ssrc->prob_ctx, sizeof(s->prob_ctx));
|
||||
|
Loading…
Reference in New Issue
Block a user