Filter SDK/avs2yuv

From Avisynth wiki
(Difference between revisions)
Jump to: navigation, search
Line 102: Line 102:
 
  }
 
  }
  
Compile this file into an EXE named avs2yuv.exe. See [[Filter_SDK/Compiling_instructions|compiling instructions]]. Now open the command line and go to the folder where avs2yuv.exe and your script (called example.avs here) is loaded:
+
Compile this file into an EXE named avs2yuv.exe. See [[Filter_SDK/Compiling_instructions|compiling instructions]]. Now open the command line and go to the folder where avs2yuv.exe and your script (called example.avs here) are located. Our script:
  
 
  ColorBars()
 
  ColorBars()
Line 112: Line 112:
  
 
  avs2yuv.exe example.avs output.raw
 
  avs2yuv.exe example.avs output.raw
 +
 +
So the output file will contains five frames of YV12 data (640x480). The raw stream can be played with [http://www.yuvtoolkit.com/ YUVtoolkit] for example. You can also import it in AviSynth using the plugin RawSource.
  
 
=== Line by line breakdown ===
 
=== Line by line breakdown ===

Revision as of 01:08, 3 January 2014

avs2yuv reads a script and outputs raw video (YUV or RGB). It's a stripped down version of the famous avs2yuv.

Here's avs2yuv.cpp:

#include <stdio.h>
#include <Windows.h>
#include "avisynth.h"

#define MY_VERSION "Avs2YUV 0.24"

const AVS_Linkage *AVS_linkage = 0;

int __cdecl main(int argc, const char* argv[])
{
const char* infile = NULL;
const char* outfile = NULL;
FILE* out_fh;
	
if (!strcmp(argv[1], "-h")) {
   fprintf(stderr, MY_VERSION "\n"
           "Usage: avs2yuv.exe in.avs out.raw\n");
   return 2;
} else {
   infile = argv[1];
   outfile = argv[2];
}

try {
   char* colorformat;
   IScriptEnvironment* (__stdcall *CreateEnv)(int);
   HMODULE avsdll = LoadLibrary("avisynth.dll");
   if (!avsdll) {
      fprintf(stderr, "failed to load avisynth.dll\n");
      return 2;
   }

   CreateEnv = (IScriptEnvironment *(__stdcall *)(int))GetProcAddress(avsdll, "CreateScriptEnvironment"); 
   if (!CreateEnv) {
      fprintf(stderr, "failed to load CreateScriptEnvironment()\n");
      return 1;
   }
	
   IScriptEnvironment* env = CreateEnv(AVISYNTH_INTERFACE_VERSION);
   env->CheckVersion(5);
   AVS_linkage = env->GetAVSLinkage();
   AVSValue arg(infile);
   AVSValue res = env->Invoke("Import", AVSValue(&arg, 1));
   if (!res.IsClip()) {
      fprintf(stderr, "Error: '%s' didn't return a video clip.\n", infile);
      return 1;
   }

   PClip clip = res.AsClip();
   VideoInfo vi = clip->GetVideoInfo();
	
   fprintf(stderr, " %s:\n", infile);
   fprintf(stderr, " %dx%d,\n", vi.width, vi.height);
   fprintf(stderr, " %d/%d fps,\n", vi.fps_numerator, vi.fps_denominator);
   fprintf(stderr, " %d frames,\n", vi.num_frames);
   if (vi.IsYUV()) {
      colorformat = "YUV";
   } else {
      colorformat = "RGB";
   }
   fprintf(stderr, " %s color format", colorformat);

   out_fh = fopen(outfile, "wb");
   if (!out_fh) {
      fprintf(stderr, "fopen(\"%s\") failed", outfile);
      return 1;
   }

   for (int frm = 0; frm < vi.num_frames; ++frm) {
      PVideoFrame f = clip->GetFrame(frm, env);
 	
      static const int planes[] = {PLANAR_Y, PLANAR_U, PLANAR_V};
      int wrote = 0;

      for (int p=0; p<3; p++) { // for interleaved formats only the first plane (being the whole frame) is written
         int w = vi.width  >> vi.GetPlaneWidthSubsampling(planes[p]);
         int h = vi.height >> vi.GetPlaneHeightSubsampling(planes[p]);
         int pitch = f->GetPitch(planes[p]);
         const BYTE* data = f->GetReadPtr(planes[p]);
         for (int y=0; y<h; y++) {
            wrote += fwrite(data, 1, w, out_fh);
            data += pitch;
         }
      }
   }

   env->DeleteScriptEnvironment();
   FreeLibrary(avsdll);

} catch(AvisynthError err) {
   fprintf(stderr, "\nAvisynth error:\n%s\n", err.msg);
   return 1;
}

AVS_linkage = 0;
fclose(out_fh);
return 0;
}

Compile this file into an EXE named avs2yuv.exe. See compiling instructions. Now open the command line and go to the folder where avs2yuv.exe and your script (called example.avs here) are located. Our script:

ColorBars()
ConvertToYV12()
Trim(0,4)
Showframenumber()

Type the following on the command line (the name of the output clip can be arbitrary in our application):

avs2yuv.exe example.avs output.raw

So the output file will contains five frames of YV12 data (640x480). The raw stream can be played with YUVtoolkit for example. You can also import it in AviSynth using the plugin RawSource.

Line by line breakdown

Here's a line-by-line breakdown of avs2yuv.cpp.

#include <stdio.h>

The header stdio.h contains objects like stderr (of type FILE *), and functions like [www.cplusplus.com/reference/cstdio/fprintf/ fprintf], fopen.

The standard error stream (stderr) is the default destination for error messages and other diagnostic warnings. Like stdout, it is usually also directed by default to the text console (generally, on the screen).

fprintf writes formatted data to stream.

fopen opens the file whose name is specified in the parameter filename and associates it with a stream that can be identified in future operations by the FILE pointer returned.


#include <Windows.h>
#include "avisynth.h"

This header declares all the classes and miscellaneous constants that you might need when accessing avisynth.dll.

#define MY_VERSION "Avs2YUV 0.24"

Defines the version numbers which will be printed (using the "-h" option) later on.

const AVS_Linkage *AVS_linkage = 0;

int __cdecl main(int argc, const char* argv[])
{
const char* infile = NULL;
const char* outfile = NULL;
FILE* out_fh;
	
if (!strcmp(argv[1], "-h")) {
   fprintf(stderr, MY_VERSION "\n"
           "Usage: avs2yuv.exe in.avs out.raw\n");
   return 2;
} else {
   infile = argv[1];
   outfile = argv[2];
}

try {
   char* colorformat;
   IScriptEnvironment* (__stdcall *CreateEnv)(int);
   HMODULE avsdll = LoadLibrary("avisynth.dll");
   if (!avsdll) {
      fprintf(stderr, "failed to load avisynth.dll\n");
      return 2;
   }

   CreateEnv = (IScriptEnvironment *(__stdcall *)(int))GetProcAddress(avsdll, "CreateScriptEnvironment"); 
   if (!CreateEnv) {
      fprintf(stderr, "failed to load CreateScriptEnvironment()\n");
      return 1;
   }
	
   IScriptEnvironment* env = CreateEnv(AVISYNTH_INTERFACE_VERSION);
   env->CheckVersion(5);
   AVS_linkage = env->GetAVSLinkage();
   AVSValue arg(infile);
   AVSValue res = env->Invoke("Import", AVSValue(&arg, 1));
   if (!res.IsClip()) {
      fprintf(stderr, "Error: '%s' didn't return a video clip.\n", infile);
      return 1;
   }

   PClip clip = res.AsClip();
   VideoInfo vi = clip->GetVideoInfo();
	
   fprintf(stderr, " %s:\n", infile);
   fprintf(stderr, " %dx%d,\n", vi.width, vi.height);
   fprintf(stderr, " %d/%d fps,\n", vi.fps_numerator, vi.fps_denominator);
   fprintf(stderr, " %d frames,\n", vi.num_frames);
   if (vi.IsYUV()) {
      colorformat = "YUV";
   } else {
      colorformat = "RGB";
   }
   fprintf(stderr, " %s color format", colorformat);

   out_fh = fopen(outfile, "wb");
   if (!out_fh) {
      fprintf(stderr, "fopen(\"%s\") failed", outfile);
      return 1;
   }

   for (int frm = 0; frm < vi.num_frames; ++frm) {
      PVideoFrame f = clip->GetFrame(frm, env);
 	
      static const int planes[] = {PLANAR_Y, PLANAR_U, PLANAR_V};
      int wrote = 0;

      for (int p=0; p<3; p++) { // for interleaved formats only the first plane (being the whole frame) is written
         int w = vi.width  >> vi.GetPlaneWidthSubsampling(planes[p]);
         int h = vi.height >> vi.GetPlaneHeightSubsampling(planes[p]);
         int pitch = f->GetPitch(planes[p]);
         const BYTE* data = f->GetReadPtr(planes[p]);
         for (int y=0; y<h; y++) {
            wrote += fwrite(data, 1, w, out_fh);
            data += pitch;
         }
      }
   }

   env->DeleteScriptEnvironment();
   FreeLibrary(avsdll);

} catch(AvisynthError err) {
   fprintf(stderr, "\nAvisynth error:\n%s\n", err.msg);
   return 1;
}

AVS_linkage = 0;
fclose(out_fh);
return 0;
}


todo - static and dynamic linking (see above) - http://msdn.microsoft.com/en-us/library/windows/desktop/ms685090%28v=vs.85%29.aspx

Personal tools