mirror of
https://github.com/nyanmisaka/ffmpeg-rockchip.git
synced 2025-10-27 19:02:13 +08:00
avcodec: add HYMT decoder
This commit is contained in:
@@ -12,6 +12,7 @@ version <next>:
|
|||||||
- PCM-DVD encoder
|
- PCM-DVD encoder
|
||||||
- GIF parser
|
- GIF parser
|
||||||
- vividas demuxer
|
- vividas demuxer
|
||||||
|
- hymt decoder
|
||||||
|
|
||||||
|
|
||||||
version 4.1:
|
version 4.1:
|
||||||
|
|||||||
@@ -383,6 +383,7 @@ OBJS-$(CONFIG_HQ_HQA_DECODER) += hq_hqa.o hq_hqadata.o hq_hqadsp.o \
|
|||||||
OBJS-$(CONFIG_HQX_DECODER) += hqx.o hqxvlc.o hqxdsp.o canopus.o
|
OBJS-$(CONFIG_HQX_DECODER) += hqx.o hqxvlc.o hqxdsp.o canopus.o
|
||||||
OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o huffyuvdec.o
|
OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o huffyuvdec.o
|
||||||
OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o huffyuvenc.o
|
OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o huffyuvenc.o
|
||||||
|
OBJS-$(CONFIG_HYMT_DECODER) += huffyuv.o huffyuvdec.o
|
||||||
OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o
|
OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o
|
||||||
OBJS-$(CONFIG_IDF_DECODER) += bintext.o cga_data.o
|
OBJS-$(CONFIG_IDF_DECODER) += bintext.o cga_data.o
|
||||||
OBJS-$(CONFIG_IFF_ILBM_DECODER) += iff.o
|
OBJS-$(CONFIG_IFF_ILBM_DECODER) += iff.o
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ extern AVCodec ff_hq_hqa_decoder;
|
|||||||
extern AVCodec ff_hqx_decoder;
|
extern AVCodec ff_hqx_decoder;
|
||||||
extern AVCodec ff_huffyuv_encoder;
|
extern AVCodec ff_huffyuv_encoder;
|
||||||
extern AVCodec ff_huffyuv_decoder;
|
extern AVCodec ff_huffyuv_decoder;
|
||||||
|
extern AVCodec ff_hymt_decoder;
|
||||||
extern AVCodec ff_idcin_decoder;
|
extern AVCodec ff_idcin_decoder;
|
||||||
extern AVCodec ff_iff_ilbm_decoder;
|
extern AVCodec ff_iff_ilbm_decoder;
|
||||||
extern AVCodec ff_imm4_decoder;
|
extern AVCodec ff_imm4_decoder;
|
||||||
|
|||||||
@@ -452,6 +452,7 @@ enum AVCodecID {
|
|||||||
AV_CODEC_ID_MWSC,
|
AV_CODEC_ID_MWSC,
|
||||||
AV_CODEC_ID_WCMV,
|
AV_CODEC_ID_WCMV,
|
||||||
AV_CODEC_ID_RASC,
|
AV_CODEC_ID_RASC,
|
||||||
|
AV_CODEC_ID_HYMT,
|
||||||
|
|
||||||
/* various PCM "codecs" */
|
/* various PCM "codecs" */
|
||||||
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
|
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
|
||||||
|
|||||||
@@ -1691,6 +1691,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
|
|||||||
.long_name = NULL_IF_CONFIG_SMALL("RemotelyAnywhere Screen Capture"),
|
.long_name = NULL_IF_CONFIG_SMALL("RemotelyAnywhere Screen Capture"),
|
||||||
.props = AV_CODEC_PROP_LOSSY,
|
.props = AV_CODEC_PROP_LOSSY,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.id = AV_CODEC_ID_HYMT,
|
||||||
|
.type = AVMEDIA_TYPE_VIDEO,
|
||||||
|
.name = "hymt",
|
||||||
|
.long_name = NULL_IF_CONFIG_SMALL("HuffYUV MT"),
|
||||||
|
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
|
||||||
|
},
|
||||||
|
|
||||||
/* various PCM "codecs" */
|
/* various PCM "codecs" */
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -905,54 +905,23 @@ static void add_median_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *s
|
|||||||
s->hdsp.add_hfyu_median_pred_int16((uint16_t *)dst, (const uint16_t *)src, (const uint16_t *)diff, s->n-1, w, left, left_top);
|
s->hdsp.add_hfyu_median_pred_int16((uint16_t *)dst, (const uint16_t *)src, (const uint16_t *)diff, s->n-1, w, left, left_top);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
|
||||||
AVPacket *avpkt)
|
static int decode_slice(AVCodecContext *avctx, AVFrame *p, int height,
|
||||||
|
int buf_size, int y_offset, int table_size)
|
||||||
{
|
{
|
||||||
const uint8_t *buf = avpkt->data;
|
|
||||||
int buf_size = avpkt->size;
|
|
||||||
HYuvContext *s = avctx->priv_data;
|
HYuvContext *s = avctx->priv_data;
|
||||||
|
int fake_ystride, fake_ustride, fake_vstride;
|
||||||
const int width = s->width;
|
const int width = s->width;
|
||||||
const int width2 = s->width >> 1;
|
const int width2 = s->width >> 1;
|
||||||
const int height = s->height;
|
int ret;
|
||||||
int fake_ystride, fake_ustride, fake_vstride;
|
|
||||||
ThreadFrame frame = { .f = data };
|
|
||||||
AVFrame *const p = data;
|
|
||||||
int table_size = 0, ret;
|
|
||||||
|
|
||||||
if (buf_size < (width * height + 7)/8)
|
if ((ret = init_get_bits8(&s->gb, s->bitstream_buffer + table_size, buf_size - table_size)) < 0)
|
||||||
return AVERROR_INVALIDDATA;
|
|
||||||
|
|
||||||
av_fast_padded_malloc(&s->bitstream_buffer,
|
|
||||||
&s->bitstream_buffer_size,
|
|
||||||
buf_size);
|
|
||||||
if (!s->bitstream_buffer)
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
|
|
||||||
s->bdsp.bswap_buf((uint32_t *) s->bitstream_buffer,
|
|
||||||
(const uint32_t *) buf, buf_size / 4);
|
|
||||||
|
|
||||||
if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (s->context) {
|
|
||||||
table_size = read_huffman_tables(s, s->bitstream_buffer, buf_size);
|
|
||||||
if (table_size < 0)
|
|
||||||
return table_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((unsigned) (buf_size - table_size) >= INT_MAX / 8)
|
|
||||||
return AVERROR_INVALIDDATA;
|
|
||||||
|
|
||||||
if ((ret = init_get_bits(&s->gb, s->bitstream_buffer + table_size,
|
|
||||||
(buf_size - table_size) * 8)) < 0)
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
fake_ystride = s->interlaced ? p->linesize[0] * 2 : p->linesize[0];
|
fake_ystride = s->interlaced ? p->linesize[0] * 2 : p->linesize[0];
|
||||||
fake_ustride = s->interlaced ? p->linesize[1] * 2 : p->linesize[1];
|
fake_ustride = s->interlaced ? p->linesize[1] * 2 : p->linesize[1];
|
||||||
fake_vstride = s->interlaced ? p->linesize[2] * 2 : p->linesize[2];
|
fake_vstride = s->interlaced ? p->linesize[2] * 2 : p->linesize[2];
|
||||||
|
|
||||||
s->last_slice_end = 0;
|
|
||||||
|
|
||||||
if (s->version > 2) {
|
if (s->version > 2) {
|
||||||
int plane;
|
int plane;
|
||||||
for(plane = 0; plane < 1 + 2*s->chroma + s->alpha; plane++) {
|
for(plane = 0; plane < 1 + 2*s->chroma + s->alpha; plane++) {
|
||||||
@@ -1034,31 +1003,31 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
|||||||
return AVERROR_PATCHWELCOME;
|
return AVERROR_PATCHWELCOME;
|
||||||
} else {
|
} else {
|
||||||
leftv =
|
leftv =
|
||||||
p->data[2][0] = get_bits(&s->gb, 8);
|
p->data[2][0 + y_offset * p->linesize[2]] = get_bits(&s->gb, 8);
|
||||||
lefty =
|
lefty =
|
||||||
p->data[0][1] = get_bits(&s->gb, 8);
|
p->data[0][1 + y_offset * p->linesize[0]] = get_bits(&s->gb, 8);
|
||||||
leftu =
|
leftu =
|
||||||
p->data[1][0] = get_bits(&s->gb, 8);
|
p->data[1][0 + y_offset * p->linesize[1]] = get_bits(&s->gb, 8);
|
||||||
p->data[0][0] = get_bits(&s->gb, 8);
|
p->data[0][0 + y_offset * p->linesize[0]] = get_bits(&s->gb, 8);
|
||||||
|
|
||||||
switch (s->predictor) {
|
switch (s->predictor) {
|
||||||
case LEFT:
|
case LEFT:
|
||||||
case PLANE:
|
case PLANE:
|
||||||
decode_422_bitstream(s, width - 2);
|
decode_422_bitstream(s, width - 2);
|
||||||
lefty = s->llviddsp.add_left_pred(p->data[0] + 2, s->temp[0],
|
lefty = s->llviddsp.add_left_pred(p->data[0] + p->linesize[0] * y_offset + 2, s->temp[0],
|
||||||
width - 2, lefty);
|
width - 2, lefty);
|
||||||
if (!(s->flags & AV_CODEC_FLAG_GRAY)) {
|
if (!(s->flags & AV_CODEC_FLAG_GRAY)) {
|
||||||
leftu = s->llviddsp.add_left_pred(p->data[1] + 1, s->temp[1], width2 - 1, leftu);
|
leftu = s->llviddsp.add_left_pred(p->data[1] + p->linesize[1] * y_offset + 1, s->temp[1], width2 - 1, leftu);
|
||||||
leftv = s->llviddsp.add_left_pred(p->data[2] + 1, s->temp[2], width2 - 1, leftv);
|
leftv = s->llviddsp.add_left_pred(p->data[2] + p->linesize[2] * y_offset + 1, s->temp[2], width2 - 1, leftv);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (cy = y = 1; y < s->height; y++, cy++) {
|
for (cy = y = 1; y < height; y++, cy++) {
|
||||||
uint8_t *ydst, *udst, *vdst;
|
uint8_t *ydst, *udst, *vdst;
|
||||||
|
|
||||||
if (s->bitstream_bpp == 12) {
|
if (s->bitstream_bpp == 12) {
|
||||||
decode_gray_bitstream(s, width);
|
decode_gray_bitstream(s, width);
|
||||||
|
|
||||||
ydst = p->data[0] + p->linesize[0] * y;
|
ydst = p->data[0] + p->linesize[0] * (y + y_offset);
|
||||||
|
|
||||||
lefty = s->llviddsp.add_left_pred(ydst, s->temp[0],
|
lefty = s->llviddsp.add_left_pred(ydst, s->temp[0],
|
||||||
width, lefty);
|
width, lefty);
|
||||||
@@ -1067,15 +1036,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
|||||||
s->llviddsp.add_bytes(ydst, ydst - fake_ystride, width);
|
s->llviddsp.add_bytes(ydst, ydst - fake_ystride, width);
|
||||||
}
|
}
|
||||||
y++;
|
y++;
|
||||||
if (y >= s->height)
|
if (y >= height)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_slice(s, p, y);
|
draw_slice(s, p, y);
|
||||||
|
|
||||||
ydst = p->data[0] + p->linesize[0] * y;
|
ydst = p->data[0] + p->linesize[0] * (y + y_offset);
|
||||||
udst = p->data[1] + p->linesize[1] * cy;
|
udst = p->data[1] + p->linesize[1] * (cy + y_offset);
|
||||||
vdst = p->data[2] + p->linesize[2] * cy;
|
vdst = p->data[2] + p->linesize[2] * (cy + y_offset);
|
||||||
|
|
||||||
decode_422_bitstream(s, width);
|
decode_422_bitstream(s, width);
|
||||||
lefty = s->llviddsp.add_left_pred(ydst, s->temp[0],
|
lefty = s->llviddsp.add_left_pred(ydst, s->temp[0],
|
||||||
@@ -1185,7 +1154,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
|||||||
} else {
|
} else {
|
||||||
int y;
|
int y;
|
||||||
uint8_t left[4];
|
uint8_t left[4];
|
||||||
const int last_line = (height - 1) * p->linesize[0];
|
const int last_line = (y_offset + height - 1) * p->linesize[0];
|
||||||
|
|
||||||
if (s->bitstream_bpp == 32) {
|
if (s->bitstream_bpp == 32) {
|
||||||
left[A] = p->data[0][last_line + A] = get_bits(&s->gb, 8);
|
left[A] = p->data[0][last_line + A] = get_bits(&s->gb, 8);
|
||||||
@@ -1208,17 +1177,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
|||||||
s->hdsp.add_hfyu_left_pred_bgr32(p->data[0] + last_line + 4,
|
s->hdsp.add_hfyu_left_pred_bgr32(p->data[0] + last_line + 4,
|
||||||
s->temp[0], width - 1, left);
|
s->temp[0], width - 1, left);
|
||||||
|
|
||||||
for (y = s->height - 2; y >= 0; y--) { // Yes it is stored upside down.
|
for (y = height - 2; y >= 0; y--) { // Yes it is stored upside down.
|
||||||
decode_bgr_bitstream(s, width);
|
decode_bgr_bitstream(s, width);
|
||||||
|
|
||||||
s->hdsp.add_hfyu_left_pred_bgr32(p->data[0] + p->linesize[0] * y,
|
s->hdsp.add_hfyu_left_pred_bgr32(p->data[0] + p->linesize[0] * (y + y_offset),
|
||||||
s->temp[0], width, left);
|
s->temp[0], width, left);
|
||||||
if (s->predictor == PLANE) {
|
if (s->predictor == PLANE) {
|
||||||
if (s->bitstream_bpp != 32)
|
if (s->bitstream_bpp != 32)
|
||||||
left[A] = 0;
|
left[A] = 0;
|
||||||
if (y < s->height - 1 - s->interlaced) {
|
if (y < height - 1 - s->interlaced) {
|
||||||
s->llviddsp.add_bytes(p->data[0] + p->linesize[0] * y,
|
s->llviddsp.add_bytes(p->data[0] + p->linesize[0] * (y + y_offset),
|
||||||
p->data[0] + p->linesize[0] * y +
|
p->data[0] + p->linesize[0] * (y + y_offset) +
|
||||||
fake_ystride, 4 * width);
|
fake_ystride, 4 * width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1236,7 +1205,82 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
|||||||
return AVERROR_PATCHWELCOME;
|
return AVERROR_PATCHWELCOME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emms_c();
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
||||||
|
AVPacket *avpkt)
|
||||||
|
{
|
||||||
|
const uint8_t *buf = avpkt->data;
|
||||||
|
int buf_size = avpkt->size;
|
||||||
|
HYuvContext *s = avctx->priv_data;
|
||||||
|
const int width = s->width;
|
||||||
|
const int height = s->height;
|
||||||
|
ThreadFrame frame = { .f = data };
|
||||||
|
AVFrame *const p = data;
|
||||||
|
int slice, table_size = 0, ret, nb_slices;
|
||||||
|
unsigned slices_info_offset;
|
||||||
|
int slice_height;
|
||||||
|
|
||||||
|
if (buf_size < (width * height + 7)/8)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
|
av_fast_padded_malloc(&s->bitstream_buffer,
|
||||||
|
&s->bitstream_buffer_size,
|
||||||
|
buf_size);
|
||||||
|
if (!s->bitstream_buffer)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
s->bdsp.bswap_buf((uint32_t *) s->bitstream_buffer,
|
||||||
|
(const uint32_t *) buf, buf_size / 4);
|
||||||
|
|
||||||
|
if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (s->context) {
|
||||||
|
table_size = read_huffman_tables(s, s->bitstream_buffer, buf_size);
|
||||||
|
if (table_size < 0)
|
||||||
|
return table_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((unsigned) (buf_size - table_size) >= INT_MAX / 8)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
|
s->last_slice_end = 0;
|
||||||
|
|
||||||
|
if (avctx->codec_id == AV_CODEC_ID_HYMT &&
|
||||||
|
(buf_size > 32 && AV_RL32(avpkt->data + buf_size - 16) == 0)) {
|
||||||
|
slices_info_offset = AV_RL32(avpkt->data + buf_size - 4);
|
||||||
|
slice_height = AV_RL32(avpkt->data + buf_size - 8);
|
||||||
|
nb_slices = AV_RL32(avpkt->data + buf_size - 12);
|
||||||
|
if (nb_slices * 8LL + slices_info_offset > buf_size - 16)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
} else {
|
||||||
|
slice_height = height;
|
||||||
|
nb_slices = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (slice = 0; slice < nb_slices; slice++) {
|
||||||
|
int y_offset, slice_offset, slice_size;
|
||||||
|
|
||||||
|
if (nb_slices > 1) {
|
||||||
|
slice_offset = AV_RL32(avpkt->data + slices_info_offset + slice * 8);
|
||||||
|
slice_size = AV_RL32(avpkt->data + slices_info_offset + slice * 8 + 4);
|
||||||
|
y_offset = height - (slice + 1) * slice_height;
|
||||||
|
s->bdsp.bswap_buf((uint32_t *)s->bitstream_buffer,
|
||||||
|
(const uint32_t *)(buf + slice_offset), slice_size / 4);
|
||||||
|
} else {
|
||||||
|
y_offset = 0;
|
||||||
|
slice_offset = 0;
|
||||||
|
slice_size = buf_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = decode_slice(avctx, p, slice_height, slice_size, y_offset, table_size);
|
||||||
|
emms_c();
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
*got_frame = 1;
|
*got_frame = 1;
|
||||||
|
|
||||||
@@ -1272,3 +1316,19 @@ AVCodec ff_ffvhuff_decoder = {
|
|||||||
.init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
|
.init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
|
||||||
};
|
};
|
||||||
#endif /* CONFIG_FFVHUFF_DECODER */
|
#endif /* CONFIG_FFVHUFF_DECODER */
|
||||||
|
|
||||||
|
#if CONFIG_HYMT_DECODER
|
||||||
|
AVCodec ff_hymt_decoder = {
|
||||||
|
.name = "hymt",
|
||||||
|
.long_name = NULL_IF_CONFIG_SMALL("HuffYUV MT"),
|
||||||
|
.type = AVMEDIA_TYPE_VIDEO,
|
||||||
|
.id = AV_CODEC_ID_HYMT,
|
||||||
|
.priv_data_size = sizeof(HYuvContext),
|
||||||
|
.init = decode_init,
|
||||||
|
.close = decode_end,
|
||||||
|
.decode = decode_frame,
|
||||||
|
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
|
||||||
|
AV_CODEC_CAP_FRAME_THREADS,
|
||||||
|
.init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
|
||||||
|
};
|
||||||
|
#endif /* CONFIG_HYMT_DECODER */
|
||||||
|
|||||||
@@ -28,8 +28,8 @@
|
|||||||
#include "libavutil/version.h"
|
#include "libavutil/version.h"
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_MAJOR 58
|
#define LIBAVCODEC_VERSION_MAJOR 58
|
||||||
#define LIBAVCODEC_VERSION_MINOR 42
|
#define LIBAVCODEC_VERSION_MINOR 43
|
||||||
#define LIBAVCODEC_VERSION_MICRO 104
|
#define LIBAVCODEC_VERSION_MICRO 100
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||||
LIBAVCODEC_VERSION_MINOR, \
|
LIBAVCODEC_VERSION_MINOR, \
|
||||||
|
|||||||
@@ -475,6 +475,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
|
|||||||
{ AV_CODEC_ID_MWSC, MKTAG('M', 'W', 'S', 'C') },
|
{ AV_CODEC_ID_MWSC, MKTAG('M', 'W', 'S', 'C') },
|
||||||
{ AV_CODEC_ID_WCMV, MKTAG('W', 'C', 'M', 'V') },
|
{ AV_CODEC_ID_WCMV, MKTAG('W', 'C', 'M', 'V') },
|
||||||
{ AV_CODEC_ID_RASC, MKTAG('R', 'A', 'S', 'C') },
|
{ AV_CODEC_ID_RASC, MKTAG('R', 'A', 'S', 'C') },
|
||||||
|
{ AV_CODEC_ID_HYMT, MKTAG('H', 'Y', 'M', 'T') },
|
||||||
{ AV_CODEC_ID_NONE, 0 }
|
{ AV_CODEC_ID_NONE, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user