---
kshishkov, not sure to understand your remark :
just allocation needs to know how much to allocate for the buffers,
about float and int32 pointers on same buffers.
Hoping its ok
libavcodec/jpeg2000.c | 9 +-
libavcodec/jpeg2000dec.c | 131 ++++++++++++++++++-------
libavcodec/jpeg2000dwt.c | 156 ++++++++++++++++++++++++------
libavcodec/jpeg2000dwt.h | 3 +-
tests/fate/video.mak | 3 +
tests/ref/fate/jpeg2000-dcinema-bitexact | 3 +
6 files changed, 239 insertions(+), 66 deletions(-)
create mode 100644 tests/ref/fate/jpeg2000-dcinema-bitexact
diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c
index 78c7a38..e96ee10 100644
--- a/libavcodec/jpeg2000.c
+++ b/libavcodec/jpeg2000.c
@@ -200,7 +200,7 @@ int ff_jpeg2000_init_component(Jpeg2000Component *comp,
Jpeg2000CodingStyle *codsty,
Jpeg2000QuantStyle *qntsty,
int cbps, int dx, int dy,
- AVCodecContext *ctx)
+ AVCodecContext *avctx)
{
uint8_t log2_band_prec_width, log2_band_prec_height;
int reslevelno, bandno, gbandno = 0, ret, i, j;
@@ -275,7 +275,7 @@ int ff_jpeg2000_init_component(Jpeg2000Component *comp,
int nb_precincts;
/* TODO: Implementation of quantization step not finished,
- * see ISO/IEC 15444-1:2002 §E.1 and §A.6.4. */
+ * see ISO/IEC 15444-1:2002 E.1 and A.6.4. */
switch (qntsty->quantsty) {
uint8_t gain;
int numbps;
@@ -308,9 +308,12 @@ int ff_jpeg2000_init_component(Jpeg2000Component *comp,
break;
default:
band->stepsize = 0;
- av_log(ctx, AV_LOG_ERROR, "Unknown quantization format\n");
+ av_log(avctx, AV_LOG_ERROR, "Unknown quantization format\n");
break;
}
+ /* BITEXACT computing case --> convert to int */
+ if (avctx->flags & CODEC_FLAG_BITEXACT)
+ band->stepsize = (int32_t)(band->stepsize * (1<<16));
/* computation of tbx_0, tbx_1, tby_0, tby_1
* see ISO/IEC 15444-1:2002 B.5 eq. B-15 and tbl B.1
diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
index 0eb6e07..e4bd83f 100644
--- a/libavcodec/jpeg2000dec.c
+++ b/libavcodec/jpeg2000dec.c
@@ -266,7 +266,11 @@ static int get_cox(Jpeg2000DecoderContext *s,
Jpeg2000CodingStyle *c)
av_log(s->avctx, AV_LOG_ERROR, "no extra cblk styles supported\n");
return -1;
}
- c->transform = bytestream_get_byte(&s->buf); // transformation
+ c->transform = bytestream_get_byte(&s->buf); // DWT transformation type
+ /* set integer 9/7 DWT in case of BITEXACT flag*/
+ if ((s->avctx->flags & CODEC_FLAG_BITEXACT) && (c->transform == FF_DWT97))
+ c->transform = FF_DWT97_INT;
+
if (c->csty & JPEG2000_CSTY_PREC) {
int i;
for (i = 0; i < c->nreslevels; i++) {
@@ -881,31 +885,96 @@ static int decode_cblk(Jpeg2000DecoderContext *s,
Jpeg2000CodingStyle *codsty,
return 0;
}
-static void mct_decode(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
+/* TODO: Verify dequantization in case of lossless case
+ * comp->data can be float or int
+ * band->stepsize can be float or int
+ * depending on the type of DWT transformation.
+ * see ISO/IEC 15444-1:2002 A.6.1 */
+
+/* Float dequantization of a codeblock.*/
+static void dequantization_float(int x, int y, Jpeg2000Cblk *cblk,
+ Jpeg2000Component *comp,
+ Jpeg2000T1Context *t1, Jpeg2000Band *band) {
+ int i, j, idx;
+ float *datap = &comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y +
x];
+ for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j)
+ for (i = 0; i < (cblk->coord[0][1] - cblk->coord[0][0]); ++i) {
+ idx = (comp->coord[0][1] - comp->coord[0][0]) * j + i;
+ datap[idx] = (float)(t1->data[j][i]) * ((float)band->stepsize);
+ }
+ return;
+}
+
+/* Integer dequantization of a codeblock.*/
+static void dequantization_int(int x, int y, Jpeg2000Cblk *cblk,
+ Jpeg2000Component *comp,
+ Jpeg2000T1Context *t1, Jpeg2000Band *band) {
+ int i, j, idx;
+ int32_t *datap =
+ (int32_t *) &comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y +
x];
+ for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j)
+ for (i = 0; i < (cblk->coord[0][1] - cblk->coord[0][0]); ++i) {
+ idx = (comp->coord[0][1] - comp->coord[0][0]) * j + i;
+ datap[idx] =
+ ((int32_t)(t1->data[j][i]) * ((int32_t)band->stepsize) + (1 <<
15)) >> 16;
+ }
+ return;
+}
+
+/* Inverse ICT parameters in float and integer.
+ * int value = (float value) * (1<<16) */
+static const float f_ict_params[4] = {
+ 1.402f,
+ 0.34413f,
+ 0.71414f,
+ 1.772f
+};
+static const int i_ict_params[4] = {
+ 91881,
+ 22553,
+ 46802,
+ 116130
+};
+
+static int mct_decode(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
{
- int i, *src[3], i0, i1, i2, csize = 1;
- float *srcf[3];
- float i0f, i1f, i2f;
+ int i, csize = 1;
+ int ret = 0;
+ int32_t *src[3], i0, i1, i2;
+ float *srcf[3], i0f, i1f, i2f;
for (i = 0; i < 3; i++)
if (tile->codsty[0].transform == FF_DWT97)
srcf[i] = tile->comp[i].data;
else
- src[i] = (int *)tile->comp[i].data;
+ src[i] = (int32_t *)tile->comp[i].data;
for (i = 0; i < 2; i++)
csize *= tile->comp[0].coord[i][1] - tile->comp[0].coord[i][0];
-
- if (tile->codsty[0].transform == FF_DWT97) {
+ switch (tile->codsty[0].transform) {
+ case FF_DWT97:
for (i = 0; i < csize; i++) {
- i0f = *srcf[0] + (1.402f * *srcf[2]);
- i1f = *srcf[0] - (0.34413f * *srcf[1]) - (0.71414f * *srcf[2]);
- i2f = *srcf[0] + (1.772f * *srcf[1]);
+ i0f = *srcf[0] + (f_ict_params[0] * *srcf[2]);
+ i1f = *srcf[0] - (f_ict_params[1] * *srcf[1])
+ - (f_ict_params[2] * *srcf[2]);
+ i2f = *srcf[0] + (f_ict_params[3] * *srcf[1]);
*srcf[0]++ = i0f;
*srcf[1]++ = i1f;
*srcf[2]++ = i2f;
}
- } else {
+ break;
+ case FF_DWT97_INT:
+ for (i = 0; i < csize; i++) {
+ i0 = *src[0] + (((i_ict_params[0] * *src[2]) + (1 << 15)) >> 16);
+ i1 = *src[0] - (((i_ict_params[1] * *src[1]) + (1 << 15)) >> 16)
+ - (((i_ict_params[2] * *src[2]) + (1 << 15)) >> 16);
+ i2 = *src[0] + (((i_ict_params[3] * *src[1]) + (1 << 15)) >> 16);
+ *src[0]++ = i0;
+ *src[1]++ = i1;
+ *src[2]++ = i2;
+ }
+ break;
+ case FF_DWT53:
for (i = 0; i < csize; i++) {
i1 = *src[0] - (*src[2] + *src[1] >> 2);
i0 = i1 + *src[2];
@@ -914,7 +983,9 @@ static void mct_decode(Jpeg2000DecoderContext *s,
Jpeg2000Tile *tile)
*src[1]++ = i1;
*src[2]++ = i2;
}
+ break;
}
+ return ret;
}
static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
@@ -938,8 +1009,6 @@ static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s,
Jpeg2000Tile *tile,
uint16_t nb_precincts, precno;
Jpeg2000Band *band = rlevel->band + bandno;
int cblkno = 0, bandpos;
- /* TODO: Why bandpos? Not used anymore.
- * Check if the can be a clever idea. */
bandpos = bandno + (reslevelno > 0);
nb_precincts = rlevel->num_precincts_x *
rlevel->num_precincts_y;
@@ -949,9 +1018,8 @@ static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s,
Jpeg2000Tile *tile,
/* Loop on codeblocks */
for (cblkno = 0; cblkno < prec->nb_codeblocks_width *
prec->nb_codeblocks_height; cblkno++) {
- int i, j, x, y;
+ int x, y;
Jpeg2000Cblk *cblk = prec->cblk + cblkno;
- float *datap;
decode_cblk(s, codsty, &t1, cblk,
cblk->coord[0][1] - cblk->coord[0][0],
cblk->coord[1][1] - cblk->coord[1][0],
@@ -969,19 +1037,11 @@ static int jpeg2000_decode_tile(Jpeg2000DecoderContext
*s, Jpeg2000Tile *tile,
y += pres->coord[1][1] - pres->coord[1][0];
}
- /* TODO: Only the case of irreversible transform is
- * implemented (float). comp->data can be float or int
- * depending on the type of transformation.
- * see ISO/IEC 15444-1:2002 §A.6.1 */
- datap = &comp->data[(comp->coord[0][1] -
comp->coord[0][0]) * y + x];
- for (int j = 0; j < (cblk->coord[1][1] -
cblk->coord[1][0]); ++j)
- for (int i = 0; i < (cblk->coord[0][1] -
cblk->coord[0][0]); ++i) {
- float tmp;
- int idx = (comp->coord[0][1] -
comp->coord[0][0]) * j + i;
- tmp = (float)(t1.data[j][i]) *
band->stepsize;
- datap[idx] = tmp;
- }
- } /* end cblk */
+ if (s->avctx->flags & CODEC_FLAG_BITEXACT)
+ dequantization_int(x, y, cblk, comp, &t1, band);
+ else
+ dequantization_float(x, y, cblk, comp, &t1, band);
+ } /* end cblk */
} /*end prec */
} /* end band */
} /* end reslevel */
@@ -1025,6 +1085,7 @@ static int jpeg2000_decode_tile(Jpeg2000DecoderContext
*s, Jpeg2000Tile *tile,
for (compno = 0; compno < s->ncomponents; compno++) {
Jpeg2000Component *comp = tile->comp + compno;
float *datap = comp->data;
+ int32_t *i_datap = (int32_t *) comp->data;
uint16_t *linel;
y = tile->comp[compno].coord[1][0] - s->image_offset_y;
@@ -1034,16 +1095,17 @@ static int jpeg2000_decode_tile(Jpeg2000DecoderContext
*s, Jpeg2000Tile *tile,
x = tile->comp[compno].coord[0][0] - s->image_offset_x;
dst = linel + (x * s->ncomponents + compno);
for (; x < s->avctx->width; x += s->cdx[compno]) {
- float fval = *datap;
int16_t val;
/* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
- val = lrintf(fval) + (1 << (s->cbps[compno] - 1));
+ if (s->avctx->flags & CODEC_FLAG_BITEXACT)
+ val = *i_datap + (1 << (s->cbps[compno] - 1));
+ else
+ val = lrintf(*datap) + (1 << (s->cbps[compno] - 1));
val = av_clip(val, 0, (1 << s->cbps[compno]) - 1);
/* align 12 bit values in little-endian mode */
- val = val << 4;
- *dst = val;
- //*datap = (float)val;
+ *dst = (val << 4);
datap++;
+ i_datap++;
dst += s->ncomponents;
}
linel += picture->linesize[0] >> 1;
@@ -1231,7 +1293,6 @@ static int jpeg2000_decode_frame(AVCodecContext *avctx,
void *data,
return s->buf - s->buf_start;
}
-
#define OFFSET(x) offsetof(Jpeg2000DecoderContext, x)
#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
diff --git a/libavcodec/jpeg2000dwt.c b/libavcodec/jpeg2000dwt.c
index c7b612c..a988a81 100644
--- a/libavcodec/jpeg2000dwt.c
+++ b/libavcodec/jpeg2000dwt.c
@@ -30,17 +30,26 @@
#include "jpeg2000dwt.h"
#include "internal.h"
-/* defines for 9/7 DWT constants*/
-#define LFTG_ALPHA 1.586134342059924f
-#define LFTG_BETA 0.052980118572961f
-#define LFTG_GAMMA 0.882911075530934f
-#define LFTG_DELTA 0.443506852043971f
-#define LFTG_K 1.230174104914001f
-
-/* TODO: 1.625786 is used but not defined in ISO/IEC 15444-1:2002.
- * Investigation needed
- */
-static const float scale97[] = { 1.625786, LFTG_K };
+/* Defines for 9/7 DWT lifting parameters.
+ * Parameters are in float. */
+#define F_LFTG_ALPHA (1.586134342059924f)
+#define F_LFTG_BETA (0.052980118572961f)
+#define F_LFTG_GAMMA (0.882911075530934f)
+#define F_LFTG_DELTA (0.443506852043971f)
+#define F_LFTG_K (1.230174104914001f)
+#define F_LFTG_X (1.625732422f )
+/* FIXME: Why use 1.625732422 instead of 1/F_LFTG_K?
+ * see (ISO/IEC 15444:1 (version 2002) F.3.8.2 */
+
+/* Lifting parameters in integer format.
+ * Computed as param = (float param) * (1 << 16) */
+#define I_LFTG_ALPHA (103949)
+#define I_LFTG_BETA ( 3472)
+#define I_LFTG_GAMMA ( 57862)
+#define I_LFTG_DELTA ( 29066)
+#define I_LFTG_K ( 80621)
+#define I_LFTG_X (106544)
+
static inline void extend53(int *p, int i0, int i1)
{
@@ -50,7 +59,17 @@ static inline void extend53(int *p, int i0, int i1)
p[i1 + 1] = p[i1 - 3];
}
-static inline void extend97(float *p, int i0, int i1)
+static inline void extend97_float(float *p, int i0, int i1)
+{
+ int i;
+
+ for (i = 1; i <= 4; i++) {
+ p[i0 - i] = p[i0 + i];
+ p[i1 + i - 1] = p[i1 - i - 1];
+ }
+}
+
+static inline void extend97_int(int32_t *p, int i0, int i1)
{
int i;
@@ -124,38 +143,36 @@ static void dwt_decode53(DWTContext *s, int *t)
}
}
-static void sr_1d97(float *p, int i0, int i1)
+static void sr_1d97_float(float *p, int i0, int i1)
{
int i;
if (i1 == i0 + 1)
return;
- extend97(p, i0, i1);
+ extend97_float(p, i0, i1);
/*step 1*/
for (i = i0 / 2 - 1; i < i1 / 2 + 2; i++)
- p[2 * i] *= LFTG_K;
+ p[2 * i] *= F_LFTG_K;
/* step 2*/
for (i = i0 / 2 - 2; i < i1 / 2 + 2; i++)
- /* FIXME: Why use 1.625732422 instead of 1/LFTG_K?
- * see (ISO/IEC 15444:1 (version 2002) F.3.8.2 */
- p[2 * i + 1] *= 1.625732422f;
+ p[2 * i + 1] *= F_LFTG_X;
/* step 3*/
for (i = i0 / 2 - 1; i < i1 / 2 + 2; i++)
- p[2 * i] -= LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]);
+ p[2 * i] -= F_LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]);
/* step 4 */
for (i = i0 / 2 - 1; i < i1 / 2 + 1; i++)
- p[2 * i + 1] -= LFTG_GAMMA * (p[2 * i] + p[2 * i + 2]);
+ p[2 * i + 1] -= F_LFTG_GAMMA * (p[2 * i] + p[2 * i + 2]);
/*step 5*/
for (i = i0 / 2; i < i1 / 2 + 1; i++)
- p[2 * i] += LFTG_BETA * (p[2 * i - 1] + p[2 * i + 1]);
+ p[2 * i] += F_LFTG_BETA * (p[2 * i - 1] + p[2 * i + 1]);
/* step 6 */
for (i = i0 / 2; i < i1 / 2; i++)
- p[2 * i + 1] += LFTG_ALPHA * (p[2 * i] + p[2 * i + 2]);
+ p[2 * i + 1] += F_LFTG_ALPHA * (p[2 * i] + p[2 * i + 2]);
}
-static void dwt_decode97(DWTContext *s, float *t)
+static void dwt_decode97_float(DWTContext *s, float *t)
{
int lev;
int w = s->linelen[s->ndeclevels - 1][0];
@@ -181,7 +198,86 @@ static void dwt_decode97(DWTContext *s, float *t)
for (i = 1 - mh; i < lh; i += 2, j++)
l[i] = data[w * lp + j];
- sr_1d97(line, mh, mh + lh);
+ sr_1d97_float(line, mh, mh + lh);
+
+ for (i = 0; i < lh; i++)
+ data[w * lp + i] = l[i];
+ }
+
+ // VER_SD
+ l = line + mv;
+ for (lp = 0; lp < lh; lp++) {
+ int i, j = 0;
+ // copy with interleaving
+ for (i = mv; i < lv; i += 2, j++)
+ l[i] = data[w * j + lp];
+ for (i = 1 - mv; i < lv; i += 2, j++)
+ l[i] = data[w * j + lp];
+
+ sr_1d97_float(line, mv, mv + lv);
+
+ for (i = 0; i < lv; i++)
+ data[w * i + lp] = l[i];
+ }
+ }
+}
+
+static void sr_1d97_int(int32_t *p, int i0, int i1)
+{
+ int i;
+
+ if (i1 == i0 + 1)
+ return;
+
+ extend97_int(p, i0, i1);
+
+ /*step 1*/
+ for (i = i0 / 2 - 1; i < i1 / 2 + 2; i++)
+ p[2 * i] = ((p[2 * i] * I_LFTG_K) + (1 << 15)) >> 16;
+ /* step 2*/
+ for (i = i0 / 2 - 2; i < i1 / 2 + 2; i++)
+ p[2 * i + 1] = ((p[2 * i + 1] * I_LFTG_X) + (1 << 15)) >> 16;
+ /* step 3*/
+ for (i = i0 / 2 - 1; i < i1 / 2 + 2; i++)
+ p[2 * i] -= (I_LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]) + (1 <<
15)) >> 16;
+ /* step 4 */
+ for (i = i0 / 2 - 1; i < i1 / 2 + 1; i++)
+ p[2 * i + 1] -= (I_LFTG_GAMMA * (p[2 * i] + p[2 * i + 2]) + (1 <<
15)) >> 16;
+ /*step 5*/
+ for (i = i0 / 2; i < i1 / 2 + 1; i++)
+ p[2 * i] += (I_LFTG_BETA * (p[2 * i - 1] + p[2 * i + 1]) + (1 <<
15)) >> 16;
+ /* step 6 */
+ for (i = i0 / 2; i < i1 / 2; i++)
+ p[2 * i + 1] += (I_LFTG_ALPHA * (p[2 * i] + p[2 * i + 2]) + (1 <<
15)) >> 16;
+}
+
+static void dwt_decode97_int(DWTContext *s, int32_t *t)
+{
+ int lev;
+ int w = s->linelen[s->ndeclevels - 1][0];
+ int32_t *line = s->linebuf;
+ int32_t *data = t;
+ /* position at index O of line range [0-5,w+5] cf. extend function */
+ line += 5;
+
+ for (lev = 0; lev < s->ndeclevels; lev++) {
+ int lh = s->linelen[lev][0],
+ lv = s->linelen[lev][1],
+ mh = s->mod[lev][0],
+ mv = s->mod[lev][1],
+ lp;
+ int32_t *l;
+ // HOR_SD
+ l = line + mh;
+ for (lp = 0; lp < lv; lp++) {
+ int i, j = 0;
+ // copy with interleaving
+ for (i = mh; i < lh; i += 2, j++)
+ l[i] = data[w * lp + j];
+ for (i = 1 - mh; i < lh; i += 2, j++)
+ l[i] = data[w * lp + j];
+
+ sr_1d97_int(line, mh, mh + lh);
for (i = 0; i < lh; i++)
data[w * lp + i] = l[i];
@@ -197,7 +293,7 @@ static void dwt_decode97(DWTContext *s, float *t)
for (i = 1 - mv; i < lv; i += 2, j++)
l[i] = data[w * j + lp];
- sr_1d97(line, mv, mv + lv);
+ sr_1d97_int(line, mv, mv + lv);
for (i = 0; i < lv; i++)
data[w * i + lp] = l[i];
@@ -231,8 +327,11 @@ int ff_jpeg2000_dwt_init(DWTContext *s, uint16_t
border[2][2],
case FF_DWT97:
s->linebuf = av_malloc((maxlen + 12) * sizeof(float));
break;
+ case FF_DWT97_INT:
+ s->linebuf = av_malloc((maxlen + 12) * sizeof(int32_t));
+ break;
case FF_DWT53:
- s->linebuf = av_malloc((maxlen + 6) * sizeof(int));
+ s->linebuf = av_malloc((maxlen + 6) * sizeof(int32_t));
break;
default:
return -1;
@@ -247,7 +346,10 @@ int ff_dwt_decode(DWTContext *s, void *t)
{
switch (s->type) {
case FF_DWT97:
- dwt_decode97(s, t);
+ dwt_decode97_float(s, t);
+ break;
+ case FF_DWT97_INT:
+ dwt_decode97_int(s, t);
break;
case FF_DWT53:
dwt_decode53(s, t);
diff --git a/libavcodec/jpeg2000dwt.h b/libavcodec/jpeg2000dwt.h
index cf9858b..ea8196c 100644
--- a/libavcodec/jpeg2000dwt.h
+++ b/libavcodec/jpeg2000dwt.h
@@ -33,7 +33,8 @@
enum DWTType {
FF_DWT97,
- FF_DWT53
+ FF_DWT53,
+ FF_DWT97_INT
};
typedef struct DWTContext {
diff --git a/tests/fate/video.mak b/tests/fate/video.mak
index 0e16670..33c3015 100644
--- a/tests/fate/video.mak
+++ b/tests/fate/video.mak
@@ -154,6 +154,9 @@ fate-interplay-mve-16bit: CMD = framecrc -i
$(SAMPLES)/interplay-mve/descent3-le
FATE_JPEG2000 += fate-jpeg2000-dcinema
fate-jpeg2000-dcinema: CMD = framecrc -i
$(SAMPLES)/jpeg2000/chiens_dcinema2K.mxf
+FATE_JPEG2000 += fate-jpeg2000-dcinema-bitexact
+fate-jpeg2000-dcinema-bitexact: CMD = framecrc -flags +bitexact -i
$(SAMPLES)/jpeg2000/chiens_dcinema2K.mxf
+
FATE_JPEG2000 += fate-jpeg2000-dcinema-xyz
fate-jpeg2000-dcinema-xyz: CMD = framecrc -i
$(SAMPLES)/jpeg2000/chiens_dcinema2K.mxf -vf xyz2rgb -pix_fmt xyz12le
diff --git a/tests/ref/fate/jpeg2000-dcinema-bitexact
b/tests/ref/fate/jpeg2000-dcinema-bitexact
new file mode 100644
index 0000000..940759a
--- /dev/null
+++ b/tests/ref/fate/jpeg2000-dcinema-bitexact
@@ -0,0 +1,3 @@
+#tb 0: 1/24
+0, 0, 0, 1, 12441600, 0xf0de508b
+0, 1, 1, 1, 12441600, 0x8e50c249
--
1.7.9.5
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel