* qatar/master: (23 commits) aacenc: Fix identification padding when the bitstream is already aligned. aacenc: Write correct length for long identification strings. aud: remove unneeded field, audio_stream_index from context aud: fix time stamp calculation for ADPCM IMA WS aud: simplify header parsing aud: set pts_wrap_bits to 64. cosmetics: indentation aud: support Westwood SND1 audio in AUD files. adpcm_ima_ws: fix stereo decoding avcodec: add a new codec_id for CRYO APC IMA ADPCM. vqa: remove unused context fields, audio_samplerate and audio_bits vqa: clean up audio header parsing vqa: set time base to frame rate as coded in the header. vqa: set packet duration. vqa: use 1/sample_rate as the audio stream time base vqa: set stream start_time to 0. lavc: postpone the removal of AVCodecContext.request_channels. lavf: postpone removing av_close_input_file(). lavc: postpone removing old audio encoding and decoding API avplay: remove the -er option. ... Conflicts: Changelog libavcodec/version.h libavdevice/v4l.c Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n0.10
@@ -1,7 +1,6 @@ | |||
Entries are sorted chronologically from oldest to youngest within each release, | |||
releases are sorted from youngest to oldest. | |||
version next: | |||
- v410 Quicktime Uncompressed 4:4:4 10-bit encoder and decoder | |||
- SBaGen (SBG) binaural beats script demuxer | |||
@@ -265,7 +265,6 @@ static int idct = FF_IDCT_AUTO; | |||
static enum AVDiscard skip_frame = AVDISCARD_DEFAULT; | |||
static enum AVDiscard skip_idct = AVDISCARD_DEFAULT; | |||
static enum AVDiscard skip_loop_filter = AVDISCARD_DEFAULT; | |||
static int error_recognition = FF_ER_CAREFUL; | |||
static int error_concealment = 3; | |||
static int decoder_reorder_pts = -1; | |||
static int autoexit; | |||
@@ -2236,7 +2235,6 @@ static int stream_component_open(VideoState *is, int stream_index) | |||
avctx->skip_frame = skip_frame; | |||
avctx->skip_idct = skip_idct; | |||
avctx->skip_loop_filter = skip_loop_filter; | |||
avctx->error_recognition = error_recognition; | |||
avctx->error_concealment = error_concealment; | |||
if(avctx->lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE; | |||
@@ -3071,7 +3069,6 @@ static const OptionDef options[] = { | |||
{ "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&skip_frame }, "", "" }, | |||
{ "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&skip_idct }, "", "" }, | |||
{ "idct", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&idct }, "set idct algo", "algo" }, | |||
{ "er", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&error_recognition }, "set error detection threshold (0-4)", "threshold" }, | |||
{ "ec", OPT_INT | HAS_ARG | OPT_EXPERT, { (void*)&error_concealment }, "set error concealment options", "bit_mask" }, | |||
{ "sync", HAS_ARG | OPT_EXPERT, { (void*)opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" }, | |||
{ "autoexit", OPT_BOOL | OPT_EXPERT, { (void*)&autoexit }, "exit at the end", "" }, | |||
@@ -548,6 +548,7 @@ OBJS-$(CONFIG_ADPCM_G722_ENCODER) += g722.o g722enc.o | |||
OBJS-$(CONFIG_ADPCM_G726_DECODER) += g726.o | |||
OBJS-$(CONFIG_ADPCM_G726_ENCODER) += g726.o | |||
OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o adpcm_data.o | |||
OBJS-$(CONFIG_ADPCM_IMA_APC_DECODER) += adpcm.o adpcm_data.o | |||
OBJS-$(CONFIG_ADPCM_IMA_DK3_DECODER) += adpcm.o adpcm_data.o | |||
OBJS-$(CONFIG_ADPCM_IMA_DK4_DECODER) += adpcm.o adpcm_data.o | |||
OBJS-$(CONFIG_ADPCM_IMA_EA_EACS_DECODER) += adpcm.o adpcm_data.o | |||
@@ -464,7 +464,7 @@ static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s, | |||
if (namelen >= 15) | |||
put_bits(&s->pb, 8, namelen - 14); | |||
put_bits(&s->pb, 4, 0); //extension type - filler | |||
padbits = 8 - (put_bits_count(&s->pb) & 7); | |||
padbits = -put_bits_count(&s->pb) & 7; | |||
avpriv_align_put_bits(&s->pb); | |||
for (i = 0; i < namelen - 2; i++) | |||
put_bits(&s->pb, 8, name[i]); | |||
@@ -86,6 +86,7 @@ static const int swf_index_tables[4][16] = { | |||
typedef struct ADPCMDecodeContext { | |||
AVFrame frame; | |||
ADPCMChannelStatus status[6]; | |||
int vqa_version; /**< VQA version. Used for ADPCM_IMA_WS */ | |||
} ADPCMDecodeContext; | |||
static av_cold int adpcm_decode_init(AVCodecContext * avctx) | |||
@@ -120,12 +121,16 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) | |||
return -1; | |||
} | |||
break; | |||
case CODEC_ID_ADPCM_IMA_WS: | |||
if (avctx->extradata && avctx->extradata_size == 2 * 4) { | |||
case CODEC_ID_ADPCM_IMA_APC: | |||
if (avctx->extradata && avctx->extradata_size >= 8) { | |||
c->status[0].predictor = AV_RL32(avctx->extradata); | |||
c->status[1].predictor = AV_RL32(avctx->extradata + 4); | |||
} | |||
break; | |||
case CODEC_ID_ADPCM_IMA_WS: | |||
if (avctx->extradata && avctx->extradata_size >= 42) | |||
c->vqa_version = AV_RL16(avctx->extradata); | |||
break; | |||
default: | |||
break; | |||
} | |||
@@ -362,6 +367,7 @@ static int get_nb_samples(AVCodecContext *avctx, const uint8_t *buf, | |||
break; | |||
/* simple 4-bit adpcm */ | |||
case CODEC_ID_ADPCM_CT: | |||
case CODEC_ID_ADPCM_IMA_APC: | |||
case CODEC_ID_ADPCM_IMA_EA_SEAD: | |||
case CODEC_ID_ADPCM_IMA_WS: | |||
case CODEC_ID_ADPCM_YAMAHA: | |||
@@ -776,13 +782,37 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, | |||
*samples++ = adpcm_ima_expand_nibble(&c->status[st], v2, 3); | |||
} | |||
break; | |||
case CODEC_ID_ADPCM_IMA_WS: | |||
case CODEC_ID_ADPCM_IMA_APC: | |||
while (src < buf + buf_size) { | |||
uint8_t v = *src++; | |||
*samples++ = adpcm_ima_expand_nibble(&c->status[0], v >> 4 , 3); | |||
*samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3); | |||
} | |||
break; | |||
case CODEC_ID_ADPCM_IMA_WS: | |||
for (channel = 0; channel < avctx->channels; channel++) { | |||
const uint8_t *src0; | |||
int src_stride; | |||
int16_t *smp = samples + channel; | |||
if (c->vqa_version == 3) { | |||
src0 = src + channel * buf_size / 2; | |||
src_stride = 1; | |||
} else { | |||
src0 = src + channel; | |||
src_stride = avctx->channels; | |||
} | |||
for (n = nb_samples / 2; n > 0; n--) { | |||
uint8_t v = *src0; | |||
src0 += src_stride; | |||
*smp = adpcm_ima_expand_nibble(&c->status[channel], v >> 4 , 3); | |||
smp += avctx->channels; | |||
*smp = adpcm_ima_expand_nibble(&c->status[channel], v & 0x0F, 3); | |||
smp += avctx->channels; | |||
} | |||
} | |||
src = buf + buf_size; | |||
break; | |||
case CODEC_ID_ADPCM_XA: | |||
while (buf_size >= 128) { | |||
xa_decode(samples, src, &c->status[0], &c->status[1], | |||
@@ -1226,6 +1256,7 @@ ADPCM_DECODER(CODEC_ID_ADPCM_EA_R2, adpcm_ea_r2, "ADPCM Electronic Arts R2"); | |||
ADPCM_DECODER(CODEC_ID_ADPCM_EA_R3, adpcm_ea_r3, "ADPCM Electronic Arts R3"); | |||
ADPCM_DECODER(CODEC_ID_ADPCM_EA_XAS, adpcm_ea_xas, "ADPCM Electronic Arts XAS"); | |||
ADPCM_DECODER(CODEC_ID_ADPCM_IMA_AMV, adpcm_ima_amv, "ADPCM IMA AMV"); | |||
ADPCM_DECODER(CODEC_ID_ADPCM_IMA_APC, adpcm_ima_apc, "ADPCM IMA CRYO APC"); | |||
ADPCM_DECODER(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3, "ADPCM IMA Duck DK3"); | |||
ADPCM_DECODER(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4, "ADPCM IMA Duck DK4"); | |||
ADPCM_DECODER(CODEC_ID_ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs, "ADPCM IMA Electronic Arts EACS"); | |||
@@ -365,6 +365,7 @@ void avcodec_register_all(void) | |||
REGISTER_ENCDEC (ADPCM_G722, adpcm_g722); | |||
REGISTER_ENCDEC (ADPCM_G726, adpcm_g726); | |||
REGISTER_DECODER (ADPCM_IMA_AMV, adpcm_ima_amv); | |||
REGISTER_DECODER (ADPCM_IMA_APC, adpcm_ima_apc); | |||
REGISTER_DECODER (ADPCM_IMA_DK3, adpcm_ima_dk3); | |||
REGISTER_DECODER (ADPCM_IMA_DK4, adpcm_ima_dk4); | |||
REGISTER_DECODER (ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs); | |||
@@ -326,6 +326,7 @@ enum CodecID { | |||
CODEC_ID_ADPCM_EA_MAXIS_XA, | |||
CODEC_ID_ADPCM_IMA_ISS, | |||
CODEC_ID_ADPCM_G722, | |||
CODEC_ID_ADPCM_IMA_APC, | |||
/* AMR */ | |||
CODEC_ID_AMR_NB = 0x12000, | |||
@@ -666,9 +666,12 @@ static int rv10_decode_frame(AVCodecContext *avctx, | |||
slice_count = avctx->slice_count; | |||
for(i=0; i<slice_count; i++){ | |||
int offset= get_slice_offset(avctx, slices_hdr, i); | |||
unsigned offset = get_slice_offset(avctx, slices_hdr, i); | |||
int size, size2; | |||
if (offset >= buf_size) | |||
return AVERROR_INVALIDDATA; | |||
if(i+1 == slice_count) | |||
size= buf_size - offset; | |||
else | |||
@@ -679,6 +682,10 @@ static int rv10_decode_frame(AVCodecContext *avctx, | |||
else | |||
size2= get_slice_offset(avctx, slices_hdr, i+2) - offset; | |||
if (size <= 0 || size2 <= 0 || | |||
offset + FFMAX(size, size2) > buf_size) | |||
return AVERROR_INVALIDDATA; | |||
if(rv10_decode_packet(avctx, buf+offset, size, size2) > 8*size) | |||
i++; | |||
} | |||
@@ -1780,6 +1780,7 @@ int av_get_bits_per_sample(enum CodecID codec_id){ | |||
return 3; | |||
case CODEC_ID_ADPCM_SBPRO_4: | |||
case CODEC_ID_ADPCM_CT: | |||
case CODEC_ID_ADPCM_IMA_APC: | |||
case CODEC_ID_ADPCM_IMA_WAV: | |||
case CODEC_ID_ADPCM_IMA_QT: | |||
case CODEC_ID_ADPCM_SWF: | |||
@@ -21,7 +21,7 @@ | |||
#define AVCODEC_VERSION_H | |||
#define LIBAVCODEC_VERSION_MAJOR 53 | |||
#define LIBAVCODEC_VERSION_MINOR 58 | |||
#define LIBAVCODEC_VERSION_MINOR 59 | |||
#define LIBAVCODEC_VERSION_MICRO 100 | |||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | |||
@@ -51,7 +51,7 @@ | |||
#define FF_API_ANTIALIAS_ALGO (LIBAVCODEC_VERSION_MAJOR < 54) | |||
#endif | |||
#ifndef FF_API_REQUEST_CHANNELS | |||
#define FF_API_REQUEST_CHANNELS (LIBAVCODEC_VERSION_MAJOR < 54) | |||
#define FF_API_REQUEST_CHANNELS (LIBAVCODEC_VERSION_MAJOR < 55) | |||
#endif | |||
#ifndef FF_API_OPT_H | |||
#define FF_API_OPT_H (LIBAVCODEC_VERSION_MAJOR < 54) | |||
@@ -114,7 +114,7 @@ | |||
#define FF_API_DATA_POINTERS (LIBAVCODEC_VERSION_MAJOR < 54) | |||
#endif | |||
#ifndef FF_API_OLD_DECODE_AUDIO | |||
#define FF_API_OLD_DECODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 54) | |||
#define FF_API_OLD_DECODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 55) | |||
#endif | |||
#ifndef FF_API_OLD_TIMECODE | |||
#define FF_API_OLD_TIMECODE (LIBAVCODEC_VERSION_MAJOR < 54) | |||
@@ -124,7 +124,7 @@ | |||
#define FF_API_AVFRAME_AGE (LIBAVCODEC_VERSION_MAJOR < 54) | |||
#endif | |||
#ifndef FF_API_OLD_ENCODE_AUDIO | |||
#define FF_API_OLD_ENCODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 54) | |||
#define FF_API_OLD_ENCODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 55) | |||
#endif | |||
#endif /* AVCODEC_VERSION_H */ |
@@ -29,7 +29,6 @@ OBJS-$(CONFIG_SDL_OUTDEV) += sdl.o | |||
OBJS-$(CONFIG_SNDIO_INDEV) += sndio_common.o sndio_dec.o | |||
OBJS-$(CONFIG_SNDIO_OUTDEV) += sndio_common.o sndio_enc.o | |||
OBJS-$(CONFIG_V4L2_INDEV) += v4l2.o | |||
OBJS-$(CONFIG_V4L_INDEV) += v4l.o | |||
OBJS-$(CONFIG_VFWCAP_INDEV) += vfwcap.o | |||
OBJS-$(CONFIG_X11_GRAB_DEVICE_INDEV) += x11grab.o | |||
@@ -51,9 +51,7 @@ void avdevice_register_all(void) | |||
REGISTER_OUTDEV (SDL, sdl); | |||
REGISTER_INOUTDEV (SNDIO, sndio); | |||
REGISTER_INDEV (V4L2, v4l2); | |||
#if FF_API_V4L | |||
REGISTER_INDEV (V4L, v4l); | |||
#endif | |||
REGISTER_INDEV (VFWCAP, vfwcap); | |||
REGISTER_INDEV (X11_GRAB_DEVICE, x11_grab_device); | |||
@@ -56,10 +56,6 @@ | |||
LIBAVDEVICE_VERSION_MICRO) | |||
#define LIBAVDEVICE_BUILD LIBAVDEVICE_VERSION_INT | |||
#ifndef FF_API_V4L | |||
#define FF_API_V4L (LIBAVDEVICE_VERSION_MAJOR < 54) | |||
#endif | |||
/** | |||
* Return the LIBAVDEVICE_VERSION_INT constant. | |||
*/ | |||
@@ -44,7 +44,7 @@ static int apc_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
return AVERROR(ENOMEM); | |||
st->codec->codec_type = AVMEDIA_TYPE_AUDIO; | |||
st->codec->codec_id = CODEC_ID_ADPCM_IMA_WS; | |||
st->codec->codec_id = CODEC_ID_ADPCM_IMA_APC; | |||
avio_rl32(pb); /* number of samples */ | |||
st->codec->sample_rate = avio_rl32(pb); | |||
@@ -123,7 +123,7 @@ | |||
#define FF_API_SET_PTS_INFO (LIBAVFORMAT_VERSION_MAJOR < 54) | |||
#endif | |||
#ifndef FF_API_CLOSE_INPUT_FILE | |||
#define FF_API_CLOSE_INPUT_FILE (LIBAVFORMAT_VERSION_MAJOR < 54) | |||
#define FF_API_CLOSE_INPUT_FILE (LIBAVFORMAT_VERSION_MAJOR < 55) | |||
#endif | |||
#endif /* AVFORMAT_VERSION_H */ |
@@ -41,15 +41,6 @@ | |||
#define AUD_CHUNK_PREAMBLE_SIZE 8 | |||
#define AUD_CHUNK_SIGNATURE 0x0000DEAF | |||
typedef struct WsAudDemuxContext { | |||
int audio_samplerate; | |||
int audio_channels; | |||
int audio_bits; | |||
enum CodecID audio_type; | |||
int audio_stream_index; | |||
int64_t audio_frame_counter; | |||
} WsAudDemuxContext; | |||
static int wsaud_probe(AVProbeData *p) | |||
{ | |||
int field; | |||
@@ -79,7 +70,7 @@ static int wsaud_probe(AVProbeData *p) | |||
/* note: only check for WS IMA (type 99) right now since there is no | |||
* support for type 1 */ | |||
if (p->buf[11] != 99) | |||
if (p->buf[11] != 99 && p->buf[11] != 1) | |||
return 0; | |||
/* read ahead to the first audio chunk and validate the first header signature */ | |||
@@ -93,41 +84,44 @@ static int wsaud_probe(AVProbeData *p) | |||
static int wsaud_read_header(AVFormatContext *s, | |||
AVFormatParameters *ap) | |||
{ | |||
WsAudDemuxContext *wsaud = s->priv_data; | |||
AVIOContext *pb = s->pb; | |||
AVStream *st; | |||
unsigned char header[AUD_HEADER_SIZE]; | |||
int sample_rate, channels, codec; | |||
if (avio_read(pb, header, AUD_HEADER_SIZE) != AUD_HEADER_SIZE) | |||
return AVERROR(EIO); | |||
wsaud->audio_samplerate = AV_RL16(&header[0]); | |||
if (header[11] == 99) | |||
wsaud->audio_type = CODEC_ID_ADPCM_IMA_WS; | |||
else | |||
return AVERROR_INVALIDDATA; | |||
/* flag 0 indicates stereo */ | |||
wsaud->audio_channels = (header[10] & 0x1) + 1; | |||
/* flag 1 indicates 16 bit audio */ | |||
wsaud->audio_bits = (((header[10] & 0x2) >> 1) + 1) * 8; | |||
sample_rate = AV_RL16(&header[0]); | |||
channels = (header[10] & 0x1) + 1; | |||
codec = header[11]; | |||
/* initialize the audio decoder stream */ | |||
st = avformat_new_stream(s, NULL); | |||
if (!st) | |||
return AVERROR(ENOMEM); | |||
avpriv_set_pts_info(st, 33, 1, wsaud->audio_samplerate); | |||
st->codec->codec_type = AVMEDIA_TYPE_AUDIO; | |||
st->codec->codec_id = wsaud->audio_type; | |||
st->codec->codec_tag = 0; /* no tag */ | |||
st->codec->channels = wsaud->audio_channels; | |||
st->codec->sample_rate = wsaud->audio_samplerate; | |||
st->codec->bits_per_coded_sample = wsaud->audio_bits; | |||
st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * | |||
st->codec->bits_per_coded_sample / 4; | |||
st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; | |||
wsaud->audio_stream_index = st->index; | |||
wsaud->audio_frame_counter = 0; | |||
switch (codec) { | |||
case 1: | |||
if (channels != 1) { | |||
av_log_ask_for_sample(s, "Stereo WS-SND1 is not supported.\n"); | |||
return AVERROR_PATCHWELCOME; | |||
} | |||
st->codec->codec_id = CODEC_ID_WESTWOOD_SND1; | |||
break; | |||
case 99: | |||
st->codec->codec_id = CODEC_ID_ADPCM_IMA_WS; | |||
st->codec->bits_per_coded_sample = 4; | |||
st->codec->bit_rate = channels * sample_rate * 4; | |||
break; | |||
default: | |||
av_log_ask_for_sample(s, "Unknown codec: %d\n", codec); | |||
return AVERROR_PATCHWELCOME; | |||
} | |||
avpriv_set_pts_info(st, 64, 1, sample_rate); | |||
st->codec->codec_type = AVMEDIA_TYPE_AUDIO; | |||
st->codec->channels = channels; | |||
st->codec->sample_rate = sample_rate; | |||
return 0; | |||
} | |||
@@ -135,11 +129,11 @@ static int wsaud_read_header(AVFormatContext *s, | |||
static int wsaud_read_packet(AVFormatContext *s, | |||
AVPacket *pkt) | |||
{ | |||
WsAudDemuxContext *wsaud = s->priv_data; | |||
AVIOContext *pb = s->pb; | |||
unsigned char preamble[AUD_CHUNK_PREAMBLE_SIZE]; | |||
unsigned int chunk_size; | |||
int ret = 0; | |||
AVStream *st = s->streams[0]; | |||
if (avio_read(pb, preamble, AUD_CHUNK_PREAMBLE_SIZE) != | |||
AUD_CHUNK_PREAMBLE_SIZE) | |||
@@ -150,15 +144,30 @@ static int wsaud_read_packet(AVFormatContext *s, | |||
return AVERROR_INVALIDDATA; | |||
chunk_size = AV_RL16(&preamble[0]); | |||
ret= av_get_packet(pb, pkt, chunk_size); | |||
if (ret != chunk_size) | |||
return AVERROR(EIO); | |||
pkt->stream_index = wsaud->audio_stream_index; | |||
pkt->pts = wsaud->audio_frame_counter; | |||
pkt->pts /= wsaud->audio_samplerate; | |||
/* 2 samples/byte, 1 or 2 samples per frame depending on stereo */ | |||
wsaud->audio_frame_counter += (chunk_size * 2) / wsaud->audio_channels; | |||
if (st->codec->codec_id == CODEC_ID_WESTWOOD_SND1) { | |||
/* For Westwood SND1 audio we need to add the output size and input | |||
size to the start of the packet to match what is in VQA. | |||
Specifically, this is needed to signal when a packet should be | |||
decoding as raw 8-bit pcm or variable-size ADPCM. */ | |||
int out_size = AV_RL16(&preamble[2]); | |||
if ((ret = av_new_packet(pkt, chunk_size + 4))) | |||
return ret; | |||
if ((ret = avio_read(pb, &pkt->data[4], chunk_size)) != chunk_size) | |||
return ret < 0 ? ret : AVERROR(EIO); | |||
AV_WL16(&pkt->data[0], out_size); | |||
AV_WL16(&pkt->data[2], chunk_size); | |||
pkt->duration = out_size; | |||
} else { | |||
ret = av_get_packet(pb, pkt, chunk_size); | |||
if (ret != chunk_size) | |||
return AVERROR(EIO); | |||
/* 2 samples/byte, 1 or 2 samples per frame depending on stereo */ | |||
pkt->duration = (chunk_size * 2) / st->codec->channels; | |||
} | |||
pkt->stream_index = st->index; | |||
return ret; | |||
} | |||
@@ -166,7 +175,6 @@ static int wsaud_read_packet(AVFormatContext *s, | |||
AVInputFormat ff_wsaud_demuxer = { | |||
.name = "wsaud", | |||
.long_name = NULL_IF_CONFIG_SMALL("Westwood Studios audio format"), | |||
.priv_data_size = sizeof(WsAudDemuxContext), | |||
.read_probe = wsaud_probe, | |||
.read_header = wsaud_read_header, | |||
.read_packet = wsaud_read_packet, | |||
@@ -51,18 +51,12 @@ | |||
#define CMDS_TAG MKBETAG('C', 'M', 'D', 'S') | |||
#define VQA_HEADER_SIZE 0x2A | |||
#define VQA_FRAMERATE 15 | |||
#define VQA_PREAMBLE_SIZE 8 | |||
typedef struct WsVqaDemuxContext { | |||
int audio_samplerate; | |||
int audio_channels; | |||
int audio_bits; | |||
int audio_stream_index; | |||
int video_stream_index; | |||
int64_t audio_frame_counter; | |||
} WsVqaDemuxContext; | |||
static int wsvqa_probe(AVProbeData *p) | |||
@@ -89,12 +83,13 @@ static int wsvqa_read_header(AVFormatContext *s, | |||
unsigned char scratch[VQA_PREAMBLE_SIZE]; | |||
unsigned int chunk_tag; | |||
unsigned int chunk_size; | |||
int fps, version, flags, sample_rate, channels; | |||
/* initialize the video decoder stream */ | |||
st = avformat_new_stream(s, NULL); | |||
if (!st) | |||
return AVERROR(ENOMEM); | |||
avpriv_set_pts_info(st, 33, 1, VQA_FRAMERATE); | |||
st->start_time = 0; | |||
wsvqa->video_stream_index = st->index; | |||
st->codec->codec_type = AVMEDIA_TYPE_VIDEO; | |||
st->codec->codec_id = CODEC_ID_WS_VQA; | |||
@@ -114,34 +109,59 @@ static int wsvqa_read_header(AVFormatContext *s, | |||
} | |||
st->codec->width = AV_RL16(&header[6]); | |||
st->codec->height = AV_RL16(&header[8]); | |||
fps = header[12]; | |||
if (fps < 1 || fps > 30) { | |||
av_log(s, AV_LOG_ERROR, "invalid fps: %d\n", fps); | |||
return AVERROR_INVALIDDATA; | |||
} | |||
avpriv_set_pts_info(st, 64, 1, fps); | |||
/* initialize the audio decoder stream for VQA v1 or nonzero samplerate */ | |||
if (AV_RL16(&header[24]) || (AV_RL16(&header[0]) == 1 && AV_RL16(&header[2]) == 1)) { | |||
version = AV_RL16(&header[ 0]); | |||
flags = AV_RL16(&header[ 2]); | |||
sample_rate = AV_RL16(&header[24]); | |||
channels = header[26]; | |||
if (sample_rate || (version == 1 && flags == 1)) { | |||
st = avformat_new_stream(s, NULL); | |||
if (!st) | |||
return AVERROR(ENOMEM); | |||
avpriv_set_pts_info(st, 33, 1, VQA_FRAMERATE); | |||
st->start_time = 0; | |||
st->codec->codec_type = AVMEDIA_TYPE_AUDIO; | |||
if (AV_RL16(&header[0]) == 1) | |||
st->codec->extradata_size = VQA_HEADER_SIZE; | |||
st->codec->extradata = av_mallocz(VQA_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); | |||
if (!st->codec->extradata) | |||
return AVERROR(ENOMEM); | |||
memcpy(st->codec->extradata, header, VQA_HEADER_SIZE); | |||
if (!sample_rate) | |||
sample_rate = 22050; | |||
st->codec->sample_rate = sample_rate; | |||
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); | |||
if (!channels) | |||
channels = 1; | |||
st->codec->channels = channels; | |||
switch (version) { | |||
case 1: | |||
st->codec->codec_id = CODEC_ID_WESTWOOD_SND1; | |||
else | |||
break; | |||
case 2: | |||
case 3: | |||
st->codec->codec_id = CODEC_ID_ADPCM_IMA_WS; | |||
st->codec->codec_tag = 0; /* no tag */ | |||
st->codec->sample_rate = AV_RL16(&header[24]); | |||
if (!st->codec->sample_rate) | |||
st->codec->sample_rate = 22050; | |||
st->codec->channels = header[26]; | |||
if (!st->codec->channels) | |||
st->codec->channels = 1; | |||
st->codec->bits_per_coded_sample = 16; | |||
st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * | |||
st->codec->bits_per_coded_sample / 4; | |||
st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; | |||
st->codec->bits_per_coded_sample = 4; | |||
st->codec->bit_rate = channels * sample_rate * 4; | |||
break; | |||
default: | |||
/* NOTE: version 0 is supposedly raw pcm_u8 or pcm_s16le, but we do | |||
not have any samples to validate this */ | |||
av_log_ask_for_sample(s, "VQA version %d audio\n", version); | |||
return AVERROR_PATCHWELCOME; | |||
} | |||
wsvqa->audio_stream_index = st->index; | |||
wsvqa->audio_samplerate = st->codec->sample_rate; | |||
wsvqa->audio_channels = st->codec->channels; | |||
wsvqa->audio_frame_counter = 0; | |||
} | |||
/* there are 0 or more chunks before the FINF chunk; iterate until | |||
@@ -208,13 +228,14 @@ static int wsvqa_read_packet(AVFormatContext *s, | |||
if (chunk_type == SND2_TAG) { | |||
pkt->stream_index = wsvqa->audio_stream_index; | |||
/* 2 samples/byte, 1 or 2 samples per frame depending on stereo */ | |||
wsvqa->audio_frame_counter += (chunk_size * 2) / wsvqa->audio_channels; | |||
pkt->duration = (chunk_size * 2) / wsvqa->audio_channels; | |||
} else if(chunk_type == SND1_TAG) { | |||
pkt->stream_index = wsvqa->audio_stream_index; | |||
/* unpacked size is stored in header */ | |||
wsvqa->audio_frame_counter += AV_RL16(pkt->data) / wsvqa->audio_channels; | |||
pkt->duration = AV_RL16(pkt->data) / wsvqa->audio_channels; | |||
} else { | |||
pkt->stream_index = wsvqa->video_stream_index; | |||
pkt->duration = 1; | |||
} | |||
/* stay on 16-bit alignment */ | |||
if (skip_byte) | |||
@@ -72,7 +72,7 @@ static int yop_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
// Audio | |||
audio_dec = audio_stream->codec; | |||
audio_dec->codec_type = AVMEDIA_TYPE_AUDIO; | |||
audio_dec->codec_id = CODEC_ID_ADPCM_IMA_WS; | |||
audio_dec->codec_id = CODEC_ID_ADPCM_IMA_APC; | |||
audio_dec->channels = 1; | |||
audio_dec->sample_rate = 22050; | |||