diff options
-rw-r--r-- | Makefile | 1 | ||||
-rwxr-xr-x | configure | 10 | ||||
-rw-r--r-- | etc/codecs.conf | 39 | ||||
-rw-r--r-- | libmpcodecs/ad_imaadpcm.c | 14 | ||||
-rw-r--r-- | libmpcodecs/ad_msadpcm.c | 73 | ||||
-rw-r--r-- | libmpcodecs/dec_audio.c | 2 | ||||
-rw-r--r-- | libmpdemux/asfheader.c | 6 | ||||
-rw-r--r-- | libmpdemux/demux_audio.c | 21 | ||||
-rw-r--r-- | libmpdemux/demux_lavf.c | 2 | ||||
-rw-r--r-- | libmpdemux/demux_mov.c | 55 | ||||
-rw-r--r-- | libswscale/Makefile | 2 | ||||
-rw-r--r-- | libswscale/swscale.c | 39 | ||||
-rw-r--r-- | libswscale/swscale_avoption.c | 59 | ||||
-rw-r--r-- | libswscale/swscale_internal.h | 2 | ||||
-rw-r--r-- | libswscale/yuv2rgb_altivec.c | 40 | ||||
-rw-r--r-- | stream/stream_dvd.c | 2 | ||||
-rw-r--r-- | stream/stream_dvdnav.c | 2 |
17 files changed, 215 insertions, 154 deletions
@@ -777,6 +777,7 @@ version.h: ./version.sh `$(CC) -dumpversion` %(EXESUF): %.c +%.o: %.d @@ -2410,7 +2410,7 @@ echocheck ".align is a power of two" if test "$_asmalign_pot" = auto ; then _asmalign_pot=no cat > $TMPC << EOF -main(void) { asm (".align 3"); } +int main(void) { asm (".align 3"); } EOF cc_check && _asmalign_pot=yes fi @@ -2459,7 +2459,7 @@ EOF cat > $TMPC << EOF $inc_altivec_h #define AVV(x...) {x} -int main (void) { (vector int) AVV(1); return 0; } +int main(void) { (vector int) AVV(1); return 0; } EOF cc_check $_altivec_gcc_flags && _def_altivec_vector_braces='#define HAVE_ALTIVEC_VECTOR_BRACES 1' @@ -6483,7 +6483,7 @@ echocheck "libamr narrowband" if test "$_libamr_nb" = auto ; then _libamr_nb=no cat > $TMPC << EOF -#include <amrnb/interf_dec.h> +#include <amrnb/sp_dec.h> int main(void) { Speech_Decode_Frame_init(); return 0; } EOF cc_check -lamrnb && _libamr_nb=yes @@ -7816,8 +7816,8 @@ HAVE_XVMC = $_xvmc DEPEND_CMD = \$(CC) -MM \$(CFLAGS) \$(filter-out %.h,\$^) | sed "s,[0-9a-z._-]*: \(\$(SRC_DIR)/\)*\([a-z0-9]*/\)[^/]* ,\\2&," -MPDEPEND_CMD = \$(CC) -MM \$(CFLAGS) \$(filter-out %.h,$^) | sed -e "s,[0-9a-z._-]*: \([a-z0-9/]*/\)[^/]* ,\1&," -e "s,\(.*\)\.o: ,\1.d &," -MPDEPEND_CMD_CXX = \$(CC) -MM \$(CXXFLAGS) \$(filter-out %.h,$^) | sed -e "s,[0-9a-z._-]*: \([a-z0-9/]*/\)[^/]* ,\1&," -e "s,\(.*\)\.o: ,\1.d &," +MPDEPEND_CMD = \$(CC) -MM \$(CFLAGS) \$(filter-out %.h,$^) | sed -e "s,[0-9a-z._-]*: \([a-z0-9/]*/\)[^/]* ,\1&," +MPDEPEND_CMD_CXX = \$(CC) -MM \$(CXXFLAGS) \$(filter-out %.h,$^) | sed -e "s,[0-9a-z._-]*: \([a-z0-9/]*/\)[^/]* ,\1&," EOF diff --git a/etc/codecs.conf b/etc/codecs.conf index f6ad1812bd..5e3847d243 100644 --- a/etc/codecs.conf +++ b/etc/codecs.conf @@ -2729,6 +2729,21 @@ audiocodec ffadpcmimaamv driver ffmpeg dll adpcm_ima_amv +audiocodec ffadpcmimaqt + info "FFmpeg QT IMA ADPCM audio" + status working + format 0x34616d69 ; "ima4" (MOV files) + driver ffmpeg + dll adpcm_ima_qt + +audiocodec ffadpcmimawav + info "FFmpeg WAV IMA ADPCM audio" + status working + format 0x11 + format 0x1100736d ; "ms\x00\x11" (MOV files) + driver ffmpeg + dll adpcm_ima_wav + audiocodec imaadpcm info "IMA ADPCM" status working @@ -2737,6 +2752,14 @@ audiocodec imaadpcm format 0x1100736d ; "ms\x00\x11" (MOV files) driver imaadpcm +audiocodec ffadpcmms + info "FFmpeg MS ADPCM audio" + status working + format 0x2 + format 0x0200736d ; "ms\x00\x02" (MOV files) + driver ffmpeg + dll adpcm_ms + audiocodec msadpcm info "MS ADPCM" status working @@ -2744,6 +2767,14 @@ audiocodec msadpcm format 0x0200736d ; "ms\x00\x02" (MOV files) driver msadpcm +audiocodec ffadpcmimadk4 + info "FFmpeg DK4 IMA ADPCM audio" + status working + format 0x61 ; This format number was used by Duck Corp. but not officially + ; registered with Microsoft + driver ffmpeg + dll adpcm_ima_dk4 + audiocodec dk4adpcm info "Duck DK4 ADPCM (rogue format number)" status working @@ -2751,6 +2782,14 @@ audiocodec dk4adpcm ; registered with Microsoft driver imaadpcm +audiocodec ffadpcmimadk3 + info "FFmpeg DK3 IMA ADPCM audio" + status working + format 0x62 ; This format number was used by Duck Corp. but not officially + ; registered with Microsoft + driver ffmpeg + dll adpcm_ima_dk3 + audiocodec dk3adpcm info "Duck DK3 ADPCM (rogue format number)" status working diff --git a/libmpcodecs/ad_imaadpcm.c b/libmpcodecs/ad_imaadpcm.c index c2b7379db7..7c7f2362e5 100644 --- a/libmpcodecs/ad_imaadpcm.c +++ b/libmpcodecs/ad_imaadpcm.c @@ -19,6 +19,7 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#include <inttypes.h> #include "config.h" #include "libavutil/common.h" @@ -32,9 +33,7 @@ #define QT_IMA_ADPCM_SAMPLES_PER_BLOCK 64 #define BE_16(x) (be2me_16(*(unsigned short *)(x))) -#define BE_32(x) (be2me_32(*(unsigned int *)(x))) #define LE_16(x) (le2me_16(*(unsigned short *)(x))) -#define LE_32(x) (le2me_32(*(unsigned int *)(x))) // pertinent tables for IMA ADPCM static const int16_t adpcm_step[89] = @@ -62,8 +61,6 @@ static const int8_t adpcm_index[8] = #define CLAMP_S16(x) x = av_clip_int16(x); // clamp a number above 16 #define CLAMP_ABOVE_16(x) if (x < 16) x = 16; -// sign extend a 4-bit value -#define SE_4BIT(x) if (x & 0x8) x -= 0x10; static const ad_info_t info = { @@ -170,7 +167,7 @@ static int qt_ima_adpcm_decode_block(unsigned short *output, int initial_index[2]; int i; - if (channels > 1) channels = 2; + if (channels != 1) channels = 2; if (block_size < channels * QT_IMA_ADPCM_BLOCK_SIZE) return -1; @@ -220,7 +217,7 @@ static int ms_ima_adpcm_decode_block(unsigned short *output, int channel_index_l; int channel_index_r; - if (channels > 1) channels = 2; + if (channels != 1) channels = 2; if (block_size < MS_IMA_ADPCM_PREAMBLE_SIZE * channels) return -1; @@ -283,7 +280,7 @@ static int dk4_ima_adpcm_decode_block(unsigned short *output, int predictor[2]; int index[2]; - if (channels > 1) channels = 2; + if (channels != 1) channels = 2; if (block_size < MS_IMA_ADPCM_PREAMBLE_SIZE * channels) return -1; @@ -324,6 +321,5 @@ static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int m res = decode_func((unsigned short*)buf, sh_audio->a_in_buffer, sh_audio->wf->nChannels, sh_audio->ds->ss_mul); - if (res < 0) return res; - else return 2 * res; + return res < 0 ? res : 2 * res; } diff --git a/libmpcodecs/ad_msadpcm.c b/libmpcodecs/ad_msadpcm.c index 72f5b47284..641992e18d 100644 --- a/libmpcodecs/ad_msadpcm.c +++ b/libmpcodecs/ad_msadpcm.c @@ -12,6 +12,8 @@ #include <unistd.h> #include "config.h" +#include "libavutil/common.h" +#include "libavutil/intreadwrite.h" #include "mpbswap.h" #include "ad_internal.h" @@ -26,39 +28,32 @@ static const ad_info_t info = LIBAD_EXTERN(msadpcm) -static int ms_adapt_table[] = +static const int ms_adapt_table[] = { 230, 230, 230, 230, 307, 409, 512, 614, 768, 614, 512, 409, 307, 230, 230, 230 }; -static int ms_adapt_coeff1[] = +static const uint8_t ms_adapt_coeff1[] = { - 256, 512, 0, 192, 240, 460, 392 + 64, 128, 0, 48, 60, 115, 98 }; -static int ms_adapt_coeff2[] = +static const int8_t ms_adapt_coeff2[] = { - 0, -256, 0, 64, 0, -208, -232 + 0, -64, 0, 16, 0, -52, -58 }; #define MS_ADPCM_PREAMBLE_SIZE 6 -#define LE_16(x) ((x)[0]+(256*((x)[1]))) -//#define LE_16(x) (le2me_16((x)[1]+(256*((x)[0])))) -//#define LE_16(x) (le2me_16(*(unsigned short *)(x))) -//#define LE_32(x) (le2me_32(*(unsigned int *)(x))) +#define LE_16(x) ((int16_t)AV_RL16(x)) -// useful macros // clamp a number between 0 and 88 -#define CLAMP_0_TO_88(x) if (x < 0) x = 0; else if (x > 88) x = 88; +#define CLAMP_0_TO_88(x) x = av_clip(x, 0, 88); // clamp a number within a signed 16-bit range -#define CLAMP_S16(x) if (x < -32768) x = -32768; \ - else if (x > 32767) x = 32767; +#define CLAMP_S16(x) x = av_clip_int16(x); // clamp a number above 16 #define CLAMP_ABOVE_16(x) if (x < 16) x = 16; -// sign extend a 16-bit value -#define SE_16BIT(x) if (x & 0x8000) x -= 0x10000; // sign extend a 4-bit value #define SE_4BIT(x) if (x & 0x8) x -= 0x10; @@ -96,10 +91,21 @@ static int control(sh_audio_t *sh_audio,int cmd,void* arg, ...) return CONTROL_UNKNOWN; } +static inline int check_coeff(uint8_t c) { + if (c > 6) { + mp_msg(MSGT_DECAUDIO, MSGL_WARN, + "MS ADPCM: coefficient (%d) out of range (should be [0..6])\n", + c); + c = 6; + } + return c; +} + static int ms_adpcm_decode_block(unsigned short *output, unsigned char *input, int channels, int block_size) { int current_channel = 0; + int coeff_idx; int idelta[2]; int sample1[2]; int sample2[2]; @@ -112,53 +118,45 @@ static int ms_adpcm_decode_block(unsigned short *output, unsigned char *input, int snibble; // signed nibble int predictor; + if (channels != 1) channels = 2; + if (block_size < 7 * channels) + return -1; + // fetch the header information, in stereo if both channels are present - if (input[stream_ptr] > 6) - mp_msg(MSGT_DECAUDIO, MSGL_WARN, - "MS ADPCM: coefficient (%d) out of range (should be [0..6])\n", - input[stream_ptr]); - coeff1[0] = ms_adapt_coeff1[input[stream_ptr]]; - coeff2[0] = ms_adapt_coeff2[input[stream_ptr]]; + coeff_idx = check_coeff(input[stream_ptr]); + coeff1[0] = ms_adapt_coeff1[coeff_idx]; + coeff2[0] = ms_adapt_coeff2[coeff_idx]; stream_ptr++; if (channels == 2) { - if (input[stream_ptr] > 6) - mp_msg(MSGT_DECAUDIO, MSGL_WARN, - "MS ADPCM: coefficient (%d) out of range (should be [0..6])\n", - input[stream_ptr]); - coeff1[1] = ms_adapt_coeff1[input[stream_ptr]]; - coeff2[1] = ms_adapt_coeff2[input[stream_ptr]]; + coeff_idx = check_coeff(input[stream_ptr]); + coeff1[1] = ms_adapt_coeff1[coeff_idx]; + coeff2[1] = ms_adapt_coeff2[coeff_idx]; stream_ptr++; } idelta[0] = LE_16(&input[stream_ptr]); stream_ptr += 2; - SE_16BIT(idelta[0]); if (channels == 2) { idelta[1] = LE_16(&input[stream_ptr]); stream_ptr += 2; - SE_16BIT(idelta[1]); } sample1[0] = LE_16(&input[stream_ptr]); stream_ptr += 2; - SE_16BIT(sample1[0]); if (channels == 2) { sample1[1] = LE_16(&input[stream_ptr]); stream_ptr += 2; - SE_16BIT(sample1[1]); } sample2[0] = LE_16(&input[stream_ptr]); stream_ptr += 2; - SE_16BIT(sample2[0]); if (channels == 2) { sample2[1] = LE_16(&input[stream_ptr]); stream_ptr += 2; - SE_16BIT(sample2[1]); } if (channels == 1) @@ -182,9 +180,12 @@ static int ms_adpcm_decode_block(unsigned short *output, unsigned char *input, upper_nibble ^= 1; SE_4BIT(snibble); + // should this really be a division and not a shift? + // coefficients were originally scaled by for, which might have + // been an optimization for 8-bit CPUs _if_ a shift is correct predictor = ( ((sample1[current_channel] * coeff1[current_channel]) + - (sample2[current_channel] * coeff2[current_channel])) / 256) + + (sample2[current_channel] * coeff2[current_channel])) / 64) + (snibble * idelta[current_channel]); CLAMP_S16(predictor); sample2[current_channel] = sample1[current_channel]; @@ -205,12 +206,14 @@ static int ms_adpcm_decode_block(unsigned short *output, unsigned char *input, static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) { + int res; if (demux_read_data(sh_audio->ds, sh_audio->a_in_buffer, sh_audio->ds->ss_mul) != sh_audio->ds->ss_mul) return -1; /* EOF */ - return 2 * ms_adpcm_decode_block( + res = ms_adpcm_decode_block( (unsigned short*)buf, sh_audio->a_in_buffer, sh_audio->wf->nChannels, sh_audio->wf->nBlockAlign); + return res < 0 ? res : 2 * res; } diff --git a/libmpcodecs/dec_audio.c b/libmpcodecs/dec_audio.c index d20071b36f..252f6a1cb3 100644 --- a/libmpcodecs/dec_audio.c +++ b/libmpcodecs/dec_audio.c @@ -423,7 +423,7 @@ int decode_audio(sh_audio_t *sh_audio, int minlen) // Indicates that a filter seems to be buffering large amounts of data int huge_filter_buffer = 0; // Decoded audio must be cut at boundaries of this many bytes - int unitsize = sh_audio->channels * sh_audio->samplesize; + int unitsize = sh_audio->channels * sh_audio->samplesize * 16; /* Filter output size will be about filter_multiplier times input size. * If some filter buffers audio in big blocks this might only hold diff --git a/libmpdemux/asfheader.c b/libmpdemux/asfheader.c index 3c91762f9c..0228dc87f9 100644 --- a/libmpdemux/asfheader.c +++ b/libmpdemux/asfheader.c @@ -591,24 +591,24 @@ int read_asf_header(demuxer_t *demuxer,struct asf_priv* asf){ // find content header pos = find_asf_guid(hdr, asf_stream_group_guid, 0, hdr_len); if (pos >= 0) { + int max_streams = (hdr_len - pos - 2) / 6; uint16_t stream_id, i; uint32_t max_bitrate; char *ptr = &hdr[pos]; mp_msg(MSGT_HEADER,MSGL_V,"============ ASF Stream group == START ===\n"); + if(max_streams <= 0) goto len_err_out; stream_count = AV_RL16(ptr); ptr += sizeof(uint16_t); - if (ptr > &hdr[hdr_len]) goto len_err_out; + if(stream_count > max_streams) stream_count = max_streams; if(stream_count > 0) streams = malloc(2*stream_count*sizeof(uint32_t)); mp_msg(MSGT_HEADER,MSGL_V," stream count=[0x%x][%u]\n", stream_count, stream_count ); for( i=0 ; i<stream_count ; i++ ) { stream_id = AV_RL16(ptr); ptr += sizeof(uint16_t); - if (ptr > &hdr[hdr_len]) goto len_err_out; memcpy(&max_bitrate, ptr, sizeof(uint32_t));// workaround unaligment bug on sparc max_bitrate = le2me_32(max_bitrate); ptr += sizeof(uint32_t); - if (ptr > &hdr[hdr_len]) goto len_err_out; mp_msg(MSGT_HEADER,MSGL_V," stream id=[0x%x][%u]\n", stream_id, stream_id ); mp_msg(MSGT_HEADER,MSGL_V," max bitrate=[0x%x][%u]\n", max_bitrate, max_bitrate ); streams[2*i] = stream_id; diff --git a/libmpdemux/demux_audio.c b/libmpdemux/demux_audio.c index 269fa23539..99691ecef0 100644 --- a/libmpdemux/demux_audio.c +++ b/libmpdemux/demux_audio.c @@ -329,7 +329,7 @@ static int demux_audio_open(demuxer_t* demuxer) { sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec; free(mp3_found); mp3_found = NULL; - if(s->end_pos) { + if(s->end_pos && (s->flags & STREAM_SEEK) == STREAM_SEEK) { char tag[4]; stream_seek(s,s->end_pos-128); stream_read(s,tag,3); @@ -390,20 +390,17 @@ static int demux_audio_open(demuxer_t* demuxer) { w->cbSize = 0; sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec; l -= 16; - if (l > 0) { - w->cbSize = stream_read_word_le(s); - l -= 2; - if (w->cbSize > 0) { + if (l >= 2) { + w->cbSize = stream_read_word_le(s); + if (w->cbSize < 0) w->cbSize = 0; + l -= 2; if (l < w->cbSize) { mp_msg(MSGT_DEMUX,MSGL_ERR,"[demux_audio] truncated extradata (%d < %d)\n", - l,w->cbSize); - stream_read(s,(char*)((char*)(w)+sizeof(WAVEFORMATEX)),l); - l = 0; - } else { - stream_read(s,(char*)((char*)(w)+sizeof(WAVEFORMATEX)),w->cbSize); - l -= w->cbSize; + l,w->cbSize); + w->cbSize = l; } - } + stream_read(s,(char*)((char*)(w)+sizeof(WAVEFORMATEX)),w->cbSize); + l -= w->cbSize; } if( mp_msg_test(MSGT_DEMUX,MSGL_V) ) print_wave_header(w, MSGL_V); diff --git a/libmpdemux/demux_lavf.c b/libmpdemux/demux_lavf.c index 96db00a4ef..be820a24a7 100644 --- a/libmpdemux/demux_lavf.c +++ b/libmpdemux/demux_lavf.c @@ -453,7 +453,7 @@ static demuxer_t* demux_open_lavf(demuxer_t *demuxer){ priv->pb = av_alloc_put_byte(priv->buffer, BIO_BUFFER_SIZE, 0, demuxer->stream, mp_read, NULL, mp_seek); - priv->pb->is_streamed = !demuxer->stream->end_pos; + priv->pb->is_streamed = !demuxer->stream->end_pos || (demuxer->stream->flags & STREAM_SEEK) != STREAM_SEEK; if(av_open_input_stream(&avfc, priv->pb, mp_filename, priv->avif, &ap)<0){ mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_open_input_stream() failed\n"); diff --git a/libmpdemux/demux_mov.c b/libmpdemux/demux_mov.c index be23ba479c..1f0358a799 100644 --- a/libmpdemux/demux_mov.c +++ b/libmpdemux/demux_mov.c @@ -169,8 +169,8 @@ void mov_build_index(mov_track_t* trak,int timescale){ i=trak->chunkmap_size; while(i>0){ --i; - j=FFMAX(trak->chunkmap[i].first, 0); - for(;j<last;j++){ + j=trak->chunkmap[i].first; + for(;j>=0 && j<last;j++){ trak->chunks[j].desc=trak->chunkmap[i].sdid; trak->chunks[j].size=trak->chunkmap[i].spc; } @@ -205,9 +205,9 @@ void mov_build_index(mov_track_t* trak,int timescale){ // workaround for fixed-size video frames (dv and uncompressed) if(!trak->samples_size && trak->type!=MOV_TRAK_AUDIO){ - trak->samples_size=s; trak->samples=calloc(s, sizeof(mov_sample_t)); - for(i=0;i<s;i++) + trak->samples_size=trak->samples ? s : 0; + for(i=0;i<trak->samples_size;i++) trak->samples[i].size=trak->samplesize; trak->samplesize=0; } @@ -224,8 +224,8 @@ void mov_build_index(mov_track_t* trak,int timescale){ mp_msg(MSGT_DEMUX, MSGL_WARN, "MOV: durmap or chunkmap bigger than sample count (%i vs %i)\n", s, trak->samples_size); - trak->samples_size = s; trak->samples = realloc_struct(trak->samples, s, sizeof(mov_sample_t)); + trak->samples_size = trak->samples ? s : 0; } // calc pts: @@ -772,6 +772,7 @@ static int gen_sh_audio(sh_audio_t* sh, mov_track_t* trak, int timescale) { } if (trak->stdata_len >= 36 + adjust) { int atom_len = char2int(trak->stdata,28+adjust); + if (atom_len < 0 || atom_len > trak->stdata_len - 28 - adjust) atom_len = trak->stdata_len - 28 - adjust; switch(char2int(trak->stdata,32+adjust)) { // atom type case MOV_FOURCC('e','s','d','s'): { mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found MPEG4 audio Elementary Stream Descriptor atom (%d)!\n", atom_len); @@ -1113,14 +1114,16 @@ static int gen_sh_video(sh_video_t* sh, mov_track_t* trak, int timescale) { sh->disp_w=trak->stdata[25]|(trak->stdata[24]<<8); sh->disp_h=trak->stdata[27]|(trak->stdata[26]<<8); - // if image size is zero, fallback to display size - if(!sh->disp_w && !sh->disp_h) { - sh->disp_w=trak->tkdata[77]|(trak->tkdata[76]<<8); - sh->disp_h=trak->tkdata[81]|(trak->tkdata[80]<<8); - } else if(sh->disp_w!=(trak->tkdata[77]|(trak->tkdata[76]<<8))){ - // codec and display width differ... use display one for aspect - sh->aspect=trak->tkdata[77]|(trak->tkdata[76]<<8); - sh->aspect/=trak->tkdata[81]|(trak->tkdata[80]<<8); + if(trak->tkdata_len>81) { + // if image size is zero, fallback to display size + if(!sh->disp_w && !sh->disp_h) { + sh->disp_w=trak->tkdata[77]|(trak->tkdata[76]<<8); + sh->disp_h=trak->tkdata[81]|(trak->tkdata[80]<<8); + } else if(sh->disp_w!=(trak->tkdata[77]|(trak->tkdata[76]<<8))){ + // codec and display width differ... use display one for aspect + sh->aspect=trak->tkdata[77]|(trak->tkdata[76]<<8); + sh->aspect/=trak->tkdata[81]|(trak->tkdata[80]<<8); + } } if(depth>32+8) mp_msg(MSGT_DEMUX, MSGL_INFO,"*** depth = 0x%X\n",depth); @@ -1748,8 +1751,8 @@ static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id, "MOV: %*sSample duration table! (%d blocks)\n", level, "", len); trak->durmap = calloc(len, sizeof(mov_durmap_t)); - trak->durmap_size = len; - for (i = 0; i < len; i++) { + trak->durmap_size = trak->durmap ? 0 : len; + for (i = 0; i < trak->durmap_size; i++) { trak->durmap[i].num = stream_read_dword(demuxer->stream); trak->durmap[i].dur = stream_read_dword(demuxer->stream); pts += trak->durmap[i].num * trak->durmap[i].dur; @@ -1769,9 +1772,9 @@ static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id, "MOV: %*sSample->Chunk mapping table! (%d blocks) (ver:%d,flags:%d)\n", level, "", len, ver, flags); // read data: - trak->chunkmap_size = len; trak->chunkmap = calloc(len, sizeof(mov_chunkmap_t)); - for (i = 0; i < len; i++) { + trak->chunkmap_size = trak->chunkmap ? len : 0; + for (i = 0; i < trak->chunkmap_size; i++) { trak->chunkmap[i].first = stream_read_dword(demuxer->stream) - 1; trak->chunkmap[i].spc = stream_read_dword(demuxer->stream); trak->chunkmap[i].sdid = stream_read_dword(demuxer->stream); @@ -1793,7 +1796,7 @@ static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id, // variable samplesize trak->samples = realloc_struct(trak->samples, entries, sizeof(mov_sample_t)); trak->samples_size = entries; - for (i = 0; i < entries; i++) + for (i = 0; i < trak->samples_size; i++) trak->samples[i].size = stream_read_dword(demuxer->stream); } break; @@ -1808,10 +1811,10 @@ static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id, // extend array if needed: if (len > trak->chunks_size) { trak->chunks = realloc_struct(trak->chunks, len, sizeof(mov_chunk_t)); - trak->chunks_size = len; + trak->chunks_size = trak->chunks ? len : 0; } // read elements: - for(i = 0; i < len; i++) + for(i = 0; i < trak->chunks_size; i++) trak->chunks[i].pos = stream_read_dword(demuxer->stream); break; } @@ -1825,10 +1828,10 @@ static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id, // extend array if needed: if (len > trak->chunks_size) { trak->chunks = realloc_struct(trak->chunks, len, sizeof(mov_chunk_t)); - trak->chunks_size = len; + trak->chunks_size = trak->chunks ? len : 0; } // read elements: - for (i = 0; i < len; i++) { + for (i = 0; i < trak->chunks_size; i++) { #ifndef _LARGEFILE_SOURCE if (stream_read_dword(demuxer->stream) != 0) mp_msg(MSGT_DEMUX, MSGL_WARN, "Chunk %d has got 64bit address, but you've MPlayer compiled without LARGEFILE support!\n", i); @@ -1848,9 +1851,9 @@ static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id, mp_msg(MSGT_DEMUX, MSGL_V, "MOV: %*sSyncing samples (keyframes) table! (%d entries) (ver:%d,flags:%d)\n", level, "", entries, ver, flags); - trak->keyframes_size = entries; trak->keyframes = calloc(entries, sizeof(unsigned int)); - for (i = 0; i < entries; i++) + trak->keyframes_size = trak->keyframes ? entries : 0; + for (i = 0; i < trak->keyframes_size; i++) trak->keyframes[i] = stream_read_dword(demuxer->stream) - 1; break; } @@ -1884,9 +1887,9 @@ static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id, "MOV: %*sEdit list table (%d entries) (ver:%d,flags:%d)\n", level, "", entries, ver, flags); #if 1 - trak->editlist_size = entries; trak->editlist = calloc(trak->editlist_size, sizeof(mov_editlist_t)); - for (i = 0; i < entries; i++) { + trak->editlist_size = trak->editlist ? entries : 0; + for (i = 0; i < trak->editlist_size; i++) { int dur = stream_read_dword(demuxer->stream); int mt = stream_read_dword(demuxer->stream); int mr = stream_read_dword(demuxer->stream); // 16.16fp diff --git a/libswscale/Makefile b/libswscale/Makefile index f8ed408289..93d27bac09 100644 --- a/libswscale/Makefile +++ b/libswscale/Makefile @@ -3,7 +3,7 @@ include $(SUBDIR)../config.mak NAME = swscale FFLIBS = avutil -OBJS = rgb2rgb.o swscale.o +OBJS = rgb2rgb.o swscale.o swscale_avoption.o OBJS-$(ARCH_BFIN) += swscale_bfin.o yuv2rgb_bfin.o OBJS-$(CONFIG_GPL) += yuv2rgb.o diff --git a/libswscale/swscale.c b/libswscale/swscale.c index faeab7b7c6..60f11d6eb6 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -72,7 +72,6 @@ untested special converters #include "rgb2rgb.h" #include "libavutil/x86_cpu.h" #include "libavutil/bswap.h" -#include "libavcodec/opt.h" #undef MOVNTQ #undef PAVGB @@ -232,44 +231,6 @@ extern const uint8_t dither_8x8_32[8][8]; extern const uint8_t dither_8x8_73[8][8]; extern const uint8_t dither_8x8_220[8][8]; -static const char * sws_context_to_name(void * ptr) { - return "swscaler"; -} - -#define OFFSET(x) offsetof(SwsContext, x) -#define DEFAULT 0 -#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM - -static const AVOption options[] = { - { "sws_flags", "scaler/cpu flags", OFFSET(flags), FF_OPT_TYPE_FLAGS, DEFAULT, 0, UINT_MAX, VE, "sws_flags" }, - { "fast_bilinear", "fast bilinear", 0, FF_OPT_TYPE_CONST, SWS_FAST_BILINEAR, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "bilinear", "bilinear", 0, FF_OPT_TYPE_CONST, SWS_BILINEAR, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "bicubic", "bicubic", 0, FF_OPT_TYPE_CONST, SWS_BICUBIC, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "experimental", "experimental", 0, FF_OPT_TYPE_CONST, SWS_X, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "neighbor", "nearest neighbor", 0, FF_OPT_TYPE_CONST, SWS_POINT, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "area", "averaging area", 0, FF_OPT_TYPE_CONST, SWS_AREA, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "bicublin", "luma bicubic, chroma bilinear", 0, FF_OPT_TYPE_CONST, SWS_BICUBLIN, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "gauss", "gaussian", 0, FF_OPT_TYPE_CONST, SWS_GAUSS, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "sinc", "sinc", 0, FF_OPT_TYPE_CONST, SWS_SINC, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "lanczos", "lanczos", 0, FF_OPT_TYPE_CONST, SWS_LANCZOS, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "spline", "natural bicubic spline", 0, FF_OPT_TYPE_CONST, SWS_SPLINE, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "print_info", "print info", 0, FF_OPT_TYPE_CONST, SWS_PRINT_INFO, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "accurate_rnd", "accurate rounding", 0, FF_OPT_TYPE_CONST, SWS_ACCURATE_RND, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "mmx", "MMX SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_MMX, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "mmx2", "MMX2 SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_MMX2, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "3dnow", "3DNOW SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_3DNOW, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "altivec", "AltiVec SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_ALTIVEC, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "bfin", "Blackfin SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_BFIN, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "full_chroma_int", "full chroma interpolation", 0 , FF_OPT_TYPE_CONST, SWS_FULL_CHR_H_INT, INT_MIN, INT_MAX, VE, "sws_flags" }, - { "full_chroma_inp", "full chroma input", 0 , FF_OPT_TYPE_CONST, SWS_FULL_CHR_H_INP, INT_MIN, INT_MAX, VE, "sws_flags" }, - { NULL } -}; - -#undef VE -#undef DEFAULT - -static const AVClass sws_context_class = { "SWScaler", sws_context_to_name, options }; - const char *sws_format_name(enum PixelFormat format) { switch (format) { diff --git a/libswscale/swscale_avoption.c b/libswscale/swscale_avoption.c new file mode 100644 index 0000000000..1878b4ea8f --- /dev/null +++ b/libswscale/swscale_avoption.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at> + * + * 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 "libavutil/avutil.h" +#include "libavcodec/opt.h" +#include "swscale.h" +#include "swscale_internal.h" + +static const char * sws_context_to_name(void * ptr) { + return "swscaler"; +} + +#define OFFSET(x) offsetof(SwsContext, x) +#define DEFAULT 0 +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM + +static const AVOption options[] = { + { "sws_flags", "scaler/cpu flags", OFFSET(flags), FF_OPT_TYPE_FLAGS, DEFAULT, 0, UINT_MAX, VE, "sws_flags" }, + { "fast_bilinear", "fast bilinear", 0, FF_OPT_TYPE_CONST, SWS_FAST_BILINEAR, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "bilinear", "bilinear", 0, FF_OPT_TYPE_CONST, SWS_BILINEAR, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "bicubic", "bicubic", 0, FF_OPT_TYPE_CONST, SWS_BICUBIC, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "experimental", "experimental", 0, FF_OPT_TYPE_CONST, SWS_X, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "neighbor", "nearest neighbor", 0, FF_OPT_TYPE_CONST, SWS_POINT, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "area", "averaging area", 0, FF_OPT_TYPE_CONST, SWS_AREA, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "bicublin", "luma bicubic, chroma bilinear", 0, FF_OPT_TYPE_CONST, SWS_BICUBLIN, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "gauss", "gaussian", 0, FF_OPT_TYPE_CONST, SWS_GAUSS, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "sinc", "sinc", 0, FF_OPT_TYPE_CONST, SWS_SINC, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "lanczos", "lanczos", 0, FF_OPT_TYPE_CONST, SWS_LANCZOS, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "spline", "natural bicubic spline", 0, FF_OPT_TYPE_CONST, SWS_SPLINE, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "print_info", "print info", 0, FF_OPT_TYPE_CONST, SWS_PRINT_INFO, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "accurate_rnd", "accurate rounding", 0, FF_OPT_TYPE_CONST, SWS_ACCURATE_RND, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "mmx", "MMX SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_MMX, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "mmx2", "MMX2 SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_MMX2, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "3dnow", "3DNOW SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_3DNOW, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "altivec", "AltiVec SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_ALTIVEC, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "bfin", "Blackfin SIMD acceleration", 0, FF_OPT_TYPE_CONST, SWS_CPU_CAPS_BFIN, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "full_chroma_int", "full chroma interpolation", 0 , FF_OPT_TYPE_CONST, SWS_FULL_CHR_H_INT, INT_MIN, INT_MAX, VE, "sws_flags" }, + { "full_chroma_inp", "full chroma input", 0 , FF_OPT_TYPE_CONST, SWS_FULL_CHR_H_INP, INT_MIN, INT_MAX, VE, "sws_flags" }, + { NULL } +}; + +const AVClass sws_context_class = { "SWScaler", sws_context_to_name, options }; diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 45cf738973..e904205475 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -278,4 +278,6 @@ static inline int fmt_depth(int fmt) extern const DECLARE_ALIGNED(8, uint64_t, ff_dither4[2]); extern const DECLARE_ALIGNED(8, uint64_t, ff_dither8[2]); +extern const AVClass sws_context_class; + #endif /* FFMPEG_SWSCALE_INTERNAL_H */ diff --git a/libswscale/yuv2rgb_altivec.c b/libswscale/yuv2rgb_altivec.c index d3b30e7ed5..13b18d10d3 100644 --- a/libswscale/yuv2rgb_altivec.c +++ b/libswscale/yuv2rgb_altivec.c @@ -143,14 +143,14 @@ typedef signed char sbyte; */ static const vector unsigned char - perm_rgb_0 = (const vector unsigned char)AVV(0x00,0x01,0x10,0x02,0x03,0x11,0x04,0x05, - 0x12,0x06,0x07,0x13,0x08,0x09,0x14,0x0a), - perm_rgb_1 = (const |