|
|
|
@@ -19,8 +19,11 @@ |
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
|
|
*/ |
|
|
|
|
|
|
|
#include "libavutil/attributes.h" |
|
|
|
#include "libavutil/internal.h" |
|
|
|
|
|
|
|
#include "libavcodec/internal.h" |
|
|
|
|
|
|
|
#include "avformat.h" |
|
|
|
#include "internal.h" |
|
|
|
#include "config.h" |
|
|
|
@@ -69,6 +72,8 @@ typedef struct AviSynthLibrary { |
|
|
|
AVSC_DECLARE_FUNC(avs_get_pitch_p); |
|
|
|
AVSC_DECLARE_FUNC(avs_get_read_ptr_p); |
|
|
|
AVSC_DECLARE_FUNC(avs_get_row_size_p); |
|
|
|
AVSC_DECLARE_FUNC(avs_is_planar_rgb); |
|
|
|
AVSC_DECLARE_FUNC(avs_is_planar_rgba); |
|
|
|
#endif |
|
|
|
#undef AVSC_DECLARE_FUNC |
|
|
|
} AviSynthLibrary; |
|
|
|
@@ -96,6 +101,14 @@ static const int avs_planes_packed[1] = { 0 }; |
|
|
|
static const int avs_planes_grey[1] = { AVS_PLANAR_Y }; |
|
|
|
static const int avs_planes_yuv[3] = { AVS_PLANAR_Y, AVS_PLANAR_U, |
|
|
|
AVS_PLANAR_V }; |
|
|
|
#ifdef USING_AVISYNTH |
|
|
|
static const int avs_planes_rgb[3] = { AVS_PLANAR_G, AVS_PLANAR_B, |
|
|
|
AVS_PLANAR_R }; |
|
|
|
static const int avs_planes_yuva[4] = { AVS_PLANAR_Y, AVS_PLANAR_U, |
|
|
|
AVS_PLANAR_V, AVS_PLANAR_A }; |
|
|
|
static const int avs_planes_rgba[4] = { AVS_PLANAR_G, AVS_PLANAR_B, |
|
|
|
AVS_PLANAR_R, AVS_PLANAR_A }; |
|
|
|
#endif |
|
|
|
|
|
|
|
/* A conflict between C++ global objects, atexit, and dynamic loading requires |
|
|
|
* us to register our own atexit handler to prevent double freeing. */ |
|
|
|
@@ -138,6 +151,8 @@ static av_cold int avisynth_load_library(void) |
|
|
|
LOAD_AVS_FUNC(avs_get_pitch_p, 1); |
|
|
|
LOAD_AVS_FUNC(avs_get_read_ptr_p, 1); |
|
|
|
LOAD_AVS_FUNC(avs_get_row_size_p, 1); |
|
|
|
LOAD_AVS_FUNC(avs_is_planar_rgb, 1); |
|
|
|
LOAD_AVS_FUNC(avs_is_planar_rgba, 1); |
|
|
|
#endif |
|
|
|
#undef LOAD_AVS_FUNC |
|
|
|
|
|
|
|
@@ -222,7 +237,7 @@ static av_cold void avisynth_atexit_handler(void) |
|
|
|
static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) |
|
|
|
{ |
|
|
|
AviSynthContext *avs = s->priv_data; |
|
|
|
int planar = 0; // 0: packed, 1: YUV, 2: Y8 |
|
|
|
int planar = 0; // 0: packed, 1: YUV, 2: Y8, 3: Planar RGB, 4: YUVA, 5: Planar RGBA |
|
|
|
|
|
|
|
st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; |
|
|
|
st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; |
|
|
|
@@ -238,6 +253,116 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) |
|
|
|
|
|
|
|
switch (avs->vi->pixel_type) { |
|
|
|
#ifdef USING_AVISYNTH |
|
|
|
/* 10~16-bit YUV pix_fmts (AviSynth+) */ |
|
|
|
case AVS_CS_YUV444P10: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUV444P10; |
|
|
|
planar = 1; |
|
|
|
break; |
|
|
|
case AVS_CS_YUV422P10: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUV422P10; |
|
|
|
planar = 1; |
|
|
|
break; |
|
|
|
case AVS_CS_YUV420P10: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUV420P10; |
|
|
|
planar = 1; |
|
|
|
break; |
|
|
|
case AVS_CS_YUV444P12: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUV444P12; |
|
|
|
planar = 1; |
|
|
|
break; |
|
|
|
case AVS_CS_YUV422P12: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUV422P12; |
|
|
|
planar = 1; |
|
|
|
break; |
|
|
|
case AVS_CS_YUV420P12: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUV420P12; |
|
|
|
planar = 1; |
|
|
|
break; |
|
|
|
case AVS_CS_YUV444P16: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUV444P16; |
|
|
|
planar = 1; |
|
|
|
break; |
|
|
|
case AVS_CS_YUV422P16: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUV422P16; |
|
|
|
planar = 1; |
|
|
|
break; |
|
|
|
case AVS_CS_YUV420P16: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUV420P16; |
|
|
|
planar = 1; |
|
|
|
break; |
|
|
|
/* 8~16-bit YUV pix_fmts with Alpha (AviSynth+) */ |
|
|
|
case AVS_CS_YUVA444: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUVA444P; |
|
|
|
planar = 4; |
|
|
|
break; |
|
|
|
case AVS_CS_YUVA422: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUVA422P; |
|
|
|
planar = 4; |
|
|
|
break; |
|
|
|
case AVS_CS_YUVA420: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUVA420P; |
|
|
|
planar = 4; |
|
|
|
break; |
|
|
|
case AVS_CS_YUVA444P10: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUVA444P10; |
|
|
|
planar = 4; |
|
|
|
break; |
|
|
|
case AVS_CS_YUVA422P10: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUVA422P10; |
|
|
|
planar = 4; |
|
|
|
break; |
|
|
|
case AVS_CS_YUVA420P10: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUVA420P10; |
|
|
|
planar = 4; |
|
|
|
break; |
|
|
|
case AVS_CS_YUVA444P16: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUVA444P16; |
|
|
|
planar = 4; |
|
|
|
break; |
|
|
|
case AVS_CS_YUVA422P16: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUVA422P16; |
|
|
|
planar = 4; |
|
|
|
break; |
|
|
|
case AVS_CS_YUVA420P16: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUVA420P16; |
|
|
|
planar = 4; |
|
|
|
break; |
|
|
|
/* Planar RGB pix_fmts (AviSynth+) */ |
|
|
|
case AVS_CS_RGBP: |
|
|
|
st->codecpar->format = AV_PIX_FMT_GBRP; |
|
|
|
planar = 3; |
|
|
|
break; |
|
|
|
case AVS_CS_RGBP10: |
|
|
|
st->codecpar->format = AV_PIX_FMT_GBRP10; |
|
|
|
planar = 3; |
|
|
|
break; |
|
|
|
case AVS_CS_RGBP12: |
|
|
|
st->codecpar->format = AV_PIX_FMT_GBRP12; |
|
|
|
planar = 3; |
|
|
|
break; |
|
|
|
case AVS_CS_RGBP16: |
|
|
|
st->codecpar->format = AV_PIX_FMT_GBRP16; |
|
|
|
planar = 3; |
|
|
|
break; |
|
|
|
/* Planar RGB pix_fmts with Alpha (AviSynth+) */ |
|
|
|
case AVS_CS_RGBAP: |
|
|
|
st->codecpar->format = AV_PIX_FMT_GBRAP; |
|
|
|
planar = 5; |
|
|
|
break; |
|
|
|
case AVS_CS_RGBAP12: |
|
|
|
st->codecpar->format = AV_PIX_FMT_GBRAP12; |
|
|
|
planar = 5; |
|
|
|
break; |
|
|
|
case AVS_CS_RGBAP16: |
|
|
|
st->codecpar->format = AV_PIX_FMT_GBRAP16; |
|
|
|
planar = 5; |
|
|
|
break; |
|
|
|
/* GRAY16 (AviSynth+) */ |
|
|
|
case AVS_CS_Y16: |
|
|
|
st->codecpar->format = AV_PIX_FMT_GRAY16; |
|
|
|
planar = 2; |
|
|
|
break; |
|
|
|
/* pix_fmts added in AviSynth 2.6 */ |
|
|
|
case AVS_CS_YV24: |
|
|
|
st->codecpar->format = AV_PIX_FMT_YUV444P; |
|
|
|
planar = 1; |
|
|
|
@@ -254,7 +379,15 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) |
|
|
|
st->codecpar->format = AV_PIX_FMT_GRAY8; |
|
|
|
planar = 2; |
|
|
|
break; |
|
|
|
/* 16-bit packed RGB pix_fmts (AviSynth+) */ |
|
|
|
case AVS_CS_BGR48: |
|
|
|
st->codecpar->format = AV_PIX_FMT_BGR48; |
|
|
|
break; |
|
|
|
case AVS_CS_BGR64: |
|
|
|
st->codecpar->format = AV_PIX_FMT_BGRA64; |
|
|
|
break; |
|
|
|
#endif |
|
|
|
/* AviSynth 2.5 and AvxSynth pix_fmts */ |
|
|
|
case AVS_CS_BGR24: |
|
|
|
st->codecpar->format = AV_PIX_FMT_BGR24; |
|
|
|
break; |
|
|
|
@@ -280,6 +413,20 @@ static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) |
|
|
|
} |
|
|
|
|
|
|
|
switch (planar) { |
|
|
|
#ifdef USING_AVISYNTH |
|
|
|
case 5: // Planar RGB + Alpha |
|
|
|
avs->n_planes = 4; |
|
|
|
avs->planes = avs_planes_rgba; |
|
|
|
break; |
|
|
|
case 4: // YUV + Alpha |
|
|
|
avs->n_planes = 4; |
|
|
|
avs->planes = avs_planes_yuva; |
|
|
|
break; |
|
|
|
case 3: // Planar RGB |
|
|
|
avs->n_planes = 3; |
|
|
|
avs->planes = avs_planes_rgb; |
|
|
|
break; |
|
|
|
#endif |
|
|
|
case 2: // Y8 |
|
|
|
avs->n_planes = 1; |
|
|
|
avs->planes = avs_planes_grey; |
|
|
|
@@ -447,6 +594,7 @@ static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, |
|
|
|
const unsigned char *src_p; |
|
|
|
int n, i, plane, rowsize, planeheight, pitch, bits; |
|
|
|
const char *error; |
|
|
|
int avsplus av_unused; |
|
|
|
|
|
|
|
if (avs->curr_frame >= avs->vi->num_frames) |
|
|
|
return AVERROR_EOF; |
|
|
|
@@ -457,6 +605,13 @@ static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, |
|
|
|
return 0; |
|
|
|
|
|
|
|
#ifdef USING_AVISYNTH |
|
|
|
/* Detect whether we're using AviSynth 2.6 or AviSynth+ by |
|
|
|
* looking for whether avs_is_planar_rgb exists. */ |
|
|
|
if (GetProcAddress(avs_library.library, "avs_is_planar_rgb") == NULL) |
|
|
|
avsplus = 0; |
|
|
|
else |
|
|
|
avsplus = 1; |
|
|
|
|
|
|
|
/* avs_bits_per_pixel changed to AVSC_API with AviSynth 2.6, which |
|
|
|
* requires going through avs_library, while AvxSynth has it under |
|
|
|
* the older AVSC_INLINE type, so special-case this. */ |
|
|
|
@@ -513,6 +668,15 @@ static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, |
|
|
|
pitch = -pitch; |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef USING_AVISYNTH |
|
|
|
/* Flip Planar RGB video */ |
|
|
|
if (avsplus && (avs_library.avs_is_planar_rgb(avs->vi) || |
|
|
|
avs_library.avs_is_planar_rgba(avs->vi))) { |
|
|
|
src_p = src_p + (planeheight - 1) * pitch; |
|
|
|
pitch = -pitch; |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
avs_library.avs_bit_blt(avs->env, dst_p, rowsize, src_p, pitch, |
|
|
|
rowsize, planeheight); |
|
|
|
dst_p += rowsize * planeheight; |
|
|
|
|