mirror of https://git.ffmpeg.org/ffmpeg.git
Merge commit '95a8a03a191204c3ca5c8cf6b69ab166765d5ff3'
* commit '95a8a03a191204c3ca5c8cf6b69ab166765d5ff3': Add FM Screen Capture Codec decoder Merged-by: James Almer <jamrial@gmail.com>
This commit is contained in:
commit
b94eda7194
|
@ -44,11 +44,11 @@ typedef struct FMVCContext {
|
||||||
size_t buffer_size;
|
size_t buffer_size;
|
||||||
uint8_t *pbuffer;
|
uint8_t *pbuffer;
|
||||||
size_t pbuffer_size;
|
size_t pbuffer_size;
|
||||||
int stride;
|
ptrdiff_t stride;
|
||||||
int bpp;
|
int bpp;
|
||||||
int yb, xb;
|
int yb, xb;
|
||||||
InterBlock *blocks;
|
InterBlock *blocks;
|
||||||
int nb_blocks;
|
unsigned nb_blocks;
|
||||||
} FMVCContext;
|
} FMVCContext;
|
||||||
|
|
||||||
static int decode_type2(GetByteContext *gb, PutByteContext *pb)
|
static int decode_type2(GetByteContext *gb, PutByteContext *pb)
|
||||||
|
@ -150,7 +150,7 @@ static int decode_type2(GetByteContext *gb, PutByteContext *pb)
|
||||||
if (opcode >= 0x40) {
|
if (opcode >= 0x40) {
|
||||||
bytestream2_skip(gb, 1);
|
bytestream2_skip(gb, 1);
|
||||||
pos = - ((opcode >> 2) & 7) - 1 - 8 * bytestream2_get_byte(gb);
|
pos = - ((opcode >> 2) & 7) - 1 - 8 * bytestream2_get_byte(gb);
|
||||||
len = (opcode >> 5) - 1;
|
len = (opcode >> 5) - 1;
|
||||||
|
|
||||||
bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);
|
bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);
|
||||||
bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
|
bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
|
||||||
|
@ -305,7 +305,7 @@ static int decode_type1(GetByteContext *gb, PutByteContext *pb)
|
||||||
break;
|
break;
|
||||||
opcode = bytestream2_get_byte(gb);
|
opcode = bytestream2_get_byte(gb);
|
||||||
if (opcode < 0xF8) {
|
if (opcode < 0xF8) {
|
||||||
opcode = opcode + 32;
|
opcode += 32;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i = opcode - 0xF8;
|
i = opcode - 0xF8;
|
||||||
|
@ -393,9 +393,8 @@ static int decode_type1(GetByteContext *gb, PutByteContext *pb)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_frame(AVCodecContext *avctx,
|
static int decode_frame(AVCodecContext *avctx, void *data,
|
||||||
void *data, int *got_frame,
|
int *got_frame, AVPacket *avpkt)
|
||||||
AVPacket *avpkt)
|
|
||||||
{
|
{
|
||||||
FMVCContext *s = avctx->priv_data;
|
FMVCContext *s = avctx->priv_data;
|
||||||
GetByteContext *gb = &s->gb;
|
GetByteContext *gb = &s->gb;
|
||||||
|
@ -414,7 +413,7 @@ static int decode_frame(AVCodecContext *avctx,
|
||||||
|
|
||||||
if (frame->key_frame) {
|
if (frame->key_frame) {
|
||||||
const uint8_t *src;
|
const uint8_t *src;
|
||||||
int type, size;
|
unsigned type, size;
|
||||||
uint8_t *dst;
|
uint8_t *dst;
|
||||||
|
|
||||||
type = bytestream2_get_le16(gb);
|
type = bytestream2_get_le16(gb);
|
||||||
|
@ -428,7 +427,7 @@ static int decode_frame(AVCodecContext *avctx,
|
||||||
} else if (type == 2){
|
} else if (type == 2){
|
||||||
decode_type2(gb, pb);
|
decode_type2(gb, pb);
|
||||||
} else {
|
} else {
|
||||||
avpriv_report_missing_feature(avctx, "compression %d", type);
|
avpriv_report_missing_feature(avctx, "Compression type %d", type);
|
||||||
return AVERROR_PATCHWELCOME;
|
return AVERROR_PATCHWELCOME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,7 +439,8 @@ static int decode_frame(AVCodecContext *avctx,
|
||||||
src += s->stride * 4;
|
src += s->stride * 4;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int block, nb_blocks, type, k, l;
|
unsigned block, nb_blocks;
|
||||||
|
int type, k, l;
|
||||||
uint8_t *ssrc, *ddst;
|
uint8_t *ssrc, *ddst;
|
||||||
const uint32_t *src;
|
const uint32_t *src;
|
||||||
uint32_t *dst;
|
uint32_t *dst;
|
||||||
|
@ -456,7 +456,8 @@ static int decode_frame(AVCodecContext *avctx,
|
||||||
|
|
||||||
type = bytestream2_get_le16(gb);
|
type = bytestream2_get_le16(gb);
|
||||||
for (block = 0; block < nb_blocks; block++) {
|
for (block = 0; block < nb_blocks; block++) {
|
||||||
int size, offset, start = 0;
|
unsigned size, offset;
|
||||||
|
int start = 0;
|
||||||
|
|
||||||
offset = bytestream2_get_le16(gb);
|
offset = bytestream2_get_le16(gb);
|
||||||
if (offset >= s->nb_blocks)
|
if (offset >= s->nb_blocks)
|
||||||
|
@ -472,7 +473,7 @@ static int decode_frame(AVCodecContext *avctx,
|
||||||
} else if (type == 2){
|
} else if (type == 2){
|
||||||
decode_type2(gb, pb);
|
decode_type2(gb, pb);
|
||||||
} else {
|
} else {
|
||||||
avpriv_report_missing_feature(avctx, "compression %d", type);
|
avpriv_report_missing_feature(avctx, "Compression type %d", type);
|
||||||
return AVERROR_PATCHWELCOME;
|
return AVERROR_PATCHWELCOME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,9 +498,8 @@ static int decode_frame(AVCodecContext *avctx,
|
||||||
if (s->blocks[block].xor) {
|
if (s->blocks[block].xor) {
|
||||||
for (k = 0; k < block_h; k++) {
|
for (k = 0; k < block_h; k++) {
|
||||||
uint32_t *column = dst;
|
uint32_t *column = dst;
|
||||||
for (l = 0; l < block_w; l++) {
|
for (l = 0; l < block_w; l++)
|
||||||
*dst++ ^= *src++;
|
*dst++ ^= *src++;
|
||||||
}
|
|
||||||
dst = &column[s->stride];
|
dst = &column[s->stride];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -529,17 +529,24 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||||
int i, j, m, block = 0, h = BLOCK_HEIGHT, w = BLOCK_WIDTH;
|
int i, j, m, block = 0, h = BLOCK_HEIGHT, w = BLOCK_WIDTH;
|
||||||
|
|
||||||
switch (avctx->bits_per_coded_sample) {
|
switch (avctx->bits_per_coded_sample) {
|
||||||
case 16: avctx->pix_fmt = AV_PIX_FMT_RGB555; break;
|
case 16:
|
||||||
case 24: avctx->pix_fmt = AV_PIX_FMT_BGR24; break;
|
avctx->pix_fmt = AV_PIX_FMT_RGB555;
|
||||||
case 32: avctx->pix_fmt = AV_PIX_FMT_BGRA; break;
|
break;
|
||||||
|
case 24:
|
||||||
|
avctx->pix_fmt = AV_PIX_FMT_BGR24;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
avctx->pix_fmt = AV_PIX_FMT_BGRA;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n", avctx->bits_per_coded_sample);
|
av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n",
|
||||||
|
avctx->bits_per_coded_sample);
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->stride = (avctx->width * avctx->bits_per_coded_sample + 31) / 32;
|
s->stride = (avctx->width * avctx->bits_per_coded_sample + 31) / 32;
|
||||||
s->xb = s->stride / BLOCK_WIDTH;
|
s->xb = s->stride / BLOCK_WIDTH;
|
||||||
m = s->stride % BLOCK_WIDTH;
|
m = s->stride % BLOCK_WIDTH;
|
||||||
if (m) {
|
if (m) {
|
||||||
if (m < 37) {
|
if (m < 37) {
|
||||||
w = m + BLOCK_WIDTH;
|
w = m + BLOCK_WIDTH;
|
||||||
|
@ -550,7 +557,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
s->yb = avctx->height / BLOCK_HEIGHT;
|
s->yb = avctx->height / BLOCK_HEIGHT;
|
||||||
m = avctx->height % BLOCK_HEIGHT;
|
m = avctx->height % BLOCK_HEIGHT;
|
||||||
if (m) {
|
if (m) {
|
||||||
if (m < 49) {
|
if (m < 49) {
|
||||||
h = m + BLOCK_HEIGHT;
|
h = m + BLOCK_HEIGHT;
|
||||||
|
@ -563,8 +570,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||||
s->nb_blocks = s->xb * s->yb;
|
s->nb_blocks = s->xb * s->yb;
|
||||||
if (!s->nb_blocks)
|
if (!s->nb_blocks)
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
s->blocks = av_calloc(s->nb_blocks, sizeof(*s->blocks));
|
||||||
s->blocks = av_calloc(s->nb_blocks, sizeof(*s->blocks));
|
|
||||||
if (!s->blocks)
|
if (!s->blocks)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
@ -572,32 +578,32 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||||
for (j = 0; j < s->xb; j++) {
|
for (j = 0; j < s->xb; j++) {
|
||||||
if (i != (s->yb - 1) || j != (s->xb - 1)) {
|
if (i != (s->yb - 1) || j != (s->xb - 1)) {
|
||||||
if (i == s->yb - 1) {
|
if (i == s->yb - 1) {
|
||||||
s->blocks[block].w = BLOCK_WIDTH;
|
s->blocks[block].w = BLOCK_WIDTH;
|
||||||
s->blocks[block].h = h;
|
s->blocks[block].h = h;
|
||||||
s->blocks[block].size = BLOCK_WIDTH * h;
|
s->blocks[block].size = BLOCK_WIDTH * h;
|
||||||
} else if (j == s->xb - 1) {
|
} else if (j == s->xb - 1) {
|
||||||
s->blocks[block].w = w;
|
s->blocks[block].w = w;
|
||||||
s->blocks[block].h = BLOCK_HEIGHT;
|
s->blocks[block].h = BLOCK_HEIGHT;
|
||||||
s->blocks[block].size = BLOCK_HEIGHT * w;
|
s->blocks[block].size = BLOCK_HEIGHT * w;
|
||||||
} else {
|
} else {
|
||||||
s->blocks[block].w = BLOCK_WIDTH;
|
s->blocks[block].w = BLOCK_WIDTH;
|
||||||
s->blocks[block].h = BLOCK_HEIGHT;
|
s->blocks[block].h = BLOCK_HEIGHT;
|
||||||
s->blocks[block].size = BLOCK_WIDTH * BLOCK_HEIGHT;
|
s->blocks[block].size = BLOCK_WIDTH * BLOCK_HEIGHT;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s->blocks[block].w = w;
|
s->blocks[block].w = w;
|
||||||
s->blocks[block].h = h;
|
s->blocks[block].h = h;
|
||||||
s->blocks[block].size = w * h;
|
s->blocks[block].size = w * h;
|
||||||
}
|
}
|
||||||
block++;
|
block++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s->bpp = avctx->bits_per_coded_sample >> 3;
|
s->bpp = avctx->bits_per_coded_sample >> 3;
|
||||||
s->buffer_size = avctx->width * avctx->height * 4;
|
s->buffer_size = avctx->width * avctx->height * 4;
|
||||||
s->pbuffer_size = avctx->width * avctx->height * 4;
|
s->pbuffer_size = avctx->width * avctx->height * 4;
|
||||||
s->buffer = av_mallocz(s->buffer_size);
|
s->buffer = av_mallocz(s->buffer_size);
|
||||||
s->pbuffer = av_mallocz(s->pbuffer_size);
|
s->pbuffer = av_mallocz(s->pbuffer_size);
|
||||||
if (!s->buffer || !s->pbuffer)
|
if (!s->buffer || !s->pbuffer)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue