46 #include "libavutil/avassert.h"
47 #include "libavutil/channel_layout.h"
48 #include "libavutil/common.h"
49 #include "libavutil/intreadwrite.h"
54 #define VMD_HEADER_SIZE 0x330
55 #define PALETTE_COUNT 256
66 const unsigned char *
buf;
76 #define QUEUE_SIZE 0x1000
77 #define QUEUE_MASK 0x0FFF
80 unsigned char *dest,
int dest_len)
86 unsigned int dataleft;
87 unsigned int chainofs;
88 unsigned int chainlen;
97 dataleft = bytestream2_get_le32(&gb);
101 if (bytestream2_peek_le32(&gb) == 0x56781234) {
111 tag = bytestream2_get_byteu(&gb);
112 if ((tag == 0xFF) && (dataleft > 8)) {
115 for (i = 0; i < 8; i++) {
116 queue[qpos++] = *d++ = bytestream2_get_byteu(&gb);
121 for (i = 0; i < 8; i++) {
127 queue[qpos++] = *d++ = bytestream2_get_byteu(&gb);
131 chainofs = bytestream2_get_byte(&gb);
132 chainofs |= ((bytestream2_peek_byte(&gb) & 0xF0) << 4);
133 chainlen = (bytestream2_get_byte(&gb) & 0x0F) + 3;
134 if (chainlen == speclen) {
135 chainlen = bytestream2_get_byte(&gb) + 0xF + 3;
137 if (d_end - d < chainlen)
139 for (j = 0; j < chainlen; j++) {
141 queue[qpos++] = *d++;
144 dataleft -= chainlen;
152 int src_count,
int src_size,
int dest_len)
156 unsigned char *dest_end = dest + dest_len;
165 *pd++ = bytestream2_get_byteu(&gb);
172 l = bytestream2_get_byteu(&gb);
183 for (i = 0; i < l; i++) {
190 }
while (used < src_count);
198 unsigned int *palette32;
199 unsigned char r,
g,
b;
209 int frame_x, frame_y;
210 int frame_width, frame_height;
214 frame_width =
AV_RL16(&s->
buf[10]) - frame_x + 1;
215 frame_height =
AV_RL16(&s->
buf[12]) - frame_y + 1;
218 (frame_x || frame_y)) {
226 if (frame_x < 0 || frame_width < 0 ||
231 "Invalid horizontal range %d-%d\n",
232 frame_x, frame_width);
235 if (frame_y < 0 || frame_height < 0 ||
240 "Invalid vertical range %d-%d\n",
241 frame_x, frame_width);
248 (frame_x || frame_y || (frame_width != s->
avctx->
width) ||
257 if (s->
buf[15] & 0x02) {
259 palette32 = (
unsigned int *)s->
palette;
262 r = bytestream2_get_byteu(&gb) * 4;
263 g = bytestream2_get_byteu(&gb) * 4;
264 b = bytestream2_get_byteu(&gb) * 4;
265 palette32[i] = 0xFF
U << 24 | (r << 16) | (g << 8) | (
b);
266 palette32[i] |= palette32[i] >> 6 & 0x30303;
280 meth = bytestream2_get_byteu(&gb);
284 "Trying to unpack LZ-compressed frame with no LZ buffer\n");
293 dp = &frame->
data[0][frame_y * frame->
linesize[0] + frame_x];
297 for (i = 0; i < frame_height; i++) {
300 len = bytestream2_get_byte(&gb);
302 len = (len & 0x7F) + 1;
303 if (ofs + len > frame_width ||
312 memcpy(&dp[ofs], &pp[ofs], len + 1);
315 }
while (ofs < frame_width);
316 if (ofs > frame_width) {
318 "offset > width (%d > %d)\n",
328 for (i = 0; i < frame_height; i++) {
336 for (i = 0; i < frame_height; i++) {
339 len = bytestream2_get_byte(&gb);
341 len = (len & 0x7F) + 1;
342 if (bytestream2_peek_byte(&gb) == 0xFF) {
344 bytestream2_get_byte(&gb);
358 memcpy(&dp[ofs], &pp[ofs], len + 1);
361 }
while (ofs < frame_width);
362 if (ofs > frame_width) {
364 "offset > width (%d > %d)\n",
380 unsigned int *palette32;
381 int palette_index = 0;
382 unsigned char r,
g,
b;
383 unsigned char *vmd_header;
384 unsigned char *raw_palette;
395 vmd_header = (
unsigned char *)avctx->
extradata;
405 raw_palette = &vmd_header[28];
406 palette32 = (
unsigned int *)s->
palette;
408 r = raw_palette[palette_index++] * 4;
409 g = raw_palette[palette_index++] * 4;
410 b = raw_palette[palette_index++] * 4;
411 palette32[i] = 0xFF
U << 24 | (r << 16) | (g << 8) | (
b);
412 palette32[i] |= palette32[i] >> 6 & 0x30303;
421 void *
data,
int *got_frame,
425 int buf_size = avpkt->
size;
471 #define BLOCK_TYPE_AUDIO 1
472 #define BLOCK_TYPE_INITIAL 2
473 #define BLOCK_TYPE_SILENCE 3
481 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
482 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
483 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
484 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
485 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
486 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
487 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
488 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
489 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
490 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
491 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
492 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
493 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
521 "block align = %d, sample rate = %d\n",
532 const uint8_t *buf_end = buf + buf_size;
534 int st = channels - 1;
537 for (ch = 0; ch < channels; ch++) {
538 predictor[ch] = (int16_t)
AV_RL16(buf);
540 *out++ = predictor[ch];
545 while (buf < buf_end) {
551 predictor[ch] = av_clip_int16(predictor[ch]);
552 *out++ = predictor[ch];
558 int *got_frame_ptr,
AVPacket *avpkt)
563 int buf_size = avpkt->
size;
565 int block_type, silent_chunks, audio_chunks;
568 int16_t *output_samples_s16;
593 silent_chunks = av_popcount(flags);
596 }
else if (block_type == BLOCK_TYPE_SILENCE) {
612 output_samples_u8 = frame->
data[0];
613 output_samples_s16 = (int16_t *)frame->
data[0];
616 if (silent_chunks > 0) {
617 int silent_size = avctx->
block_align * silent_chunks;
621 memset(output_samples_s16, 0x00, silent_size * 2);
622 output_samples_s16 += silent_size;
624 memset(output_samples_u8, 0x80, silent_size);
625 output_samples_u8 += silent_size;
630 if (audio_chunks > 0) {
631 buf_end = buf + buf_size;
639 memcpy(output_samples_u8, buf, s->
chunk_size);
static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
This structure describes decoded (raw) audio or video data.
#define BLOCK_TYPE_SILENCE
#define AV_LOG_WARNING
Something somehow does not look correct.
static av_cold int init(AVCodecContext *avctx)
void av_log(void *avcl, int level, const char *fmt,...) av_printf_format(3
Send the specified message to the log if the level is less than or equal to the current av_log_level...
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
#define AV_CH_LAYOUT_STEREO
int block_align
number of bytes per packet if constant and known or 0 Used by some WAV based audio codecs...
static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g, uint8_t *dst, unsigned int size)
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
if((e=av_dict_get(options,"", NULL, AV_DICT_IGNORE_SUFFIX)))
enum AVSampleFormat sample_fmt
audio sample format
static int vmdvideo_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
const char * name
Name of the codec implementation.
int av_frame_ref(AVFrame *dst, AVFrame *src)
Setup a new reference to the data described by a given frame.
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
unsigned char * unpack_buffer
static av_always_inline void bytestream2_skipu(GetByteContext *g, unsigned int size)
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
#define BLOCK_TYPE_INITIAL
unsigned char palette[PALETTE_COUNT *4]
static void lz_unpack(const unsigned char *src, int src_len, unsigned char *dest, int dest_len)
static void predictor(uint8_t *src, int size)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
#define bytestream2_get_ne16
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
const unsigned char * buf
Libavcodec external API header.
static int rle_unpack(const unsigned char *src, unsigned char *dest, int src_count, int src_size, int dest_len)
uint64_t channel_layout
Audio channel layout.
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
int width
picture width / height.
static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
void * av_malloc(size_t size) av_malloc_attrib 1(1)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
static av_always_inline int bytestream2_tell(GetByteContext *g)
AVCodec ff_vmdaudio_decoder
static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size, int channels)
int sample_rate
samples per second
main external API structure.
static void close(AVCodecParserContext *s)
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
void avcodec_get_frame_defaults(AVFrame *frame)
Set the fields of the given AVFrame to default values.
static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt)
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
AVCodec ff_vmdvideo_decoder
common internal api header.
static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
#define AVERROR_INVALIDDATA
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);ff_audio_convert_init_arm(ac);ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_dlog(ac->avr,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> out
int channels
number of audio channels
static const uint16_t vmdaudio_table[128]
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
8 bit with PIX_FMT_RGB32 palette
#define AV_CH_LAYOUT_MONO
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
This structure stores compressed data.
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
int nb_samples
number of audio samples (per channel) described by this frame
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.