Beispiel #1
0
PVideoFrame __stdcall ConditionalSelect::GetFrame(int n, IScriptEnvironment* env) {

  AVSValue prev_last = env->GetVarDef("last");  // Store previous last
  AVSValue prev_current_frame = env->GetVarDef("current_frame");  // Store previous current_frame

  env->SetVar("last", (AVSValue)child);      // Set implicit last
  env->SetVar("current_frame", (AVSValue)n); // Set frame to be tested by the conditional filters.

  AVSValue result;

  try {
    ScriptParser parser(env, expression, "[Conditional Select, Expression]");
    PExpression exp = parser.Parse();
    result = exp->Evaluate(env);

    if (!result.IsInt())
      env->ThrowError("Conditional Select: Expression must return an integer!");
  }
  catch (AvisynthError error) {    
    env->SetVar("last", prev_last);                   // Restore implicit last
    env->SetVar("current_frame", prev_current_frame); // Restore current_frame

    const int num_frames = child->GetVideoInfo().num_frames;
    PVideoFrame dst = child->GetFrame(min(num_frames-1, n), env);

    env->MakeWritable(&dst);
    env->ApplyMessage(&dst, vi, error.msg, vi.width/W_DIVISOR, 0xa0a0a0, 0, 0);

    return dst;
  }

  env->SetVar("last", prev_last);                   // Restore implicit last
  env->SetVar("current_frame", prev_current_frame); // Restore current_frame

  const int i = result.AsInt();
  
  PVideoFrame dst;

  if (i < 0 || i >= num_args) {
    const int num_frames = child->GetVideoInfo().num_frames;
    dst = child->GetFrame(min(num_frames-1, n), env);
  }
  else {
    const int num_frames = child_array[i]->GetVideoInfo().num_frames;
    dst = child_array[i]->GetFrame(min(num_frames-1, n), env);
  }

  if (show) {
    char text[32];

    _snprintf(text, sizeof(text)-1, "Expression Result:%i\n", result.AsInt());
    text[sizeof(text)-1] = '\0';

    env->MakeWritable(&dst);
    env->ApplyMessage(&dst, vi, text, vi.width/4, 0xa0a0a0, 0, 0);
  }

  return dst;
}
Beispiel #2
0
PVideoFrame __stdcall ScriptClip::GetFrame(int n, IScriptEnvironment* env) {
  AVSValue prev_last = env->GetVar("last");  // Store previous last
  AVSValue prev_current_frame = GetVar(env, "current_frame");  // Store previous current_frame

  env->SetVar("last",(AVSValue)child);       // Set explicit last
  env->SetVar("current_frame",(AVSValue)n);  // Set frame to be tested by the conditional filters.

  if (show) {
    PVideoFrame dst = child->GetFrame(n,env);
    env->MakeWritable(&dst);
    ApplyMessage(&dst, vi, script.AsString(), vi.width/6, 0xa0a0a0,0,0 , env );
    env->SetVar("last",prev_last);       // Restore implicit last
    env->SetVar("current_frame",prev_current_frame);       // Restore current_frame
    return dst;
  }

  AVSValue result;
  PVideoFrame eval_return;   // Frame to be returned if script should be evaluated AFTER frame has been fetched. Otherwise not used.

  if (eval_after) eval_return = child->GetFrame(n,env);

  try {
    ScriptParser parser(env, script.AsString(), "[ScriptClip]");
    PExpression exp = parser.Parse();
    result = exp->Evaluate(env);
  } catch (AvisynthError error) {    
    const char* error_msg = error.msg;  

    PVideoFrame dst = child->GetFrame(n,env);
    env->MakeWritable(&dst);
    ApplyMessage(&dst, vi, error_msg, vi.width/W_DIVISOR, 0xa0a0a0,0,0 , env );
    env->SetVar("last",prev_last);       // Restore implicit last
    env->SetVar("current_frame",prev_current_frame);       // Restore current_frame
    return dst;
  }

  env->SetVar("last",prev_last);       // Restore implicit last
  env->SetVar("current_frame",prev_current_frame);       // Restore current_frame

  if (eval_after && only_eval) return eval_return;
  if (only_eval) return child->GetFrame(n,env);
  
  const char* error = NULL;
  VideoInfo vi2;
  if (!result.IsClip()) {
    error = "ScriptClip: Function did not return a video clip!";
  } else {
    vi2 = result.AsClip()->GetVideoInfo();
    if (!vi.IsSameColorspace(vi2)) { 
      error = "ScriptClip: Function did not return a video clip of the same colorspace as the source clip!";
    } else if (vi2.width != vi.width) {
      error = "ScriptClip: Function did not return a video clip with the same width as the source clip!";
    } else if (vi2.height != vi.height) {
      error = "ScriptClip: Function did not return a video clip with the same height as the source clip!";
    }
  }

  if (error != NULL) {
    PVideoFrame dst = child->GetFrame(n,env);
    env->MakeWritable(&dst);
    ApplyMessage(&dst, vi, error, vi.width/W_DIVISOR, 0xa0a0a0,0,0 , env );
    return dst;
  }

  n = min(n,vi2.num_frames-1);  // We ignore it if the new clip is not as long as the current one. This can allow the resulting clip to be one frame.

  return result.AsClip()->GetFrame(n,env);
}
Beispiel #3
0
PVideoFrame __stdcall ConditionalFilter::GetFrame(int n, IScriptEnvironment* env) {

  VideoInfo vi1 = source1->GetVideoInfo();
  VideoInfo vi2 = source2->GetVideoInfo();

  AVSValue prev_last = env->GetVar("last");  // Store previous last
  AVSValue prev_current_frame = GetVar(env, "current_frame");  // Store previous current_frame

  env->SetVar("last",(AVSValue)child);       // Set implicit last
  env->SetVar("current_frame",(AVSValue)n);  // Set frame to be tested by the conditional filters.

  AVSValue e1_result;
  AVSValue e2_result;
  try {
    ScriptParser parser(env, eval1.AsString(), "[Conditional Filter, Expresion 1]");
    PExpression exp = parser.Parse();
    e1_result = exp->Evaluate(env);

    ScriptParser parser2(env, eval2.AsString(), "[Conditional Filter, Expression 2]");
    exp = parser2.Parse();
    e2_result = exp->Evaluate(env);
  } catch (AvisynthError error) {    
    const char* error_msg = error.msg;  

    PVideoFrame dst = source1->GetFrame(n,env);
    env->MakeWritable(&dst);
    ApplyMessage(&dst, vi1, error_msg, vi.width/W_DIVISOR, 0xa0a0a0,0,0 , env );
    env->SetVar("last",prev_last);       // Restore implicit last
    env->SetVar("current_frame",prev_current_frame);       // Restore current_frame
    return dst;
  }

  env->SetVar("last",prev_last);       // Restore implicit last
  env->SetVar("current_frame",prev_current_frame);       // Restore current_frame

  int test_int=false;

  int e1 = 0;
  int e2 = 0;
  float f1 = 0.0f;
  float f2 = 0.0f;
  try {
    if (e1_result.IsInt() || e1_result.IsBool()) {
      test_int = true;
      e1 = e1_result.IsInt() ? e1_result.AsInt() : e1_result.AsBool();
      if (!(e2_result.IsInt() || e2_result.IsBool()))
        env->ThrowError("Conditional filter: Second expression did not return an integer or bool, as first expression.");
      e2 = e2_result.IsInt() ? e2_result.AsInt() : e2_result.AsBool();

    } else if (e1_result.IsFloat()) {
      f1 = e1_result.AsFloat();
      if (!e2_result.IsFloat()) 
        env->ThrowError("Conditional filter: Second expression did not return a float or an integer, as first expression.");
      f2 = e2_result.AsFloat();
    } else {
      env->ThrowError("ConditionalFilter: First condition did not return an int, bool or float!");
    }
  } catch (AvisynthError error) {    
    const char* error_msg = error.msg;  

    PVideoFrame dst = source1->GetFrame(n,env);
    env->MakeWritable(&dst);
    ApplyMessage(&dst, vi1, error_msg, vi.width/W_DIVISOR, 0xa0a0a0,0,0 , env );
    return dst;
  }


  bool state = false;

  if (test_int) {
    if (evaluator&EQUALS) 
      if (e1 == e2) state = true;

    if (evaluator&GREATERTHAN) 
      if (e1 > e2) state = true;

    if (evaluator&LESSTHAN) 
      if (e1 < e2) state = true;
  } else {  // Float compare
    if (evaluator&EQUALS) 
      if (fabs(f1-f2)<0.000001f) state = true;   // Exact equal will sometimes be rounded to wrong values.

    if (evaluator&GREATERTHAN) 
      if (f1 > f2) state = true;

    if (evaluator&LESSTHAN) 
      if (f1 < f2) state = true;    
  }

  if (show) {
      char text[400];
      if (test_int) {
        sprintf(text,
          "Left side Conditional Result:%i\n"
          "Right side Conditional Result:%i\n"
          "Evaluate result: %s\n",
          e1, e2, (state) ? t_TRUE : t_FALSE
        );
      } else {
        sprintf(text,
          "Left side Conditional Result:%7.4f\n"
          "Right side Conditional Result:%7.4f\n"
          "Evaluate result: %s\n", 
          f1, f2, (state) ? t_TRUE : t_FALSE
        );
      }

      PVideoFrame dst = (state) ? source1->GetFrame(min(vi1.num_frames-1,n),env) : source2->GetFrame(min(vi2.num_frames-1,n),env);
      env->MakeWritable(&dst);
      ApplyMessage(&dst, vi, text, vi.width/4, 0xa0a0a0,0,0 , env );

    return dst;
  }

  if (state) 
    return source1->GetFrame(min(vi1.num_frames-1,n),env);
  
  return source2->GetFrame(min(vi1.num_frames-1,n),env);
}