mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-24 00:02:52 +00:00
Merge commit 'c45fcf30cfab687004ed1cdc06ebaa21f4262a0b'
* commit 'c45fcf30cfab687004ed1cdc06ebaa21f4262a0b': DXV decoder Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>
This commit is contained in:
commit
d02d208211
@ -2,6 +2,7 @@ Entries are sorted chronologically from oldest to youngest within each release,
|
||||
releases are sorted from youngest to oldest.
|
||||
|
||||
version <next>:
|
||||
- DXV decoding
|
||||
|
||||
|
||||
version 2.8:
|
||||
|
1
configure
vendored
1
configure
vendored
@ -2189,6 +2189,7 @@ dnxhd_encoder_select="aandcttables blockdsp fdctdsp idctdsp mpegvideoenc pixbloc
|
||||
dvvideo_decoder_select="dvprofile idctdsp"
|
||||
dvvideo_encoder_select="dvprofile fdctdsp me_cmp pixblockdsp"
|
||||
dxa_decoder_select="zlib"
|
||||
dxv_decoder_select="lzf texturedsp"
|
||||
eac3_decoder_select="ac3_decoder"
|
||||
eac3_encoder_select="ac3_encoder"
|
||||
eamad_decoder_select="aandcttables blockdsp bswapdsp idctdsp mpegvideo"
|
||||
|
@ -463,6 +463,7 @@ library:
|
||||
@item Redirector @tab @tab X
|
||||
@item RedSpark @tab @tab X
|
||||
@item Renderware TeXture Dictionary @tab @tab X
|
||||
@item Resolume DXV @tab @tab X
|
||||
@item RL2 @tab @tab X
|
||||
@tab Audio and video format used in some games by Entertainment Software Partners.
|
||||
@item RPL/ARMovie @tab @tab X
|
||||
|
@ -242,6 +242,7 @@ OBJS-$(CONFIG_DVVIDEO_DECODER) += dvdec.o dv.o dvdata.o
|
||||
OBJS-$(CONFIG_DVVIDEO_ENCODER) += dvenc.o dv.o dvdata.o
|
||||
OBJS-$(CONFIG_DXA_DECODER) += dxa.o
|
||||
OBJS-$(CONFIG_DXTORY_DECODER) += dxtory.o
|
||||
OBJS-$(CONFIG_DXV_DECODER) += dxv.o
|
||||
OBJS-$(CONFIG_EAC3_DECODER) += eac3_data.o
|
||||
OBJS-$(CONFIG_EAC3_ENCODER) += eac3enc.o eac3_data.o
|
||||
OBJS-$(CONFIG_EACMV_DECODER) += eacmv.o
|
||||
|
@ -159,6 +159,7 @@ void avcodec_register_all(void)
|
||||
REGISTER_ENCDEC (DVVIDEO, dvvideo);
|
||||
REGISTER_DECODER(DXA, dxa);
|
||||
REGISTER_DECODER(DXTORY, dxtory);
|
||||
REGISTER_DECODER(DXV, dxv);
|
||||
REGISTER_DECODER(EACMV, eacmv);
|
||||
REGISTER_DECODER(EAMAD, eamad);
|
||||
REGISTER_DECODER(EATGQ, eatgq);
|
||||
|
@ -295,6 +295,7 @@ enum AVCodecID {
|
||||
AV_CODEC_ID_HQ_HQA,
|
||||
AV_CODEC_ID_HAP,
|
||||
AV_CODEC_ID_DDS,
|
||||
AV_CODEC_ID_DXV,
|
||||
|
||||
AV_CODEC_ID_BRENDER_PIX= MKBETAG('B','P','I','X'),
|
||||
AV_CODEC_ID_Y41P = MKBETAG('Y','4','1','P'),
|
||||
|
461
libavcodec/dxv.c
Normal file
461
libavcodec/dxv.c
Normal file
@ -0,0 +1,461 @@
|
||||
/*
|
||||
* Resolume DXV decoder
|
||||
* Copyright (C) 2015 Vittorio Giovara <vittorio.giovara@gmail.com>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "libavutil/imgutils.h"
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "bytestream.h"
|
||||
#include "internal.h"
|
||||
#include "lzf.h"
|
||||
#include "texturedsp.h"
|
||||
#include "thread.h"
|
||||
|
||||
typedef struct DXVContext {
|
||||
TextureDSPContext texdsp;
|
||||
GetByteContext gbc;
|
||||
|
||||
uint8_t *tex_data; // Compressed texture
|
||||
int tex_rat; // Compression ratio
|
||||
int tex_step; // Distance between blocks
|
||||
int64_t tex_size; // Texture size
|
||||
|
||||
/* Optimal number of slices for parallel decoding */
|
||||
int slice_count;
|
||||
|
||||
/* Pointer to the selected decompression function */
|
||||
int (*tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block);
|
||||
} DXVContext;
|
||||
|
||||
static int decompress_texture_thread(AVCodecContext *avctx, void *arg,
|
||||
int slice, int thread_nb)
|
||||
{
|
||||
DXVContext *ctx = avctx->priv_data;
|
||||
AVFrame *frame = arg;
|
||||
const uint8_t *d = ctx->tex_data;
|
||||
int w_block = avctx->coded_width / TEXTURE_BLOCK_W;
|
||||
int h_block = avctx->coded_height / TEXTURE_BLOCK_H;
|
||||
int x, y;
|
||||
int start_slice, end_slice;
|
||||
int base_blocks_per_slice = h_block / ctx->slice_count;
|
||||
int remainder_blocks = h_block % ctx->slice_count;
|
||||
|
||||
/* When the frame height (in blocks) doesn't divide evenly between the
|
||||
* number of slices, spread the remaining blocks evenly between the first
|
||||
* operations */
|
||||
start_slice = slice * base_blocks_per_slice;
|
||||
/* Add any extra blocks (one per slice) that have been added
|
||||
* before this slice */
|
||||
start_slice += FFMIN(slice, remainder_blocks);
|
||||
|
||||
end_slice = start_slice + base_blocks_per_slice;
|
||||
/* Add an extra block if there are remainder blocks to be accounted for */
|
||||
if (slice < remainder_blocks)
|
||||
end_slice++;
|
||||
|
||||
for (y = start_slice; y < end_slice; y++) {
|
||||
uint8_t *p = frame->data[0] + y * frame->linesize[0] * TEXTURE_BLOCK_H;
|
||||
int off = y * w_block;
|
||||
for (x = 0; x < w_block; x++) {
|
||||
ctx->tex_funct(p + x * 16, frame->linesize[0],
|
||||
d + (off + x) * ctx->tex_step);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This scheme addresses already decoded elements depending on 2-bit status:
|
||||
* 0 -> copy new element
|
||||
* 1 -> copy one element from position -x
|
||||
* 2 -> copy one element from position -(get_byte() + 2) * x
|
||||
* 3 -> copy one element from position -(get_16le() + 0x102) * x
|
||||
* x is always 2 for dxt1 and 4 for dxt5. */
|
||||
#define CHECKPOINT(x) \
|
||||
do { \
|
||||
if (state == 0) { \
|
||||
value = bytestream2_get_le32(gbc); \
|
||||
state = 16; \
|
||||
} \
|
||||
op = value & 0x3; \
|
||||
value >>= 2; \
|
||||
state--; \
|
||||
switch (op) { \
|
||||
case 1: \
|
||||
idx = x; \
|
||||
break; \
|
||||
case 2: \
|
||||
idx = (bytestream2_get_byte(gbc) + 2) * x; \
|
||||
break; \
|
||||
case 3: \
|
||||
idx = (bytestream2_get_le16(gbc) + 0x102) * x; \
|
||||
break; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
static int dxv_decompress_dxt1(AVCodecContext *avctx)
|
||||
{
|
||||
DXVContext *ctx = avctx->priv_data;
|
||||
GetByteContext *gbc = &ctx->gbc;
|
||||
uint32_t value, prev, op;
|
||||
int idx = 0, state = 0;
|
||||
int pos = 2;
|
||||
|
||||
/* Copy the first two elements */
|
||||
AV_WL32(ctx->tex_data, bytestream2_get_le32(gbc));
|
||||
AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc));
|
||||
|
||||
/* Process input until the whole texture has been filled */
|
||||
while (pos < ctx->tex_size / 4) {
|
||||
CHECKPOINT(2);
|
||||
|
||||
/* Copy two elements from a previous offset or from the input buffer */
|
||||
if (op) {
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
} else {
|
||||
CHECKPOINT(2);
|
||||
|
||||
if (op)
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
|
||||
else
|
||||
prev = bytestream2_get_le32(gbc);
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
|
||||
CHECKPOINT(2);
|
||||
|
||||
if (op)
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
|
||||
else
|
||||
prev = bytestream2_get_le32(gbc);
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dxv_decompress_dxt5(AVCodecContext *avctx)
|
||||
{
|
||||
DXVContext *ctx = avctx->priv_data;
|
||||
GetByteContext *gbc = &ctx->gbc;
|
||||
uint32_t value, op;
|
||||
int idx, prev, state = 0;
|
||||
int pos = 4;
|
||||
int run = 0;
|
||||
int probe, check;
|
||||
|
||||
/* Copy the first four elements */
|
||||
AV_WL32(ctx->tex_data + 0, bytestream2_get_le32(gbc));
|
||||
AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc));
|
||||
AV_WL32(ctx->tex_data + 8, bytestream2_get_le32(gbc));
|
||||
AV_WL32(ctx->tex_data + 12, bytestream2_get_le32(gbc));
|
||||
|
||||
/* Process input until the whole texture has been filled */
|
||||
while (pos < ctx->tex_size / 4) {
|
||||
if (run) {
|
||||
run--;
|
||||
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
} else {
|
||||
if (state == 0) {
|
||||
value = bytestream2_get_le32(gbc);
|
||||
state = 16;
|
||||
}
|
||||
op = value & 0x3;
|
||||
value >>= 2;
|
||||
state--;
|
||||
|
||||
switch (op) {
|
||||
case 0:
|
||||
/* Long copy */
|
||||
check = bytestream2_get_byte(gbc) + 1;
|
||||
if (check == 256) {
|
||||
do {
|
||||
probe = bytestream2_get_le16(gbc);
|
||||
check += probe;
|
||||
} while (probe == 0xFFFF);
|
||||
}
|
||||
while (check && pos < ctx->tex_size / 4) {
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
|
||||
check--;
|
||||
}
|
||||
|
||||
/* Restart (or exit) the loop */
|
||||
continue;
|
||||
break;
|
||||
case 1:
|
||||
/* Load new run value */
|
||||
run = bytestream2_get_byte(gbc);
|
||||
if (run == 255) {
|
||||
do {
|
||||
probe = bytestream2_get_le16(gbc);
|
||||
run += probe;
|
||||
} while (probe == 0xFFFF);
|
||||
}
|
||||
|
||||
/* Copy two dwords from previous data */
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - 4));
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
break;
|
||||
case 2:
|
||||
/* Copy two dwords from a previous index */
|
||||
idx = 8 + bytestream2_get_le16(gbc);
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
break;
|
||||
case 3:
|
||||
/* Copy two dwords from input */
|
||||
prev = bytestream2_get_le32(gbc);
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
|
||||
prev = bytestream2_get_le32(gbc);
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CHECKPOINT(4);
|
||||
|
||||
/* Copy two elements from a previous offset or from the input buffer */
|
||||
if (op) {
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
} else {
|
||||
CHECKPOINT(4);
|
||||
|
||||
if (op)
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
|
||||
else
|
||||
prev = bytestream2_get_le32(gbc);
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
|
||||
CHECKPOINT(4);
|
||||
|
||||
if (op)
|
||||
prev = AV_RL32(ctx->tex_data + 4 * (pos - idx));
|
||||
else
|
||||
prev = bytestream2_get_le32(gbc);
|
||||
AV_WL32(ctx->tex_data + 4 * pos, prev);
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dxv_decompress_lzf(AVCodecContext *avctx)
|
||||
{
|
||||
DXVContext *ctx = avctx->priv_data;
|
||||
return ff_lzf_uncompress(&ctx->gbc, &ctx->tex_data, &ctx->tex_size);
|
||||
}
|
||||
|
||||
static int dxv_decode(AVCodecContext *avctx, void *data,
|
||||
int *got_frame, AVPacket *avpkt)
|
||||
{
|
||||
DXVContext *ctx = avctx->priv_data;
|
||||
ThreadFrame tframe;
|
||||
GetByteContext *gbc = &ctx->gbc;
|
||||
int (*decompress_tex)(AVCodecContext *avctx);
|
||||
uint32_t tag;
|
||||
int channels, size = 0, old_type = 0;
|
||||
int ret;
|
||||
|
||||
bytestream2_init(gbc, avpkt->data, avpkt->size);
|
||||
|
||||
tag = bytestream2_get_le32(gbc);
|
||||
switch (tag) {
|
||||
case MKBETAG('D', 'X', 'T', '1'):
|
||||
decompress_tex = dxv_decompress_dxt1;
|
||||
ctx->tex_funct = ctx->texdsp.dxt1_block;
|
||||
ctx->tex_rat = 8;
|
||||
ctx->tex_step = 8;
|
||||
av_log(avctx, AV_LOG_DEBUG, "DXTR1 compression and DXT1 texture ");
|
||||
break;
|
||||
case MKBETAG('D', 'X', 'T', '5'):
|
||||
decompress_tex = dxv_decompress_dxt5;
|
||||
ctx->tex_funct = ctx->texdsp.dxt5_block;
|
||||
ctx->tex_rat = 4;
|
||||
ctx->tex_step = 16;
|
||||
av_log(avctx, AV_LOG_DEBUG, "DXTR5 compression and DXT5 texture ");
|
||||
break;
|
||||
case MKBETAG('Y', 'C', 'G', '6'):
|
||||
case MKBETAG('Y', 'G', '1', '0'):
|
||||
avpriv_report_missing_feature(avctx, "Tag 0x%08X", tag);
|
||||
return AVERROR_PATCHWELCOME;
|
||||
default:
|
||||
/* Old version does not have a real header, just size and type. */
|
||||
size = tag & 0x00FFFFFF;
|
||||
old_type = tag >> 24;
|
||||
channels = old_type & 0x0F;
|
||||
if (old_type & 0x40) {
|
||||
av_log(avctx, AV_LOG_DEBUG, "LZF compression and DXT5 texture ");
|
||||
ctx->tex_funct = ctx->texdsp.dxt5_block;
|
||||
ctx->tex_step = 16;
|
||||
} else if (old_type & 0x20) {
|
||||
av_log(avctx, AV_LOG_DEBUG, "LZF compression and DXT1 texture ");
|
||||
ctx->tex_funct = ctx->texdsp.dxt1_block;
|
||||
ctx->tex_step = 8;
|
||||
} else {
|
||||
av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08X)\n.", tag);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
decompress_tex = dxv_decompress_lzf;
|
||||
ctx->tex_rat = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* New header is 12 bytes long. */
|
||||
if (!old_type) {
|
||||
channels = bytestream2_get_byte(gbc);
|
||||
bytestream2_skip(gbc, 3); // unknown
|
||||
size = bytestream2_get_le32(gbc);
|
||||
}
|
||||
av_log(avctx, AV_LOG_DEBUG, "(%d channels)\n", channels);
|
||||
|
||||
if (size != bytestream2_get_bytes_left(gbc)) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Incomplete or invalid file (%u > %u)\n.",
|
||||
size, bytestream2_get_bytes_left(gbc));
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
ctx->tex_size = avctx->coded_width * avctx->coded_height * 4 / ctx->tex_rat;
|
||||
ret = av_reallocp(&ctx->tex_data, ctx->tex_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Decompress texture out of the intermediate compression. */
|
||||
ret = decompress_tex(avctx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
tframe.f = data;
|
||||
ret = ff_thread_get_buffer(avctx, &tframe, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ff_thread_finish_setup(avctx);
|
||||
|
||||
/* Now decompress the texture with the standard functions. */
|
||||
avctx->execute2(avctx, decompress_texture_thread,
|
||||
tframe.f, NULL, ctx->slice_count);
|
||||
|
||||
/* Frame is ready to be output. */
|
||||
tframe.f->pict_type = AV_PICTURE_TYPE_I;
|
||||
tframe.f->key_frame = 1;
|
||||
*got_frame = 1;
|
||||
|
||||
return avpkt->size;
|
||||
}
|
||||
|
||||
static int dxv_init(AVCodecContext *avctx)
|
||||
{
|
||||
DXVContext *ctx = avctx->priv_data;
|
||||
int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
|
||||
|
||||
if (ret < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n",
|
||||
avctx->width, avctx->height);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Codec requires 16x16 alignment. */
|
||||
avctx->coded_width = FFALIGN(avctx->width, 16);
|
||||
avctx->coded_height = FFALIGN(avctx->height, 16);
|
||||
|
||||
ff_texturedsp_init(&ctx->texdsp);
|
||||
avctx->pix_fmt = AV_PIX_FMT_RGBA;
|
||||
|
||||
ctx->slice_count = av_clip(avctx->thread_count, 1,
|
||||
avctx->coded_height / TEXTURE_BLOCK_H);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dxv_close(AVCodecContext *avctx)
|
||||
{
|
||||
DXVContext *ctx = avctx->priv_data;
|
||||
|
||||
av_freep(&ctx->tex_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec ff_dxv_decoder = {
|
||||
.name = "dxv",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Resolume DXV"),
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.id = AV_CODEC_ID_DXV,
|
||||
.init = dxv_init,
|
||||
.decode = dxv_decode,
|
||||
.close = dxv_close,
|
||||
.priv_data_size = sizeof(DXVContext),
|
||||
.capabilities = AV_CODEC_CAP_DR1 |
|
||||
AV_CODEC_CAP_SLICE_THREADS |
|
||||
AV_CODEC_CAP_FRAME_THREADS,
|
||||
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
|
||||
FF_CODEC_CAP_INIT_CLEANUP,
|
||||
};
|
@ -1227,9 +1227,9 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
|
||||
goto free_and_end;
|
||||
}
|
||||
|
||||
// only call ff_set_dimensions() for non H.264/VP6F codecs so as not to overwrite previously setup dimensions
|
||||
// only call ff_set_dimensions() for non H.264/VP6F/DXV codecs so as not to overwrite previously setup dimensions
|
||||
if (!(avctx->coded_width && avctx->coded_height && avctx->width && avctx->height &&
|
||||
(avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_VP6F))) {
|
||||
(avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_VP6F || avctx->codec_id == AV_CODEC_ID_DXV))) {
|
||||
if (avctx->coded_width && avctx->coded_height)
|
||||
ret = ff_set_dimensions(avctx, avctx->coded_width, avctx->coded_height);
|
||||
else if (avctx->width && avctx->height)
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include "libavutil/version.h"
|
||||
|
||||
#define LIBAVCODEC_VERSION_MAJOR 57
|
||||
#define LIBAVCODEC_VERSION_MINOR 0
|
||||
#define LIBAVCODEC_VERSION_MINOR 1
|
||||
#define LIBAVCODEC_VERSION_MICRO 100
|
||||
|
||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||
|
@ -262,6 +262,9 @@ const AVCodecTag ff_codec_movvideo_tags[] = {
|
||||
{ AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', '5') },
|
||||
{ AV_CODEC_ID_HAP, MKTAG('H', 'a', 'p', 'Y') },
|
||||
|
||||
{ AV_CODEC_ID_DXV, MKTAG('D', 'X', 'D', '3') },
|
||||
{ AV_CODEC_ID_DXV, MKTAG('D', 'X', 'D', 'I') },
|
||||
|
||||
{ AV_CODEC_ID_NONE, 0 },
|
||||
};
|
||||
|
||||
|
@ -144,6 +144,21 @@ fate-dxa-scummvm: CMD = framecrc -i $(TARGET_SAMPLES)/dxa/scummvm.dxa -pix_fmt r
|
||||
FATE_VIDEO-$(call DEMDEC, DXA, DXA) += $(FATE_DXA)
|
||||
fate-dxa: $(FATE_DXA)
|
||||
|
||||
FATE_DXV += fate-dxv-dxt1
|
||||
fate-dxv-dxt1: CMD = framecrc -i $(TARGET_SAMPLES)/dxv/dxv-na.mov
|
||||
|
||||
FATE_DXV += fate-dxv-dxt5
|
||||
fate-dxv-dxt5: CMD = framecrc -i $(TARGET_SAMPLES)/dxv/dxv-wa.mov
|
||||
|
||||
FATE_DXV += fate-dxv3-dxt1
|
||||
fate-dxv3-dxt1: CMD = framecrc -i $(TARGET_SAMPLES)/dxv/dxv3-nqna.mov
|
||||
|
||||
FATE_DXV += fate-dxv3-dxt5
|
||||
fate-dxv3-dxt5: CMD = framecrc -i $(TARGET_SAMPLES)/dxv/dxv3-nqwa.mov
|
||||
|
||||
FATE_VIDEO-$(call DEMDEC, MOV, DXV) += $(FATE_DXV)
|
||||
fate-dxv: $(FATE_DXV)
|
||||
|
||||
FATE_VIDEO-$(call DEMDEC, SEGAFILM, CINEPAK) += fate-film-cvid
|
||||
fate-film-cvid: CMD = framecrc -i $(TARGET_SAMPLES)/film/logo-capcom.cpk -an
|
||||
|
||||
|
2
tests/ref/fate/dxv-dxt1
Normal file
2
tests/ref/fate/dxv-dxt1
Normal file
@ -0,0 +1,2 @@
|
||||
#tb 0: 1001/30000
|
||||
0, 0, 0, 1, 8294400, 0x0797cd53
|
2
tests/ref/fate/dxv-dxt5
Normal file
2
tests/ref/fate/dxv-dxt5
Normal file
@ -0,0 +1,2 @@
|
||||
#tb 0: 1001/30000
|
||||
0, 0, 0, 1, 8294400, 0x0797cd53
|
2
tests/ref/fate/dxv3-dxt1
Normal file
2
tests/ref/fate/dxv3-dxt1
Normal file
@ -0,0 +1,2 @@
|
||||
#tb 0: 1001/30000
|
||||
0, 0, 0, 1, 8294400, 0x98bbcc85
|
2
tests/ref/fate/dxv3-dxt5
Normal file
2
tests/ref/fate/dxv3-dxt5
Normal file
@ -0,0 +1,2 @@
|
||||
#tb 0: 1001/30000
|
||||
0, 0, 0, 1, 8294400, 0x0797cd53
|
Loading…
Reference in New Issue
Block a user