Merge commit '97b052e56807fab6887e9ba210a28a622e6a4b78'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 6 Sep 2013 11:33:01 +0000 (13:33 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 6 Sep 2013 11:39:15 +0000 (13:39 +0200)
* commit '97b052e56807fab6887e9ba210a28a622e6a4b78':
  avisynth: Add missing #include for NULL_IF_CONFIG_SMALL

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavformat/avisynth.c

   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
+ #include "libavutil/internal.h"
  #include "avformat.h"
  #include "internal.h"
 -#include "riff.h"
 -
 -#include <windows.h>
 -#include <vfw.h>
 +#include "libavcodec/internal.h"
 +
 +// Enable function pointer definitions for runtime loading.
 +#define AVSC_NO_DECLSPEC
 +
 +// Shut up ffmpeg error messages.
 +// avisynth_c.h contains inline functions that call these functions.
 +#undef malloc
 +#undef free
 +#undef printf
 +
 +// Platform-specific directives for AviSynth vs AvxSynth.
 +#ifdef _WIN32
 +  #include <windows.h>
 +  #undef EXTERN_C
 +  #include "compat/avisynth/avisynth_c.h"
 +  #include "compat/avisynth/avisynth_c_25.h"
 +  #define AVISYNTH_LIB "avisynth"
 +#else
 +  #include <dlfcn.h>
 +  #include "compat/avisynth/avxsynth_c.h"
 +   #if defined (__APPLE__)
 +     #define AVISYNTH_LIB "libavxsynth.dylib"
 +   #else
 +     #define AVISYNTH_LIB "libavxsynth.so"
 +   #endif
 +
 +  #define LoadLibrary(x) dlopen(x, RTLD_NOW | RTLD_GLOBAL)
 +  #define GetProcAddress dlsym
 +  #define FreeLibrary dlclose
 +#endif
 +
 +// AvxSynth doesn't have these colorspaces, so disable them
 +#ifndef _WIN32
 +#define avs_is_yv24(vi) 0
 +#define avs_is_yv16(vi) 0
 +#define avs_is_yv411(vi) 0
 +#define avs_is_y8(vi) 0
 +#endif
  
  typedef struct {
 -  PAVISTREAM handle;
 -  AVISTREAMINFO info;
 -  DWORD read;
 -  LONG chunck_size;
 -  LONG chunck_samples;
 -} AviSynthStream;
 +    void *library;
 +#define AVSC_DECLARE_FUNC(name) name##_func name
 +    AVSC_DECLARE_FUNC(avs_bit_blt);
 +    AVSC_DECLARE_FUNC(avs_clip_get_error);
 +    AVSC_DECLARE_FUNC(avs_create_script_environment);
 +    AVSC_DECLARE_FUNC(avs_delete_script_environment);
 +    AVSC_DECLARE_FUNC(avs_get_audio);
 +    AVSC_DECLARE_FUNC(avs_get_error);
 +    AVSC_DECLARE_FUNC(avs_get_frame);
 +    AVSC_DECLARE_FUNC(avs_get_version);
 +    AVSC_DECLARE_FUNC(avs_get_video_info);
 +    AVSC_DECLARE_FUNC(avs_invoke);
 +    AVSC_DECLARE_FUNC(avs_release_clip);
 +    AVSC_DECLARE_FUNC(avs_release_value);
 +    AVSC_DECLARE_FUNC(avs_release_video_frame);
 +    AVSC_DECLARE_FUNC(avs_take_clip);
 +#undef AVSC_DECLARE_FUNC
 +} AviSynthLibrary;
 +
 +struct AviSynthContext {
 +    AVS_ScriptEnvironment *env;
 +    AVS_Clip *clip;
 +    const AVS_VideoInfo *vi;
 +
 +    // avisynth_read_packet_video() iterates over this.
 +    int n_planes;
 +    const int *planes;
 +
 +    int curr_stream;
 +    int curr_frame;
 +    int64_t curr_sample;
 +
 +    int error;
 +
 +    // Linked list pointers.
 +    struct AviSynthContext *next;
 +};
 +typedef struct AviSynthContext AviSynthContext;
  
 -typedef struct {
 -  PAVIFILE file;
 -  AviSynthStream *streams;
 -  int nb_streams;
 -  int next_stream;
 -} AviSynthContext;
 -
 -static int avisynth_read_header(AVFormatContext *s)
 -{
 -  AviSynthContext *avs = s->priv_data;
 -  HRESULT res;
 -  AVIFILEINFO info;
 -  DWORD id;
 -  AVStream *st;
 -  AviSynthStream *stream;
 -  wchar_t filename_wchar[1024] = { 0 };
 -  char filename_char[1024] = { 0 };
 -
 -  AVIFileInit();
 -
 -  /* AviSynth cannot accept UTF-8 file names. */
 -  MultiByteToWideChar(CP_UTF8, 0, s->filename, -1, filename_wchar, 1024);
 -  WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wchar, -1, filename_char, 1024, NULL, NULL);
 -  res = AVIFileOpen(&avs->file, filename_char, OF_READ|OF_SHARE_DENY_WRITE, NULL);
 -  if (res != S_OK)
 -    {
 -      av_log(s, AV_LOG_ERROR, "AVIFileOpen failed with error %ld", res);
 -      AVIFileExit();
 -      return -1;
 -    }
 -
 -  res = AVIFileInfo(avs->file, &info, sizeof(info));
 -  if (res != S_OK)
 -    {
 -      av_log(s, AV_LOG_ERROR, "AVIFileInfo failed with error %ld", res);
 -      AVIFileExit();
 -      return -1;
 -    }
 -
 -  avs->streams = av_mallocz(info.dwStreams * sizeof(AviSynthStream));
 -
 -  for (id=0; id<info.dwStreams; id++)
 -    {
 -      stream = &avs->streams[id];
 -      stream->read = 0;
 -      if (AVIFileGetStream(avs->file, &stream->handle, 0, id) == S_OK)
 -        {
 -          if (AVIStreamInfo(stream->handle, &stream->info, sizeof(stream->info)) == S_OK)
 -            {
 -              if (stream->info.fccType == streamtypeAUDIO)
 -                {
 -                  WAVEFORMATEX wvfmt;
 -                  LONG struct_size = sizeof(WAVEFORMATEX);
 -                  if (AVIStreamReadFormat(stream->handle, 0, &wvfmt, &struct_size) != S_OK)
 -                    continue;
 -
 -                  st = avformat_new_stream(s, NULL);
 -                  st->id = id;
 -                  st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
 -
 -                  st->codec->block_align = wvfmt.nBlockAlign;
 -                  st->codec->channels = wvfmt.nChannels;
 -                  st->codec->sample_rate = wvfmt.nSamplesPerSec;
 -                  st->codec->bit_rate = wvfmt.nAvgBytesPerSec * 8;
 -                  st->codec->bits_per_coded_sample = wvfmt.wBitsPerSample;
 -
 -                  stream->chunck_samples = wvfmt.nSamplesPerSec * (uint64_t)info.dwScale / (uint64_t)info.dwRate;
 -                  stream->chunck_size = stream->chunck_samples * wvfmt.nChannels * wvfmt.wBitsPerSample / 8;
 -
 -                  st->codec->codec_tag = wvfmt.wFormatTag;
 -                  st->codec->codec_id = ff_wav_codec_get_id(wvfmt.wFormatTag, st->codec->bits_per_coded_sample);
 -                }
 -              else if (stream->info.fccType == streamtypeVIDEO)
 -                {
 -                  BITMAPINFO imgfmt;
 -                  LONG struct_size = sizeof(BITMAPINFO);
 -
 -                  stream->chunck_size = stream->info.dwSampleSize;
 -                  stream->chunck_samples = 1;
 -
 -                  if (AVIStreamReadFormat(stream->handle, 0, &imgfmt, &struct_size) != S_OK)
 -                    continue;
 -
 -                  st = avformat_new_stream(s, NULL);
 -                  st->id = id;
 -                  st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
 -                  st->avg_frame_rate.num = stream->info.dwRate;
 -                  st->avg_frame_rate.den = stream->info.dwScale;
 -
 -                  st->codec->width = imgfmt.bmiHeader.biWidth;
 -                  st->codec->height = imgfmt.bmiHeader.biHeight;
 -
 -                  st->codec->bits_per_coded_sample = imgfmt.bmiHeader.biBitCount;
 -                  st->codec->bit_rate = (uint64_t)stream->info.dwSampleSize * (uint64_t)stream->info.dwRate * 8 / (uint64_t)stream->info.dwScale;
 -                  st->codec->codec_tag = imgfmt.bmiHeader.biCompression;
 -                  st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, imgfmt.bmiHeader.biCompression);
 -
 -                  st->duration = stream->info.dwLength;
 -                }
 -              else
 -                {
 -                  AVIStreamRelease(stream->handle);
 -                  continue;
 -                }
 -
 -              avs->nb_streams++;
 -
 -              st->codec->stream_codec_tag = stream->info.fccHandler;
 -
 -              avpriv_set_pts_info(st, 64, info.dwScale, info.dwRate);
 -              st->start_time = stream->info.dwStart;
 -            }
 +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};
 +
 +// A conflict between C++ global objects, atexit, and dynamic loading requires
 +// us to register our own atexit handler to prevent double freeing.
 +static AviSynthLibrary *avs_library = NULL;
 +static int avs_atexit_called = 0;
 +
 +// Linked list of AviSynthContexts. An atexit handler destroys this list.
 +static AviSynthContext *avs_ctx_list = NULL;
 +
 +static av_cold void avisynth_atexit_handler(void);
 +
 +static av_cold int avisynth_load_library(void) {
 +    avs_library = av_mallocz(sizeof(AviSynthLibrary));
 +    if (!avs_library)
 +        return AVERROR_UNKNOWN;
 +
 +    avs_library->library = LoadLibrary(AVISYNTH_LIB);
 +    if (!avs_library->library)
 +        goto init_fail;
 +
 +#define LOAD_AVS_FUNC(name, continue_on_fail) \
 +{ \
 +    avs_library->name = (void*)GetProcAddress(avs_library->library, #name); \
 +    if(!continue_on_fail && !avs_library->name) \
 +        goto fail; \
 +}
 +    LOAD_AVS_FUNC(avs_bit_blt, 0);
 +    LOAD_AVS_FUNC(avs_clip_get_error, 0);
 +    LOAD_AVS_FUNC(avs_create_script_environment, 0);
 +    LOAD_AVS_FUNC(avs_delete_script_environment, 0);
 +    LOAD_AVS_FUNC(avs_get_audio, 0);
 +    LOAD_AVS_FUNC(avs_get_error, 1); // New to AviSynth 2.6
 +    LOAD_AVS_FUNC(avs_get_frame, 0);
 +    LOAD_AVS_FUNC(avs_get_version, 0);
 +    LOAD_AVS_FUNC(avs_get_video_info, 0);
 +    LOAD_AVS_FUNC(avs_invoke, 0);
 +    LOAD_AVS_FUNC(avs_release_clip, 0);
 +    LOAD_AVS_FUNC(avs_release_value, 0);
 +    LOAD_AVS_FUNC(avs_release_video_frame, 0);
 +    LOAD_AVS_FUNC(avs_take_clip, 0);
 +#undef LOAD_AVS_FUNC
 +
 +    atexit(avisynth_atexit_handler);
 +    return 0;
 +
 +fail:
 +    FreeLibrary(avs_library->library);
 +init_fail:
 +    av_freep(&avs_library);
 +    return AVERROR_UNKNOWN;
 +}
 +
 +// Note that avisynth_context_create and avisynth_context_destroy
 +// do not allocate or free the actual context! That is taken care of
 +// by libavformat.
 +static av_cold int avisynth_context_create(AVFormatContext *s) {
 +    AviSynthContext *avs = (AviSynthContext *)s->priv_data;
 +    int ret;
 +
 +    if (!avs_library) {
 +        if (ret = avisynth_load_library())
 +            return ret;
 +    }
 +
 +    avs->env = avs_library->avs_create_script_environment(3);
 +    if (avs_library->avs_get_error) {
 +        const char *error = avs_library->avs_get_error(avs->env);
 +        if (error) {
 +            av_log(s, AV_LOG_ERROR, "%s\n", error);
 +            return AVERROR_UNKNOWN;
          }
      }