#include <stdlib.h>
#include <string.h>
+#define YLC_VLC_BITS 10
+
#include "libavutil/imgutils.h"
#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
typedef struct YLCContext {
VLC vlc[4];
- uint32_t table[1024];
- uint8_t *table_bits;
- uint8_t *bitstream_bits;
- int table_bits_size;
- int bitstream_bits_size;
+ uint32_t table[256];
+ uint8_t *buffer;
+ int buffer_size;
BswapDSPContext bdsp;
} YLCContext;
typedef struct Node {
int16_t sym;
- int16_t n0;
uint32_t count;
int16_t l, r;
} Node;
for (i = 0; i < 256; i++) {
nodes[i].count = table[i];
nodes[i].sym = i;
- nodes[i].n0 = -2;
nodes[i].l = i;
nodes[i].r = i;
}
}
nodes[cur_node].count = nd + st;
nodes[cur_node].sym = -1;
- nodes[cur_node].n0 = cur_node;
nodes[cur_node].l = first_node;
nodes[cur_node].r = second_node;
cur_node++;
get_tree_codes(bits, lens, xlat, nodes, cur_node - 1, 0, 0, &pos);
- return ff_init_vlc_sparse(vlc, 10, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0);
+ return ff_init_vlc_sparse(vlc, YLC_VLC_BITS, pos, lens, 2, 2,
+ bits, 4, 4, xlat, 1, 1, 0);
}
static const uint8_t table_y1[] = {
if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
return ret;
- av_fast_malloc(&s->table_bits, &s->table_bits_size,
- boffset - toffset + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!s->table_bits)
+ av_fast_malloc(&s->buffer, &s->buffer_size,
+ FFMAX(boffset - toffset, avpkt->size - boffset)
+ + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!s->buffer)
return AVERROR(ENOMEM);
- memcpy(s->table_bits, avpkt->data + toffset, boffset - toffset);
- memset(s->table_bits + boffset - toffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- s->bdsp.bswap_buf((uint32_t *) s->table_bits,
- (uint32_t *) s->table_bits,
+ memcpy(s->buffer, avpkt->data + toffset, boffset - toffset);
+ memset(s->buffer + boffset - toffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ s->bdsp.bswap_buf((uint32_t *) s->buffer,
+ (uint32_t *) s->buffer,
(boffset - toffset + 3) >> 2);
- if ((ret = init_get_bits8(&gb, s->table_bits, boffset - toffset)) < 0)
+ if ((ret = init_get_bits8(&gb, s->buffer, boffset - toffset)) < 0)
return ret;
- for (x = 0; x < 1024; x++) {
- unsigned len = get_unary(&gb, 1, 31);
- uint32_t val = ((1U << len) - 1) + get_bits_long(&gb, len);
-
- s->table[x] = val;
- }
+ for (int i = 0; i < 4; i++) {
+ for (x = 0; x < 256; x++) {
+ unsigned len = get_unary(&gb, 1, 31);
+ uint32_t val = ((1U << len) - 1) + get_bits_long(&gb, len);
- ret = build_vlc(avctx, &s->vlc[0], &s->table[0 ]);
- if (ret < 0)
- return ret;
- ret = build_vlc(avctx, &s->vlc[1], &s->table[256]);
- if (ret < 0)
- return ret;
- ret = build_vlc(avctx, &s->vlc[2], &s->table[512]);
- if (ret < 0)
- return ret;
- ret = build_vlc(avctx, &s->vlc[3], &s->table[768]);
- if (ret < 0)
- return ret;
+ s->table[x] = val;
+ }
- av_fast_malloc(&s->bitstream_bits, &s->bitstream_bits_size,
- avpkt->size - boffset + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!s->bitstream_bits)
- return AVERROR(ENOMEM);
+ ret = build_vlc(avctx, &s->vlc[i], s->table);
+ if (ret < 0)
+ return ret;
+ }
- memcpy(s->bitstream_bits, avpkt->data + boffset, avpkt->size - boffset);
- memset(s->bitstream_bits + avpkt->size - boffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- s->bdsp.bswap_buf((uint32_t *) s->bitstream_bits,
- (uint32_t *) s->bitstream_bits,
+ memcpy(s->buffer, avpkt->data + boffset, avpkt->size - boffset);
+ memset(s->buffer + avpkt->size - boffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ s->bdsp.bswap_buf((uint32_t *) s->buffer,
+ (uint32_t *) s->buffer,
(avpkt->size - boffset) >> 2);
- if ((ret = init_get_bits8(&gb, s->bitstream_bits, avpkt->size - boffset)) < 0)
+ if ((ret = init_get_bits8(&gb, s->buffer, avpkt->size - boffset)) < 0)
return ret;
dst = p->data[0];
return AVERROR_INVALIDDATA;
if (get_bits1(&gb)) {
- int val = get_vlc2(&gb, s->vlc[0].table, s->vlc[0].bits, 3);
+ int val = get_vlc2(&gb, s->vlc[0].table, YLC_VLC_BITS, 3);
if (val < 0) {
return AVERROR_INVALIDDATA;
} else if (val < 0xE1) {
} else {
int y1, y2, u, v;
- y1 = get_vlc2(&gb, s->vlc[1].table, s->vlc[1].bits, 3);
- u = get_vlc2(&gb, s->vlc[2].table, s->vlc[2].bits, 3);
- y2 = get_vlc2(&gb, s->vlc[1].table, s->vlc[1].bits, 3);
- v = get_vlc2(&gb, s->vlc[3].table, s->vlc[3].bits, 3);
+ y1 = get_vlc2(&gb, s->vlc[1].table, YLC_VLC_BITS, 3);
+ u = get_vlc2(&gb, s->vlc[2].table, YLC_VLC_BITS, 3);
+ y2 = get_vlc2(&gb, s->vlc[1].table, YLC_VLC_BITS, 3);
+ v = get_vlc2(&gb, s->vlc[3].table, YLC_VLC_BITS, 3);
if (y1 < 0 || y2 < 0 || u < 0 || v < 0)
return AVERROR_INVALIDDATA;
dst[x ] = y1;
return avpkt->size;
}
-#if HAVE_THREADS
-static int init_thread_copy(AVCodecContext *avctx)
-{
- YLCContext *s = avctx->priv_data;
-
- memset(&s->vlc[0], 0, sizeof(VLC));
- memset(&s->vlc[1], 0, sizeof(VLC));
- memset(&s->vlc[2], 0, sizeof(VLC));
- memset(&s->vlc[3], 0, sizeof(VLC));
- s->table_bits = NULL;
- s->table_bits_size = 0;
- s->bitstream_bits = NULL;
- s->bitstream_bits_size = 0;
-
- return 0;
-}
-#endif
-
static av_cold int decode_end(AVCodecContext *avctx)
{
YLCContext *s = avctx->priv_data;
- ff_free_vlc(&s->vlc[0]);
- ff_free_vlc(&s->vlc[1]);
- ff_free_vlc(&s->vlc[2]);
- ff_free_vlc(&s->vlc[3]);
- av_freep(&s->table_bits);
- s->table_bits_size = 0;
- av_freep(&s->bitstream_bits);
- s->bitstream_bits_size = 0;
+ for (int i = 0; i < FF_ARRAY_ELEMS(s->vlc); i++)
+ ff_free_vlc(&s->vlc[i]);
+ av_freep(&s->buffer);
+ s->buffer_size = 0;
return 0;
}
-AVCodec ff_ylc_decoder = {
+const AVCodec ff_ylc_decoder = {
.name = "ylc",
.long_name = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_YLC,
.priv_data_size = sizeof(YLCContext),
.init = decode_init,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
.close = decode_end,
.decode = decode_frame,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,