diff --git a/compat/avisynth/avisynth_c_25.h b/compat/avisynth/avisynth_c_25.h new file mode 100644 index 0000000000..9288761331 --- /dev/null +++ b/compat/avisynth/avisynth_c_25.h @@ -0,0 +1,68 @@ +// Copyright (c) 2011 FFmpegSource Project +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +/* these are defines/functions that are used and were changed in the switch to 2.6 + * and are needed to maintain full compatility with 2.5 */ + +enum { + AVS_CS_YV12_25 = 1<<3 | AVS_CS_YUV | AVS_CS_PLANAR, // y-v-u, planar + AVS_CS_I420_25 = 1<<4 | AVS_CS_YUV | AVS_CS_PLANAR, // y-u-v, planar +}; + +AVSC_INLINE int avs_get_height_p_25(const AVS_VideoFrame * p, int plane) { + switch (plane) + { + case AVS_PLANAR_U: case AVS_PLANAR_V: + if (p->pitchUV) + return p->height>>1; + return 0; + } + return p->height;} + +AVSC_INLINE int avs_get_row_size_p_25(const AVS_VideoFrame * p, int plane) { + int r; + switch (plane) + { + case AVS_PLANAR_U: case AVS_PLANAR_V: + if (p->pitchUV) + return p->row_size>>1; + else + return 0; + case AVS_PLANAR_U_ALIGNED: case AVS_PLANAR_V_ALIGNED: + if (p->pitchUV) + { + r = ((p->row_size+AVS_FRAME_ALIGN-1)&(~(AVS_FRAME_ALIGN-1)) )>>1; // Aligned rowsize + if (r < p->pitchUV) + return r; + return p->row_size>>1; + } + else + return 0; + case AVS_PLANAR_Y_ALIGNED: + r = (p->row_size+AVS_FRAME_ALIGN-1)&(~(AVS_FRAME_ALIGN-1)); // Aligned rowsize + if (r <= p->pitch) + return r; + return p->row_size; + } + return p->row_size; +} + +AVSC_INLINE int avs_is_yv12_25(const AVS_VideoInfo * p) + { return ((p->pixel_type & AVS_CS_YV12_25) == AVS_CS_YV12_25)||((p->pixel_type & AVS_CS_I420_25) == AVS_CS_I420_25); } diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c index 8a480ede21..afacf04dd1 100644 --- a/libavformat/avisynth.c +++ b/libavformat/avisynth.c @@ -36,6 +36,7 @@ #include #undef EXTERN_C #include "compat/avisynth/avisynth_c.h" + #include "compat/avisynth/avisynth_c_25.h" #define AVISYNTH_LIB "avisynth" #else #include @@ -471,9 +472,20 @@ static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, int dis for (i = 0; i < avs->n_planes; i++) { plane = avs->planes[i]; src_p = avs_get_read_ptr_p(frame, plane); + pitch = avs_get_pitch_p(frame, plane); + +#ifdef _WIN32 + if (avs_library->avs_get_version(avs->clip) == 3) { + rowsize = avs_get_row_size_p_25(frame, plane); + planeheight = avs_get_height_p_25(frame, plane); + } else { + rowsize = avs_get_row_size_p(frame, plane); + planeheight = avs_get_height_p(frame, plane); + } +#else rowsize = avs_get_row_size_p(frame, plane); planeheight = avs_get_height_p(frame, plane); - pitch = avs_get_pitch_p(frame, plane); +#endif // Flip RGB video. if (avs_is_rgb24(avs->vi) || avs_is_rgb(avs->vi)) { @@ -481,26 +493,7 @@ static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, int dis pitch = -pitch; } - // An issue with avs_bit_blt on 2.5.8 prevents video from working correctly. - // This problem doesn't exist for 2.6 and AvxSynth, so enable the workaround - // for 2.5.8 only. This only displays the warning and exits if the script has - // video. 2.5.8's internal interface version is 3, so avs_get_version allows - // it to work only in the circumstance that the interface is 5 or higher (4 is - // unused). There's a strong chance that AvxSynth, having been based on 2.5.8, - // would also be identified as interface version 3, but since AvxSynth doesn't - // suffer from this problem, special-case it. -#ifdef _WIN32 - if (avs_library->avs_get_version(avs->clip) > 3) { avs_library->avs_bit_blt(avs->env, dst_p, rowsize, src_p, pitch, rowsize, planeheight); - } else { - av_log(s, AV_LOG_ERROR, "Video input from AviSynth 2.5.8 is not supported. Please upgrade to 2.6.\n"); - avs->error = 1; - av_freep(&pkt->data); - return AVERROR_UNKNOWN; - } -#else - avs_library->avs_bit_blt(avs->env, dst_p, rowsize, src_p, pitch, rowsize, planeheight); -#endif dst_p += rowsize * planeheight; }