Merge remote-tracking branch 'qatar/master'

* qatar/master:
  ppc: fix some pointer to integer casts
  ppc: fix 32-bit PIC build
  vmdaudio: fix decoding of 16-bit audio format.
  lavf: do not set codec_tag for rawvideo
  h264: check for out of bounds reads in ff_h264_decode_extradata().
  flvdec: Check for overflow before allocating arrays
  avconv: use correct output stream index when checking max_frames
  avconv: remove fake coded_frame on streamcopy hack

Conflicts:
	avconv.c
	libavcodec/h264.c
	libavcodec/ppc/asm.S
	libavcodec/vmdav.c
	libavformat/flvdec.c
	libavformat/utils.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
pull/2/head
Michael Niedermayer 13 years ago
commit 537a9e5cc2
  1. 9
      avconv.c
  2. 9
      ffmpeg.c
  3. 23
      libavcodec/ppc/asm.S
  4. 7
      libavcodec/ppc/fft_altivec_s.S
  5. 119
      libavcodec/vmdav.c
  6. 6
      libswscale/ppc/swscale_altivec.c

@ -1826,7 +1826,6 @@ static int output_packet(InputStream *ist, int ist_index,
abort(); abort();
} }
} else { } else {
AVFrame avframe; //FIXME/XXX remove this
AVPicture pict; AVPicture pict;
AVPacket opkt; AVPacket opkt;
int64_t ost_tb_start_time= av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base); int64_t ost_tb_start_time= av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base);
@ -1842,10 +1841,6 @@ static int output_packet(InputStream *ist, int ist_index,
/* no reencoding needed : output the packet directly */ /* no reencoding needed : output the packet directly */
/* force the input stream PTS */ /* force the input stream PTS */
avcodec_get_frame_defaults(&avframe);
ost->st->codec->coded_frame= &avframe;
avframe.key_frame = pkt->flags & AV_PKT_FLAG_KEY;
if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
audio_size += data_size; audio_size += data_size;
else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
@ -2455,8 +2450,8 @@ static int transcode(OutputFile *output_files,
} }
if (ost->frame_number >= ost->max_frames) { if (ost->frame_number >= ost->max_frames) {
int j; int j;
for (j = of->ost_index; j < of->ctx->nb_streams; j++) for (j = 0; j < of->ctx->nb_streams; j++)
output_streams[j].is_past_recording_time = 1; output_streams[of->ost_index + j].is_past_recording_time = 1;
continue; continue;
} }
} }

@ -1845,7 +1845,6 @@ static int output_packet(InputStream *ist, int ist_index,
abort(); abort();
} }
} else { } else {
AVFrame avframe; //FIXME/XXX remove this
AVPicture pict; AVPicture pict;
AVPacket opkt; AVPacket opkt;
int64_t ost_tb_start_time= av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base); int64_t ost_tb_start_time= av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base);
@ -1861,10 +1860,6 @@ static int output_packet(InputStream *ist, int ist_index,
/* no reencoding needed : output the packet directly */ /* no reencoding needed : output the packet directly */
/* force the input stream PTS */ /* force the input stream PTS */
avcodec_get_frame_defaults(&avframe);
ost->st->codec->coded_frame= &avframe;
avframe.key_frame = pkt->flags & AV_PKT_FLAG_KEY;
if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
audio_size += data_size; audio_size += data_size;
else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
@ -2503,8 +2498,8 @@ static int transcode(OutputFile *output_files, int nb_output_files,
} }
if (ost->frame_number >= ost->max_frames) { if (ost->frame_number >= ost->max_frames) {
int j; int j;
for (j = of->ost_index; j < of->ctx->nb_streams; j++) for (j = 0; j < of->ctx->nb_streams; j++)
output_streams[j].is_past_recording_time = 1; output_streams[of->ost_index + j].is_past_recording_time = 1;
continue; continue;
} }
} }

@ -44,10 +44,13 @@ X(\name):
L(\name): L(\name):
.endm .endm
.macro movrel rd, sym .macro movrel rd, sym, gp
ld \rd, \sym@got(r2) ld \rd, \sym@got(r2)
.endm .endm
.macro get_got rd
.endm
#else /* ARCH_PPC64 */ #else /* ARCH_PPC64 */
#define PTR .int #define PTR .int
@ -65,19 +68,25 @@ X(\name):
\name: \name:
.endm .endm
.macro movrel rd, sym .macro movrel rd, sym, gp
#if CONFIG_PIC #if CONFIG_PIC
bcl 20, 31, lab_pic_\@ lwz \rd, \sym@got(\gp)
lab_pic_\@:
mflr \rd
addis \rd, \rd, (\sym - lab_pic_\@)@ha
addi \rd, \rd, (\sym - lab_pic_\@)@l
#else #else
lis \rd, \sym@ha lis \rd, \sym@ha
la \rd, \sym@l(\rd) la \rd, \sym@l(\rd)
#endif #endif
.endm .endm
.macro get_got rd
#if CONFIG_PIC
bcl 20, 31, .Lgot\@
.Lgot\@:
mflr \rd
addis \rd, \rd, _GLOBAL_OFFSET_TABLE_ - .Lgot\@@ha
addi \rd, \rd, _GLOBAL_OFFSET_TABLE_ - .Lgot\@@l
#endif
.endm
#endif /* ARCH_PPC64 */ #endif /* ARCH_PPC64 */
#if HAVE_IBM_ASM #if HAVE_IBM_ASM

@ -353,6 +353,7 @@ extfunc ff_fft_calc\interleave\()_altivec
mflr r0 mflr r0
stp r0, 2*PS(r1) stp r0, 2*PS(r1)
stpu r1, -(160+16*PS)(r1) stpu r1, -(160+16*PS)(r1)
get_got r11
addi r6, r1, 16*PS addi r6, r1, 16*PS
stvm r6, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29 stvm r6, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29
mfvrsave r0 mfvrsave r0
@ -360,14 +361,14 @@ extfunc ff_fft_calc\interleave\()_altivec
li r6, 0xfffffffc li r6, 0xfffffffc
mtvrsave r6 mtvrsave r6
movrel r6, fft_data movrel r6, fft_data, r11
lvm r6, v14, v15, v16, v17, v18, v19, v20, v21 lvm r6, v14, v15, v16, v17, v18, v19, v20, v21
lvm r6, v22, v23, v24, v25, v26, v27, v28, v29 lvm r6, v22, v23, v24, v25, v26, v27, v28, v29
li r9, 16 li r9, 16
movrel r12, X(ff_cos_tabs) movrel r12, X(ff_cos_tabs), r11
movrel r6, fft_dispatch_tab\interleave\()_altivec movrel r6, fft_dispatch_tab\interleave\()_altivec, r11
lwz r3, 0(r3) lwz r3, 0(r3)
subi r3, r3, 2 subi r3, r3, 2
slwi r3, r3, 2+ARCH_PPC64 slwi r3, r3, 2+ARCH_PPC64

@ -465,9 +465,8 @@ static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
#define BLOCK_TYPE_SILENCE 3 #define BLOCK_TYPE_SILENCE 3
typedef struct VmdAudioContext { typedef struct VmdAudioContext {
AVCodecContext *avctx;
int out_bps; int out_bps;
int predictors[2]; int chunk_size;
} VmdAudioContext; } VmdAudioContext;
static const uint16_t vmdaudio_table[128] = { static const uint16_t vmdaudio_table[128] = {
@ -490,13 +489,23 @@ static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
{ {
VmdAudioContext *s = avctx->priv_data; VmdAudioContext *s = avctx->priv_data;
s->avctx = avctx; if (avctx->channels < 1 || avctx->channels > 2) {
av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
return AVERROR(EINVAL);
}
if (avctx->block_align < 1) {
av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
return AVERROR(EINVAL);
}
if (avctx->bits_per_coded_sample == 16) if (avctx->bits_per_coded_sample == 16)
avctx->sample_fmt = AV_SAMPLE_FMT_S16; avctx->sample_fmt = AV_SAMPLE_FMT_S16;
else else
avctx->sample_fmt = AV_SAMPLE_FMT_U8; avctx->sample_fmt = AV_SAMPLE_FMT_U8;
s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt); s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt);
s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, " av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
"block align = %d, sample rate = %d\n", "block align = %d, sample rate = %d\n",
avctx->channels, avctx->bits_per_coded_sample, avctx->block_align, avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
@ -505,52 +514,47 @@ static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
return 0; return 0;
} }
static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data, static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
const uint8_t *buf, int buf_size, int stereo) int channels)
{ {
int i; int ch;
int chan = 0; const uint8_t *buf_end = buf + buf_size;
int16_t *out = (int16_t*)data; int predictor[2];
int st = channels - 1;
for(i = 0; i < buf_size; i++) {
if(buf[i] & 0x80) /* decode initial raw sample */
s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F]; for (ch = 0; ch < channels; ch++) {
predictor[ch] = (int16_t)AV_RL16(buf);
buf += 2;
*out++ = predictor[ch];
}
/* decode DPCM samples */
ch = 0;
while (buf < buf_end) {
uint8_t b = *buf++;
if (b & 0x80)
predictor[ch] -= vmdaudio_table[b & 0x7F];
else else
s->predictors[chan] += vmdaudio_table[buf[i]]; predictor[ch] += vmdaudio_table[b];
s->predictors[chan] = av_clip_int16(s->predictors[chan]); predictor[ch] = av_clip_int16(predictor[ch]);
out[i] = s->predictors[chan]; *out++ = predictor[ch];
chan ^= stereo; ch ^= st;
} }
} }
static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
const uint8_t *buf, int silent_chunks, int data_size)
{
int silent_size = s->avctx->block_align * silent_chunks * s->out_bps;
if (silent_chunks) {
memset(data, s->out_bps == 2 ? 0x00 : 0x80, silent_size);
data += silent_size;
}
if (s->avctx->bits_per_coded_sample == 16)
vmdaudio_decode_audio(s, data, buf, data_size, s->avctx->channels == 2);
else {
/* just copy the data */
memcpy(data, buf, data_size);
}
return silent_size + data_size * s->out_bps;
}
static int vmdaudio_decode_frame(AVCodecContext *avctx, static int vmdaudio_decode_frame(AVCodecContext *avctx,
void *data, int *data_size, void *data, int *data_size,
AVPacket *avpkt) AVPacket *avpkt)
{ {
const uint8_t *buf = avpkt->data; const uint8_t *buf = avpkt->data;
const uint8_t *buf_end;
int buf_size = avpkt->size; int buf_size = avpkt->size;
VmdAudioContext *s = avctx->priv_data; VmdAudioContext *s = avctx->priv_data;
int block_type, silent_chunks; int block_type, silent_chunks, audio_chunks;
unsigned char *output_samples = (unsigned char *)data; int nb_samples, out_size;
uint8_t *output_samples_u8 = data;
int16_t *output_samples_s16 = data;
if (buf_size < 16) { if (buf_size < 16) {
av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n"); av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
@ -566,11 +570,14 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx,
buf += 16; buf += 16;
buf_size -= 16; buf_size -= 16;
/* get number of silent chunks */
silent_chunks = 0; silent_chunks = 0;
if (block_type == BLOCK_TYPE_INITIAL) { if (block_type == BLOCK_TYPE_INITIAL) {
uint32_t flags; uint32_t flags;
if (buf_size < 4) if (buf_size < 4) {
return -1; av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
return AVERROR(EINVAL);
}
flags = AV_RB32(buf); flags = AV_RB32(buf);
silent_chunks = av_popcount(flags); silent_chunks = av_popcount(flags);
buf += 4; buf += 4;
@ -581,11 +588,41 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx,
} }
/* ensure output buffer is large enough */ /* ensure output buffer is large enough */
if (*data_size < (avctx->block_align*silent_chunks + buf_size) * s->out_bps) audio_chunks = buf_size / s->chunk_size;
nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels;
out_size = nb_samples * avctx->channels * s->out_bps;
if (*data_size < out_size)
return -1; return -1;
*data_size = vmdaudio_loadsound(s, output_samples, buf, silent_chunks, buf_size); /* decode silent chunks */
if (silent_chunks > 0) {
int silent_size = avctx->block_align * silent_chunks;
if (s->out_bps == 2) {
memset(output_samples_s16, 0x00, silent_size * 2);
output_samples_s16 += silent_size;
} else {
memset(output_samples_u8, 0x80, silent_size);
output_samples_u8 += silent_size;
}
}
/* decode audio chunks */
if (audio_chunks > 0) {
buf_end = buf + buf_size;
while (buf < buf_end) {
if (s->out_bps == 2) {
decode_audio_s16(output_samples_s16, buf, s->chunk_size,
avctx->channels);
output_samples_s16 += avctx->block_align;
} else {
memcpy(output_samples_u8, buf, s->chunk_size);
output_samples_u8 += avctx->block_align;
}
buf += s->chunk_size;
}
}
*data_size = out_size;
return avpkt->size; return avpkt->size;
} }

@ -242,7 +242,7 @@ static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW,
vector unsigned char src_v1, src_vF; vector unsigned char src_v1, src_vF;
vector signed short src_v, filter_v; vector signed short src_v, filter_v;
vector signed int val_vEven, val_s; vector signed int val_vEven, val_s;
if ((((int)src + srcPos)% 16) > 12) { if ((((uintptr_t)src + srcPos) % 16) > 12) {
src_v1 = vec_ld(srcPos + 16, src); src_v1 = vec_ld(srcPos + 16, src);
} }
src_vF = vec_perm(src_v0, src_v1, vec_lvsl(srcPos, src)); src_vF = vec_perm(src_v0, src_v1, vec_lvsl(srcPos, src));
@ -281,7 +281,7 @@ static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW,
vector unsigned char src_v1, src_vF; vector unsigned char src_v1, src_vF;
vector signed short src_v, filter_v; vector signed short src_v, filter_v;
vector signed int val_v, val_s; vector signed int val_v, val_s;
if ((((int)src + srcPos)% 16) > 8) { if ((((uintptr_t)src + srcPos) % 16) > 8) {
src_v1 = vec_ld(srcPos + 16, src); src_v1 = vec_ld(srcPos + 16, src);
} }
src_vF = vec_perm(src_v0, src_v1, vec_lvsl(srcPos, src)); src_vF = vec_perm(src_v0, src_v1, vec_lvsl(srcPos, src));
@ -367,7 +367,7 @@ static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW,
//vector unsigned char src_v0 = vec_ld(srcPos + j, src); //vector unsigned char src_v0 = vec_ld(srcPos + j, src);
vector unsigned char src_v1, src_vF; vector unsigned char src_v1, src_vF;
vector signed short src_v, filter_v1R, filter_v; vector signed short src_v, filter_v1R, filter_v;
if ((((int)src + srcPos)% 16) > 8) { if ((((uintptr_t)src + srcPos) % 16) > 8) {
src_v1 = vec_ld(srcPos + j + 16, src); src_v1 = vec_ld(srcPos + j + 16, src);
} }
src_vF = vec_perm(src_v0, src_v1, permS); src_vF = vec_perm(src_v0, src_v1, permS);

Loading…
Cancel
Save