* qatar/master: (21 commits) build: simplify commands for clean target swscale: split swscale.c in unscaled and generic conversion routines. swscale: cosmetics. swscale: integrate (literally) swscale_template.c in swscale.c. swscale: split out x86/swscale_template.c from swscale.c. swscale: enable hScale_altivec_real. swscale: split out ppc _template.c files from main swscale.c. swscale: remove indirections in ppc/swscale_template.c. swscale: split out unscaled altivec YUV converters in their own file. mpegvideoenc: fix multislice fate tests with threading disabled. mpegts: Wrap #ifdef DEBUG and av_hex_dump_log() combination in a macro. build: Simplify texi2html invocation through the --output option. Mark some variables with av_unused Replace avcodec_get_pix_fmt_name() by av_get_pix_fmt_name(). svq3: Check negative mb_type to fix potential crash. svq3: Move svq3-specific fields to their own context. rawdec: initialize return value to 0. Remove unused get_psnr() prototype rawdec: don't leak option strings. bktr: get default framerate from video standard. ... Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n0.8
| @@ -123,7 +123,7 @@ TEXIDEP = awk '/^@include/ { printf "$@: $(@D)/%s\n", $$2 }' <$< >$(@:%=%.d) | |||
| doc/%.html: TAG = HTML | |||
| doc/%.html: doc/%.texi $(SRC_PATH_BARE)/doc/t2h.init | |||
| $(Q)$(TEXIDEP) | |||
| $(M)cd doc && texi2html -monolithic --init-file $(SRC_PATH_BARE)/doc/t2h.init $(<:doc/%=%) | |||
| $(M)texi2html -monolithic --init-file $(SRC_PATH_BARE)/doc/t2h.init --output $@ $< | |||
| doc/%.pod: TAG = POD | |||
| doc/%.pod: doc/%.texi | |||
| @@ -1208,8 +1208,8 @@ static void do_video_out(AVFormatContext *s, | |||
| av_log(NULL, AV_LOG_INFO, | |||
| "Input stream #%d.%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n", | |||
| ist->file_index, ist->st->index, | |||
| ost->resample_width, ost->resample_height, avcodec_get_pix_fmt_name(ost->resample_pix_fmt), | |||
| dec->width , dec->height , avcodec_get_pix_fmt_name(dec->pix_fmt)); | |||
| ost->resample_width, ost->resample_height, av_get_pix_fmt_name(ost->resample_pix_fmt), | |||
| dec->width , dec->height , av_get_pix_fmt_name(dec->pix_fmt)); | |||
| ost->resample_width = dec->width; | |||
| ost->resample_height = dec->height; | |||
| ost->resample_pix_fmt = dec->pix_fmt; | |||
| @@ -687,11 +687,6 @@ void ff_mlp_init_x86(DSPContext* c, AVCodecContext *avctx); | |||
| # define LOCAL_ALIGNED_16(t, v, ...) LOCAL_ALIGNED(16, t, v, __VA_ARGS__) | |||
| #endif | |||
| /* PSNR */ | |||
| void get_psnr(uint8_t *orig_image[3], uint8_t *coded_image[3], | |||
| int orig_linesize[3], int coded_linesize, | |||
| AVCodecContext *avctx); | |||
| #define WRAPPER8_16(name8, name16)\ | |||
| static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ | |||
| return name8(s, dst , src , stride, h)\ | |||
| @@ -38,6 +38,7 @@ | |||
| * DV codec. | |||
| */ | |||
| #define ALT_BITSTREAM_READER | |||
| #include "libavutil/pixdesc.h" | |||
| #include "avcodec.h" | |||
| #include "dsputil.h" | |||
| #include "get_bits.h" | |||
| @@ -350,7 +351,7 @@ static av_cold int dvvideo_init_encoder(AVCodecContext *avctx) | |||
| { | |||
| if (!ff_dv_codec_profile(avctx)) { | |||
| av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video\n", | |||
| avctx->width, avctx->height, avcodec_get_pix_fmt_name(avctx->pix_fmt)); | |||
| avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt)); | |||
| return -1; | |||
| } | |||
| @@ -1002,7 +1002,7 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) | |||
| static int count_frame_header(FlacEncodeContext *s) | |||
| { | |||
| uint8_t tmp; | |||
| uint8_t av_unused tmp; | |||
| int count; | |||
| /* | |||
| @@ -586,8 +586,7 @@ av_cold int MPV_common_init(MpegEncContext *s) | |||
| return -1; | |||
| } | |||
| if((s->avctx->active_thread_type & FF_THREAD_SLICE) && | |||
| if((s->encoding || (s->avctx->active_thread_type & FF_THREAD_SLICE)) && | |||
| (s->avctx->thread_count > MAX_THREADS || (s->avctx->thread_count > s->mb_height && s->mb_height))){ | |||
| av_log(s->avctx, AV_LOG_ERROR, "too many threads\n"); | |||
| return -1; | |||
| @@ -746,7 +745,7 @@ av_cold int MPV_common_init(MpegEncContext *s) | |||
| s->context_initialized = 1; | |||
| s->thread_context[0]= s; | |||
| if (HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_SLICE) { | |||
| if (s->encoding || (HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_SLICE)) { | |||
| threads = s->avctx->thread_count; | |||
| for(i=1; i<threads; i++){ | |||
| @@ -778,7 +777,7 @@ void MPV_common_end(MpegEncContext *s) | |||
| { | |||
| int i, j, k; | |||
| if (HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_SLICE) { | |||
| if (s->encoding || (HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_SLICE)) { | |||
| for(i=0; i<s->avctx->thread_count; i++){ | |||
| free_duplicate_context(s->thread_context[i]); | |||
| } | |||
| @@ -1226,7 +1226,7 @@ int MPV_encode_picture(AVCodecContext *avctx, | |||
| { | |||
| MpegEncContext *s = avctx->priv_data; | |||
| AVFrame *pic_arg = data; | |||
| int i, stuffing_count, context_count = avctx->active_thread_type&FF_THREAD_SLICE ? avctx->thread_count : 1; | |||
| int i, stuffing_count, context_count = avctx->thread_count; | |||
| for(i=0; i<context_count; i++){ | |||
| int start_y= s->thread_context[i]->start_mb_y; | |||
| @@ -2759,7 +2759,7 @@ static int encode_picture(MpegEncContext *s, int picture_number) | |||
| { | |||
| int i; | |||
| int bits; | |||
| int context_count = (s->avctx->active_thread_type & FF_THREAD_SLICE) ? s->avctx->thread_count : 1; | |||
| int context_count = s->avctx->thread_count; | |||
| s->picture_number = picture_number; | |||
| @@ -821,9 +821,10 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) | |||
| if (!s->context_initialized) { | |||
| h->chroma_qp[0] = h->chroma_qp[1] = 4; | |||
| svq3->halfpel_flag = 1; | |||
| svq3->halfpel_flag = 1; | |||
| svq3->thirdpel_flag = 1; | |||
| svq3->unknown_flag = 0; | |||
| svq3->unknown_flag = 0; | |||
| /* prowl for the "SEQH" marker in the extradata */ | |||
| extradata = (unsigned char *)avctx->extradata; | |||
| @@ -20,6 +20,7 @@ | |||
| */ | |||
| #include "libavutil/intreadwrite.h" | |||
| #include "libavutil/pixdesc.h" | |||
| #include "avcodec.h" | |||
| #include "rle.h" | |||
| #include "targa.h" | |||
| @@ -119,7 +120,7 @@ static int targa_encode_frame(AVCodecContext *avctx, | |||
| break; | |||
| default: | |||
| av_log(avctx, AV_LOG_ERROR, "Pixel format '%s' not supported.\n", | |||
| avcodec_get_pix_fmt_name(avctx->pix_fmt)); | |||
| av_get_pix_fmt_name(avctx->pix_fmt)); | |||
| return AVERROR(EINVAL); | |||
| } | |||
| bpp = outbuf[16] >> 3; | |||
| @@ -1012,7 +1012,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) | |||
| if (enc->pix_fmt != PIX_FMT_NONE) { | |||
| snprintf(buf + strlen(buf), buf_size - strlen(buf), | |||
| ", %s", | |||
| avcodec_get_pix_fmt_name(enc->pix_fmt)); | |||
| av_get_pix_fmt_name(enc->pix_fmt)); | |||
| } | |||
| if (enc->width) { | |||
| snprintf(buf + strlen(buf), buf_size - strlen(buf), | |||
| @@ -1320,7 +1320,7 @@ static int decode_frame(WMAProDecodeCtx *s) | |||
| /** no idea what these are for, might be the number of samples | |||
| that need to be skipped at the beginning or end of a stream */ | |||
| if (get_bits1(gb)) { | |||
| int skip; | |||
| int av_unused skip; | |||
| /** usually true for the first frame */ | |||
| if (get_bits1(gb)) { | |||
| @@ -256,10 +256,32 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) | |||
| goto out; | |||
| } | |||
| #if FF_API_FORMAT_PARAMETERS | |||
| if (ap->standard) { | |||
| if (!strcasecmp(ap->standard, "pal")) | |||
| s->standard = PAL; | |||
| else if (!strcasecmp(ap->standard, "secam")) | |||
| s->standard = SECAM; | |||
| else if (!strcasecmp(ap->standard, "ntsc")) | |||
| s->standard = NTSC; | |||
| } | |||
| #endif | |||
| if ((ret = av_parse_video_size(&width, &height, s->video_size)) < 0) { | |||
| av_log(s1, AV_LOG_ERROR, "Couldn't parse video size.\n"); | |||
| goto out; | |||
| } | |||
| if (!s->framerate) | |||
| switch (s->standard) { | |||
| case PAL: s->framerate = av_strdup("pal"); break; | |||
| case NTSC: s->framerate = av_strdup("ntsc"); break; | |||
| case SECAM: s->framerate = av_strdup("25"); break; | |||
| default: | |||
| av_log(s1, AV_LOG_ERROR, "Unknown standard.\n"); | |||
| ret = AVERROR(EINVAL); | |||
| goto out; | |||
| } | |||
| if ((ret = av_parse_video_rate(&fps, s->framerate)) < 0) { | |||
| av_log(s1, AV_LOG_ERROR, "Couldn't parse framerate.\n"); | |||
| goto out; | |||
| @@ -292,16 +314,6 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) | |||
| st->codec->time_base.den = fps.num; | |||
| st->codec->time_base.num = fps.den; | |||
| #if FF_API_FORMAT_PARAMETERS | |||
| if (ap->standard) { | |||
| if (!strcasecmp(ap->standard, "pal")) | |||
| s->standard = PAL; | |||
| else if (!strcasecmp(ap->standard, "secam")) | |||
| s->standard = SECAM; | |||
| else if (!strcasecmp(ap->standard, "ntsc")) | |||
| s->standard = NTSC; | |||
| } | |||
| #endif | |||
| if (bktr_init(s1->filename, width, height, s->standard, | |||
| &(s->video_fd), &(s->tuner_fd), -1, 0.0) < 0) { | |||
| @@ -347,7 +359,7 @@ static const AVOption options[] = { | |||
| { "PALM", "", 0, FF_OPT_TYPE_CONST, {.dbl = PALM}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" }, | |||
| { "NTSCJ", "", 0, FF_OPT_TYPE_CONST, {.dbl = NTSCJ}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" }, | |||
| { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = "vga"}, 0, 0, DEC }, | |||
| { "framerate", "", OFFSET(framerate), FF_OPT_TYPE_STRING, {.str = "ntsc"}, 0, 0, DEC }, | |||
| { "framerate", "", OFFSET(framerate), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, | |||
| { NULL }, | |||
| }; | |||
| @@ -162,7 +162,7 @@ static inline int dc1394_read_common(AVFormatContext *c, AVFormatParameters *ap, | |||
| break; | |||
| if (!fps->frame_rate || !fmt->width) { | |||
| av_log(c, AV_LOG_ERROR, "Can't find matching camera format for %s, %dx%d@%d:1000fps\n", avcodec_get_pix_fmt_name(pix_fmt), | |||
| av_log(c, AV_LOG_ERROR, "Can't find matching camera format for %s, %dx%d@%d:1000fps\n", av_get_pix_fmt_name(pix_fmt), | |||
| width, height, dc1394->frame_rate); | |||
| ret = AVERROR(EINVAL); | |||
| goto out; | |||
| @@ -26,6 +26,12 @@ | |||
| #define MAX_URL_SIZE 4096 | |||
| #ifdef DEBUG | |||
| # define hex_dump_debug(class, buf, size) av_hex_dump_log(class, AV_LOG_DEBUG, buf, size) | |||
| #else | |||
| # define hex_dump_debug(class, buf, size) | |||
| #endif | |||
| typedef struct AVCodecTag { | |||
| enum CodecID id; | |||
| unsigned int tag; | |||
| @@ -433,7 +433,7 @@ static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom) | |||
| { | |||
| AVStream *st; | |||
| uint32_t type; | |||
| uint32_t ctype; | |||
| uint32_t av_unused ctype; | |||
| if (c->fc->nb_streams < 1) // meta before first trak | |||
| return 0; | |||
| @@ -1029,10 +1029,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len | |||
| int mp4_dec_config_descr_len = 0; | |||
| int mp4_es_id = 0; | |||
| #ifdef DEBUG | |||
| av_dlog(ts->stream, "PMT: len %i\n", section_len); | |||
| av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len); | |||
| #endif | |||
| hex_dump_debug(ts->stream, (uint8_t *)section, section_len); | |||
| p_end = section + section_len - 4; | |||
| p = section; | |||
| @@ -1151,10 +1149,9 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len | |||
| int sid, pmt_pid; | |||
| AVProgram *program; | |||
| #ifdef DEBUG | |||
| av_dlog(ts->stream, "PAT:\n"); | |||
| av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len); | |||
| #endif | |||
| hex_dump_debug(ts->stream, (uint8_t *)section, section_len); | |||
| p_end = section + section_len - 4; | |||
| p = section; | |||
| if (parse_section_header(h, &p, p_end) < 0) | |||
| @@ -1199,10 +1196,8 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len | |||
| int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type; | |||
| char *name, *provider_name; | |||
| #ifdef DEBUG | |||
| av_dlog(ts->stream, "SDT:\n"); | |||
| av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len); | |||
| #endif | |||
| hex_dump_debug(ts->stream, (uint8_t *)section, section_len); | |||
| p_end = section + section_len - 4; | |||
| p = section; | |||
| @@ -267,7 +267,8 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap) | |||
| { | |||
| NSVContext *nsv = s->priv_data; | |||
| AVIOContext *pb = s->pb; | |||
| unsigned int file_size, size; | |||
| unsigned int av_unused file_size; | |||
| unsigned int size; | |||
| int64_t duration; | |||
| int strings_size; | |||
| int table_entries; | |||
| @@ -546,7 +547,7 @@ static int nsv_read_chunk(AVFormatContext *s, int fill_header) | |||
| uint32_t vsize; | |||
| uint16_t asize; | |||
| uint16_t auxsize; | |||
| uint32_t auxtag; | |||
| uint32_t av_unused auxtag; | |||
| av_dlog(s, "%s(%d)\n", __FUNCTION__, fill_header); | |||
| @@ -52,7 +52,8 @@ static int r3d_read_red1(AVFormatContext *s) | |||
| { | |||
| AVStream *st = av_new_stream(s, 0); | |||
| char filename[258]; | |||
| int tmp, tmp2; | |||
| int tmp; | |||
| int av_unused tmp2; | |||
| if (!st) | |||
| return AVERROR(ENOMEM); | |||
| @@ -139,7 +140,7 @@ static int r3d_read_rdvo(AVFormatContext *s, Atom *atom) | |||
| static void r3d_read_reos(AVFormatContext *s) | |||
| { | |||
| R3DContext *r3d = s->priv_data; | |||
| int tmp; | |||
| int av_unused tmp; | |||
| r3d->rdvo_offset = avio_rb32(s->pb); | |||
| avio_rb32(s->pb); // rdvs offset | |||
| @@ -209,7 +210,8 @@ static int r3d_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
| static int r3d_read_redv(AVFormatContext *s, AVPacket *pkt, Atom *atom) | |||
| { | |||
| AVStream *st = s->streams[0]; | |||
| int tmp, tmp2; | |||
| int tmp; | |||
| int av_unused tmp2; | |||
| uint64_t pos = avio_tell(s->pb); | |||
| unsigned dts; | |||
| int ret; | |||
| @@ -263,7 +265,8 @@ static int r3d_read_redv(AVFormatContext *s, AVPacket *pkt, Atom *atom) | |||
| static int r3d_read_reda(AVFormatContext *s, AVPacket *pkt, Atom *atom) | |||
| { | |||
| AVStream *st = s->streams[1]; | |||
| int tmp, tmp2, samples, size; | |||
| int av_unused tmp, tmp2; | |||
| int samples, size; | |||
| uint64_t pos = avio_tell(s->pb); | |||
| unsigned dts; | |||
| int ret; | |||
| @@ -70,7 +70,7 @@ int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
| } | |||
| case AVMEDIA_TYPE_VIDEO: { | |||
| FFRawVideoDemuxerContext *s1 = s->priv_data; | |||
| int width = 0, height = 0, ret; | |||
| int width = 0, height = 0, ret = 0; | |||
| enum PixelFormat pix_fmt; | |||
| if(ap->time_base.num) | |||
| @@ -97,7 +97,6 @@ int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
| st->codec->width = width; | |||
| st->codec->height = height; | |||
| st->codec->pix_fmt = pix_fmt; | |||
| break; | |||
| fail: | |||
| av_freep(&s1->video_size); | |||
| av_freep(&s1->pixel_format); | |||
| @@ -321,7 +321,7 @@ int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count) | |||
| avio_flush(pb); | |||
| len = avio_close_dyn_buf(pb, &buf); | |||
| if ((len > 0) && buf) { | |||
| int result; | |||
| int av_unused result; | |||
| av_dlog(s->ic, "sending %d bytes of RR\n", len); | |||
| result= ffurl_write(s->rtp_ctx, buf, len); | |||
| av_dlog(s->ic, "result from ffurl_write: %d\n", result); | |||
| @@ -2019,7 +2019,7 @@ static void av_estimate_timings(AVFormatContext *ic, int64_t old_offset) | |||
| #if 0 | |||
| { | |||
| int i; | |||
| AVStream *st; | |||
| AVStream av_unused *st; | |||
| for(i = 0;i < ic->nb_streams; i++) { | |||
| st = ic->streams[i]; | |||
| printf("%d: start_time: %0.3f duration: %0.3f\n", | |||
| @@ -5,14 +5,18 @@ FFLIBS = avutil | |||
| HEADERS = swscale.h | |||
| OBJS = options.o rgb2rgb.o swscale.o utils.o yuv2rgb.o | |||
| OBJS = options.o rgb2rgb.o swscale.o utils.o yuv2rgb.o \ | |||
| swscale_unscaled.o | |||
| OBJS-$(ARCH_BFIN) += bfin/internal_bfin.o \ | |||
| bfin/swscale_bfin.o \ | |||
| bfin/yuv2rgb_bfin.o | |||
| OBJS-$(CONFIG_MLIB) += mlib/yuv2rgb_mlib.o | |||
| OBJS-$(HAVE_ALTIVEC) += ppc/yuv2rgb_altivec.o | |||
| OBJS-$(HAVE_ALTIVEC) += ppc/swscale_altivec.o \ | |||
| ppc/yuv2rgb_altivec.o \ | |||
| ppc/yuv2yuv_altivec.o | |||
| OBJS-$(HAVE_MMX) += x86/rgb2rgb.o \ | |||
| x86/swscale_mmx.o \ | |||
| x86/yuv2rgb_mmx.o | |||
| OBJS-$(HAVE_VIS) += sparc/yuv2rgb_vis.o | |||
| @@ -21,6 +21,13 @@ | |||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #include <inttypes.h> | |||
| #include "config.h" | |||
| #include "libswscale/swscale.h" | |||
| #include "libswscale/swscale_internal.h" | |||
| #include "libavutil/cpu.h" | |||
| #include "yuv2rgb_altivec.h" | |||
| #define vzero vec_splat_s32(0) | |||
| static inline void | |||
| @@ -85,12 +92,15 @@ altivec_packIntArrayToCharArray(int *val, uint8_t* dest, int dstW) | |||
| } | |||
| } | |||
| static inline void | |||
| yuv2yuvX_altivec_real(const int16_t *lumFilter, const int16_t **lumSrc, | |||
| static void | |||
| yuv2yuvX_altivec_real(SwsContext *c, | |||
| const int16_t *lumFilter, const int16_t **lumSrc, | |||
| int lumFilterSize, const int16_t *chrFilter, | |||
| const int16_t **chrUSrc, const int16_t **chrVSrc, | |||
| int chrFilterSize, uint8_t *dest, uint8_t *uDest, | |||
| uint8_t *vDest, int dstW, int chrDstW) | |||
| int chrFilterSize, const int16_t **alpSrc, | |||
| uint8_t *dest, uint8_t *uDest, | |||
| uint8_t *vDest, uint8_t *aDest, | |||
| int dstW, int chrDstW) | |||
| { | |||
| const vector signed int vini = {(1 << 18), (1 << 18), (1 << 18), (1 << 18)}; | |||
| register int i, j; | |||
| @@ -211,10 +221,10 @@ yuv2yuvX_altivec_real(const int16_t *lumFilter, const int16_t **lumSrc, | |||
| } | |||
| } | |||
| static inline void hScale_altivec_real(int16_t *dst, int dstW, | |||
| const uint8_t *src, int srcW, | |||
| int xInc, const int16_t *filter, | |||
| const int16_t *filterPos, int filterSize) | |||
| static void hScale_altivec_real(int16_t *dst, int dstW, | |||
| const uint8_t *src, int srcW, | |||
| int xInc, const int16_t *filter, | |||
| const int16_t *filterPos, int filterSize) | |||
| { | |||
| register int i; | |||
| DECLARE_ALIGNED(16, int, tempo)[4]; | |||
| @@ -391,157 +401,20 @@ static inline void hScale_altivec_real(int16_t *dst, int dstW, | |||
| } | |||
| } | |||
| static inline int yv12toyuy2_unscaled_altivec(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dstParam[], int dstStride_a[]) | |||
| void ff_sws_init_swScale_altivec(SwsContext *c) | |||
| { | |||
| uint8_t *dst=dstParam[0] + dstStride_a[0]*srcSliceY; | |||
| // yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]); | |||
| const uint8_t *ysrc = src[0]; | |||
| const uint8_t *usrc = src[1]; | |||
| const uint8_t *vsrc = src[2]; | |||
| const int width = c->srcW; | |||
| const int height = srcSliceH; | |||
| const int lumStride = srcStride[0]; | |||
| const int chromStride = srcStride[1]; | |||
| const int dstStride = dstStride_a[0]; | |||
| const vector unsigned char yperm = vec_lvsl(0, ysrc); | |||
| const int vertLumPerChroma = 2; | |||
| register unsigned int y; | |||
| if (width&15) { | |||
| yv12toyuy2(ysrc, usrc, vsrc, dst, c->srcW, srcSliceH, lumStride, chromStride, dstStride); | |||
| return srcSliceH; | |||
| } | |||
| /* This code assumes: | |||
| 1) dst is 16 bytes-aligned | |||
| 2) dstStride is a multiple of 16 | |||
| 3) width is a multiple of 16 | |||
| 4) lum & chrom stride are multiples of 8 | |||
| */ | |||
| for (y=0; y<height; y++) { | |||
| int i; | |||
| for (i = 0; i < width - 31; i+= 32) { | |||
| const unsigned int j = i >> 1; | |||
| vector unsigned char v_yA = vec_ld(i, ysrc); | |||
| vector unsigned char v_yB = vec_ld(i + 16, ysrc); | |||
| vector unsigned char v_yC = vec_ld(i + 32, ysrc); | |||
| vector unsigned char v_y1 = vec_perm(v_yA, v_yB, yperm); | |||
| vector unsigned char v_y2 = vec_perm(v_yB, v_yC, yperm); | |||
| vector unsigned char v_uA = vec_ld(j, usrc); | |||
| vector unsigned char v_uB = vec_ld(j + 16, usrc); | |||
| vector unsigned char v_u = vec_perm(v_uA, v_uB, vec_lvsl(j, usrc)); | |||
| vector unsigned char v_vA = vec_ld(j, vsrc); | |||
| vector unsigned char v_vB = vec_ld(j + 16, vsrc); | |||
| vector unsigned char v_v = vec_perm(v_vA, v_vB, vec_lvsl(j, vsrc)); | |||
| vector unsigned char v_uv_a = vec_mergeh(v_u, v_v); | |||
| vector unsigned char v_uv_b = vec_mergel(v_u, v_v); | |||
| vector unsigned char v_yuy2_0 = vec_mergeh(v_y1, v_uv_a); | |||
| vector unsigned char v_yuy2_1 = vec_mergel(v_y1, v_uv_a); | |||
| vector unsigned char v_yuy2_2 = vec_mergeh(v_y2, v_uv_b); | |||
| vector unsigned char v_yuy2_3 = vec_mergel(v_y2, v_uv_b); | |||
| vec_st(v_yuy2_0, (i << 1), dst); | |||
| vec_st(v_yuy2_1, (i << 1) + 16, dst); | |||
| vec_st(v_yuy2_2, (i << 1) + 32, dst); | |||
| vec_st(v_yuy2_3, (i << 1) + 48, dst); | |||
| } | |||
| if (i < width) { | |||
| const unsigned int j = i >> 1; | |||
| vector unsigned char v_y1 = vec_ld(i, ysrc); | |||
| vector unsigned char v_u = vec_ld(j, usrc); | |||
| vector unsigned char v_v = vec_ld(j, vsrc); | |||
| vector unsigned char v_uv_a = vec_mergeh(v_u, v_v); | |||
| vector unsigned char v_yuy2_0 = vec_mergeh(v_y1, v_uv_a); | |||
| vector unsigned char v_yuy2_1 = vec_mergel(v_y1, v_uv_a); | |||
| vec_st(v_yuy2_0, (i << 1), dst); | |||
| vec_st(v_yuy2_1, (i << 1) + 16, dst); | |||
| if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) | |||
| return; | |||
| c->hScale = hScale_altivec_real; | |||
| c->yuv2yuvX = yuv2yuvX_altivec_real; | |||
| /* The following list of supported dstFormat values should | |||
| * match what's found in the body of ff_yuv2packedX_altivec() */ | |||
| if (!(c->flags & SWS_BITEXACT) && !c->alpPixBuf && | |||
| (c->dstFormat==PIX_FMT_ABGR || c->dstFormat==PIX_FMT_BGRA || | |||
| c->dstFormat==PIX_FMT_BGR24 || c->dstFormat==PIX_FMT_RGB24 || | |||
| c->dstFormat==PIX_FMT_RGBA || c->dstFormat==PIX_FMT_ARGB)) { | |||
| c->yuv2packedX = ff_yuv2packedX_altivec; | |||
| } | |||
| if ((y&(vertLumPerChroma-1)) == vertLumPerChroma-1) { | |||
| usrc += chromStride; | |||
| vsrc += chromStride; | |||
| } | |||
| ysrc += lumStride; | |||
| dst += dstStride; | |||
| } | |||
| return srcSliceH; | |||
| } | |||
| static inline int yv12touyvy_unscaled_altivec(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dstParam[], int dstStride_a[]) | |||
| { | |||
| uint8_t *dst=dstParam[0] + dstStride_a[0]*srcSliceY; | |||
| // yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]); | |||
| const uint8_t *ysrc = src[0]; | |||
| const uint8_t *usrc = src[1]; | |||
| const uint8_t *vsrc = src[2]; | |||
| const int width = c->srcW; | |||
| const int height = srcSliceH; | |||
| const int lumStride = srcStride[0]; | |||
| const int chromStride = srcStride[1]; | |||
| const int dstStride = dstStride_a[0]; | |||
| const int vertLumPerChroma = 2; | |||
| const vector unsigned char yperm = vec_lvsl(0, ysrc); | |||
| register unsigned int y; | |||
| if (width&15) { | |||
| yv12touyvy(ysrc, usrc, vsrc, dst, c->srcW, srcSliceH, lumStride, chromStride, dstStride); | |||
| return srcSliceH; | |||
| } | |||
| /* This code assumes: | |||
| 1) dst is 16 bytes-aligned | |||
| 2) dstStride is a multiple of 16 | |||
| 3) width is a multiple of 16 | |||
| 4) lum & chrom stride are multiples of 8 | |||
| */ | |||
| for (y=0; y<height; y++) { | |||
| int i; | |||
| for (i = 0; i < width - 31; i+= 32) { | |||
| const unsigned int j = i >> 1; | |||
| vector unsigned char v_yA = vec_ld(i, ysrc); | |||
| vector unsigned char v_yB = vec_ld(i + 16, ysrc); | |||
| vector unsigned char v_yC = vec_ld(i + 32, ysrc); | |||
| vector unsigned char v_y1 = vec_perm(v_yA, v_yB, yperm); | |||
| vector unsigned char v_y2 = vec_perm(v_yB, v_yC, yperm); | |||
| vector unsigned char v_uA = vec_ld(j, usrc); | |||
| vector unsigned char v_uB = vec_ld(j + 16, usrc); | |||
| vector unsigned char v_u = vec_perm(v_uA, v_uB, vec_lvsl(j, usrc)); | |||
| vector unsigned char v_vA = vec_ld(j, vsrc); | |||
| vector unsigned char v_vB = vec_ld(j + 16, vsrc); | |||
| vector unsigned char v_v = vec_perm(v_vA, v_vB, vec_lvsl(j, vsrc)); | |||
| vector unsigned char v_uv_a = vec_mergeh(v_u, v_v); | |||
| vector unsigned char v_uv_b = vec_mergel(v_u, v_v); | |||
| vector unsigned char v_uyvy_0 = vec_mergeh(v_uv_a, v_y1); | |||
| vector unsigned char v_uyvy_1 = vec_mergel(v_uv_a, v_y1); | |||
| vector unsigned char v_uyvy_2 = vec_mergeh(v_uv_b, v_y2); | |||
| vector unsigned char v_uyvy_3 = vec_mergel(v_uv_b, v_y2); | |||
| vec_st(v_uyvy_0, (i << 1), dst); | |||
| vec_st(v_uyvy_1, (i << 1) + 16, dst); | |||
| vec_st(v_uyvy_2, (i << 1) + 32, dst); | |||
| vec_st(v_uyvy_3, (i << 1) + 48, dst); | |||
| } | |||
| if (i < width) { | |||
| const unsigned int j = i >> 1; | |||
| vector unsigned char v_y1 = vec_ld(i, ysrc); | |||
| vector unsigned char v_u = vec_ld(j, usrc); | |||
| vector unsigned char v_v = vec_ld(j, vsrc); | |||
| vector unsigned char v_uv_a = vec_mergeh(v_u, v_v); | |||
| vector unsigned char v_uyvy_0 = vec_mergeh(v_uv_a, v_y1); | |||
| vector unsigned char v_uyvy_1 = vec_mergel(v_uv_a, v_y1); | |||
| vec_st(v_uyvy_0, (i << 1), dst); | |||
| vec_st(v_uyvy_1, (i << 1) + 16, dst); | |||
| } | |||
| if ((y&(vertLumPerChroma-1)) == vertLumPerChroma-1) { | |||
| usrc += chromStride; | |||
| vsrc += chromStride; | |||
| } | |||
| ysrc += lumStride; | |||
| dst += dstStride; | |||
| } | |||
| return srcSliceH; | |||
| } | |||
| @@ -1,71 +0,0 @@ | |||
| /* | |||
| * 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 | |||
| */ | |||
| #if COMPILE_TEMPLATE_ALTIVEC | |||
| #include "swscale_altivec_template.c" | |||
| #endif | |||
| #if COMPILE_TEMPLATE_ALTIVEC | |||
| static inline void RENAME(yuv2yuvX)(SwsContext *c, const int16_t *lumFilter, | |||
| const int16_t **lumSrc, int lumFilterSize, | |||
| const int16_t *chrFilter, const int16_t **chrUSrc, | |||
| const int16_t **chrVSrc, int chrFilterSize, | |||
| const int16_t **alpSrc, | |||
| uint8_t *dest, uint8_t *uDest, uint8_t *vDest, | |||
| uint8_t *aDest, int dstW, int chrDstW) | |||
| { | |||
| yuv2yuvX_altivec_real(lumFilter, lumSrc, lumFilterSize, | |||
| chrFilter, chrUSrc, chrVSrc, chrFilterSize, | |||
| dest, uDest, vDest, dstW, chrDstW); | |||
| } | |||
| /** | |||
| * vertical scale YV12 to RGB | |||
| */ | |||
| static inline void RENAME(yuv2packedX)(SwsContext *c, const int16_t *lumFilter, | |||
| const int16_t **lumSrc, int lumFilterSize, | |||
| const int16_t *chrFilter, const int16_t **chrUSrc, | |||
| const int16_t **chrVSrc, int chrFilterSize, | |||
| const int16_t **alpSrc, uint8_t *dest, | |||
| int dstW, int dstY) | |||
| { | |||
| /* The following list of supported dstFormat values should | |||
| match what's found in the body of ff_yuv2packedX_altivec() */ | |||
| if (!(c->flags & SWS_BITEXACT) && !c->alpPixBuf && | |||
| (c->dstFormat==PIX_FMT_ABGR || c->dstFormat==PIX_FMT_BGRA || | |||
| c->dstFormat==PIX_FMT_BGR24 || c->dstFormat==PIX_FMT_RGB24 || | |||
| c->dstFormat==PIX_FMT_RGBA || c->dstFormat==PIX_FMT_ARGB)) | |||
| ff_yuv2packedX_altivec(c, lumFilter, lumSrc, lumFilterSize, | |||
| chrFilter, chrUSrc, chrVSrc, chrFilterSize, | |||
| dest, dstW, dstY); | |||
| else | |||
| yuv2packedXinC(c, lumFilter, lumSrc, lumFilterSize, | |||
| chrFilter, chrUSrc, chrVSrc, chrFilterSize, | |||
| alpSrc, dest, dstW, dstY); | |||
| } | |||
| #endif | |||
| static void RENAME(sws_init_swScale)(SwsContext *c) | |||
| { | |||
| c->yuv2yuvX = RENAME(yuv2yuvX ); | |||
| c->yuv2packedX = RENAME(yuv2packedX ); | |||
| } | |||
| @@ -96,6 +96,7 @@ adjustment. | |||
| #include "libswscale/swscale_internal.h" | |||
| #include "libavutil/cpu.h" | |||
| #include "libavutil/pixdesc.h" | |||
| #include "yuv2rgb_altivec.h" | |||
| #undef PROFILE_THE_BEAST | |||
| #undef INC_SCALING | |||
| @@ -631,7 +632,8 @@ ff_yuv2packedX_altivec(SwsContext *c, const int16_t *lumFilter, | |||
| const int16_t **lumSrc, int lumFilterSize, | |||
| const int16_t *chrFilter, const int16_t **chrUSrc, | |||
| const int16_t **chrVSrc, int chrFilterSize, | |||
| uint8_t *dest, int dstW, int dstY) | |||
| const int16_t **alpSrc, uint8_t *dest, | |||
| int dstW, int dstY) | |||
| { | |||
| int i,j; | |||
| vector signed short X,X0,X1,Y0,U0,V0,Y1,U1,V1,U,V; | |||
| @@ -0,0 +1,34 @@ | |||
| /* | |||
| * AltiVec-enhanced yuv2yuvX | |||
| * | |||
| * Copyright (C) 2004 Romain Dolbeau <romain@dolbeau.org> | |||
| * based on the equivalent C code in swscale.c | |||
| * | |||
| * 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 | |||
| */ | |||
| #ifndef PPC_YUV2RGB_ALTIVEC_H | |||
| #define PPC_YUV2RGB_ALTIVEC_H 1 | |||
| void ff_yuv2packedX_altivec(SwsContext *c, const int16_t *lumFilter, | |||
| const int16_t **lumSrc, int lumFilterSize, | |||
| const int16_t *chrFilter, const int16_t **chrUSrc, | |||
| const int16_t **chrVSrc, int chrFilterSize, | |||
| const int16_t **alpSrc, uint8_t *dest, | |||
| int dstW, int dstY); | |||
| #endif /* PPC_YUV2RGB_ALTIVEC_H */ | |||
| @@ -0,0 +1,191 @@ | |||
| /* | |||
| * AltiVec-enhanced yuv-to-yuv convertion routines. | |||
| * | |||
| * Copyright (C) 2004 Romain Dolbeau <romain@dolbeau.org> | |||
| * based on the equivalent C code in swscale.c | |||
| * | |||
| * 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 <inttypes.h> | |||
| #include "config.h" | |||
| #include "libswscale/swscale.h" | |||
| #include "libswscale/swscale_internal.h" | |||
| #include "libavutil/cpu.h" | |||
| static int yv12toyuy2_unscaled_altivec(SwsContext *c, const uint8_t* src[], | |||
| int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dstParam[], | |||
| int dstStride_a[]) | |||
| { | |||
| uint8_t *dst=dstParam[0] + dstStride_a[0]*srcSliceY; | |||
| // yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]); | |||
| const uint8_t *ysrc = src[0]; | |||
| const uint8_t *usrc = src[1]; | |||
| const uint8_t *vsrc = src[2]; | |||
| const int width = c->srcW; | |||
| const int height = srcSliceH; | |||
| const int lumStride = srcStride[0]; | |||
| const int chromStride = srcStride[1]; | |||
| const int dstStride = dstStride_a[0]; | |||
| const vector unsigned char yperm = vec_lvsl(0, ysrc); | |||
| const int vertLumPerChroma = 2; | |||
| register unsigned int y; | |||
| /* This code assumes: | |||
| 1) dst is 16 bytes-aligned | |||
| 2) dstStride is a multiple of 16 | |||
| 3) width is a multiple of 16 | |||
| 4) lum & chrom stride are multiples of 8 | |||
| */ | |||
| for (y=0; y<height; y++) { | |||
| int i; | |||
| for (i = 0; i < width - 31; i+= 32) { | |||
| const unsigned int j = i >> 1; | |||
| vector unsigned char v_yA = vec_ld(i, ysrc); | |||
| vector unsigned char v_yB = vec_ld(i + 16, ysrc); | |||
| vector unsigned char v_yC = vec_ld(i + 32, ysrc); | |||
| vector unsigned char v_y1 = vec_perm(v_yA, v_yB, yperm); | |||
| vector unsigned char v_y2 = vec_perm(v_yB, v_yC, yperm); | |||
| vector unsigned char v_uA = vec_ld(j, usrc); | |||
| vector unsigned char v_uB = vec_ld(j + 16, usrc); | |||
| vector unsigned char v_u = vec_perm(v_uA, v_uB, vec_lvsl(j, usrc)); | |||
| vector unsigned char v_vA = vec_ld(j, vsrc); | |||
| vector unsigned char v_vB = vec_ld(j + 16, vsrc); | |||
| vector unsigned char v_v = vec_perm(v_vA, v_vB, vec_lvsl(j, vsrc)); | |||
| vector unsigned char v_uv_a = vec_mergeh(v_u, v_v); | |||
| vector unsigned char v_uv_b = vec_mergel(v_u, v_v); | |||
| vector unsigned char v_yuy2_0 = vec_mergeh(v_y1, v_uv_a); | |||
| vector unsigned char v_yuy2_1 = vec_mergel(v_y1, v_uv_a); | |||
| vector unsigned char v_yuy2_2 = vec_mergeh(v_y2, v_uv_b); | |||
| vector unsigned char v_yuy2_3 = vec_mergel(v_y2, v_uv_b); | |||
| vec_st(v_yuy2_0, (i << 1), dst); | |||
| vec_st(v_yuy2_1, (i << 1) + 16, dst); | |||
| vec_st(v_yuy2_2, (i << 1) + 32, dst); | |||
| vec_st(v_yuy2_3, (i << 1) + 48, dst); | |||
| } | |||
| if (i < width) { | |||
| const unsigned int j = i >> 1; | |||
| vector unsigned char v_y1 = vec_ld(i, ysrc); | |||
| vector unsigned char v_u = vec_ld(j, usrc); | |||
| vector unsigned char v_v = vec_ld(j, vsrc); | |||
| vector unsigned char v_uv_a = vec_mergeh(v_u, v_v); | |||
| vector unsigned char v_yuy2_0 = vec_mergeh(v_y1, v_uv_a); | |||
| vector unsigned char v_yuy2_1 = vec_mergel(v_y1, v_uv_a); | |||
| vec_st(v_yuy2_0, (i << 1), dst); | |||
| vec_st(v_yuy2_1, (i << 1) + 16, dst); | |||
| } | |||
| if ((y&(vertLumPerChroma-1)) == vertLumPerChroma-1) { | |||
| usrc += chromStride; | |||
| vsrc += chromStride; | |||
| } | |||
| ysrc += lumStride; | |||
| dst += dstStride; | |||
| } | |||
| return srcSliceH; | |||
| } | |||
| static int yv12touyvy_unscaled_altivec(SwsContext *c, const uint8_t* src[], | |||
| int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dstParam[], | |||
| int dstStride_a[]) | |||
| { | |||
| uint8_t *dst=dstParam[0] + dstStride_a[0]*srcSliceY; | |||
| // yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]); | |||
| const uint8_t *ysrc = src[0]; | |||
| const uint8_t *usrc = src[1]; | |||
| const uint8_t *vsrc = src[2]; | |||
| const int width = c->srcW; | |||
| const int height = srcSliceH; | |||
| const int lumStride = srcStride[0]; | |||
| const int chromStride = srcStride[1]; | |||
| const int dstStride = dstStride_a[0]; | |||
| const int vertLumPerChroma = 2; | |||
| const vector unsigned char yperm = vec_lvsl(0, ysrc); | |||
| register unsigned int y; | |||
| /* This code assumes: | |||
| 1) dst is 16 bytes-aligned | |||
| 2) dstStride is a multiple of 16 | |||
| 3) width is a multiple of 16 | |||
| 4) lum & chrom stride are multiples of 8 | |||
| */ | |||
| for (y=0; y<height; y++) { | |||
| int i; | |||
| for (i = 0; i < width - 31; i+= 32) { | |||
| const unsigned int j = i >> 1; | |||
| vector unsigned char v_yA = vec_ld(i, ysrc); | |||
| vector unsigned char v_yB = vec_ld(i + 16, ysrc); | |||
| vector unsigned char v_yC = vec_ld(i + 32, ysrc); | |||
| vector unsigned char v_y1 = vec_perm(v_yA, v_yB, yperm); | |||
| vector unsigned char v_y2 = vec_perm(v_yB, v_yC, yperm); | |||
| vector unsigned char v_uA = vec_ld(j, usrc); | |||
| vector unsigned char v_uB = vec_ld(j + 16, usrc); | |||
| vector unsigned char v_u = vec_perm(v_uA, v_uB, vec_lvsl(j, usrc)); | |||
| vector unsigned char v_vA = vec_ld(j, vsrc); | |||
| vector unsigned char v_vB = vec_ld(j + 16, vsrc); | |||
| vector unsigned char v_v = vec_perm(v_vA, v_vB, vec_lvsl(j, vsrc)); | |||
| vector unsigned char v_uv_a = vec_mergeh(v_u, v_v); | |||
| vector unsigned char v_uv_b = vec_mergel(v_u, v_v); | |||
| vector unsigned char v_uyvy_0 = vec_mergeh(v_uv_a, v_y1); | |||
| vector unsigned char v_uyvy_1 = vec_mergel(v_uv_a, v_y1); | |||
| vector unsigned char v_uyvy_2 = vec_mergeh(v_uv_b, v_y2); | |||
| vector unsigned char v_uyvy_3 = vec_mergel(v_uv_b, v_y2); | |||
| vec_st(v_uyvy_0, (i << 1), dst); | |||
| vec_st(v_uyvy_1, (i << 1) + 16, dst); | |||
| vec_st(v_uyvy_2, (i << 1) + 32, dst); | |||
| vec_st(v_uyvy_3, (i << 1) + 48, dst); | |||
| } | |||
| if (i < width) { | |||
| const unsigned int j = i >> 1; | |||
| vector unsigned char v_y1 = vec_ld(i, ysrc); | |||
| vector unsigned char v_u = vec_ld(j, usrc); | |||
| vector unsigned char v_v = vec_ld(j, vsrc); | |||
| vector unsigned char v_uv_a = vec_mergeh(v_u, v_v); | |||
| vector unsigned char v_uyvy_0 = vec_mergeh(v_uv_a, v_y1); | |||
| vector unsigned char v_uyvy_1 = vec_mergel(v_uv_a, v_y1); | |||
| vec_st(v_uyvy_0, (i << 1), dst); | |||
| vec_st(v_uyvy_1, (i << 1) + 16, dst); | |||
| } | |||
| if ((y&(vertLumPerChroma-1)) == vertLumPerChroma-1) { | |||
| usrc += chromStride; | |||
| vsrc += chromStride; | |||
| } | |||
| ysrc += lumStride; | |||
| dst += dstStride; | |||
| } | |||
| return srcSliceH; | |||
| } | |||
| void ff_swscale_get_unscaled_altivec(SwsContext *c) | |||
| { | |||
| if ((av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) && !(c->srcW & 15) && | |||
| !(c->flags & SWS_BITEXACT) && c->srcFormat == PIX_FMT_YUV420P) { | |||
| enum PixelFormat dstFormat = c->dstFormat; | |||
| // unscaled YV12 -> packed YUV, we want speed | |||
| if (dstFormat == PIX_FMT_YUYV422) | |||
| c->swScale= yv12toyuy2_unscaled_altivec; | |||
| else if (dstFormat == PIX_FMT_UYVY422) | |||
| c->swScale= yv12touyvy_unscaled_altivec; | |||
| } | |||
| } | |||
| @@ -35,6 +35,8 @@ | |||
| #define MAX_FILTER_SIZE 256 | |||
| #define DITHER1XBPP | |||
| #if HAVE_BIGENDIAN | |||
| #define ALT32_CORR (-1) | |||
| #else | |||
| @@ -337,17 +339,15 @@ int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], | |||
| void ff_yuv2rgb_init_tables_altivec(SwsContext *c, const int inv_table[4], | |||
| int brightness, int contrast, int saturation); | |||
| void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufIndex, | |||
| int lastInLumBuf, int lastInChrBuf); | |||
| SwsFunc ff_yuv2rgb_init_mmx(SwsContext *c); | |||
| SwsFunc ff_yuv2rgb_init_vis(SwsContext *c); | |||
| SwsFunc ff_yuv2rgb_init_mlib(SwsContext *c); | |||
| SwsFunc ff_yuv2rgb_init_altivec(SwsContext *c); | |||
| SwsFunc ff_yuv2rgb_get_func_ptr_bfin(SwsContext *c); | |||
| void ff_bfin_get_unscaled_swscale(SwsContext *c); | |||
| void ff_yuv2packedX_altivec(SwsContext *c, const int16_t *lumFilter, | |||
| const int16_t **lumSrc, int lumFilterSize, | |||
| const int16_t *chrFilter, const int16_t **chrUSrc, | |||
| const int16_t **chrVSrc, int chrFilterSize, | |||
| uint8_t *dest, int dstW, int dstY); | |||
| #if FF_API_SWS_FORMAT_NAME | |||
| /** | |||
| @@ -486,10 +486,20 @@ const char *sws_format_name(enum PixelFormat format); | |||
| || (x)==PIX_FMT_GRAY8A \ | |||
| || (x)==PIX_FMT_YUVA420P \ | |||
| ) | |||
| #define isPacked(x) ( \ | |||
| (x)==PIX_FMT_PAL8 \ | |||
| || (x)==PIX_FMT_YUYV422 \ | |||
| || (x)==PIX_FMT_UYVY422 \ | |||
| || (x)==PIX_FMT_Y400A \ | |||
| || isAnyRGB(x) \ | |||
| ) | |||
| #define usePal(x) ((av_pix_fmt_descriptors[x].flags & PIX_FMT_PAL) || (x) == PIX_FMT_GRAY8A) | |||
| extern const uint64_t ff_dither4[2]; | |||
| extern const uint64_t ff_dither8[2]; | |||
| extern const uint8_t dithers[8][8][8]; | |||
| extern uint16_t dither_scale[15][16]; | |||
| extern const AVClass sws_context_class; | |||
| @@ -499,10 +509,15 @@ extern const AVClass sws_context_class; | |||
| */ | |||
| void ff_get_unscaled_swscale(SwsContext *c); | |||
| void ff_swscale_get_unscaled_altivec(SwsContext *c); | |||
| /** | |||
| * Returns function pointer to fastest main scaler path function depending | |||
| * on architecture and available optimizations. | |||
| */ | |||
| SwsFunc ff_getSwsFunc(SwsContext *c); | |||
| void ff_sws_init_swScale_altivec(SwsContext *c); | |||
| void ff_sws_init_swScale_mmx(SwsContext *c); | |||
| #endif /* SWSCALE_SWSCALE_INTERNAL_H */ | |||
| @@ -242,93 +242,6 @@ static inline void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV, | |||
| nvXXtoUV_c(dstV, dstU, src1, width); | |||
| } | |||
| static inline void bgr24ToY_c(int16_t *dst, const uint8_t *src, | |||
| int width, uint32_t *unused) | |||
| { | |||
| int i; | |||
| for (i=0; i<width; i++) { | |||
| int b= src[i*3+0]; | |||
| int g= src[i*3+1]; | |||
| int r= src[i*3+2]; | |||
| dst[i]= ((RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6)); | |||
| } | |||
| } | |||
| static inline void bgr24ToUV_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1, | |||
| const uint8_t *src2, int width, uint32_t *unused) | |||
| { | |||
| int i; | |||
| for (i=0; i<width; i++) { | |||
| int b= src1[3*i + 0]; | |||
| int g= src1[3*i + 1]; | |||
| int r= src1[3*i + 2]; | |||
| dstU[i]= (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6); | |||
| dstV[i]= (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6); | |||
| } | |||
| assert(src1 == src2); | |||
| } | |||
| static inline void bgr24ToUV_half_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1, | |||
| const uint8_t *src2, int width, uint32_t *unused) | |||
| { | |||
| int i; | |||
| for (i=0; i<width; i++) { | |||
| int b= src1[6*i + 0] + src1[6*i + 3]; | |||
| int g= src1[6*i + 1] + src1[6*i + 4]; | |||
| int r= src1[6*i + 2] + src1[6*i + 5]; | |||
| dstU[i]= (RU*r + GU*g + BU*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5); | |||
| dstV[i]= (RV*r + GV*g + BV*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5); | |||
| } | |||
| assert(src1 == src2); | |||
| } | |||
| static inline void rgb24ToY_c(int16_t *dst, const uint8_t *src, int width, | |||
| uint32_t *unused) | |||
| { | |||
| int i; | |||
| for (i=0; i<width; i++) { | |||
| int r= src[i*3+0]; | |||
| int g= src[i*3+1]; | |||
| int b= src[i*3+2]; | |||
| dst[i]= ((RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6)); | |||
| } | |||
| } | |||
| static inline void rgb24ToUV_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1, | |||
| const uint8_t *src2, int width, uint32_t *unused) | |||
| { | |||
| int i; | |||
| assert(src1==src2); | |||
| for (i=0; i<width; i++) { | |||
| int r= src1[3*i + 0]; | |||
| int g= src1[3*i + 1]; | |||
| int b= src1[3*i + 2]; | |||
| dstU[i]= (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6); | |||
| dstV[i]= (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6); | |||
| } | |||
| } | |||
| static inline void rgb24ToUV_half_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1, | |||
| const uint8_t *src2, int width, uint32_t *unused) | |||
| { | |||
| int i; | |||
| assert(src1==src2); | |||
| for (i=0; i<width; i++) { | |||
| int r= src1[6*i + 0] + src1[6*i + 3]; | |||
| int g= src1[6*i + 1] + src1[6*i + 4]; | |||
| int b= src1[6*i + 2] + src1[6*i + 5]; | |||
| dstU[i]= (RU*r + GU*g + BU*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5); | |||
| dstV[i]= (RV*r + GV*g + BV*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5); | |||
| } | |||
| } | |||
| // bilinear / bicubic scaling | |||
| static inline void hScale_c(int16_t *dst, int dstW, const uint8_t *src, | |||
| int srcW, int xInc, | |||
| @@ -349,162 +262,6 @@ static inline void hScale_c(int16_t *dst, int dstW, const uint8_t *src, | |||
| } | |||
| } | |||
| static inline void hScale16_c(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc, | |||
| const int16_t *filter, const int16_t *filterPos, long filterSize, int shift) | |||
| { | |||
| int i, j; | |||
| for (i=0; i<dstW; i++) { | |||
| int srcPos= filterPos[i]; | |||
| int val=0; | |||
| for (j=0; j<filterSize; j++) { | |||
| val += ((int)src[srcPos + j])*filter[filterSize*i + j]; | |||
| } | |||
| dst[i] = FFMIN(val>>shift, (1<<15)-1); // the cubic equation does overflow ... | |||
| } | |||
| } | |||
| static inline void hScale16X_c(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc, | |||
| const int16_t *filter, const int16_t *filterPos, long filterSize, int shift) | |||
| { | |||
| int i, j; | |||
| for (i=0; i<dstW; i++) { | |||
| int srcPos= filterPos[i]; | |||
| int val=0; | |||
| for (j=0; j<filterSize; j++) { | |||
| val += ((int)av_bswap16(src[srcPos + j]))*filter[filterSize*i + j]; | |||
| } | |||
| dst[i] = FFMIN(val>>shift, (1<<15)-1); // the cubic equation does overflow ... | |||
| } | |||
| } | |||
| //FIXME all pal and rgb srcFormats could do this convertion as well | |||
| //FIXME all scalers more complex than bilinear could do half of this transform | |||
| static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width) | |||
| { | |||
| int i; | |||
| for (i = 0; i < width; i++) { | |||
| dstU[i] = (FFMIN(dstU[i],30775)*4663 - 9289992)>>12; //-264 | |||
| dstV[i] = (FFMIN(dstV[i],30775)*4663 - 9289992)>>12; //-264 | |||
| } | |||
| } | |||
| static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width) | |||
| { | |||
| int i; | |||
| for (i = 0; i < width; i++) { | |||
| dstU[i] = (dstU[i]*1799 + 4081085)>>11; //1469 | |||
| dstV[i] = (dstV[i]*1799 + 4081085)>>11; //1469 | |||
| } | |||
| } | |||
| static void lumRangeToJpeg_c(int16_t *dst, int width) | |||
| { | |||
| int i; | |||
| for (i = 0; i < width; i++) | |||
| dst[i] = (FFMIN(dst[i],30189)*19077 - 39057361)>>14; | |||
| } | |||
| static void lumRangeFromJpeg_c(int16_t *dst, int width) | |||
| { | |||
| int i; | |||
| for (i = 0; i < width; i++) | |||
| dst[i] = (dst[i]*14071 + 33561947)>>14; | |||
| } | |||
| static inline void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth, | |||
| const uint8_t *src, int srcW, int xInc) | |||
| { | |||
| int i; | |||
| unsigned int xpos=0; | |||
| for (i=0;i<dstWidth;i++) { | |||
| register unsigned int xx=xpos>>16; | |||
| register unsigned int xalpha=(xpos&0xFFFF)>>9; | |||
| dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha; | |||
| xpos+=xInc; | |||
| } | |||
| for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) | |||
| dst[i] = src[srcW-1]*128; | |||
| } | |||
| // *** horizontal scale Y line to temp buffer | |||
| static inline void hyscale_c(SwsContext *c, uint16_t *dst, int dstWidth, | |||
| const uint8_t *src, int srcW, int xInc, | |||
| const int16_t *hLumFilter, | |||
| const int16_t *hLumFilterPos, int hLumFilterSize, | |||
| uint8_t *formatConvBuffer, | |||
| uint32_t *pal, int isAlpha) | |||
| { | |||
| void (*toYV12)(uint8_t *, const uint8_t *, int, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12; | |||
| void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange; | |||
| src += isAlpha ? c->alpSrcOffset : c->lumSrcOffset; | |||
| if (toYV12) { | |||
| toYV12(formatConvBuffer, src, srcW, pal); | |||
| src= formatConvBuffer; | |||
| } | |||
| if (c->hScale16) { | |||
| int shift= isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8 ? 13 : av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1; | |||
| c->hScale16(dst, dstWidth, (const uint16_t*)src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize, shift); | |||
| } else if (!c->hyscale_fast) { | |||
| c->hScale(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize); | |||
| } else { // fast bilinear upscale / crap downscale | |||
| c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc); | |||
| } | |||
| if (convertRange) | |||
| convertRange(dst, dstWidth); | |||
| } | |||
| static inline void hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2, | |||
| int dstWidth, const uint8_t *src1, | |||
| const uint8_t *src2, int srcW, int xInc) | |||
| { | |||
| int i; | |||
| unsigned int xpos=0; | |||
| for (i=0;i<dstWidth;i++) { | |||
| register unsigned int xx=xpos>>16; | |||
| register unsigned int xalpha=(xpos&0xFFFF)>>9; | |||
| dst1[i]=(src1[xx]*(xalpha^127)+src1[xx+1]*xalpha); | |||
| dst2[i]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha); | |||
| xpos+=xInc; | |||
| } | |||
| for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) { | |||
| dst1[i] = src1[srcW-1]*128; | |||
| dst2[i] = src2[srcW-1]*128; | |||
| } | |||
| } | |||
| inline static void hcscale_c(SwsContext *c, uint16_t *dst1, uint16_t *dst2, int dstWidth, | |||
| const uint8_t *src1, const uint8_t *src2, | |||
| int srcW, int xInc, const int16_t *hChrFilter, | |||
| const int16_t *hChrFilterPos, int hChrFilterSize, | |||
| uint8_t *formatConvBuffer, uint32_t *pal) | |||
| { | |||
| src1 += c->chrSrcOffset; | |||
| src2 += c->chrSrcOffset; | |||
| if (c->chrToYV12) { | |||
| uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW*2+78, 16); | |||
| c->chrToYV12(formatConvBuffer, buf2, src1, src2, srcW, pal); | |||
| src1= formatConvBuffer; | |||
| src2= buf2; | |||
| } | |||
| if (c->hScale16) { | |||
| int shift= isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8 ? 13 : av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1; | |||
| c->hScale16(dst1, dstWidth, (const uint16_t*)src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, shift); | |||
| c->hScale16(dst2, dstWidth, (const uint16_t*)src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, shift); | |||
| } else if (!c->hcscale_fast) { | |||
| c->hScale(dst1, dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize); | |||
| c->hScale(dst2, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize); | |||
| } else { // fast bilinear upscale / crap downscale | |||
| c->hcscale_fast(c, dst1, dst2, dstWidth, src1, src2, srcW, xInc); | |||
| } | |||
| if (c->chrConvertRange) | |||
| c->chrConvertRange(dst1, dst2, dstWidth); | |||
| } | |||
| #define DEBUG_SWSCALE_BUFFERS 0 | |||
| #define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__) | |||
| @@ -0,0 +1,849 @@ | |||
| /* | |||
| * 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 <inttypes.h> | |||
| #include <string.h> | |||
| #include <math.h> | |||
| #include <stdio.h> | |||
| #include "config.h" | |||
| #include <assert.h> | |||
| #include "swscale.h" | |||
| #include "swscale_internal.h" | |||
| #include "rgb2rgb.h" | |||
| #include "libavutil/intreadwrite.h" | |||
| #include "libavutil/cpu.h" | |||
| #include "libavutil/avutil.h" | |||
| #include "libavutil/mathematics.h" | |||
| #include "libavutil/bswap.h" | |||
| #include "libavutil/pixdesc.h" | |||
| #define RGB2YUV_SHIFT 15 | |||
| #define BY ( (int)(0.114*219/255*(1<<RGB2YUV_SHIFT)+0.5)) | |||
| #define BV (-(int)(0.081*224/255*(1<<RGB2YUV_SHIFT)+0.5)) | |||
| #define BU ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5)) | |||
| #define GY ( (int)(0.587*219/255*(1<<RGB2YUV_SHIFT)+0.5)) | |||
| #define GV (-(int)(0.419*224/255*(1<<RGB2YUV_SHIFT)+0.5)) | |||
| #define GU (-(int)(0.331*224/255*(1<<RGB2YUV_SHIFT)+0.5)) | |||
| #define RY ( (int)(0.299*219/255*(1<<RGB2YUV_SHIFT)+0.5)) | |||
| #define RV ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5)) | |||
| #define RU (-(int)(0.169*224/255*(1<<RGB2YUV_SHIFT)+0.5)) | |||
| static void fillPlane(uint8_t* plane, int stride, int width, int height, int y, uint8_t val) | |||
| { | |||
| int i; | |||
| uint8_t *ptr = plane + stride*y; | |||
| for (i=0; i<height; i++) { | |||
| memset(ptr, val, width); | |||
| ptr += stride; | |||
| } | |||
| } | |||
| static void copyPlane(const uint8_t *src, int srcStride, | |||
| int srcSliceY, int srcSliceH, int width, | |||
| uint8_t *dst, int dstStride) | |||
| { | |||
| dst += dstStride * srcSliceY; | |||
| if (dstStride == srcStride && srcStride > 0) { | |||
| memcpy(dst, src, srcSliceH * dstStride); | |||
| } else { | |||
| int i; | |||
| for (i=0; i<srcSliceH; i++) { | |||
| memcpy(dst, src, width); | |||
| src += srcStride; | |||
| dst += dstStride; | |||
| } | |||
| } | |||
| } | |||
| static int planarToNv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dstParam[], int dstStride[]) | |||
| { | |||
| uint8_t *dst = dstParam[1] + dstStride[1]*srcSliceY/2; | |||
| copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW, | |||
| dstParam[0], dstStride[0]); | |||
| if (c->dstFormat == PIX_FMT_NV12) | |||
| interleaveBytes(src[1], src[2], dst, c->srcW/2, srcSliceH/2, srcStride[1], srcStride[2], dstStride[0]); | |||
| else | |||
| interleaveBytes(src[2], src[1], dst, c->srcW/2, srcSliceH/2, srcStride[2], srcStride[1], dstStride[0]); | |||
| return srcSliceH; | |||
| } | |||
| static int planarToYuy2Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dstParam[], int dstStride[]) | |||
| { | |||
| uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; | |||
| yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]); | |||
| return srcSliceH; | |||
| } | |||
| static int planarToUyvyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dstParam[], int dstStride[]) | |||
| { | |||
| uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; | |||
| yv12touyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]); | |||
| return srcSliceH; | |||
| } | |||
| static int yuv422pToYuy2Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dstParam[], int dstStride[]) | |||
| { | |||
| uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; | |||
| yuv422ptoyuy2(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]); | |||
| return srcSliceH; | |||
| } | |||
| static int yuv422pToUyvyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dstParam[], int dstStride[]) | |||
| { | |||
| uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; | |||
| yuv422ptouyvy(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]); | |||
| return srcSliceH; | |||
| } | |||
| static int yuyvToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dstParam[], int dstStride[]) | |||
| { | |||
| uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; | |||
| uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2; | |||
| uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2; | |||
| yuyvtoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); | |||
| if (dstParam[3]) | |||
| fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); | |||
| return srcSliceH; | |||
| } | |||
| static int yuyvToYuv422Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dstParam[], int dstStride[]) | |||
| { | |||
| uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; | |||
| uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY; | |||
| uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY; | |||
| yuyvtoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); | |||
| return srcSliceH; | |||
| } | |||
| static int uyvyToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dstParam[], int dstStride[]) | |||
| { | |||
| uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; | |||
| uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2; | |||
| uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2; | |||
| uyvytoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); | |||
| if (dstParam[3]) | |||
| fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); | |||
| return srcSliceH; | |||
| } | |||
| static int uyvyToYuv422Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dstParam[], int dstStride[]) | |||
| { | |||
| uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; | |||
| uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY; | |||
| uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY; | |||
| uyvytoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); | |||
| return srcSliceH; | |||
| } | |||
| static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) | |||
| { | |||
| int i; | |||
| for (i=0; i<num_pixels; i++) | |||
| ((uint32_t *) dst)[i] = ((const uint32_t *)palette)[src[i<<1]] | (src[(i<<1)+1] << 24); | |||
| } | |||
| static void gray8aToPacked32_1(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) | |||
| { | |||
| int i; | |||
| for (i=0; i<num_pixels; i++) | |||
| ((uint32_t *) dst)[i] = ((const uint32_t *)palette)[src[i<<1]] | src[(i<<1)+1]; | |||
| } | |||
| static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) | |||
| { | |||
| int i; | |||
| for (i=0; i<num_pixels; i++) { | |||
| //FIXME slow? | |||
| dst[0]= palette[src[i<<1]*4+0]; | |||
| dst[1]= palette[src[i<<1]*4+1]; | |||
| dst[2]= palette[src[i<<1]*4+2]; | |||
| dst+= 3; | |||
| } | |||
| } | |||
| static int palToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dst[], int dstStride[]) | |||
| { | |||
| const enum PixelFormat srcFormat= c->srcFormat; | |||
| const enum PixelFormat dstFormat= c->dstFormat; | |||
| void (*conv)(const uint8_t *src, uint8_t *dst, int num_pixels, | |||
| const uint8_t *palette)=NULL; | |||
| int i; | |||
| uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY; | |||
| const uint8_t *srcPtr= src[0]; | |||
| if (srcFormat == PIX_FMT_GRAY8A) { | |||
| switch (dstFormat) { | |||
| case PIX_FMT_RGB32 : conv = gray8aToPacked32; break; | |||
| case PIX_FMT_BGR32 : conv = gray8aToPacked32; break; | |||
| case PIX_FMT_BGR32_1: conv = gray8aToPacked32_1; break; | |||
| case PIX_FMT_RGB32_1: conv = gray8aToPacked32_1; break; | |||
| case PIX_FMT_RGB24 : conv = gray8aToPacked24; break; | |||
| case PIX_FMT_BGR24 : conv = gray8aToPacked24; break; | |||
| } | |||
| } else if (usePal(srcFormat)) { | |||
| switch (dstFormat) { | |||
| case PIX_FMT_RGB32 : conv = sws_convertPalette8ToPacked32; break; | |||
| case PIX_FMT_BGR32 : conv = sws_convertPalette8ToPacked32; break; | |||
| case PIX_FMT_BGR32_1: conv = sws_convertPalette8ToPacked32; break; | |||
| case PIX_FMT_RGB32_1: conv = sws_convertPalette8ToPacked32; break; | |||
| case PIX_FMT_RGB24 : conv = sws_convertPalette8ToPacked24; break; | |||
| case PIX_FMT_BGR24 : conv = sws_convertPalette8ToPacked24; break; | |||
| } | |||
| } | |||
| if (!conv) | |||
| av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n", | |||
| av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat)); | |||
| else { | |||
| for (i=0; i<srcSliceH; i++) { | |||
| conv(srcPtr, dstPtr, c->srcW, (uint8_t *) c->pal_rgb); | |||
| srcPtr+= srcStride[0]; | |||
| dstPtr+= dstStride[0]; | |||
| } | |||
| } | |||
| return srcSliceH; | |||
| } | |||
| #define isRGBA32(x) ( \ | |||
| (x) == PIX_FMT_ARGB \ | |||
| || (x) == PIX_FMT_RGBA \ | |||
| || (x) == PIX_FMT_BGRA \ | |||
| || (x) == PIX_FMT_ABGR \ | |||
| ) | |||
| /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */ | |||
| static int rgbToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dst[], int dstStride[]) | |||
| { | |||
| const enum PixelFormat srcFormat= c->srcFormat; | |||
| const enum PixelFormat dstFormat= c->dstFormat; | |||
| const int srcBpp= (c->srcFormatBpp + 7) >> 3; | |||
| const int dstBpp= (c->dstFormatBpp + 7) >> 3; | |||
| const int srcId= c->srcFormatBpp >> 2; /* 1:0, 4:1, 8:2, 15:3, 16:4, 24:6, 32:8 */ | |||
| const int dstId= c->dstFormatBpp >> 2; | |||
| void (*conv)(const uint8_t *src, uint8_t *dst, int src_size)=NULL; | |||
| #define CONV_IS(src, dst) (srcFormat == PIX_FMT_##src && dstFormat == PIX_FMT_##dst) | |||
| if (isRGBA32(srcFormat) && isRGBA32(dstFormat)) { | |||
| if ( CONV_IS(ABGR, RGBA) | |||
| || CONV_IS(ARGB, BGRA) | |||
| || CONV_IS(BGRA, ARGB) | |||
| || CONV_IS(RGBA, ABGR)) conv = shuffle_bytes_3210; | |||
| else if (CONV_IS(ABGR, ARGB) | |||
| || CONV_IS(ARGB, ABGR)) conv = shuffle_bytes_0321; | |||
| else if (CONV_IS(ABGR, BGRA) | |||
| || CONV_IS(ARGB, RGBA)) conv = shuffle_bytes_1230; | |||
| else if (CONV_IS(BGRA, RGBA) | |||
| || CONV_IS(RGBA, BGRA)) conv = shuffle_bytes_2103; | |||
| else if (CONV_IS(BGRA, ABGR) | |||
| || CONV_IS(RGBA, ARGB)) conv = shuffle_bytes_3012; | |||
| } else | |||
| /* BGR -> BGR */ | |||
| if ( (isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) | |||
| || (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) { | |||
| switch(srcId | (dstId<<4)) { | |||
| case 0x34: conv= rgb16to15; break; | |||
| case 0x36: conv= rgb24to15; break; | |||
| case 0x38: conv= rgb32to15; break; | |||
| case 0x43: conv= rgb15to16; break; | |||
| case 0x46: conv= rgb24to16; break; | |||
| case 0x48: conv= rgb32to16; break; | |||
| case 0x63: conv= rgb15to24; break; | |||
| case 0x64: conv= rgb16to24; break; | |||
| case 0x68: conv= rgb32to24; break; | |||
| case 0x83: conv= rgb15to32; break; | |||
| case 0x84: conv= rgb16to32; break; | |||
| case 0x86: conv= rgb24to32; break; | |||
| } | |||
| } else if ( (isBGRinInt(srcFormat) && isRGBinInt(dstFormat)) | |||
| || (isRGBinInt(srcFormat) && isBGRinInt(dstFormat))) { | |||
| switch(srcId | (dstId<<4)) { | |||
| case 0x33: conv= rgb15tobgr15; break; | |||
| case 0x34: conv= rgb16tobgr15; break; | |||
| case 0x36: conv= rgb24tobgr15; break; | |||
| case 0x38: conv= rgb32tobgr15; break; | |||
| case 0x43: conv= rgb15tobgr16; break; | |||
| case 0x44: conv= rgb16tobgr16; break; | |||
| case 0x46: conv= rgb24tobgr16; break; | |||
| case 0x48: conv= rgb32tobgr16; break; | |||
| case 0x63: conv= rgb15tobgr24; break; | |||
| case 0x64: conv= rgb16tobgr24; break; | |||
| case 0x66: conv= rgb24tobgr24; break; | |||
| case 0x68: conv= rgb32tobgr24; break; | |||
| case 0x83: conv= rgb15tobgr32; break; | |||
| case 0x84: conv= rgb16tobgr32; break; | |||
| case 0x86: conv= rgb24tobgr32; break; | |||
| } | |||
| } | |||
| if (!conv) { | |||
| av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n", | |||
| av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat)); | |||
| } else { | |||
| const uint8_t *srcPtr= src[0]; | |||
| uint8_t *dstPtr= dst[0]; | |||
| if ((srcFormat == PIX_FMT_RGB32_1 || srcFormat == PIX_FMT_BGR32_1) && !isRGBA32(dstFormat)) | |||
| srcPtr += ALT32_CORR; | |||
| if ((dstFormat == PIX_FMT_RGB32_1 || dstFormat == PIX_FMT_BGR32_1) && !isRGBA32(srcFormat)) | |||
| dstPtr += ALT32_CORR; | |||
| if (dstStride[0]*srcBpp == srcStride[0]*dstBpp && srcStride[0] > 0 && !(srcStride[0]%srcBpp)) | |||
| conv(srcPtr, dstPtr + dstStride[0]*srcSliceY, srcSliceH*srcStride[0]); | |||
| else { | |||
| int i; | |||
| dstPtr += dstStride[0]*srcSliceY; | |||
| for (i=0; i<srcSliceH; i++) { | |||
| conv(srcPtr, dstPtr, c->srcW*srcBpp); | |||
| srcPtr+= srcStride[0]; | |||
| dstPtr+= dstStride[0]; | |||
| } | |||
| } | |||
| } | |||
| return srcSliceH; | |||
| } | |||
| static int bgr24ToYv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dst[], int dstStride[]) | |||
| { | |||
| rgb24toyv12( | |||
| src[0], | |||
| dst[0]+ srcSliceY *dstStride[0], | |||
| dst[1]+(srcSliceY>>1)*dstStride[1], | |||
| dst[2]+(srcSliceY>>1)*dstStride[2], | |||
| c->srcW, srcSliceH, | |||
| dstStride[0], dstStride[1], srcStride[0]); | |||
| if (dst[3]) | |||
| fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); | |||
| return srcSliceH; | |||
| } | |||
| static int yvu9ToYv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dst[], int dstStride[]) | |||
| { | |||
| copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW, | |||
| dst[0], dstStride[0]); | |||
| planar2x(src[1], dst[1] + dstStride[1]*(srcSliceY >> 1), c->chrSrcW, | |||
| srcSliceH >> 2, srcStride[1], dstStride[1]); | |||
| planar2x(src[2], dst[2] + dstStride[2]*(srcSliceY >> 1), c->chrSrcW, | |||
| srcSliceH >> 2, srcStride[2], dstStride[2]); | |||
| if (dst[3]) | |||
| fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); | |||
| return srcSliceH; | |||
| } | |||
| /* unscaled copy like stuff (assumes nearly identical formats) */ | |||
| static int packedCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dst[], int dstStride[]) | |||
| { | |||
| if (dstStride[0]==srcStride[0] && srcStride[0] > 0) | |||
| memcpy(dst[0] + dstStride[0]*srcSliceY, src[0], srcSliceH*dstStride[0]); | |||
| else { | |||
| int i; | |||
| const uint8_t *srcPtr= src[0]; | |||
| uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY; | |||
| int length=0; | |||
| /* universal length finder */ | |||
| while(length+c->srcW <= FFABS(dstStride[0]) | |||
| && length+c->srcW <= FFABS(srcStride[0])) length+= c->srcW; | |||
| assert(length!=0); | |||
| for (i=0; i<srcSliceH; i++) { | |||
| memcpy(dstPtr, srcPtr, length); | |||
| srcPtr+= srcStride[0]; | |||
| dstPtr+= dstStride[0]; | |||
| } | |||
| } | |||
| return srcSliceH; | |||
| } | |||
| #define DITHER_COPY(dst, dstStride, src, srcStride, bswap, dbswap)\ | |||
| uint16_t scale= dither_scale[dst_depth-1][src_depth-1];\ | |||
| int shift= src_depth-dst_depth + dither_scale[src_depth-2][dst_depth-1];\ | |||
| for (i = 0; i < height; i++) {\ | |||
| const uint8_t *dither= dithers[src_depth-9][i&7];\ | |||
| for (j = 0; j < length-7; j+=8){\ | |||
| dst[j+0] = dbswap((bswap(src[j+0]) + dither[0])*scale>>shift);\ | |||
| dst[j+1] = dbswap((bswap(src[j+1]) + dither[1])*scale>>shift);\ | |||
| dst[j+2] = dbswap((bswap(src[j+2]) + dither[2])*scale>>shift);\ | |||
| dst[j+3] = dbswap((bswap(src[j+3]) + dither[3])*scale>>shift);\ | |||
| dst[j+4] = dbswap((bswap(src[j+4]) + dither[4])*scale>>shift);\ | |||
| dst[j+5] = dbswap((bswap(src[j+5]) + dither[5])*scale>>shift);\ | |||
| dst[j+6] = dbswap((bswap(src[j+6]) + dither[6])*scale>>shift);\ | |||
| dst[j+7] = dbswap((bswap(src[j+7]) + dither[7])*scale>>shift);\ | |||
| }\ | |||
| for (; j < length; j++)\ | |||
| dst[j] = dbswap((bswap(src[j]) + dither[j&7])*scale>>shift);\ | |||
| dst += dstStride;\ | |||
| src += srcStride;\ | |||
| } | |||
| static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dst[], int dstStride[]) | |||
| { | |||
| int plane, i, j; | |||
| for (plane=0; plane<4; plane++) { | |||
| int length= (plane==0 || plane==3) ? c->srcW : -((-c->srcW )>>c->chrDstHSubSample); | |||
| int y= (plane==0 || plane==3) ? srcSliceY: -((-srcSliceY)>>c->chrDstVSubSample); | |||
| int height= (plane==0 || plane==3) ? srcSliceH: -((-srcSliceH)>>c->chrDstVSubSample); | |||
| const uint8_t *srcPtr= src[plane]; | |||
| uint8_t *dstPtr= dst[plane] + dstStride[plane]*y; | |||
| if (!dst[plane]) continue; | |||
| // ignore palette for GRAY8 | |||
| if (plane == 1 && !dst[2]) continue; | |||
| if (!src[plane] || (plane == 1 && !src[2])) { | |||
| if(is16BPS(c->dstFormat)) | |||
| length*=2; | |||
| fillPlane(dst[plane], dstStride[plane], length, height, y, (plane==3) ? 255 : 128); | |||
| } else { | |||
| if(isNBPS(c->srcFormat) || isNBPS(c->dstFormat) | |||
| || (is16BPS(c->srcFormat) != is16BPS(c->dstFormat)) | |||
| ) { | |||
| const int src_depth = av_pix_fmt_descriptors[c->srcFormat].comp[plane].depth_minus1+1; | |||
| const int dst_depth = av_pix_fmt_descriptors[c->dstFormat].comp[plane].depth_minus1+1; | |||
| const uint16_t *srcPtr2 = (const uint16_t*)srcPtr; | |||
| uint16_t *dstPtr2 = (uint16_t*)dstPtr; | |||
| if (dst_depth == 8) { | |||
| if(isBE(c->srcFormat) == HAVE_BIGENDIAN){ | |||
| DITHER_COPY(dstPtr, dstStride[plane], srcPtr2, srcStride[plane]/2, , ) | |||
| } else { | |||
| DITHER_COPY(dstPtr, dstStride[plane], srcPtr2, srcStride[plane]/2, av_bswap16, ) | |||
| } | |||
| } else if (src_depth == 8) { | |||
| for (i = 0; i < height; i++) { | |||
| if(isBE(c->dstFormat)){ | |||
| for (j = 0; j < length; j++) | |||
| AV_WB16(&dstPtr2[j], (srcPtr[j]<<(dst_depth-8)) | | |||
| (srcPtr[j]>>(2*8-dst_depth))); | |||
| } else { | |||
| for (j = 0; j < length; j++) | |||
| AV_WL16(&dstPtr2[j], (srcPtr[j]<<(dst_depth-8)) | | |||
| (srcPtr[j]>>(2*8-dst_depth))); | |||
| } | |||
| dstPtr2 += dstStride[plane]/2; | |||
| srcPtr += srcStride[plane]; | |||
| } | |||
| } else if (src_depth <= dst_depth) { | |||
| for (i = 0; i < height; i++) { | |||
| #define COPY_UP(r,w) \ | |||
| for (j = 0; j < length; j++){ \ | |||
| unsigned int v= r(&srcPtr2[j]);\ | |||
| w(&dstPtr2[j], (v<<(dst_depth-src_depth)) | \ | |||
| (v>>(2*src_depth-dst_depth)));\ | |||
| } | |||
| if(isBE(c->srcFormat)){ | |||
| if(isBE(c->dstFormat)){ | |||
| COPY_UP(AV_RB16, AV_WB16) | |||
| } else { | |||
| COPY_UP(AV_RB16, AV_WL16) | |||
| } | |||
| } else { | |||
| if(isBE(c->dstFormat)){ | |||
| COPY_UP(AV_RL16, AV_WB16) | |||
| } else { | |||
| COPY_UP(AV_RL16, AV_WL16) | |||
| } | |||
| } | |||
| dstPtr2 += dstStride[plane]/2; | |||
| srcPtr2 += srcStride[plane]/2; | |||
| } | |||
| } else { | |||
| if(isBE(c->srcFormat) == HAVE_BIGENDIAN){ | |||
| if(isBE(c->dstFormat) == HAVE_BIGENDIAN){ | |||
| DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, , ) | |||
| } else { | |||
| DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, , av_bswap16) | |||
| } | |||
| }else{ | |||
| if(isBE(c->dstFormat) == HAVE_BIGENDIAN){ | |||
| DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, av_bswap16, ) | |||
| } else { | |||
| DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, av_bswap16, av_bswap16) | |||
| } | |||
| } | |||
| } | |||
| } else if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat) | |||
| && isBE(c->srcFormat) != isBE(c->dstFormat)) { | |||
| for (i=0; i<height; i++) { | |||
| for (j=0; j<length; j++) | |||
| ((uint16_t*)dstPtr)[j] = av_bswap16(((const uint16_t*)srcPtr)[j]); | |||
| srcPtr+= srcStride[plane]; | |||
| dstPtr+= dstStride[plane]; | |||
| } | |||
| } else if (dstStride[plane] == srcStride[plane] && | |||
| srcStride[plane] > 0 && srcStride[plane] == length) { | |||
| memcpy(dst[plane] + dstStride[plane]*y, src[plane], | |||
| height*dstStride[plane]); | |||
| } else { | |||
| if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) | |||
| length*=2; | |||
| for (i=0; i<height; i++) { | |||
| memcpy(dstPtr, srcPtr, length); | |||
| srcPtr+= srcStride[plane]; | |||
| dstPtr+= dstStride[plane]; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| return srcSliceH; | |||
| } | |||
| void ff_get_unscaled_swscale(SwsContext *c) | |||
| { | |||
| const enum PixelFormat srcFormat = c->srcFormat; | |||
| const enum PixelFormat dstFormat = c->dstFormat; | |||
| const int flags = c->flags; | |||
| const int dstH = c->dstH; | |||
| int needsDither; | |||
| needsDither= isAnyRGB(dstFormat) | |||
| && c->dstFormatBpp < 24 | |||
| && (c->dstFormatBpp < c->srcFormatBpp || (!isAnyRGB(srcFormat))); | |||
| /* yv12_to_nv12 */ | |||
| if ((srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUVA420P) && (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21)) { | |||
| c->swScale= planarToNv12Wrapper; | |||
| } | |||
| /* yuv2bgr */ | |||
| if ((srcFormat==PIX_FMT_YUV420P || srcFormat==PIX_FMT_YUV422P || srcFormat==PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) | |||
| && !(flags & SWS_ACCURATE_RND) && !(dstH&1)) { | |||
| c->swScale= ff_yuv2rgb_get_func_ptr(c); | |||
| } | |||
| if (srcFormat==PIX_FMT_YUV410P && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_BITEXACT)) { | |||
| c->swScale= yvu9ToYv12Wrapper; | |||
| } | |||
| /* bgr24toYV12 */ | |||
| if (srcFormat==PIX_FMT_BGR24 && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_ACCURATE_RND)) | |||
| c->swScale= bgr24ToYv12Wrapper; | |||
| /* RGB/BGR -> RGB/BGR (no dither needed forms) */ | |||
| if ( isAnyRGB(srcFormat) | |||
| && isAnyRGB(dstFormat) | |||
| && srcFormat != PIX_FMT_BGR8 && dstFormat != PIX_FMT_BGR8 | |||
| && srcFormat != PIX_FMT_RGB8 && dstFormat != PIX_FMT_RGB8 | |||
| && srcFormat != PIX_FMT_BGR4 && dstFormat != PIX_FMT_BGR4 | |||
| && srcFormat != PIX_FMT_RGB4 && dstFormat != PIX_FMT_RGB4 | |||
| && srcFormat != PIX_FMT_BGR4_BYTE && dstFormat != PIX_FMT_BGR4_BYTE | |||
| && srcFormat != PIX_FMT_RGB4_BYTE && dstFormat != PIX_FMT_RGB4_BYTE | |||
| && srcFormat != PIX_FMT_MONOBLACK && dstFormat != PIX_FMT_MONOBLACK | |||
| && srcFormat != PIX_FMT_MONOWHITE && dstFormat != PIX_FMT_MONOWHITE | |||
| && srcFormat != PIX_FMT_RGB48LE && dstFormat != PIX_FMT_RGB48LE | |||
| && srcFormat != PIX_FMT_RGB48BE && dstFormat != PIX_FMT_RGB48BE | |||
| && srcFormat != PIX_FMT_BGR48LE && dstFormat != PIX_FMT_BGR48LE | |||
| && srcFormat != PIX_FMT_BGR48BE && dstFormat != PIX_FMT_BGR48BE | |||
| && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)))) | |||
| c->swScale= rgbToRgbWrapper; | |||
| if ((usePal(srcFormat) && ( | |||
| dstFormat == PIX_FMT_RGB32 || | |||
| dstFormat == PIX_FMT_RGB32_1 || | |||
| dstFormat == PIX_FMT_RGB24 || | |||
| dstFormat == PIX_FMT_BGR32 || | |||
| dstFormat == PIX_FMT_BGR32_1 || | |||
| dstFormat == PIX_FMT_BGR24))) | |||
| c->swScale= palToRgbWrapper; | |||
| if (srcFormat == PIX_FMT_YUV422P) { | |||
| if (dstFormat == PIX_FMT_YUYV422) | |||
| c->swScale= yuv422pToYuy2Wrapper; | |||
| else if (dstFormat == PIX_FMT_UYVY422) | |||
| c->swScale= yuv422pToUyvyWrapper; | |||
| } | |||
| /* LQ converters if -sws 0 or -sws 4*/ | |||
| if (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)) { | |||
| /* yv12_to_yuy2 */ | |||
| if (srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUVA420P) { | |||
| if (dstFormat == PIX_FMT_YUYV422) | |||
| c->swScale= planarToYuy2Wrapper; | |||
| else if (dstFormat == PIX_FMT_UYVY422) | |||
| c->swScale= planarToUyvyWrapper; | |||
| } | |||
| } | |||
| if(srcFormat == PIX_FMT_YUYV422 && (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P)) | |||
| c->swScale= yuyvToYuv420Wrapper; | |||
| if(srcFormat == PIX_FMT_UYVY422 && (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P)) | |||
| c->swScale= uyvyToYuv420Wrapper; | |||
| if(srcFormat == PIX_FMT_YUYV422 && dstFormat == PIX_FMT_YUV422P) | |||
| c->swScale= yuyvToYuv422Wrapper; | |||
| if(srcFormat == PIX_FMT_UYVY422 && dstFormat == PIX_FMT_YUV422P) | |||
| c->swScale= uyvyToYuv422Wrapper; | |||
| /* simple copy */ | |||
| if ( srcFormat == dstFormat | |||
| || (srcFormat == PIX_FMT_YUVA420P && dstFormat == PIX_FMT_YUV420P) | |||
| || (srcFormat == PIX_FMT_YUV420P && dstFormat == PIX_FMT_YUVA420P) | |||
| || (isPlanarYUV(srcFormat) && isGray(dstFormat)) | |||
| || (isPlanarYUV(dstFormat) && isGray(srcFormat)) | |||
| || (isGray(dstFormat) && isGray(srcFormat)) | |||
| || (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat) | |||
| && c->chrDstHSubSample == c->chrSrcHSubSample | |||
| && c->chrDstVSubSample == c->chrSrcVSubSample | |||
| && dstFormat != PIX_FMT_NV12 && dstFormat != PIX_FMT_NV21 | |||
| && srcFormat != PIX_FMT_NV12 && srcFormat != PIX_FMT_NV21)) | |||
| { | |||
| if (isPacked(c->srcFormat)) | |||
| c->swScale= packedCopyWrapper; | |||
| else /* Planar YUV or gray */ | |||
| c->swScale= planarCopyWrapper; | |||
| } | |||
| if (ARCH_BFIN) | |||
| ff_bfin_get_unscaled_swscale(c); | |||
| if (HAVE_ALTIVEC) | |||
| ff_swscale_get_unscaled_altivec(c); | |||
| } | |||
| static void reset_ptr(const uint8_t* src[], int format) | |||
| { | |||
| if(!isALPHA(format)) | |||
| src[3]=NULL; | |||
| if(!isPlanarYUV(format)) { | |||
| src[3]=src[2]=NULL; | |||
| if (!usePal(format)) | |||
| src[1]= NULL; | |||
| } | |||
| } | |||
| static int check_image_pointers(uint8_t *data[4], enum PixelFormat pix_fmt, | |||
| const int linesizes[4]) | |||
| { | |||
| const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; | |||
| int i; | |||
| for (i = 0; i < 4; i++) { | |||
| int plane = desc->comp[i].plane; | |||
| if (!data[plane] || !linesizes[plane]) | |||
| return 0; | |||
| } | |||
| return 1; | |||
| } | |||
| /** | |||
| * swscale wrapper, so we don't need to export the SwsContext. | |||
| * Assumes planar YUV to be in YUV order instead of YVU. | |||
| */ | |||
| int sws_scale(SwsContext *c, const uint8_t* const src[], const int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* const dst[], const int dstStride[]) | |||
| { | |||
| int i; | |||
| const uint8_t* src2[4]= {src[0], src[1], src[2], src[3]}; | |||
| uint8_t* dst2[4]= {dst[0], dst[1], dst[2], dst[3]}; | |||
| // do not mess up sliceDir if we have a "trailing" 0-size slice | |||
| if (srcSliceH == 0) | |||
| return 0; | |||
| if (!check_image_pointers(src, c->srcFormat, srcStride)) { | |||
| av_log(c, AV_LOG_ERROR, "bad src image pointers\n"); | |||
| return 0; | |||
| } | |||
| if (!check_image_pointers(dst, c->dstFormat, dstStride)) { | |||
| av_log(c, AV_LOG_ERROR, "bad dst image pointers\n"); | |||
| return 0; | |||
| } | |||
| if (c->sliceDir == 0 && srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) { | |||
| av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n"); | |||
| return 0; | |||
| } | |||
| if (c->sliceDir == 0) { | |||
| if (srcSliceY == 0) c->sliceDir = 1; else c->sliceDir = -1; | |||
| } | |||
| if (usePal(c->srcFormat)) { | |||
| for (i=0; i<256; i++) { | |||
| int p, r, g, b, y, u, v, a = 0xff; | |||
| if(c->srcFormat == PIX_FMT_PAL8) { | |||
| p=((const uint32_t*)(src[1]))[i]; | |||
| a= (p>>24)&0xFF; | |||
| r= (p>>16)&0xFF; | |||
| g= (p>> 8)&0xFF; | |||
| b= p &0xFF; | |||
| } else if(c->srcFormat == PIX_FMT_RGB8) { | |||
| r= (i>>5 )*36; | |||
| g= ((i>>2)&7)*36; | |||
| b= (i&3 )*85; | |||
| } else if(c->srcFormat == PIX_FMT_BGR8) { | |||
| b= (i>>6 )*85; | |||
| g= ((i>>3)&7)*36; | |||
| r= (i&7 )*36; | |||
| } else if(c->srcFormat == PIX_FMT_RGB4_BYTE) { | |||
| r= (i>>3 )*255; | |||
| g= ((i>>1)&3)*85; | |||
| b= (i&1 )*255; | |||
| } else if(c->srcFormat == PIX_FMT_GRAY8 || c->srcFormat == PIX_FMT_GRAY8A) { | |||
| r = g = b = i; | |||
| } else { | |||
| assert(c->srcFormat == PIX_FMT_BGR4_BYTE); | |||
| b= (i>>3 )*255; | |||
| g= ((i>>1)&3)*85; | |||
| r= (i&1 )*255; | |||
| } | |||
| y= av_clip_uint8((RY*r + GY*g + BY*b + ( 33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT); | |||
| u= av_clip_uint8((RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT); | |||
| v= av_clip_uint8((RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT); | |||
| c->pal_yuv[i]= y + (u<<8) + (v<<16) + (a<<24); | |||
| switch(c->dstFormat) { | |||
| case PIX_FMT_BGR32: | |||
| #if !HAVE_BIGENDIAN | |||
| case PIX_FMT_RGB24: | |||
| #endif | |||
| c->pal_rgb[i]= r + (g<<8) + (b<<16) + (a<<24); | |||
| break; | |||
| case PIX_FMT_BGR32_1: | |||
| #if HAVE_BIGENDIAN | |||
| case PIX_FMT_BGR24: | |||
| #endif | |||
| c->pal_rgb[i]= a + (r<<8) + (g<<16) + (b<<24); | |||
| break; | |||
| case PIX_FMT_RGB32_1: | |||
| #if HAVE_BIGENDIAN | |||
| case PIX_FMT_RGB24: | |||
| #endif | |||
| c->pal_rgb[i]= a + (b<<8) + (g<<16) + (r<<24); | |||
| break; | |||
| case PIX_FMT_RGB32: | |||
| #if !HAVE_BIGENDIAN | |||
| case PIX_FMT_BGR24: | |||
| #endif | |||
| default: | |||
| c->pal_rgb[i]= b + (g<<8) + (r<<16) + (a<<24); | |||
| } | |||
| } | |||
| } | |||
| // copy strides, so they can safely be modified | |||
| if (c->sliceDir == 1) { | |||
| // slices go from top to bottom | |||
| int srcStride2[4]= {srcStride[0], srcStride[1], srcStride[2], srcStride[3]}; | |||
| int dstStride2[4]= {dstStride[0], dstStride[1], dstStride[2], dstStride[3]}; | |||
| reset_ptr(src2, c->srcFormat); | |||
| reset_ptr((const uint8_t**)dst2, c->dstFormat); | |||
| /* reset slice direction at end of frame */ | |||
| if (srcSliceY + srcSliceH == c->srcH) | |||
| c->sliceDir = 0; | |||
| return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2, dstStride2); | |||
| } else { | |||
| // slices go from bottom to top => we flip the image internally | |||
| int srcStride2[4]= {-srcStride[0], -srcStride[1], -srcStride[2], -srcStride[3]}; | |||
| int dstStride2[4]= {-dstStride[0], -dstStride[1], -dstStride[2], -dstStride[3]}; | |||
| src2[0] += (srcSliceH-1)*srcStride[0]; | |||
| if (!usePal(c->srcFormat)) | |||
| src2[1] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[1]; | |||
| src2[2] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[2]; | |||
| src2[3] += (srcSliceH-1)*srcStride[3]; | |||
| dst2[0] += ( c->dstH -1)*dstStride[0]; | |||
| dst2[1] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[1]; | |||
| dst2[2] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[2]; | |||
| dst2[3] += ( c->dstH -1)*dstStride[3]; | |||
| reset_ptr(src2, c->srcFormat); | |||
| reset_ptr((const uint8_t**)dst2, c->dstFormat); | |||
| /* reset slice direction at end of frame */ | |||
| if (!srcSliceY) | |||
| c->sliceDir = 0; | |||
| return c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH, srcSliceH, dst2, dstStride2); | |||
| } | |||
| } | |||
| #if LIBSWSCALE_VERSION_MAJOR < 1 | |||
| int sws_scale_ordered(SwsContext *c, const uint8_t* const src[], int srcStride[], int srcSliceY, | |||
| int srcSliceH, uint8_t* dst[], int dstStride[]) | |||
| { | |||
| return sws_scale(c, src, srcStride, srcSliceY, srcSliceH, dst, dstStride); | |||
| } | |||
| #endif | |||
| /* Convert the palette to the same packed 32-bit format as the palette */ | |||
| void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) | |||
| { | |||
| int i; | |||
| for (i=0; i<num_pixels; i++) | |||
| ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i]]; | |||
| } | |||
| /* Palette format: ABCD -> dst format: ABC */ | |||
| void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) | |||
| { | |||
| int i; | |||
| for (i=0; i<num_pixels; i++) { | |||
| //FIXME slow? | |||
| dst[0]= palette[src[i]*4+0]; | |||
| dst[1]= palette[src[i]*4+1]; | |||
| dst[2]= palette[src[i]*4+2]; | |||
| dst+= 3; | |||
| } | |||
| } | |||
| @@ -0,0 +1,187 @@ | |||
| /* | |||
| * 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 <inttypes.h> | |||
| #include "config.h" | |||
| #include "libswscale/swscale.h" | |||
| #include "libswscale/swscale_internal.h" | |||
| #include "libavutil/intreadwrite.h" | |||
| #include "libavutil/x86_cpu.h" | |||
| #include "libavutil/cpu.h" | |||
| #include "libavutil/pixdesc.h" | |||
| DECLARE_ASM_CONST(8, uint64_t, bF8)= 0xF8F8F8F8F8F8F8F8LL; | |||
| DECLARE_ASM_CONST(8, uint64_t, bFC)= 0xFCFCFCFCFCFCFCFCLL; | |||
| DECLARE_ASM_CONST(8, uint64_t, w10)= 0x0010001000100010LL; | |||
| DECLARE_ASM_CONST(8, uint64_t, w02)= 0x0002000200020002LL; | |||
| DECLARE_ASM_CONST(8, uint64_t, bm00001111)=0x00000000FFFFFFFFLL; | |||
| DECLARE_ASM_CONST(8, uint64_t, bm00000111)=0x0000000000FFFFFFLL; | |||
| DECLARE_ASM_CONST(8, uint64_t, bm11111000)=0xFFFFFFFFFF000000LL; | |||
| DECLARE_ASM_CONST(8, uint64_t, bm01010101)=0x00FF00FF00FF00FFLL; | |||
| const DECLARE_ALIGNED(8, uint64_t, ff_dither4)[2] = { | |||
| 0x0103010301030103LL, | |||
| 0x0200020002000200LL,}; | |||
| const DECLARE_ALIGNED(8, uint64_t, ff_dither8)[2] = { | |||
| 0x0602060206020602LL, | |||
| 0x0004000400040004LL,}; | |||
| DECLARE_ASM_CONST(8, uint64_t, b16Mask)= 0x001F001F001F001FLL; | |||
| DECLARE_ASM_CONST(8, uint64_t, g16Mask)= 0x07E007E007E007E0LL; | |||
| DECLARE_ASM_CONST(8, uint64_t, r16Mask)= 0xF800F800F800F800LL; | |||
| DECLARE_ASM_CONST(8, uint64_t, b15Mask)= 0x001F001F001F001FLL; | |||
| DECLARE_ASM_CONST(8, uint64_t, g15Mask)= 0x03E003E003E003E0LL; | |||
| DECLARE_ASM_CONST(8, uint64_t, r15Mask)= 0x7C007C007C007C00LL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_M24A) = 0x00FF0000FF0000FFLL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_M24B) = 0xFF0000FF0000FF00LL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_M24C) = 0x0000FF0000FF0000LL; | |||
| #ifdef FAST_BGR2YV12 | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2YCoeff) = 0x000000210041000DULL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2UCoeff) = 0x0000FFEEFFDC0038ULL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2VCoeff) = 0x00000038FFD2FFF8ULL; | |||
| #else | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2YCoeff) = 0x000020E540830C8BULL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2UCoeff) = 0x0000ED0FDAC23831ULL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2VCoeff) = 0x00003831D0E6F6EAULL; | |||
| #endif /* FAST_BGR2YV12 */ | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2YOffset) = 0x1010101010101010ULL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2UVOffset) = 0x8080808080808080ULL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_w1111) = 0x0001000100010001ULL; | |||
| DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toY1Coeff) = 0x0C88000040870C88ULL; | |||
| DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toY2Coeff) = 0x20DE4087000020DEULL; | |||
| DECLARE_ASM_CONST(8, uint64_t, ff_rgb24toY1Coeff) = 0x20DE0000408720DEULL; | |||
| DECLARE_ASM_CONST(8, uint64_t, ff_rgb24toY2Coeff) = 0x0C88408700000C88ULL; | |||
| DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toYOffset) = 0x0008010000080100ULL; | |||
| DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toUV)[2][4] = { | |||
| {0x38380000DAC83838ULL, 0xECFFDAC80000ECFFULL, 0xF6E40000D0E3F6E4ULL, 0x3838D0E300003838ULL}, | |||
| {0xECFF0000DAC8ECFFULL, 0x3838DAC800003838ULL, 0x38380000D0E33838ULL, 0xF6E4D0E30000F6E4ULL}, | |||
| }; | |||
| DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toUVOffset)= 0x0040010000400100ULL; | |||
| //MMX versions | |||
| #if HAVE_MMX | |||
| #undef RENAME | |||
| #define COMPILE_TEMPLATE_MMX2 0 | |||
| #define RENAME(a) a ## _MMX | |||
| #include "swscale_template.c" | |||
| #endif | |||
| //MMX2 versions | |||
| #if HAVE_MMX2 | |||
| #undef RENAME | |||
| #undef COMPILE_TEMPLATE_MMX2 | |||
| #define COMPILE_TEMPLATE_MMX2 1 | |||
| #define RENAME(a) a ## _MMX2 | |||
| #include "swscale_template.c" | |||
| #endif | |||
| void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufIndex, | |||
| int lastInLumBuf, int lastInChrBuf) | |||
| { | |||
| const int dstH= c->dstH; | |||
| const int flags= c->flags; | |||
| int16_t **lumPixBuf= c->lumPixBuf; | |||
| int16_t **chrUPixBuf= c->chrUPixBuf; | |||
| int16_t **alpPixBuf= c->alpPixBuf; | |||
| const int vLumBufSize= c->vLumBufSize; | |||
| const int vChrBufSize= c->vChrBufSize; | |||
| int16_t *vLumFilterPos= c->vLumFilterPos; | |||
| int16_t *vChrFilterPos= c->vChrFilterPos; | |||
| int16_t *vLumFilter= c->vLumFilter; | |||
| int16_t *vChrFilter= c->vChrFilter; | |||
| int32_t *lumMmxFilter= c->lumMmxFilter; | |||
| int32_t *chrMmxFilter= c->chrMmxFilter; | |||
| int32_t av_unused *alpMmxFilter= c->alpMmxFilter; | |||
| const int vLumFilterSize= c->vLumFilterSize; | |||
| const int vChrFilterSize= c->vChrFilterSize; | |||
| const int chrDstY= dstY>>c->chrDstVSubSample; | |||
| const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input | |||
| const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input | |||
| c->blueDither= ff_dither8[dstY&1]; | |||
| if (c->dstFormat == PIX_FMT_RGB555 || c->dstFormat == PIX_FMT_BGR555) | |||
| c->greenDither= ff_dither8[dstY&1]; | |||
| else | |||
| c->greenDither= ff_dither4[dstY&1]; | |||
| c->redDither= ff_dither8[(dstY+1)&1]; | |||
| if (dstY < dstH - 2) { | |||
| const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize; | |||
| const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; | |||
| const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL; | |||
| int i; | |||
| if (flags & SWS_ACCURATE_RND) { | |||
| int s= APCK_SIZE / 8; | |||
| for (i=0; i<vLumFilterSize; i+=2) { | |||
| *(const void**)&lumMmxFilter[s*i ]= lumSrcPtr[i ]; | |||
| *(const void**)&lumMmxFilter[s*i+APCK_PTR2/4 ]= lumSrcPtr[i+(vLumFilterSize>1)]; | |||
| lumMmxFilter[s*i+APCK_COEF/4 ]= | |||
| lumMmxFilter[s*i+APCK_COEF/4+1]= vLumFilter[dstY*vLumFilterSize + i ] | |||
| + (vLumFilterSize>1 ? vLumFilter[dstY*vLumFilterSize + i + 1]<<16 : 0); | |||
| if (CONFIG_SWSCALE_ALPHA && alpPixBuf) { | |||
| *(const void**)&alpMmxFilter[s*i ]= alpSrcPtr[i ]; | |||
| *(const void**)&alpMmxFilter[s*i+APCK_PTR2/4 ]= alpSrcPtr[i+(vLumFilterSize>1)]; | |||
| alpMmxFilter[s*i+APCK_COEF/4 ]= | |||
| alpMmxFilter[s*i+APCK_COEF/4+1]= lumMmxFilter[s*i+APCK_COEF/4 ]; | |||
| } | |||
| } | |||
| for (i=0; i<vChrFilterSize; i+=2) { | |||
| *(const void**)&chrMmxFilter[s*i ]= chrUSrcPtr[i ]; | |||
| *(const void**)&chrMmxFilter[s*i+APCK_PTR2/4 ]= chrUSrcPtr[i+(vChrFilterSize>1)]; | |||
| chrMmxFilter[s*i+APCK_COEF/4 ]= | |||
| chrMmxFilter[s*i+APCK_COEF/4+1]= vChrFilter[chrDstY*vChrFilterSize + i ] | |||
| + (vChrFilterSize>1 ? vChrFilter[chrDstY*vChrFilterSize + i + 1]<<16 : 0); | |||
| } | |||
| } else { | |||
| for (i=0; i<vLumFilterSize; i++) { | |||
| *(const void**)&lumMmxFilter[4*i+0]= lumSrcPtr[i]; | |||
| lumMmxFilter[4*i+2]= | |||
| lumMmxFilter[4*i+3]= | |||
| ((uint16_t)vLumFilter[dstY*vLumFilterSize + i])*0x10001; | |||
| if (CONFIG_SWSCALE_ALPHA && alpPixBuf) { | |||
| *(const void**)&alpMmxFilter[4*i+0]= alpSrcPtr[i]; | |||
| alpMmxFilter[4*i+2]= | |||
| alpMmxFilter[4*i+3]= lumMmxFilter[4*i+2]; | |||
| } | |||
| } | |||
| for (i=0; i<vChrFilterSize; i++) { | |||
| *(const void**)&chrMmxFilter[4*i+0]= chrUSrcPtr[i]; | |||
| chrMmxFilter[4*i+2]= | |||
| chrMmxFilter[4*i+3]= | |||
| ((uint16_t)vChrFilter[chrDstY*vChrFilterSize + i])*0x10001; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| void ff_sws_init_swScale_mmx(SwsContext *c) | |||
| { | |||
| int cpu_flags = av_get_cpu_flags(); | |||
| if (cpu_flags & AV_CPU_FLAG_MMX) | |||
| sws_init_swScale_MMX(c); | |||
| if (cpu_flags & AV_CPU_FLAG_MMX2) | |||
| sws_init_swScale_MMX2(c); | |||
| } | |||
| @@ -18,8 +18,6 @@ | |||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #include "swscale_template.h" | |||
| #undef REAL_MOVNTQ | |||
| #undef MOVNTQ | |||
| #undef PREFETCH | |||
| @@ -2351,86 +2349,6 @@ static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst1, int16_t *d | |||
| } | |||
| #endif /* COMPILE_TEMPLATE_MMX2 */ | |||
| #if !COMPILE_TEMPLATE_MMX2 | |||
| static void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufIndex, | |||
| int lastInLumBuf, int lastInChrBuf) | |||
| { | |||
| const int dstH= c->dstH; | |||
| const int flags= c->flags; | |||
| int16_t **lumPixBuf= c->lumPixBuf; | |||
| int16_t **chrUPixBuf= c->chrUPixBuf; | |||
| int16_t **alpPixBuf= c->alpPixBuf; | |||
| const int vLumBufSize= c->vLumBufSize; | |||
| const int vChrBufSize= c->vChrBufSize; | |||
| int16_t *vLumFilterPos= c->vLumFilterPos; | |||
| int16_t *vChrFilterPos= c->vChrFilterPos; | |||
| int16_t *vLumFilter= c->vLumFilter; | |||
| int16_t *vChrFilter= c->vChrFilter; | |||
| int32_t *lumMmxFilter= c->lumMmxFilter; | |||
| int32_t *chrMmxFilter= c->chrMmxFilter; | |||
| int32_t av_unused *alpMmxFilter= c->alpMmxFilter; | |||
| const int vLumFilterSize= c->vLumFilterSize; | |||
| const int vChrFilterSize= c->vChrFilterSize; | |||
| const int chrDstY= dstY>>c->chrDstVSubSample; | |||
| const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input | |||
| const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input | |||
| c->blueDither= ff_dither8[dstY&1]; | |||
| if (c->dstFormat == PIX_FMT_RGB555 || c->dstFormat == PIX_FMT_BGR555) | |||
| c->greenDither= ff_dither8[dstY&1]; | |||
| else | |||
| c->greenDither= ff_dither4[dstY&1]; | |||
| c->redDither= ff_dither8[(dstY+1)&1]; | |||
| if (dstY < dstH - 2) { | |||
| const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize; | |||
| const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; | |||
| const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL; | |||
| int i; | |||
| if (flags & SWS_ACCURATE_RND) { | |||
| int s= APCK_SIZE / 8; | |||
| for (i=0; i<vLumFilterSize; i+=2) { | |||
| *(const void**)&lumMmxFilter[s*i ]= lumSrcPtr[i ]; | |||
| *(const void**)&lumMmxFilter[s*i+APCK_PTR2/4 ]= lumSrcPtr[i+(vLumFilterSize>1)]; | |||
| lumMmxFilter[s*i+APCK_COEF/4 ]= | |||
| lumMmxFilter[s*i+APCK_COEF/4+1]= vLumFilter[dstY*vLumFilterSize + i ] | |||
| + (vLumFilterSize>1 ? vLumFilter[dstY*vLumFilterSize + i + 1]<<16 : 0); | |||
| if (CONFIG_SWSCALE_ALPHA && alpPixBuf) { | |||
| *(const void**)&alpMmxFilter[s*i ]= alpSrcPtr[i ]; | |||
| *(const void**)&alpMmxFilter[s*i+APCK_PTR2/4 ]= alpSrcPtr[i+(vLumFilterSize>1)]; | |||
| alpMmxFilter[s*i+APCK_COEF/4 ]= | |||
| alpMmxFilter[s*i+APCK_COEF/4+1]= lumMmxFilter[s*i+APCK_COEF/4 ]; | |||
| } | |||
| } | |||
| for (i=0; i<vChrFilterSize; i+=2) { | |||
| *(const void**)&chrMmxFilter[s*i ]= chrUSrcPtr[i ]; | |||
| *(const void**)&chrMmxFilter[s*i+APCK_PTR2/4 ]= chrUSrcPtr[i+(vChrFilterSize>1)]; | |||
| chrMmxFilter[s*i+APCK_COEF/4 ]= | |||
| chrMmxFilter[s*i+APCK_COEF/4+1]= vChrFilter[chrDstY*vChrFilterSize + i ] | |||
| + (vChrFilterSize>1 ? vChrFilter[chrDstY*vChrFilterSize + i + 1]<<16 : 0); | |||
| } | |||
| } else { | |||
| for (i=0; i<vLumFilterSize; i++) { | |||
| *(const void**)&lumMmxFilter[4*i+0]= lumSrcPtr[i]; | |||
| lumMmxFilter[4*i+2]= | |||
| lumMmxFilter[4*i+3]= | |||
| ((uint16_t)vLumFilter[dstY*vLumFilterSize + i])*0x10001; | |||
| if (CONFIG_SWSCALE_ALPHA && alpPixBuf) { | |||
| *(const void**)&alpMmxFilter[4*i+0]= alpSrcPtr[i]; | |||
| alpMmxFilter[4*i+2]= | |||
| alpMmxFilter[4*i+3]= lumMmxFilter[4*i+2]; | |||
| } | |||
| } | |||
| for (i=0; i<vChrFilterSize; i++) { | |||
| *(const void**)&chrMmxFilter[4*i+0]= chrUSrcPtr[i]; | |||
| chrMmxFilter[4*i+2]= | |||
| chrMmxFilter[4*i+3]= | |||
| ((uint16_t)vChrFilter[chrDstY*vChrFilterSize + i])*0x10001; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| #endif /* !COMPILE_TEMPLATE_MMX2 */ | |||
| static void RENAME(sws_init_swScale)(SwsContext *c) | |||
| { | |||
| enum PixelFormat srcFormat = c->srcFormat; | |||
| @@ -1,79 +0,0 @@ | |||
| /* | |||
| * 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 | |||
| */ | |||
| #ifndef SWSCALE_X86_SWSCALE_TEMPLATE_H | |||
| #define SWSCALE_X86_SWSCALE_TEMPLATE_H | |||
| DECLARE_ASM_CONST(8, uint64_t, bF8)= 0xF8F8F8F8F8F8F8F8LL; | |||
| DECLARE_ASM_CONST(8, uint64_t, bFC)= 0xFCFCFCFCFCFCFCFCLL; | |||
| DECLARE_ASM_CONST(8, uint64_t, w10)= 0x0010001000100010LL; | |||
| DECLARE_ASM_CONST(8, uint64_t, w02)= 0x0002000200020002LL; | |||
| DECLARE_ASM_CONST(8, uint64_t, bm00001111)=0x00000000FFFFFFFFLL; | |||
| DECLARE_ASM_CONST(8, uint64_t, bm00000111)=0x0000000000FFFFFFLL; | |||
| DECLARE_ASM_CONST(8, uint64_t, bm11111000)=0xFFFFFFFFFF000000LL; | |||
| DECLARE_ASM_CONST(8, uint64_t, bm01010101)=0x00FF00FF00FF00FFLL; | |||
| const DECLARE_ALIGNED(8, uint64_t, ff_dither4)[2] = { | |||
| 0x0103010301030103LL, | |||
| 0x0200020002000200LL,}; | |||
| const DECLARE_ALIGNED(8, uint64_t, ff_dither8)[2] = { | |||
| 0x0602060206020602LL, | |||
| 0x0004000400040004LL,}; | |||
| DECLARE_ASM_CONST(8, uint64_t, b16Mask)= 0x001F001F001F001FLL; | |||
| DECLARE_ASM_CONST(8, uint64_t, g16Mask)= 0x07E007E007E007E0LL; | |||
| DECLARE_ASM_CONST(8, uint64_t, r16Mask)= 0xF800F800F800F800LL; | |||
| DECLARE_ASM_CONST(8, uint64_t, b15Mask)= 0x001F001F001F001FLL; | |||
| DECLARE_ASM_CONST(8, uint64_t, g15Mask)= 0x03E003E003E003E0LL; | |||
| DECLARE_ASM_CONST(8, uint64_t, r15Mask)= 0x7C007C007C007C00LL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_M24A) = 0x00FF0000FF0000FFLL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_M24B) = 0xFF0000FF0000FF00LL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_M24C) = 0x0000FF0000FF0000LL; | |||
| #ifdef FAST_BGR2YV12 | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2YCoeff) = 0x000000210041000DULL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2UCoeff) = 0x0000FFEEFFDC0038ULL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2VCoeff) = 0x00000038FFD2FFF8ULL; | |||
| #else | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2YCoeff) = 0x000020E540830C8BULL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2UCoeff) = 0x0000ED0FDAC23831ULL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2VCoeff) = 0x00003831D0E6F6EAULL; | |||
| #endif /* FAST_BGR2YV12 */ | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2YOffset) = 0x1010101010101010ULL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_bgr2UVOffset) = 0x8080808080808080ULL; | |||
| DECLARE_ALIGNED(8, const uint64_t, ff_w1111) = 0x0001000100010001ULL; | |||
| DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toY1Coeff) = 0x0C88000040870C88ULL; | |||
| DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toY2Coeff) = 0x20DE4087000020DEULL; | |||
| DECLARE_ASM_CONST(8, uint64_t, ff_rgb24toY1Coeff) = 0x20DE0000408720DEULL; | |||
| DECLARE_ASM_CONST(8, uint64_t, ff_rgb24toY2Coeff) = 0x0C88408700000C88ULL; | |||
| DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toYOffset) = 0x0008010000080100ULL; | |||
| DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toUV)[2][4] = { | |||
| {0x38380000DAC83838ULL, 0xECFFDAC80000ECFFULL, 0xF6E40000D0E3F6E4ULL, 0x3838D0E300003838ULL}, | |||
| {0xECFF0000DAC8ECFFULL, 0x3838DAC800003838ULL, 0x38380000D0E33838ULL, 0xF6E4D0E30000F6E4ULL}, | |||
| }; | |||
| DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toUVOffset)= 0x0040010000400100ULL; | |||
| #endif /* SWSCALE_X86_SWSCALE_TEMPLATE_H */ | |||
| @@ -50,12 +50,12 @@ endif | |||
| clean:: | |||
| $(RM) $(addprefix $(SUBDIR),*-example$(EXESUF) *-test$(EXESUF) $(CLEANFILES) $(CLEANSUFFIXES) $(LIBSUFFIXES)) \ | |||
| $(addprefix $(SUBDIR), $(foreach suffix,$(CLEANSUFFIXES),$(addsuffix /$(suffix),$(DIRS)))) \ | |||
| $(foreach dir,$(DIRS),$(CLEANSUFFIXES:%=$(SUBDIR)$(dir)/%)) \ | |||
| $(HOSTOBJS) $(HOSTPROGS) | |||
| distclean:: clean | |||
| $(RM) $(addprefix $(SUBDIR),$(DISTCLEANSUFFIXES)) \ | |||
| $(addprefix $(SUBDIR), $(foreach suffix,$(DISTCLEANSUFFIXES),$(addsuffix /$(suffix),$(DIRS)))) | |||
| $(RM) $(DISTCLEANSUFFIXES:%=$(SUBDIR)%) \ | |||
| $(foreach dir,$(DIRS),$(DISTCLEANSUFFIXES:%=$(SUBDIR)$(dir)/%)) | |||
| install-lib$(NAME)-shared: $(SUBDIR)$(SLIBNAME) | |||
| $(Q)mkdir -p "$(SHLIBDIR)" | |||