summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Vignali <martin.vignali@gmail.com>2018-11-17 23:36:23 +0100
committerMartin Vignali <martin.vignali@gmail.com>2018-12-02 12:55:40 +0100
commit1cccf9365df0351467eca13313ae989da5c2b0f3 (patch)
tree2d406d4178b05b6153f38001005bb69ef6a603d0
parent9a22e6fa1dec29cc2f8bc3cd217d20573e19ebe7 (diff)
downloadffmpeg-1cccf9365df0351467eca13313ae989da5c2b0f3.tar.gz
avcodec/proresdec : put unpack alpha func in prores ctx
-rw-r--r--libavcodec/proresdec.h1
-rw-r--r--libavcodec/proresdec2.c100
2 files changed, 54 insertions, 47 deletions
diff --git a/libavcodec/proresdec.h b/libavcodec/proresdec.h
index 14ede5d16b..3d99eba078 100644
--- a/libavcodec/proresdec.h
+++ b/libavcodec/proresdec.h
@@ -50,6 +50,7 @@ typedef struct {
const uint8_t *scan;
int first_field;
int alpha_info;
+ void (*unpack_alpha)(GetBitContext *gb, uint16_t *dst, int num_coeffs, const int num_bits);
} ProresContext;
#endif /* AVCODEC_PRORESDEC_H */
diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c
index 12b2cba090..94323df128 100644
--- a/libavcodec/proresdec2.c
+++ b/libavcodec/proresdec2.c
@@ -46,6 +46,51 @@ static void permute(uint8_t *dst, const uint8_t *src, const uint8_t permutation[
dst[i] = permutation[src[i]];
}
+static void unpack_alpha_10(GetBitContext *gb, uint16_t *dst, int num_coeffs,
+ const int num_bits)
+{
+ const int mask = (1 << num_bits) - 1;
+ int i, idx, val, alpha_val;
+
+ idx = 0;
+ alpha_val = mask;
+ do {
+ do {
+ if (get_bits1(gb)) {
+ val = get_bits(gb, num_bits);
+ } else {
+ int sign;
+ val = get_bits(gb, num_bits == 16 ? 7 : 4);
+ sign = val & 1;
+ val = (val + 2) >> 1;
+ if (sign)
+ val = -val;
+ }
+ alpha_val = (alpha_val + val) & mask;
+ if (num_bits == 16) {
+ dst[idx++] = alpha_val >> 6;
+ } else {
+ dst[idx++] = (alpha_val << 2) | (alpha_val >> 6);
+ }
+ if (idx >= num_coeffs)
+ break;
+ } while (get_bits_left(gb)>0 && get_bits1(gb));
+ val = get_bits(gb, 4);
+ if (!val)
+ val = get_bits(gb, 11);
+ if (idx + val > num_coeffs)
+ val = num_coeffs - idx;
+ if (num_bits == 16) {
+ for (i = 0; i < val; i++)
+ dst[idx++] = alpha_val >> 6;
+ } else {
+ for (i = 0; i < val; i++)
+ dst[idx++] = (alpha_val << 2) | (alpha_val >> 6);
+
+ }
+ } while (idx < num_coeffs);
+}
+
static av_cold int decode_init(AVCodecContext *avctx)
{
int ret = 0;
@@ -91,6 +136,12 @@ static av_cold int decode_init(AVCodecContext *avctx)
permute(ctx->progressive_scan, ff_prores_progressive_scan, idct_permutation);
permute(ctx->interlaced_scan, ff_prores_interlaced_scan, idct_permutation);
+ if (avctx->bits_per_raw_sample == 10){
+ ctx->unpack_alpha = unpack_alpha_10;
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "Fail to set unpack_alpha for bits per raw sample %d\n", avctx->bits_per_raw_sample);
+ return AVERROR_BUG;
+ }
return ret;
}
@@ -466,51 +517,6 @@ static int decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice,
return 0;
}
-static void unpack_alpha(GetBitContext *gb, uint16_t *dst, int num_coeffs,
- const int num_bits)
-{
- const int mask = (1 << num_bits) - 1;
- int i, idx, val, alpha_val;
-
- idx = 0;
- alpha_val = mask;
- do {
- do {
- if (get_bits1(gb)) {
- val = get_bits(gb, num_bits);
- } else {
- int sign;
- val = get_bits(gb, num_bits == 16 ? 7 : 4);
- sign = val & 1;
- val = (val + 2) >> 1;
- if (sign)
- val = -val;
- }
- alpha_val = (alpha_val + val) & mask;
- if (num_bits == 16) {
- dst[idx++] = alpha_val >> 6;
- } else {
- dst[idx++] = (alpha_val << 2) | (alpha_val >> 6);
- }
- if (idx >= num_coeffs)
- break;
- } while (get_bits_left(gb)>0 && get_bits1(gb));
- val = get_bits(gb, 4);
- if (!val)
- val = get_bits(gb, 11);
- if (idx + val > num_coeffs)
- val = num_coeffs - idx;
- if (num_bits == 16) {
- for (i = 0; i < val; i++)
- dst[idx++] = alpha_val >> 6;
- } else {
- for (i = 0; i < val; i++)
- dst[idx++] = (alpha_val << 2) | (alpha_val >> 6);
-
- }
- } while (idx < num_coeffs);
-}
-
/**
* Decode alpha slice plane.
*/
@@ -530,9 +536,9 @@ static void decode_slice_alpha(ProresContext *ctx,
init_get_bits(&gb, buf, buf_size << 3);
if (ctx->alpha_info == 2) {
- unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 16);
+ ctx->unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 16);
} else {
- unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 8);
+ ctx->unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 8);
}
block = blocks;