* 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: TAG = HTML | ||||
| doc/%.html: doc/%.texi $(SRC_PATH_BARE)/doc/t2h.init | doc/%.html: doc/%.texi $(SRC_PATH_BARE)/doc/t2h.init | ||||
| $(Q)$(TEXIDEP) | $(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: TAG = POD | ||||
| doc/%.pod: doc/%.texi | doc/%.pod: doc/%.texi | ||||
| @@ -1208,8 +1208,8 @@ static void do_video_out(AVFormatContext *s, | |||||
| av_log(NULL, AV_LOG_INFO, | 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", | "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, | 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_width = dec->width; | ||||
| ost->resample_height = dec->height; | ost->resample_height = dec->height; | ||||
| ost->resample_pix_fmt = dec->pix_fmt; | 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__) | # define LOCAL_ALIGNED_16(t, v, ...) LOCAL_ALIGNED(16, t, v, __VA_ARGS__) | ||||
| #endif | #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)\ | #define WRAPPER8_16(name8, name16)\ | ||||
| static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ | static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ | ||||
| return name8(s, dst , src , stride, h)\ | return name8(s, dst , src , stride, h)\ | ||||
| @@ -38,6 +38,7 @@ | |||||
| * DV codec. | * DV codec. | ||||
| */ | */ | ||||
| #define ALT_BITSTREAM_READER | #define ALT_BITSTREAM_READER | ||||
| #include "libavutil/pixdesc.h" | |||||
| #include "avcodec.h" | #include "avcodec.h" | ||||
| #include "dsputil.h" | #include "dsputil.h" | ||||
| #include "get_bits.h" | #include "get_bits.h" | ||||
| @@ -350,7 +351,7 @@ static av_cold int dvvideo_init_encoder(AVCodecContext *avctx) | |||||
| { | { | ||||
| if (!ff_dv_codec_profile(avctx)) { | if (!ff_dv_codec_profile(avctx)) { | ||||
| av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video\n", | 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; | return -1; | ||||
| } | } | ||||
| @@ -1002,7 +1002,7 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) | |||||
| static int count_frame_header(FlacEncodeContext *s) | static int count_frame_header(FlacEncodeContext *s) | ||||
| { | { | ||||
| uint8_t tmp; | |||||
| uint8_t av_unused tmp; | |||||
| int count; | int count; | ||||
| /* | /* | ||||
| @@ -586,8 +586,7 @@ av_cold int MPV_common_init(MpegEncContext *s) | |||||
| return -1; | 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))){ | (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"); | av_log(s->avctx, AV_LOG_ERROR, "too many threads\n"); | ||||
| return -1; | return -1; | ||||
| @@ -746,7 +745,7 @@ av_cold int MPV_common_init(MpegEncContext *s) | |||||
| s->context_initialized = 1; | s->context_initialized = 1; | ||||
| s->thread_context[0]= s; | 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; | threads = s->avctx->thread_count; | ||||
| for(i=1; i<threads; i++){ | for(i=1; i<threads; i++){ | ||||
| @@ -778,7 +777,7 @@ void MPV_common_end(MpegEncContext *s) | |||||
| { | { | ||||
| int i, j, k; | 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++){ | for(i=0; i<s->avctx->thread_count; i++){ | ||||
| free_duplicate_context(s->thread_context[i]); | free_duplicate_context(s->thread_context[i]); | ||||
| } | } | ||||
| @@ -1226,7 +1226,7 @@ int MPV_encode_picture(AVCodecContext *avctx, | |||||
| { | { | ||||
| MpegEncContext *s = avctx->priv_data; | MpegEncContext *s = avctx->priv_data; | ||||
| AVFrame *pic_arg = 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++){ | for(i=0; i<context_count; i++){ | ||||
| int start_y= s->thread_context[i]->start_mb_y; | 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 i; | ||||
| int bits; | 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; | s->picture_number = picture_number; | ||||
| @@ -821,9 +821,10 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) | |||||
| if (!s->context_initialized) { | if (!s->context_initialized) { | ||||
| h->chroma_qp[0] = h->chroma_qp[1] = 4; | h->chroma_qp[0] = h->chroma_qp[1] = 4; | ||||
| svq3->halfpel_flag = 1; | |||||
| svq3->halfpel_flag = 1; | |||||
| svq3->thirdpel_flag = 1; | svq3->thirdpel_flag = 1; | ||||
| svq3->unknown_flag = 0; | |||||
| svq3->unknown_flag = 0; | |||||
| /* prowl for the "SEQH" marker in the extradata */ | /* prowl for the "SEQH" marker in the extradata */ | ||||
| extradata = (unsigned char *)avctx->extradata; | extradata = (unsigned char *)avctx->extradata; | ||||
| @@ -20,6 +20,7 @@ | |||||
| */ | */ | ||||
| #include "libavutil/intreadwrite.h" | #include "libavutil/intreadwrite.h" | ||||
| #include "libavutil/pixdesc.h" | |||||
| #include "avcodec.h" | #include "avcodec.h" | ||||
| #include "rle.h" | #include "rle.h" | ||||
| #include "targa.h" | #include "targa.h" | ||||
| @@ -119,7 +120,7 @@ static int targa_encode_frame(AVCodecContext *avctx, | |||||
| break; | break; | ||||
| default: | default: | ||||
| av_log(avctx, AV_LOG_ERROR, "Pixel format '%s' not supported.\n", | 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); | return AVERROR(EINVAL); | ||||
| } | } | ||||
| bpp = outbuf[16] >> 3; | 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) { | if (enc->pix_fmt != PIX_FMT_NONE) { | ||||
| snprintf(buf + strlen(buf), buf_size - strlen(buf), | snprintf(buf + strlen(buf), buf_size - strlen(buf), | ||||
| ", %s", | ", %s", | ||||
| avcodec_get_pix_fmt_name(enc->pix_fmt)); | |||||
| av_get_pix_fmt_name(enc->pix_fmt)); | |||||
| } | } | ||||
| if (enc->width) { | if (enc->width) { | ||||
| snprintf(buf + strlen(buf), buf_size - strlen(buf), | 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 | /** 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 */ | that need to be skipped at the beginning or end of a stream */ | ||||
| if (get_bits1(gb)) { | if (get_bits1(gb)) { | ||||
| int skip; | |||||
| int av_unused skip; | |||||
| /** usually true for the first frame */ | /** usually true for the first frame */ | ||||
| if (get_bits1(gb)) { | if (get_bits1(gb)) { | ||||
| @@ -256,10 +256,32 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) | |||||
| goto out; | 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) { | if ((ret = av_parse_video_size(&width, &height, s->video_size)) < 0) { | ||||
| av_log(s1, AV_LOG_ERROR, "Couldn't parse video size.\n"); | av_log(s1, AV_LOG_ERROR, "Couldn't parse video size.\n"); | ||||
| goto out; | 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) { | if ((ret = av_parse_video_rate(&fps, s->framerate)) < 0) { | ||||
| av_log(s1, AV_LOG_ERROR, "Couldn't parse framerate.\n"); | av_log(s1, AV_LOG_ERROR, "Couldn't parse framerate.\n"); | ||||
| goto out; | 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.den = fps.num; | ||||
| st->codec->time_base.num = fps.den; | 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, | if (bktr_init(s1->filename, width, height, s->standard, | ||||
| &(s->video_fd), &(s->tuner_fd), -1, 0.0) < 0) { | &(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" }, | { "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" }, | { "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 }, | { "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 }, | { NULL }, | ||||
| }; | }; | ||||
| @@ -162,7 +162,7 @@ static inline int dc1394_read_common(AVFormatContext *c, AVFormatParameters *ap, | |||||
| break; | break; | ||||
| if (!fps->frame_rate || !fmt->width) { | 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); | width, height, dc1394->frame_rate); | ||||
| ret = AVERROR(EINVAL); | ret = AVERROR(EINVAL); | ||||
| goto out; | goto out; | ||||
| @@ -26,6 +26,12 @@ | |||||
| #define MAX_URL_SIZE 4096 | #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 { | typedef struct AVCodecTag { | ||||
| enum CodecID id; | enum CodecID id; | ||||
| unsigned int tag; | unsigned int tag; | ||||
| @@ -433,7 +433,7 @@ static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom) | |||||
| { | { | ||||
| AVStream *st; | AVStream *st; | ||||
| uint32_t type; | uint32_t type; | ||||
| uint32_t ctype; | |||||
| uint32_t av_unused ctype; | |||||
| if (c->fc->nb_streams < 1) // meta before first trak | if (c->fc->nb_streams < 1) // meta before first trak | ||||
| return 0; | 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_dec_config_descr_len = 0; | ||||
| int mp4_es_id = 0; | int mp4_es_id = 0; | ||||
| #ifdef DEBUG | |||||
| av_dlog(ts->stream, "PMT: len %i\n", section_len); | 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_end = section + section_len - 4; | ||||
| p = section; | p = section; | ||||
| @@ -1151,10 +1149,9 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len | |||||
| int sid, pmt_pid; | int sid, pmt_pid; | ||||
| AVProgram *program; | AVProgram *program; | ||||
| #ifdef DEBUG | |||||
| av_dlog(ts->stream, "PAT:\n"); | 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_end = section + section_len - 4; | ||||
| p = section; | p = section; | ||||
| if (parse_section_header(h, &p, p_end) < 0) | 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; | int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type; | ||||
| char *name, *provider_name; | char *name, *provider_name; | ||||
| #ifdef DEBUG | |||||
| av_dlog(ts->stream, "SDT:\n"); | 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_end = section + section_len - 4; | ||||
| p = section; | p = section; | ||||
| @@ -267,7 +267,8 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| { | { | ||||
| NSVContext *nsv = s->priv_data; | NSVContext *nsv = s->priv_data; | ||||
| AVIOContext *pb = s->pb; | AVIOContext *pb = s->pb; | ||||
| unsigned int file_size, size; | |||||
| unsigned int av_unused file_size; | |||||
| unsigned int size; | |||||
| int64_t duration; | int64_t duration; | ||||
| int strings_size; | int strings_size; | ||||
| int table_entries; | int table_entries; | ||||
| @@ -546,7 +547,7 @@ static int nsv_read_chunk(AVFormatContext *s, int fill_header) | |||||
| uint32_t vsize; | uint32_t vsize; | ||||
| uint16_t asize; | uint16_t asize; | ||||
| uint16_t auxsize; | uint16_t auxsize; | ||||
| uint32_t auxtag; | |||||
| uint32_t av_unused auxtag; | |||||
| av_dlog(s, "%s(%d)\n", __FUNCTION__, fill_header); | 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); | AVStream *st = av_new_stream(s, 0); | ||||
| char filename[258]; | char filename[258]; | ||||
| int tmp, tmp2; | |||||
| int tmp; | |||||
| int av_unused tmp2; | |||||
| if (!st) | if (!st) | ||||
| return AVERROR(ENOMEM); | return AVERROR(ENOMEM); | ||||
| @@ -139,7 +140,7 @@ static int r3d_read_rdvo(AVFormatContext *s, Atom *atom) | |||||
| static void r3d_read_reos(AVFormatContext *s) | static void r3d_read_reos(AVFormatContext *s) | ||||
| { | { | ||||
| R3DContext *r3d = s->priv_data; | R3DContext *r3d = s->priv_data; | ||||
| int tmp; | |||||
| int av_unused tmp; | |||||
| r3d->rdvo_offset = avio_rb32(s->pb); | r3d->rdvo_offset = avio_rb32(s->pb); | ||||
| avio_rb32(s->pb); // rdvs offset | 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) | static int r3d_read_redv(AVFormatContext *s, AVPacket *pkt, Atom *atom) | ||||
| { | { | ||||
| AVStream *st = s->streams[0]; | AVStream *st = s->streams[0]; | ||||
| int tmp, tmp2; | |||||
| int tmp; | |||||
| int av_unused tmp2; | |||||
| uint64_t pos = avio_tell(s->pb); | uint64_t pos = avio_tell(s->pb); | ||||
| unsigned dts; | unsigned dts; | ||||
| int ret; | 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) | static int r3d_read_reda(AVFormatContext *s, AVPacket *pkt, Atom *atom) | ||||
| { | { | ||||
| AVStream *st = s->streams[1]; | 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); | uint64_t pos = avio_tell(s->pb); | ||||
| unsigned dts; | unsigned dts; | ||||
| int ret; | int ret; | ||||
| @@ -70,7 +70,7 @@ int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| } | } | ||||
| case AVMEDIA_TYPE_VIDEO: { | case AVMEDIA_TYPE_VIDEO: { | ||||
| FFRawVideoDemuxerContext *s1 = s->priv_data; | FFRawVideoDemuxerContext *s1 = s->priv_data; | ||||
| int width = 0, height = 0, ret; | |||||
| int width = 0, height = 0, ret = 0; | |||||
| enum PixelFormat pix_fmt; | enum PixelFormat pix_fmt; | ||||
| if(ap->time_base.num) | if(ap->time_base.num) | ||||
| @@ -97,7 +97,6 @@ int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| st->codec->width = width; | st->codec->width = width; | ||||
| st->codec->height = height; | st->codec->height = height; | ||||
| st->codec->pix_fmt = pix_fmt; | st->codec->pix_fmt = pix_fmt; | ||||
| break; | |||||
| fail: | fail: | ||||
| av_freep(&s1->video_size); | av_freep(&s1->video_size); | ||||
| av_freep(&s1->pixel_format); | av_freep(&s1->pixel_format); | ||||
| @@ -321,7 +321,7 @@ int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count) | |||||
| avio_flush(pb); | avio_flush(pb); | ||||
| len = avio_close_dyn_buf(pb, &buf); | len = avio_close_dyn_buf(pb, &buf); | ||||
| if ((len > 0) && buf) { | if ((len > 0) && buf) { | ||||
| int result; | |||||
| int av_unused result; | |||||
| av_dlog(s->ic, "sending %d bytes of RR\n", len); | av_dlog(s->ic, "sending %d bytes of RR\n", len); | ||||
| result= ffurl_write(s->rtp_ctx, buf, len); | result= ffurl_write(s->rtp_ctx, buf, len); | ||||
| av_dlog(s->ic, "result from ffurl_write: %d\n", result); | 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 | #if 0 | ||||
| { | { | ||||
| int i; | int i; | ||||
| AVStream *st; | |||||
| AVStream av_unused *st; | |||||
| for(i = 0;i < ic->nb_streams; i++) { | for(i = 0;i < ic->nb_streams; i++) { | ||||
| st = ic->streams[i]; | st = ic->streams[i]; | ||||
| printf("%d: start_time: %0.3f duration: %0.3f\n", | printf("%d: start_time: %0.3f duration: %0.3f\n", | ||||
| @@ -5,14 +5,18 @@ FFLIBS = avutil | |||||
| HEADERS = swscale.h | 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 \ | OBJS-$(ARCH_BFIN) += bfin/internal_bfin.o \ | ||||
| bfin/swscale_bfin.o \ | bfin/swscale_bfin.o \ | ||||
| bfin/yuv2rgb_bfin.o | bfin/yuv2rgb_bfin.o | ||||
| OBJS-$(CONFIG_MLIB) += mlib/yuv2rgb_mlib.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 \ | OBJS-$(HAVE_MMX) += x86/rgb2rgb.o \ | ||||
| x86/swscale_mmx.o \ | |||||
| x86/yuv2rgb_mmx.o | x86/yuv2rgb_mmx.o | ||||
| OBJS-$(HAVE_VIS) += sparc/yuv2rgb_vis.o | OBJS-$(HAVE_VIS) += sparc/yuv2rgb_vis.o | ||||
| @@ -21,6 +21,13 @@ | |||||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | * 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) | #define vzero vec_splat_s32(0) | ||||
| static inline void | 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, | int lumFilterSize, const int16_t *chrFilter, | ||||
| const int16_t **chrUSrc, const int16_t **chrVSrc, | 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)}; | const vector signed int vini = {(1 << 18), (1 << 18), (1 << 18), (1 << 18)}; | ||||
| register int i, j; | 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; | register int i; | ||||
| DECLARE_ALIGNED(16, int, tempo)[4]; | 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 "libswscale/swscale_internal.h" | ||||
| #include "libavutil/cpu.h" | #include "libavutil/cpu.h" | ||||
| #include "libavutil/pixdesc.h" | #include "libavutil/pixdesc.h" | ||||
| #include "yuv2rgb_altivec.h" | |||||
| #undef PROFILE_THE_BEAST | #undef PROFILE_THE_BEAST | ||||
| #undef INC_SCALING | #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 **lumSrc, int lumFilterSize, | ||||
| const int16_t *chrFilter, const int16_t **chrUSrc, | const int16_t *chrFilter, const int16_t **chrUSrc, | ||||
| const int16_t **chrVSrc, int chrFilterSize, | 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; | int i,j; | ||||
| vector signed short X,X0,X1,Y0,U0,V0,Y1,U1,V1,U,V; | 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 MAX_FILTER_SIZE 256 | ||||
| #define DITHER1XBPP | |||||
| #if HAVE_BIGENDIAN | #if HAVE_BIGENDIAN | ||||
| #define ALT32_CORR (-1) | #define ALT32_CORR (-1) | ||||
| #else | #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], | void ff_yuv2rgb_init_tables_altivec(SwsContext *c, const int inv_table[4], | ||||
| int brightness, int contrast, int saturation); | 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_mmx(SwsContext *c); | ||||
| SwsFunc ff_yuv2rgb_init_vis(SwsContext *c); | SwsFunc ff_yuv2rgb_init_vis(SwsContext *c); | ||||
| SwsFunc ff_yuv2rgb_init_mlib(SwsContext *c); | SwsFunc ff_yuv2rgb_init_mlib(SwsContext *c); | ||||
| SwsFunc ff_yuv2rgb_init_altivec(SwsContext *c); | SwsFunc ff_yuv2rgb_init_altivec(SwsContext *c); | ||||
| SwsFunc ff_yuv2rgb_get_func_ptr_bfin(SwsContext *c); | SwsFunc ff_yuv2rgb_get_func_ptr_bfin(SwsContext *c); | ||||
| void ff_bfin_get_unscaled_swscale(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 | #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_GRAY8A \ | ||||
| || (x)==PIX_FMT_YUVA420P \ | || (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) | #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_dither4[2]; | ||||
| extern const uint64_t ff_dither8[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; | 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_get_unscaled_swscale(SwsContext *c); | ||||
| void ff_swscale_get_unscaled_altivec(SwsContext *c); | |||||
| /** | /** | ||||
| * Returns function pointer to fastest main scaler path function depending | * Returns function pointer to fastest main scaler path function depending | ||||
| * on architecture and available optimizations. | * on architecture and available optimizations. | ||||
| */ | */ | ||||
| SwsFunc ff_getSwsFunc(SwsContext *c); | 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 */ | #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); | 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 | // bilinear / bicubic scaling | ||||
| static inline void hScale_c(int16_t *dst, int dstW, const uint8_t *src, | static inline void hScale_c(int16_t *dst, int dstW, const uint8_t *src, | ||||
| int srcW, int xInc, | 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_SWSCALE_BUFFERS 0 | ||||
| #define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__) | #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 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||
| */ | */ | ||||
| #include "swscale_template.h" | |||||
| #undef REAL_MOVNTQ | #undef REAL_MOVNTQ | ||||
| #undef MOVNTQ | #undef MOVNTQ | ||||
| #undef PREFETCH | #undef PREFETCH | ||||
| @@ -2351,86 +2349,6 @@ static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst1, int16_t *d | |||||
| } | } | ||||
| #endif /* COMPILE_TEMPLATE_MMX2 */ | #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) | static void RENAME(sws_init_swScale)(SwsContext *c) | ||||
| { | { | ||||
| enum PixelFormat srcFormat = c->srcFormat; | 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:: | clean:: | ||||
| $(RM) $(addprefix $(SUBDIR),*-example$(EXESUF) *-test$(EXESUF) $(CLEANFILES) $(CLEANSUFFIXES) $(LIBSUFFIXES)) \ | $(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) | $(HOSTOBJS) $(HOSTPROGS) | ||||
| distclean:: clean | 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) | install-lib$(NAME)-shared: $(SUBDIR)$(SLIBNAME) | ||||
| $(Q)mkdir -p "$(SHLIBDIR)" | $(Q)mkdir -p "$(SHLIBDIR)" | ||||