#include "mathops.h"
#include "dsputil.h"
#include "lagarithrac.h"
+#include "thread.h"
enum LagarithFrameType {
FRAME_RAW = 1, /**< uncompressed */
typedef struct LagarithContext {
AVCodecContext *avctx;
- AVFrame picture;
DSPContext dsp;
int zeros; /**< number of consecutive zero bytes encountered */
int zeros_rem; /**< number of zero bytes remaining to output */
}
/* 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
+ * // since the compression change is negligible and fixing it
+ * // breaks backwards compatibility
* b =- (signed int)b;
* b &= 0xFF;
* } else {
if (line == 1) {
/* Second line, left predict first pixel, the rest of the line is median predicted
* NOTE: In the case of RGB this pixel is top predicted */
- TL = l->avctx->pix_fmt == PIX_FMT_YUV420P ? buf[-stride] : L;
+ TL = l->avctx->pix_fmt == AV_PIX_FMT_YUV420P ? buf[-stride] : L;
} else {
/* Top left is 2 rows back, last pixel */
TL = buf[width - (2 * stride) - 1];
output_zeros:
if (l->zeros_rem) {
count = FFMIN(l->zeros_rem, width - i);
+ if (end - dst < count) {
+ av_log(l->avctx, AV_LOG_ERROR, "Too many zeros remaining.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
memset(dst, 0, count);
l->zeros_rem -= count;
dst += count;
return -1;
}
- if (l->avctx->pix_fmt != PIX_FMT_YUV422P) {
+ if (l->avctx->pix_fmt != AV_PIX_FMT_YUV422P) {
for (i = 0; i < height; i++) {
lag_pred_line(l, dst, width, stride, i);
dst += stride;
* @return number of consumed bytes on success or negative if decode fails
*/
static int lag_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size, AVPacket *avpkt)
+ void *data, int *got_frame, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
LagarithContext *l = avctx->priv_data;
- AVFrame *const p = &l->picture;
+ ThreadFrame frame = { .f = data };
+ AVFrame *const p = data;
uint8_t frametype = 0;
uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
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);
-
- p->reference = 0;
p->key_frame = 1;
frametype = buf[0];
switch (frametype) {
case FRAME_SOLID_RGBA:
- avctx->pix_fmt = PIX_FMT_RGB32;
+ avctx->pix_fmt = AV_PIX_FMT_RGB32;
- if (avctx->get_buffer(avctx, p) < 0) {
+ if (ff_thread_get_buffer(avctx, &frame, 0) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
}
break;
case FRAME_ARITH_RGBA:
- avctx->pix_fmt = PIX_FMT_RGB32;
+ avctx->pix_fmt = AV_PIX_FMT_RGB32;
planes = 4;
offset_ry += 4;
offs[3] = AV_RL32(buf + 9);
case FRAME_ARITH_RGB24:
case FRAME_U_RGB24:
if (frametype == FRAME_ARITH_RGB24 || frametype == FRAME_U_RGB24)
- avctx->pix_fmt = PIX_FMT_RGB24;
+ avctx->pix_fmt = AV_PIX_FMT_RGB24;
- if (avctx->get_buffer(avctx, p) < 0) {
+ if (ff_thread_get_buffer(avctx, &frame, 0) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
}
break;
case FRAME_ARITH_YUY2:
- avctx->pix_fmt = PIX_FMT_YUV422P;
+ avctx->pix_fmt = AV_PIX_FMT_YUV422P;
- if (avctx->get_buffer(avctx, p) < 0) {
+ if (ff_thread_get_buffer(avctx, &frame, 0) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
buf + offset_bv, buf_size - offset_bv);
break;
case FRAME_ARITH_YV12:
- avctx->pix_fmt = PIX_FMT_YUV420P;
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- if (avctx->get_buffer(avctx, p) < 0) {
+ if (ff_thread_get_buffer(avctx, &frame, 0) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
return -1;
}
- *picture = *p;
- *data_size = sizeof(AVFrame);
+ *got_frame = 1;
return buf_size;
}
{
LagarithContext *l = avctx->priv_data;
- if (l->picture.data[0])
- avctx->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"),
};