void VerifyParamTypeFail(int paramNum) {
  VMRegAnchor _;
  const ActRec* ar = curFrame();
  const Func* func = ar->m_func;
  const TypeConstraint& tc = func->params()[paramNum].typeConstraint();
  TypedValue* tv = frame_local(ar, paramNum);
  assert(!tc.check(tv, func));
  tc.verifyFail(func, paramNum, tv);
}
//////////////////
// Actually parse
void MatroskaWrapper::Parse() {
    // Clear keyframes and timecodes
    keyFrames.Clear();
    bytePos.Clear();
    timecodes.clear();

    // Get info
    int tracks = mkv_GetNumTracks(file);
    TrackInfo *trackInfo;
    SegmentInfo *segInfo = mkv_GetFileInfo(file);

    // Parse tracks
    for (int track=0; track<tracks; track++) {
        trackInfo = mkv_GetTrackInfo(file,track);

        // Video track
        if (trackInfo->Type == 1) {
            // Variables
            ulonglong startTime, endTime, filePos;
            unsigned int rt, frameSize, frameFlags;
            CompressedStream *cs = NULL;

            // Timecode scale
            __int64 timecodeScale = mkv_TruncFloat(trackInfo->TimecodeScale) * segInfo->TimecodeScale;

            // Mask other tracks away
            mkv_SetTrackMask(file, ~(1 << track));

            // Progress bar
            int totalTime = double(segInfo->Duration) / timecodeScale;
            volatile bool canceled = false;
            DialogProgress *progress = new DialogProgress(NULL,_("Parsing Matroska"),&canceled,_("Reading keyframe and timecode data from Matroska file."),0,totalTime);
            progress->Show();
            progress->SetProgress(0,1);

            // Read frames
            int frameN = 0;
            while (mkv_ReadFrame(file,0,&rt,&startTime,&endTime,&filePos,&frameSize,&frameFlags) == 0) {
                // Read value
                double curTime = double(startTime) / 1000000.0;
                frames.push_back(MkvFrame((frameFlags & FRAME_KF) != 0,curTime,filePos));
                frameN++;

                // Cancelled?
                if (canceled) {
                    Close();
                    throw _T("Canceled");
                }

                // Update progress
                progress->SetProgress(curTime,totalTime);
            }

            // Clean up progress
            if (!canceled) progress->Destroy();

            break;
        }
    }

    // Copy raw
    for (std::list<MkvFrame>::iterator cur=frames.begin(); cur!=frames.end(); cur++) {
        rawFrames.push_back(*cur);
    }

    // Process timecodes and keyframes
    frames.sort();
    MkvFrame curFrame(false,0,0);
    int i = 0;
    for (std::list<MkvFrame>::iterator cur=frames.begin(); cur!=frames.end(); cur++) {
        curFrame = *cur;
        if (curFrame.isKey) keyFrames.Add(i);
        bytePos.Add(curFrame.filePos);
        timecodes.push_back(curFrame.time);
        i++;
    }
}