1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

Merge remote-tracking branch 'qatar/master'

* qatar/master:
  cosmetics: fix some then/than typos
  doxygen: Include libavcodec and libavformat examples into the documentation
  avutil: elaborate documentation for av_get_random_seed
  Add support for aac streams in mp4/mov without extradata.
  aes: whitespace cosmetics
  adler32: whitespace cosmetics
  swscale: fix another yuv range conversion overflow in 16bit scaling.
  Fix cpu flags test program
  opt-test: Add missing braces to silence compiler warnings.
  build: Eliminate obsolete test targets.
  udp: Fix a compilation warning
  swscale: Unbreak build with --enable-small
  base64: add fate test
  aes: improve test program and add fate test
  adler32: make test program more useful and add fate test
  swscale: fix yuv range correction when using 16-bit scaling.
  aacenc: Make chan_map const correct

Conflicts:
	Makefile
	doc/examples/muxing-example.c
	libavformat/udp.c
	libavutil/random_seed.h

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2011-07-01 05:33:39 +02:00
commit 721be99371
22 changed files with 330 additions and 189 deletions

View File

@ -591,7 +591,7 @@ EXCLUDE_SYMBOLS =
# directories that contain example code fragments that are included (see # directories that contain example code fragments that are included (see
# the \include command). # the \include command).
EXAMPLE_PATH = EXAMPLE_PATH = libavcodec/api-example.c libavformat/output-example.c
# If the value of the EXAMPLE_PATH tag contains directories, you can use the # If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp

View File

@ -150,8 +150,6 @@ distclean::
config: config:
$(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION) $(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION)
check: test
include $(SRC_PATH)/doc/Makefile include $(SRC_PATH)/doc/Makefile
include $(SRC_PATH)/tests/Makefile include $(SRC_PATH)/tests/Makefile

View File

@ -20,8 +20,9 @@
/** /**
* @file * @file
* avcodec API use example. * libavcodec API use example.
* *
* @example libavcodec/api-example.c
* Note that this library only handles codecs (mpeg, mpeg4, etc...), * Note that this library only handles codecs (mpeg, mpeg4, etc...),
* not file formats (avi, vob, etc...). See library 'libavformat' for the * not file formats (avi, vob, etc...). See library 'libavformat' for the
* format handling * format handling

View File

@ -22,8 +22,11 @@
/** /**
* @file * @file
* Libavformat API example: Output a media file in any supported * libavformat API example.
* libavformat format. The default codecs are used. *
* @example libavformat/output-example.c
* Output a media file in any supported libavformat format.
* The default codecs are used.
*/ */
#include <stdlib.h> #include <stdlib.h>

View File

@ -532,6 +532,22 @@ static void reset_all_predictors(PredictorState *ps)
reset_predict_state(&ps[i]); reset_predict_state(&ps[i]);
} }
static int sample_rate_idx (int rate)
{
if (92017 <= rate) return 0;
else if (75132 <= rate) return 1;
else if (55426 <= rate) return 2;
else if (46009 <= rate) return 3;
else if (37566 <= rate) return 4;
else if (27713 <= rate) return 5;
else if (23004 <= rate) return 6;
else if (18783 <= rate) return 7;
else if (13856 <= rate) return 8;
else if (11502 <= rate) return 9;
else if (9391 <= rate) return 10;
else return 11;
}
static void reset_predictor_group(PredictorState *ps, int group_num) static void reset_predictor_group(PredictorState *ps, int group_num)
{ {
int i; int i;
@ -554,10 +570,33 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
ac->m4ac.sample_rate = avctx->sample_rate; ac->m4ac.sample_rate = avctx->sample_rate;
if (avctx->extradata_size > 0) { if (avctx->extradata_size > 0) {
avctx->channels = 0;
avctx->frame_size = 0;
avctx->sample_rate = 0;
if (decode_audio_specific_config(ac, ac->avctx, &ac->m4ac, if (decode_audio_specific_config(ac, ac->avctx, &ac->m4ac,
avctx->extradata, avctx->extradata,
avctx->extradata_size) < 0) avctx->extradata_size) < 0)
return -1; return -1;
} else {
int sr, i;
enum ChannelPosition new_che_pos[4][MAX_ELEM_ID];
sr = sample_rate_idx(avctx->sample_rate);
ac->m4ac.sampling_index = sr;
ac->m4ac.channels = avctx->channels;
for (i = 0; i < FF_ARRAY_ELEMS(ff_mpeg4audio_channels); i++)
if (ff_mpeg4audio_channels[i] == avctx->channels)
break;
if (i == FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) {
i = 0;
}
ac->m4ac.chan_config = i;
if (ac->m4ac.chan_config) {
set_default_channel_config(avctx, new_che_pos, ac->m4ac.chan_config);
output_configure(ac, ac->che_pos, new_che_pos, ac->m4ac.chan_config, OC_GLOBAL_HDR);
}
} }
if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) { if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) {
@ -2049,6 +2088,7 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb)
if (output_configure(ac, ac->che_pos, new_che_pos, hdr_info.chan_config, OC_TRIAL_FRAME)) if (output_configure(ac, ac->che_pos, new_che_pos, hdr_info.chan_config, OC_TRIAL_FRAME))
return -7; return -7;
} else if (ac->output_configured != OC_LOCKED) { } else if (ac->output_configured != OC_LOCKED) {
ac->m4ac.chan_config = 0;
ac->output_configured = OC_NONE; ac->output_configured = OC_NONE;
} }
if (ac->output_configured != OC_LOCKED) { if (ac->output_configured != OC_LOCKED) {
@ -2516,6 +2556,7 @@ AVCodec ff_aac_decoder = {
.sample_fmts = (const enum AVSampleFormat[]) { .sample_fmts = (const enum AVSampleFormat[]) {
AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
}, },
.capabilities = CODEC_CAP_CHANNEL_CONF,
.channel_layouts = aac_channel_layout, .channel_layouts = aac_channel_layout,
}; };
@ -2536,5 +2577,6 @@ AVCodec ff_aac_latm_decoder = {
.sample_fmts = (const enum AVSampleFormat[]) { .sample_fmts = (const enum AVSampleFormat[]) {
AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
}, },
.capabilities = CODEC_CAP_CHANNEL_CONF,
.channel_layouts = aac_channel_layout, .channel_layouts = aac_channel_layout,
}; };

View File

@ -61,7 +61,7 @@ typedef struct AACEncContext {
int16_t *samples; ///< saved preprocessed input int16_t *samples; ///< saved preprocessed input
int samplerate_index; ///< MPEG-4 samplerate index int samplerate_index; ///< MPEG-4 samplerate index
uint8_t *chan_map; ///< channel configuration map const uint8_t *chan_map; ///< channel configuration map
ChannelElement *cpe; ///< channel elements ChannelElement *cpe; ///< channel elements
FFPsyContext psy; FFPsyContext psy;

View File

@ -1410,7 +1410,7 @@ typedef struct AVCodecContext {
* A demuxer should set this to what is stored in the field used to identify the codec. * A demuxer should set this to what is stored in the field used to identify the codec.
* If there are multiple such fields in a container then the demuxer should choose the one * If there are multiple such fields in a container then the demuxer should choose the one
* which maximizes the information about the used codec. * which maximizes the information about the used codec.
* If the codec tag field in a container is larger then 32 bits then the demuxer should * If the codec tag field in a container is larger than 32 bits then the demuxer should
* remap the longer ID to 32 bits with a table or other structure. Alternatively a new * remap the longer ID to 32 bits with a table or other structure. Alternatively a new
* extra_codec_tag + size could be added but for this a clear advantage must be demonstrated * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated
* first. * first.

View File

@ -1316,7 +1316,7 @@ static int dca_convert_bitstream(const uint8_t * src, int src_size, uint8_t * ds
PutBitContext pb; PutBitContext pb;
if ((unsigned)src_size > (unsigned)max_size) { if ((unsigned)src_size > (unsigned)max_size) {
// av_log(NULL, AV_LOG_ERROR, "Input frame size larger then DCA_MAX_FRAME_SIZE!\n"); // av_log(NULL, AV_LOG_ERROR, "Input frame size larger than DCA_MAX_FRAME_SIZE!\n");
// return -1; // return -1;
src_size = max_size; src_size = max_size;
} }

View File

@ -150,7 +150,7 @@ void clear_blocks_c(DCTELEM *blocks);
/* add and put pixel (decoding) */ /* add and put pixel (decoding) */
// blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16 // blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16
//h for op_pixels_func is limited to {width/2, width} but never larger than 16 and never smaller then 4 //h for op_pixels_func is limited to {width/2, width} but never larger than 16 and never smaller than 4
typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int h); typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int h);
typedef void (*tpel_mc_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int w, int h); typedef void (*tpel_mc_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int w, int h);
typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride); typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);
@ -183,7 +183,7 @@ static void a(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
} }
/* motion estimation */ /* motion estimation */
// h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller then 2 // h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller than 2
// although currently h<4 is not used as functions with width <8 are neither used nor implemented // although currently h<4 is not used as functions with width <8 are neither used nor implemented
typedef int (*me_cmp_func)(void /*MpegEncContext*/ *s, uint8_t *blk1/*align width (8 or 16)*/, uint8_t *blk2/*align 1*/, int line_size, int h)/* __attribute__ ((const))*/; typedef int (*me_cmp_func)(void /*MpegEncContext*/ *s, uint8_t *blk1/*align width (8 or 16)*/, uint8_t *blk2/*align 1*/, int line_size, int h)/* __attribute__ ((const))*/;

View File

@ -381,7 +381,7 @@ static inline int check_marker(GetBitContext *s, const char *msg)
/** /**
* init GetBitContext. * init GetBitContext.
* @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger then the actual read bits * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger than the actual read bits
* because some optimized bitstream readers read 32 or 64 bit at once and could read over the end * because some optimized bitstream readers read 32 or 64 bit at once and could read over the end
* @param bit_size the size of the buffer in bits * @param bit_size the size of the buffer in bits
* *
@ -504,7 +504,7 @@ void free_vlc(VLC *vlc);
/** /**
* parses a vlc code, faster then get_vlc() * parses a vlc code, faster than get_vlc()
* @param bits is the number of bits which will be read at once, must be * @param bits is the number of bits which will be read at once, must be
* identical to nb_bits in init_vlc() * identical to nb_bits in init_vlc()
* @param max_depth is the number of times bits bits must be read to completely * @param max_depth is the number of times bits bits must be read to completely

View File

@ -1787,7 +1787,7 @@ static av_always_inline void encode_mb(MpegEncContext *s, int motion_x, int moti
static inline void copy_context_before_encode(MpegEncContext *d, MpegEncContext *s, int type){ static inline void copy_context_before_encode(MpegEncContext *d, MpegEncContext *s, int type){
int i; int i;
memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop? memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster than a loop?
/* mpeg1 */ /* mpeg1 */
d->mb_skip_run= s->mb_skip_run; d->mb_skip_run= s->mb_skip_run;
@ -1816,7 +1816,7 @@ static inline void copy_context_after_encode(MpegEncContext *d, MpegEncContext *
int i; int i;
memcpy(d->mv, s->mv, 2*4*2*sizeof(int)); memcpy(d->mv, s->mv, 2*4*2*sizeof(int));
memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop? memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster than a loop?
/* mpeg1 */ /* mpeg1 */
d->mb_skip_run= s->mb_skip_run; d->mb_skip_run= s->mb_skip_run;

View File

@ -198,7 +198,7 @@ static int parse_picture_segment(AVCodecContext *avctx,
/* Make sure the bitmap is not too large */ /* Make sure the bitmap is not too large */
if (avctx->width < width || avctx->height < height) { if (avctx->width < width || avctx->height < height) {
av_log(avctx, AV_LOG_ERROR, "Bitmap dimensions larger then video.\n"); av_log(avctx, AV_LOG_ERROR, "Bitmap dimensions larger than video.\n");
return -1; return -1;
} }

View File

@ -404,7 +404,7 @@ static int udp_open(URLContext *h, const char *uri, int flags)
p = strchr(uri, '?'); p = strchr(uri, '?');
if (p) { if (p) {
if (av_find_info_tag(buf, sizeof(buf), "reuse", p)) { if (av_find_info_tag(buf, sizeof(buf), "reuse", p)) {
char *endptr=NULL; char *endptr = NULL;
s->reuse_socket = strtol(buf, &endptr, 10); s->reuse_socket = strtol(buf, &endptr, 10);
/* assume if no digits were found it is a request to enable it */ /* assume if no digits were found it is a request to enable it */
if (buf == endptr) if (buf == endptr)

View File

@ -2246,11 +2246,7 @@ int av_find_stream_info(AVFormatContext *ic)
for(i=0;i<ic->nb_streams;i++) { for(i=0;i<ic->nb_streams;i++) {
AVCodec *codec; AVCodec *codec;
st = ic->streams[i]; st = ic->streams[i];
if (st->codec->codec_id == CODEC_ID_AAC) {
st->codec->sample_rate = 0;
st->codec->frame_size = 0;
st->codec->channels = 0;
}
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO || if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
/* if(!st->time_base.num) /* if(!st->time_base.num)
@ -2268,13 +2264,6 @@ int av_find_stream_info(AVFormatContext *ic)
assert(!st->codec->codec); assert(!st->codec->codec);
codec = avcodec_find_decoder(st->codec->codec_id); codec = avcodec_find_decoder(st->codec->codec_id);
/* Force decoding of at least one frame of codec data
* this makes sure the codec initializes the channel configuration
* and does not trust the values from the container.
*/
if (codec && codec->capabilities & CODEC_CAP_CHANNEL_CONF)
st->codec->channels = 0;
/* Ensure that subtitle_header is properly set. */ /* Ensure that subtitle_header is properly set. */
if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
&& codec && !st->codec->codec) && codec && !st->codec->codec)
@ -2417,8 +2406,16 @@ int av_find_stream_info(AVFormatContext *ic)
/* if still no information, we try to open the codec and to /* if still no information, we try to open the codec and to
decompress the frame. We try to avoid that in most cases as decompress the frame. We try to avoid that in most cases as
it takes longer and uses more memory. For MPEG-4, we need to it takes longer and uses more memory. For MPEG-4, we need to
decompress for QuickTime. */ decompress for QuickTime.
if (!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st))
If CODEC_CAP_CHANNEL_CONF is set this will force decoding of at
least one frame of codec data, this makes sure the codec initializes
the channel configuration and does not only trust the values from the container.
*/
if (!has_codec_parameters(st->codec) ||
!has_decode_delay_been_guessed(st) ||
(st->codec->codec &&
st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF))
try_decode_frame(st, pkt); try_decode_frame(st, pkt);
st->codec_info_nb_frames++; st->codec_info_nb_frames++;

View File

@ -26,24 +26,28 @@
#define BASE 65521L /* largest prime smaller than 65536 */ #define BASE 65521L /* largest prime smaller than 65536 */
#define DO1(buf) {s1 += *buf++; s2 += s1;} #define DO1(buf) { s1 += *buf++; s2 += s1; }
#define DO4(buf) DO1(buf); DO1(buf); DO1(buf); DO1(buf); #define DO4(buf) DO1(buf); DO1(buf); DO1(buf); DO1(buf);
#define DO16(buf) DO4(buf); DO4(buf); DO4(buf); DO4(buf); #define DO16(buf) DO4(buf); DO4(buf); DO4(buf); DO4(buf);
unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf, unsigned int len) unsigned long av_adler32_update(unsigned long adler, const uint8_t * buf,
unsigned int len)
{ {
unsigned long s1 = adler & 0xffff; unsigned long s1 = adler & 0xffff;
unsigned long s2 = adler >> 16; unsigned long s2 = adler >> 16;
while (len>0) { while (len > 0) {
#if CONFIG_SMALL #if CONFIG_SMALL
while(len>4 && s2 < (1U<<31)){ while (len > 4 && s2 < (1U << 31)) {
DO4(buf); len-=4; DO4(buf);
#else len -= 4;
while(len>16 && s2 < (1U<<31)){
DO16(buf); len-=16;
#endif
} }
#else
while (len > 16 && s2 < (1U << 31)) {
DO16(buf);
len -= 16;
}
#endif
DO1(buf); len--; DO1(buf); len--;
s1 %= BASE; s1 %= BASE;
s2 %= BASE; s2 %= BASE;
@ -52,22 +56,32 @@ unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf, unsigne
} }
#ifdef TEST #ifdef TEST
#include <string.h>
#include "log.h" #include "log.h"
#include "timer.h" #include "timer.h"
#define LEN 7001 #define LEN 7001
volatile int checksum; volatile int checksum;
int main(void){ int main(int argc, char **argv)
{
int i; int i;
char data[LEN]; char data[LEN];
av_log_set_level(AV_LOG_DEBUG); av_log_set_level(AV_LOG_DEBUG);
for(i=0; i<LEN; i++)
data[i]= ((i*i)>>3) + 123*i; for (i = 0; i < LEN; i++)
for(i=0; i<1000; i++){ data[i] = ((i * i) >> 3) + 123 * i;
START_TIMER
checksum= av_adler32_update(1, data, LEN); if (argc > 1 && !strcmp(argv[1], "-t")) {
STOP_TIMER("adler") for (i = 0; i < 1000; i++) {
START_TIMER;
checksum = av_adler32_update(1, data, LEN);
STOP_TIMER("adler");
}
} else {
checksum = av_adler32_update(1, data, LEN);
} }
av_log(NULL, AV_LOG_DEBUG, "%X == 50E6E508\n", checksum);
return 0; av_log(NULL, AV_LOG_DEBUG, "%X (expected 50E6E508)\n", checksum);
return checksum == 0x50e6e508 ? 0 : 1;
} }
#endif #endif

View File

@ -30,13 +30,13 @@ typedef union {
uint8_t u8[16]; uint8_t u8[16];
} av_aes_block; } av_aes_block;
typedef struct AVAES{ typedef struct AVAES {
// Note: round_key[16] is accessed in the init code, but this only // Note: round_key[16] is accessed in the init code, but this only
// overwrites state, which does not matter (see also r7471). // overwrites state, which does not matter (see also r7471).
av_aes_block round_key[15]; av_aes_block round_key[15];
av_aes_block state[2]; av_aes_block state[2];
int rounds; int rounds;
}AVAES; } AVAES;
const int av_aes_size= sizeof(AVAES); const int av_aes_size= sizeof(AVAES);
@ -54,18 +54,34 @@ static uint32_t enc_multbl[4][256];
static uint32_t dec_multbl[4][256]; static uint32_t dec_multbl[4][256];
#endif #endif
static inline void addkey(av_aes_block *dst, const av_aes_block *src, const av_aes_block *round_key){ static inline void addkey(av_aes_block *dst, const av_aes_block *src,
const av_aes_block *round_key)
{
dst->u64[0] = src->u64[0] ^ round_key->u64[0]; dst->u64[0] = src->u64[0] ^ round_key->u64[0];
dst->u64[1] = src->u64[1] ^ round_key->u64[1]; dst->u64[1] = src->u64[1] ^ round_key->u64[1];
} }
static void subshift(av_aes_block s0[2], int s, const uint8_t *box){ static void subshift(av_aes_block s0[2], int s, const uint8_t *box)
av_aes_block *s1= (av_aes_block *)(s0[0].u8 - s); {
av_aes_block *s3= (av_aes_block *)(s0[0].u8 + s); av_aes_block *s1 = (av_aes_block *) (s0[0].u8 - s);
s0[0].u8[0]=box[s0[1].u8[ 0]]; s0[0].u8[ 4]=box[s0[1].u8[ 4]]; s0[0].u8[ 8]=box[s0[1].u8[ 8]]; s0[0].u8[12]=box[s0[1].u8[12]]; av_aes_block *s3 = (av_aes_block *) (s0[0].u8 + s);
s1[0].u8[3]=box[s1[1].u8[ 7]]; s1[0].u8[ 7]=box[s1[1].u8[11]]; s1[0].u8[11]=box[s1[1].u8[15]]; s1[0].u8[15]=box[s1[1].u8[ 3]];
s0[0].u8[2]=box[s0[1].u8[10]]; s0[0].u8[10]=box[s0[1].u8[ 2]]; s0[0].u8[ 6]=box[s0[1].u8[14]]; s0[0].u8[14]=box[s0[1].u8[ 6]]; s0[0].u8[ 0] = box[s0[1].u8[ 0]];
s3[0].u8[1]=box[s3[1].u8[13]]; s3[0].u8[13]=box[s3[1].u8[ 9]]; s3[0].u8[ 9]=box[s3[1].u8[ 5]]; s3[0].u8[ 5]=box[s3[1].u8[ 1]]; s0[0].u8[ 4] = box[s0[1].u8[ 4]];
s0[0].u8[ 8] = box[s0[1].u8[ 8]];
s0[0].u8[12] = box[s0[1].u8[12]];
s1[0].u8[ 3] = box[s1[1].u8[ 7]];
s1[0].u8[ 7] = box[s1[1].u8[11]];
s1[0].u8[11] = box[s1[1].u8[15]];
s1[0].u8[15] = box[s1[1].u8[ 3]];
s0[0].u8[ 2] = box[s0[1].u8[10]];
s0[0].u8[10] = box[s0[1].u8[ 2]];
s0[0].u8[ 6] = box[s0[1].u8[14]];
s0[0].u8[14] = box[s0[1].u8[ 6]];
s3[0].u8[ 1] = box[s3[1].u8[13]];
s3[0].u8[13] = box[s3[1].u8[ 9]];
s3[0].u8[ 9] = box[s3[1].u8[ 5]];
s3[0].u8[ 5] = box[s3[1].u8[ 1]];
} }
static inline int mix_core(uint32_t multbl[][256], int a, int b, int c, int d){ static inline int mix_core(uint32_t multbl[][256], int a, int b, int c, int d){
@ -85,116 +101,134 @@ static inline void mix(av_aes_block state[2], uint32_t multbl[][256], int s1, in
state[0].u32[3] = mix_core(multbl, src[3][0], src[s1-1][1], src[1][2], src[s3-1][3]); state[0].u32[3] = mix_core(multbl, src[3][0], src[s1-1][1], src[1][2], src[s3-1][3]);
} }
static inline void crypt(AVAES *a, int s, const uint8_t *sbox, uint32_t multbl[][256]){ static inline void crypt(AVAES *a, int s, const uint8_t *sbox,
uint32_t multbl[][256])
{
int r; int r;
for(r=a->rounds-1; r>0; r--){ for (r = a->rounds - 1; r > 0; r--) {
mix(a->state, multbl, 3-s, 1+s); mix(a->state, multbl, 3 - s, 1 + s);
addkey(&a->state[1], &a->state[0], &a->round_key[r]); addkey(&a->state[1], &a->state[0], &a->round_key[r]);
} }
subshift(&a->state[0], s, sbox); subshift(&a->state[0], s, sbox);
} }
void av_aes_crypt(AVAES *a, uint8_t *dst_, const uint8_t *src_, int count, uint8_t *iv_, int decrypt){ void av_aes_crypt(AVAES *a, uint8_t *dst_, const uint8_t *src_,
av_aes_block *dst = (av_aes_block *)dst_; int count, uint8_t *iv_, int decrypt)
const av_aes_block *src = (const av_aes_block *)src_; {
av_aes_block *iv = (av_aes_block *)iv_; av_aes_block *dst = (av_aes_block *) dst_;
while(count--){ const av_aes_block *src = (const av_aes_block *) src_;
av_aes_block *iv = (av_aes_block *) iv_;
while (count--) {
addkey(&a->state[1], src, &a->round_key[a->rounds]); addkey(&a->state[1], src, &a->round_key[a->rounds]);
if(decrypt) { if (decrypt) {
crypt(a, 0, inv_sbox, dec_multbl); crypt(a, 0, inv_sbox, dec_multbl);
if(iv){ if (iv) {
addkey(&a->state[0], &a->state[0], iv); addkey(&a->state[0], &a->state[0], iv);
memcpy(iv, src, 16); memcpy(iv, src, 16);
} }
addkey(dst, &a->state[0], &a->round_key[0]); addkey(dst, &a->state[0], &a->round_key[0]);
}else{ } else {
if(iv) addkey(&a->state[1], &a->state[1], iv); if (iv)
crypt(a, 2, sbox, enc_multbl); addkey(&a->state[1], &a->state[1], iv);
crypt(a, 2, sbox, enc_multbl);
addkey(dst, &a->state[0], &a->round_key[0]); addkey(dst, &a->state[0], &a->round_key[0]);
if(iv) memcpy(iv, dst, 16); if (iv)
memcpy(iv, dst, 16);
} }
src++; src++;
dst++; dst++;
} }
} }
static void init_multbl2(uint8_t tbl[1024], const int c[4], const uint8_t *log8, const uint8_t *alog8, const uint8_t *sbox){ static void init_multbl2(uint8_t tbl[1024], const int c[4],
const uint8_t *log8, const uint8_t *alog8,
const uint8_t *sbox)
{
int i, j; int i, j;
for(i=0; i<1024; i++){
int x= sbox[i>>2]; for (i = 0; i < 1024; i++) {
if(x) tbl[i]= alog8[ log8[x] + log8[c[i&3]] ]; int x = sbox[i >> 2];
if (x)
tbl[i] = alog8[log8[x] + log8[c[i & 3]]];
} }
#if !CONFIG_SMALL #if !CONFIG_SMALL
for(j=256; j<1024; j++) for (j = 256; j < 1024; j++)
for(i=0; i<4; i++) for (i = 0; i < 4; i++)
tbl[4*j+i]= tbl[4*j + ((i-1)&3) - 1024]; tbl[4*j + i] = tbl[4*j + ((i - 1) & 3) - 1024];
#endif #endif
} }
// this is based on the reference AES code by Paulo Barreto and Vincent Rijmen // this is based on the reference AES code by Paulo Barreto and Vincent Rijmen
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt) { int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
{
int i, j, t, rconpointer = 0; int i, j, t, rconpointer = 0;
uint8_t tk[8][4]; uint8_t tk[8][4];
int KC= key_bits>>5; int KC = key_bits >> 5;
int rounds= KC + 6; int rounds = KC + 6;
uint8_t log8[256]; uint8_t log8[256];
uint8_t alog8[512]; uint8_t alog8[512];
if(!enc_multbl[FF_ARRAY_ELEMS(enc_multbl)-1][FF_ARRAY_ELEMS(enc_multbl[0])-1]){ if (!enc_multbl[FF_ARRAY_ELEMS(enc_multbl)-1][FF_ARRAY_ELEMS(enc_multbl[0])-1]) {
j=1; j = 1;
for(i=0; i<255; i++){ for (i = 0; i < 255; i++) {
alog8[i]= alog8[i] = alog8[i + 255] = j;
alog8[i+255]= j; log8[j] = i;
log8[j]= i; j ^= j + j;
j^= j+j; if (j > 255)
if(j>255) j^= 0x11B; j ^= 0x11B;
} }
for(i=0; i<256; i++){ for (i = 0; i < 256; i++) {
j= i ? alog8[255-log8[i]] : 0; j = i ? alog8[255 - log8[i]] : 0;
j ^= (j<<1) ^ (j<<2) ^ (j<<3) ^ (j<<4); j ^= (j << 1) ^ (j << 2) ^ (j << 3) ^ (j << 4);
j = (j ^ (j>>8) ^ 99) & 255; j = (j ^ (j >> 8) ^ 99) & 255;
inv_sbox[j]= i; inv_sbox[j] = i;
sbox [i]= j; sbox[i] = j;
} }
init_multbl2(dec_multbl[0], (const int[4]){0xe, 0x9, 0xd, 0xb}, log8, alog8, inv_sbox); init_multbl2(dec_multbl[0], (const int[4]) { 0xe, 0x9, 0xd, 0xb },
init_multbl2(enc_multbl[0], (const int[4]){0x2, 0x1, 0x1, 0x3}, log8, alog8, sbox); log8, alog8, inv_sbox);
init_multbl2(enc_multbl[0], (const int[4]) { 0x2, 0x1, 0x1, 0x3 },
log8, alog8, sbox);
} }
if(key_bits!=128 && key_bits!=192 && key_bits!=256) if (key_bits != 128 && key_bits != 192 && key_bits != 256)
return -1; return -1;
a->rounds= rounds; a->rounds = rounds;
memcpy(tk, key, KC*4); memcpy(tk, key, KC * 4);
for(t= 0; t < (rounds+1)*16;) { for (t = 0; t < (rounds + 1) * 16;) {
memcpy(a->round_key[0].u8+t, tk, KC*4); memcpy(a->round_key[0].u8 + t, tk, KC * 4);
t+= KC*4; t += KC * 4;
for(i = 0; i < 4; i++) for (i = 0; i < 4; i++)
tk[0][i] ^= sbox[tk[KC-1][(i+1)&3]]; tk[0][i] ^= sbox[tk[KC - 1][(i + 1) & 3]];
tk[0][0] ^= rcon[rconpointer++]; tk[0][0] ^= rcon[rconpointer++];
for(j = 1; j < KC; j++){ for (j = 1; j < KC; j++) {
if(KC != 8 || j != KC>>1) if (KC != 8 || j != KC >> 1)
for(i = 0; i < 4; i++) tk[j][i] ^= tk[j-1][i]; for (i = 0; i < 4; i++)
tk[j][i] ^= tk[j - 1][i];
else else
for(i = 0; i < 4; i++) tk[j][i] ^= sbox[tk[j-1][i]]; for (i = 0; i < 4; i++)
tk[j][i] ^= sbox[tk[j - 1][i]];
} }
} }
if(decrypt){ if (decrypt) {
for(i=1; i<rounds; i++){ for (i = 1; i < rounds; i++) {
av_aes_block tmp[3]; av_aes_block tmp[3];
memcpy(&tmp[2], &a->round_key[i], 16); memcpy(&tmp[2], &a->round_key[i], 16);
subshift(&tmp[1], 0, sbox); subshift(&tmp[1], 0, sbox);
mix(tmp, dec_multbl, 1, 3); mix(tmp, dec_multbl, 1, 3);
memcpy(&a->round_key[i], &tmp[0], 16); memcpy(&a->round_key[i], &tmp[0], 16);
} }
}else{ } else {
for(i=0; i<(rounds+1)>>1; i++){ for (i = 0; i < (rounds + 1) >> 1; i++) {
for(j=0; j<16; j++) for (j = 0; j < 16; j++)
FFSWAP(int, a->round_key[i].u8[j], a->round_key[rounds-i].u8[j]); FFSWAP(int, a->round_key[i].u8[j], a->round_key[rounds-i].u8[j]);
} }
} }
@ -203,53 +237,76 @@ int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt) {
} }
#ifdef TEST #ifdef TEST
#include <string.h>
#include "lfg.h" #include "lfg.h"
#include "log.h" #include "log.h"
int main(void){ int main(int argc, char **argv)
int i,j; {
AVAES ae, ad, b; int i, j;
uint8_t rkey[2][16]= { AVAES b;
{0}, uint8_t rkey[2][16] = {
{0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3, 0x74, 0xcf, 0x86, 0x7c, 0xfb, 0x47, 0x38, 0x59}}; { 0 },
{ 0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3,
0x74, 0xcf, 0x86, 0x7c, 0xfb, 0x47, 0x38, 0x59 }
};
uint8_t pt[16], rpt[2][16]= { uint8_t pt[16], rpt[2][16]= {
{0x6a, 0x84, 0x86, 0x7c, 0xd7, 0x7e, 0x12, 0xad, 0x07, 0xea, 0x1b, 0xe8, 0x95, 0xc5, 0x3f, 0xa3}, { 0x6a, 0x84, 0x86, 0x7c, 0xd7, 0x7e, 0x12, 0xad,
{0}}; 0x07, 0xea, 0x1b, 0xe8, 0x95, 0xc5, 0x3f, 0xa3 },
{ 0 }
};
uint8_t rct[2][16]= { uint8_t rct[2][16]= {
{0x73, 0x22, 0x81, 0xc0, 0xa0, 0xaa, 0xb8, 0xf7, 0xa5, 0x4a, 0x0c, 0x67, 0xa0, 0xc4, 0x5e, 0xcf}, { 0x73, 0x22, 0x81, 0xc0, 0xa0, 0xaa, 0xb8, 0xf7,
{0x6d, 0x25, 0x1e, 0x69, 0x44, 0xb0, 0x51, 0xe0, 0x4e, 0xaa, 0x6f, 0xb4, 0xdb, 0xf7, 0x84, 0x65}}; 0xa5, 0x4a, 0x0c, 0x67, 0xa0, 0xc4, 0x5e, 0xcf },
{ 0x6d, 0x25, 0x1e, 0x69, 0x44, 0xb0, 0x51, 0xe0,
0x4e, 0xaa, 0x6f, 0xb4, 0xdb, 0xf7, 0x84, 0x65 }
};
uint8_t temp[16]; uint8_t temp[16];
AVLFG prng; int err = 0;
av_aes_init(&ae, "PI=3.141592654..", 128, 0);
av_aes_init(&ad, "PI=3.141592654..", 128, 1);
av_log_set_level(AV_LOG_DEBUG); av_log_set_level(AV_LOG_DEBUG);
av_lfg_init(&prng, 1);
for(i=0; i<2; i++){ for (i = 0; i < 2; i++) {
av_aes_init(&b, rkey[i], 128, 1); av_aes_init(&b, rkey[i], 128, 1);
av_aes_crypt(&b, temp, rct[i], 1, NULL, 1); av_aes_crypt(&b, temp, rct[i], 1, NULL, 1);
for(j=0; j<16; j++) for (j = 0; j < 16; j++) {
if(rpt[i][j] != temp[j]) if (rpt[i][j] != temp[j]) {
av_log(NULL, AV_LOG_ERROR, "%d %02X %02X\n", j, rpt[i][j], temp[j]); av_log(NULL, AV_LOG_ERROR, "%d %02X %02X\n",
} j, rpt[i][j], temp[j]);
err = 1;
for(i=0; i<10000; i++){
for(j=0; j<16; j++){
pt[j] = av_lfg_get(&prng);
}
{START_TIMER
av_aes_crypt(&ae, temp, pt, 1, NULL, 0);
if(!(i&(i-1)))
av_log(NULL, AV_LOG_ERROR, "%02X %02X %02X %02X\n", temp[0], temp[5], temp[10], temp[15]);
av_aes_crypt(&ad, temp, temp, 1, NULL, 1);
STOP_TIMER("aes")}
for(j=0; j<16; j++){
if(pt[j] != temp[j]){
av_log(NULL, AV_LOG_ERROR, "%d %d %02X %02X\n", i,j, pt[j], temp[j]);
} }
} }
} }
return 0;
if (argc > 1 && !strcmp(argv[1], "-t")) {
AVAES ae, ad;
AVLFG prng;
av_aes_init(&ae, "PI=3.141592654..", 128, 0);
av_aes_init(&ad, "PI=3.141592654..", 128, 1);
av_lfg_init(&prng, 1);
for (i = 0; i < 10000; i++) {
for (j = 0; j < 16; j++) {
pt[j] = av_lfg_get(&prng);
}
{
START_TIMER;
av_aes_crypt(&ae, temp, pt, 1, NULL, 0);
if (!(i & (i - 1)))
av_log(NULL, AV_LOG_ERROR, "%02X %02X %02X %02X\n",
temp[0], temp[5], temp[10], temp[15]);
av_aes_crypt(&ad, temp, temp, 1, NULL, 1);
STOP_TIMER("aes");
}
for (j = 0; j < 16; j++) {
if (pt[j] != temp[j]) {
av_log(NULL, AV_LOG_ERROR, "%d %d %02X %02X\n",
i, j, pt[j], temp[j]);
}
}
}
}
return err;
} }
#endif #endif

View File

@ -44,32 +44,45 @@ int av_get_cpu_flags(void)
#undef printf #undef printf
#include <stdio.h> #include <stdio.h>
static const struct {
int flag;
const char *name;
} cpu_flag_tab[] = {
#if ARCH_ARM
{ AV_CPU_FLAG_IWMMXT, "iwmmxt" },
#elif ARCH_PPC
{ AV_CPU_FLAG_ALTIVEC, "altivec" },
#elif ARCH_X86
{ AV_CPU_FLAG_MMX, "mmx" },
{ AV_CPU_FLAG_MMX2, "mmx2" },
{ AV_CPU_FLAG_SSE, "sse" },
{ AV_CPU_FLAG_SSE2, "sse2" },
{ AV_CPU_FLAG_SSE2SLOW, "sse2(slow)" },
{ AV_CPU_FLAG_SSE3, "sse3" },
{ AV_CPU_FLAG_SSE3SLOW, "sse3(slow)" },
{ AV_CPU_FLAG_SSSE3, "ssse3" },
{ AV_CPU_FLAG_ATOM, "atom" },
{ AV_CPU_FLAG_SSE4, "sse4.1" },
{ AV_CPU_FLAG_SSE42, "sse4.2" },
{ AV_CPU_FLAG_AVX, "avx" },
{ AV_CPU_FLAG_3DNOW, "3dnow" },
{ AV_CPU_FLAG_3DNOWEXT, "3dnowext" },
#endif
{ 0 }
};
int main(void) int main(void)
{ {
int cpu_flags = av_get_cpu_flags(); int cpu_flags = av_get_cpu_flags();
int i;
printf("cpu_flags = 0x%08X\n", cpu_flags); printf("cpu_flags = 0x%08X\n", cpu_flags);
printf("cpu_flags = %s%s%s%s%s%s%s%s%s%s%s%s%s\n", printf("cpu_flags =");
#if ARCH_ARM for (i = 0; cpu_flag_tab[i].flag; i++)
cpu_flags & AV_CPU_FLAG_IWMMXT ? "IWMMXT " : "", if (cpu_flags & cpu_flag_tab[i].flag)
#elif ARCH_PPC printf(" %s", cpu_flag_tab[i].name);
cpu_flags & AV_CPU_FLAG_ALTIVEC ? "ALTIVEC " : "", printf("\n");
#elif ARCH_X86
cpu_flags & AV_CPU_FLAG_MMX ? "MMX " : "",
cpu_flags & AV_CPU_FLAG_MMX2 ? "MMX2 " : "",
cpu_flags & AV_CPU_FLAG_SSE ? "SSE " : "",
cpu_flags & AV_CPU_FLAG_SSE2 ? "SSE2 " : "",
cpu_flags & AV_CPU_FLAG_SSE2SLOW ? "SSE2(slow) " : "",
cpu_flags & AV_CPU_FLAG_SSE3 ? "SSE3 " : "",
cpu_flags & AV_CPU_FLAG_SSE3SLOW ? "SSE3(slow) " : "",
cpu_flags & AV_CPU_FLAG_SSSE3 ? "SSSE3 " : "",
cpu_flags & AV_CPU_FLAG_ATOM ? "Atom " : "",
cpu_flags & AV_CPU_FLAG_SSE4 ? "SSE4.1 " : "",
cpu_flags & AV_CPU_FLAG_SSE42 ? "SSE4.2 " : "",
cpu_flags & AV_CPU_FLAG_AVX ? "AVX " : "",
cpu_flags & AV_CPU_FLAG_3DNOW ? "3DNow " : "",
cpu_flags & AV_CPU_FLAG_3DNOWEXT ? "3DNowExt " : "");
#endif
return 0; return 0;
} }

View File

@ -603,14 +603,14 @@ typedef struct TestContext
#define TEST_FLAG_MU 04 #define TEST_FLAG_MU 04
static const AVOption test_options[]= { static const AVOption test_options[]= {
{"num", "set num", OFFSET(num), FF_OPT_TYPE_INT, 0, 0, 100 }, {"num", "set num", OFFSET(num), FF_OPT_TYPE_INT, {0}, 0, 100 },
{"toggle", "set toggle", OFFSET(toggle), FF_OPT_TYPE_INT, 0, 0, 1 }, {"toggle", "set toggle", OFFSET(toggle), FF_OPT_TYPE_INT, {0}, 0, 1 },
{"rational", "set rational", OFFSET(rational), FF_OPT_TYPE_RATIONAL, 0, 0, 10 }, {"rational", "set rational", OFFSET(rational), FF_OPT_TYPE_RATIONAL, {0}, 0, 10 },
{"string", "set string", OFFSET(string), FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX }, {"string", "set string", OFFSET(string), FF_OPT_TYPE_STRING, {0}, CHAR_MIN, CHAR_MAX },
{"flags", "set flags", OFFSET(flags), FF_OPT_TYPE_FLAGS, 0, 0, INT_MAX, 0, "flags" }, {"flags", "set flags", OFFSET(flags), FF_OPT_TYPE_FLAGS, {0}, 0, INT_MAX, 0, "flags" },
{"cool", "set cool flag ", 0, FF_OPT_TYPE_CONST, TEST_FLAG_COOL, INT_MIN, INT_MAX, 0, "flags" }, {"cool", "set cool flag ", 0, FF_OPT_TYPE_CONST, {TEST_FLAG_COOL}, INT_MIN, INT_MAX, 0, "flags" },
{"lame", "set lame flag ", 0, FF_OPT_TYPE_CONST, TEST_FLAG_LAME, INT_MIN, INT_MAX, 0, "flags" }, {"lame", "set lame flag ", 0, FF_OPT_TYPE_CONST, {TEST_FLAG_LAME}, INT_MIN, INT_MAX, 0, "flags" },
{"mu", "set mu flag ", 0, FF_OPT_TYPE_CONST, TEST_FLAG_MU, INT_MIN, INT_MAX, 0, "flags" }, {"mu", "set mu flag ", 0, FF_OPT_TYPE_CONST, {TEST_FLAG_MU}, INT_MIN, INT_MAX, 0, "flags" },
{NULL}, {NULL},
}; };

View File

@ -988,7 +988,7 @@ yuv2rgb_write(uint8_t *_dest, int i, int Y1, int Y2,
const uint32_t *b = (const uint32_t *) _b; const uint32_t *b = (const uint32_t *) _b;
#if CONFIG_SMALL #if CONFIG_SMALL
int sh = hasAlpha ? ((fmt == PIX_FMT_RGB32_1 || fmt == PIX_FMT_BGR32_1) ? 0 : 24) : 0; int sh = hasAlpha ? ((target == PIX_FMT_RGB32_1 || target == PIX_FMT_BGR32_1) ? 0 : 24) : 0;
dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (hasAlpha ? A1 << sh : 0); dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (hasAlpha ? A1 << sh : 0);
dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (hasAlpha ? A2 << sh : 0); dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (hasAlpha ? A2 << sh : 0);

View File

@ -1,12 +1,5 @@
fulltest test: codectest lavftest lavfitest seektest
FFSERVER_REFFILE = $(SRC_PATH)/tests/ffserver.regression.ref FFSERVER_REFFILE = $(SRC_PATH)/tests/ffserver.regression.ref
codectest: fate-codec
lavftest: fate-lavf
lavfitest: fate-lavfi
seektest: fate-seek
AREF = fate-acodec-aref AREF = fate-acodec-aref
VREF = fate-vsynth1-vref fate-vsynth2-vref VREF = fate-vsynth1-vref fate-vsynth2-vref
REFS = $(AREF) $(VREF) REFS = $(AREF) $(VREF)
@ -120,4 +113,4 @@ testclean:
-include $(wildcard tests/*.d) -include $(wildcard tests/*.d)
.PHONY: fate* *test .PHONY: fate*

View File

@ -217,6 +217,20 @@ FATE_TESTS += fate-sha
fate-sha: libavutil/sha-test$(EXESUF) fate-sha: libavutil/sha-test$(EXESUF)
fate-sha: CMD = run libavutil/sha-test fate-sha: CMD = run libavutil/sha-test
FATE_TESTS += fate-adler32
fate-adler32: libavutil/adler32-test$(EXESUF)
fate-adler32: CMD = run libavutil/adler32-test
fate-adler32: REF = /dev/null
FATE_TESTS += fate-aes
fate-aes: libavutil/aes-test$(EXESUF)
fate-aes: CMD = run libavutil/aes-test
fate-aes: REF = /dev/null
FATE_TESTS += fate-base64
fate-base64: libavutil/base64-test$(EXESUF)
fate-base64: CMD = run libavutil/base64-test
FATE_TESTS += fate-musepack7 FATE_TESTS += fate-musepack7
fate-musepack7: CMD = pcm -i $(SAMPLES)/musepack/inside-mp7.mpc fate-musepack7: CMD = pcm -i $(SAMPLES)/musepack/inside-mp7.mpc
fate-musepack7: CMP = oneoff fate-musepack7: CMP = oneoff

9
tests/ref/fate/base64 Normal file
View File

@ -0,0 +1,9 @@
Encoding/decoding tests
Passed!
Passed!
Passed!
Passed!
Passed!
Passed!
Passed!
Passed!