#include "mathops.h"
#include "dsputil.h"
#include "lagarithrac.h"
+#include "thread.h"
enum LagarithFrameType {
FRAME_RAW = 1, /**< uncompressed */
/* Comment from reference source:
* if (b & 0x80 == 0) { // order of operations is 'wrong'; it has been left this way
* // since the compression change is negligable and fixing it
- * // breaks backwards compatibilty
+ * // breaks backwards compatibility
* b =- (signed int)b;
* b &= 0xFF;
* } else {
}
}
+static void lag_pred_line_yuy2(LagarithContext *l, uint8_t *buf,
+ int width, int stride, int line,
+ int is_luma)
+{
+ int L, TL;
+
+ if (!line) {
+ if (is_luma) {
+ buf++;
+ width--;
+ }
+ l->dsp.add_hfyu_left_prediction(buf + 1, buf + 1, width - 1, buf[0]);
+ return;
+ }
+ if (line == 1) {
+ const int HEAD = is_luma ? 4 : 2;
+ int i;
+
+ L = buf[width - stride - 1];
+ TL = buf[HEAD - stride - 1];
+ for (i = 0; i < HEAD; i++) {
+ L += buf[i];
+ buf[i] = L;
+ }
+ buf += HEAD;
+ width -= HEAD;
+ } else {
+ TL = buf[width - (2 * stride) - 1];
+ L = buf[width - stride - 1];
+ }
+ l->dsp.add_hfyu_median_prediction(buf, buf - stride, buf, width,
+ &L, &TL);
+}
+
static int lag_decode_line(LagarithContext *l, lag_rac *rac,
uint8_t *dst, int width, int stride,
int esc_count)
return -1;
}
- for (i = 0; i < height; i++) {
- lag_pred_line(l, dst, width, stride, i);
- dst += stride;
+ if (l->avctx->pix_fmt != PIX_FMT_YUV422P) {
+ for (i = 0; i < height; i++) {
+ lag_pred_line(l, dst, width, stride, i);
+ dst += stride;
+ }
+ } else {
+ for (i = 0; i < height; i++) {
+ lag_pred_line_yuy2(l, dst, width, stride, i,
+ width == l->avctx->width);
+ dst += stride;
+ }
}
return 0;
AVFrame *const p = &l->picture;
uint8_t frametype = 0;
uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
- int offs[4];
+ uint32_t offs[4];
uint8_t *srcs[4], *dst;
int i, j, planes = 3;
AVFrame *picture = data;
if (p->data[0])
- avctx->release_buffer(avctx, p);
+ ff_thread_release_buffer(avctx, p);
p->reference = 0;
p->key_frame = 1;
case FRAME_SOLID_RGBA:
avctx->pix_fmt = PIX_FMT_RGB32;
- if (avctx->get_buffer(avctx, p) < 0) {
+ if (ff_thread_get_buffer(avctx, p) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
if (frametype == FRAME_ARITH_RGB24 || frametype == FRAME_U_RGB24)
avctx->pix_fmt = PIX_FMT_RGB24;
- if (avctx->get_buffer(avctx, p) < 0) {
+ if (ff_thread_get_buffer(avctx, p) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
srcs[i] += l->rgb_stride;
}
break;
+ case FRAME_ARITH_YUY2:
+ avctx->pix_fmt = PIX_FMT_YUV422P;
+
+ if (ff_thread_get_buffer(avctx, p) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return -1;
+ }
+
+ if (offset_ry >= buf_size ||
+ offset_gu >= buf_size ||
+ offset_bv >= buf_size) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid frame offsets\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
+ p->linesize[0], buf + offset_ry,
+ buf_size - offset_ry);
+ lag_decode_arith_plane(l, p->data[1], avctx->width / 2,
+ avctx->height, p->linesize[1],
+ buf + offset_gu, buf_size - offset_gu);
+ lag_decode_arith_plane(l, p->data[2], avctx->width / 2,
+ avctx->height, p->linesize[2],
+ buf + offset_bv, buf_size - offset_bv);
+ break;
case FRAME_ARITH_YV12:
avctx->pix_fmt = PIX_FMT_YUV420P;
- if (avctx->get_buffer(avctx, p) < 0) {
+ if (ff_thread_get_buffer(avctx, p) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
LagarithContext *l = avctx->priv_data;
if (l->picture.data[0])
- avctx->release_buffer(avctx, &l->picture);
+ ff_thread_release_buffer(avctx, &l->picture);
av_freep(&l->rgb_planes);
return 0;
.init = lag_decode_init,
.close = lag_decode_end,
.decode = lag_decode_frame,
- .capabilities = CODEC_CAP_DR1,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
.long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"),
};