⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 api.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
	  }
	} else if (sInfo.fccType == streamtypeAUDIO) {
	  ACMFORMATTAGDETAILSW aftd;
	  ACMFORMATDETAILSW    afd;

	  memset(&aftd, 0, sizeof(aftd));
	  memset(&afd, 0, sizeof(afd));

	  aftd.cbStruct     = sizeof(aftd);
	  aftd.dwFormatTag  = afd.dwFormatTag =
	    ((PWAVEFORMATEX)lpFormat)->wFormatTag;
	  aftd.cbFormatSize = afd.cbwfx = size;

	  afd.cbStruct      = sizeof(afd);
	  afd.pwfx          = lpFormat;

	  if (acmFormatTagDetailsW(NULL, &aftd,
				   ACM_FORMATTAGDETAILSF_FORMATTAG) == S_OK) {
	    if (acmFormatDetailsW(NULL,&afd,ACM_FORMATDETAILSF_FORMAT) == S_OK)
	      wsprintfW(szFormat, szAudioFmt, afd.szFormat, aftd.szFormatTag);
	  }
	}
      }
      HeapFree(GetProcessHeap(), 0, lpFormat);
    }

    /* set text for format description */
    SetDlgItemTextW(hWnd, IDC_FORMATTEXT, szFormat);

    /* Disable option button for unsupported streamtypes */
    if (sInfo.fccType == streamtypeVIDEO ||
	sInfo.fccType == streamtypeAUDIO)
      EnableWindow(GetDlgItem(hWnd, IDC_OPTIONS), TRUE);
    else
      EnableWindow(GetDlgItem(hWnd, IDC_OPTIONS), FALSE);
  }

}

static INT_PTR CALLBACK AVISaveOptionsDlgProc(HWND hWnd, UINT uMsg,
                                              WPARAM wParam, LPARAM lParam)
{
  DWORD dwInterleave;
  BOOL  bIsInterleaved;
  INT   n;

  /*TRACE("(%p,%u,0x%04X,0x%08lX)\n", hWnd, uMsg, wParam, lParam);*/

  switch (uMsg) {
  case WM_INITDIALOG:
    SaveOpts.nCurrent = 0;
    if (SaveOpts.nStreams == 1) {
      EndDialog(hWnd, AVISaveOptionsFmtChoose(hWnd));
      return TRUE;
    }

    /* add streams */
    for (n = 0; n < SaveOpts.nStreams; n++) {
      AVISTREAMINFOW sInfo;

      AVIStreamInfoW(SaveOpts.ppavis[n], &sInfo, sizeof(sInfo));
      SendDlgItemMessageW(hWnd, IDC_STREAM, CB_ADDSTRING,
			  0L, (LPARAM)sInfo.szName);
    }

    /* select first stream */
    SendDlgItemMessageW(hWnd, IDC_STREAM, CB_SETCURSEL, 0, 0);
    SendMessageW(hWnd, WM_COMMAND, MAKELONG(IDC_STREAM, CBN_SELCHANGE), (LPARAM)hWnd);

    /* initialize interleave */
    if (SaveOpts.ppOptions[0] != NULL &&
	(SaveOpts.ppOptions[0]->dwFlags & AVICOMPRESSF_VALID)) {
      bIsInterleaved = (SaveOpts.ppOptions[0]->dwFlags & AVICOMPRESSF_INTERLEAVE);
      dwInterleave = SaveOpts.ppOptions[0]->dwInterleaveEvery;
    } else {
      bIsInterleaved = TRUE;
      dwInterleave   = 0;
    }
    CheckDlgButton(hWnd, IDC_INTERLEAVE, bIsInterleaved);
    SetDlgItemInt(hWnd, IDC_INTERLEAVEEVERY, dwInterleave, FALSE);
    EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY), bIsInterleaved);
    break;
  case WM_COMMAND:
    switch (LOWORD(wParam)) {
    case IDOK:
      /* get data from controls and save them */
      dwInterleave   = GetDlgItemInt(hWnd, IDC_INTERLEAVEEVERY, NULL, 0);
      bIsInterleaved = IsDlgButtonChecked(hWnd, IDC_INTERLEAVE);
      for (n = 0; n < SaveOpts.nStreams; n++) {
	if (SaveOpts.ppOptions[n] != NULL) {
	  if (bIsInterleaved) {
	    SaveOpts.ppOptions[n]->dwFlags |= AVICOMPRESSF_INTERLEAVE;
	    SaveOpts.ppOptions[n]->dwInterleaveEvery = dwInterleave;
	  } else
	    SaveOpts.ppOptions[n]->dwFlags &= ~AVICOMPRESSF_INTERLEAVE;
	}
      }
      /* fall through */
    case IDCANCEL:
      EndDialog(hWnd, LOWORD(wParam) == IDOK);
      break;
    case IDC_INTERLEAVE:
      EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY),
		   IsDlgButtonChecked(hWnd, IDC_INTERLEAVE));
      break;
    case IDC_STREAM:
      if (HIWORD(wParam) == CBN_SELCHANGE) {
	/* update control elements */
	AVISaveOptionsUpdate(hWnd);
      }
      break;
    case IDC_OPTIONS:
      AVISaveOptionsFmtChoose(hWnd);
      break;
    };
    return TRUE;
  };

  return FALSE;
}

/***********************************************************************
 *		AVISaveOptions		(AVIFIL32.@)
 */
BOOL WINAPI AVISaveOptions(HWND hWnd, UINT uFlags, INT nStreams,
			   PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *ppOptions)
{
  LPAVICOMPRESSOPTIONS pSavedOptions = NULL;
  INT ret, n;

  TRACE("(%p,0x%X,%d,%p,%p)\n", hWnd, uFlags, nStreams,
	ppavi, ppOptions);

  /* check parameters */
  if (nStreams <= 0 || ppavi == NULL || ppOptions == NULL)
    return AVIERR_BADPARAM;

  /* save options in case the user presses cancel */
  if (ppOptions != NULL && nStreams > 1) {
    pSavedOptions = HeapAlloc(GetProcessHeap(), 0, nStreams * sizeof(AVICOMPRESSOPTIONS));
    if (pSavedOptions == NULL)
      return FALSE;

    for (n = 0; n < nStreams; n++) {
      if (ppOptions[n] != NULL)
	memcpy(pSavedOptions + n, ppOptions[n], sizeof(AVICOMPRESSOPTIONS));
    }
  }

  SaveOpts.uFlags    = uFlags;
  SaveOpts.nStreams  = nStreams;
  SaveOpts.ppavis    = ppavi;
  SaveOpts.ppOptions = ppOptions;

  ret = DialogBoxW(AVIFILE_hModule, MAKEINTRESOURCEW(IDD_SAVEOPTIONS),
		   hWnd, AVISaveOptionsDlgProc);

  if (ret == -1)
    ret = FALSE;

  /* restore options when user pressed cancel */
  if (pSavedOptions != NULL) {
    if (ret == FALSE) {
      for (n = 0; n < nStreams; n++) {
	if (ppOptions[n] != NULL)
	  memcpy(ppOptions[n], pSavedOptions + n, sizeof(AVICOMPRESSOPTIONS));
      }
    }
    HeapFree(GetProcessHeap(), 0, pSavedOptions);
  }

  return (BOOL)ret;
}

/***********************************************************************
 *		AVISaveOptionsFree	(AVIFIL32.@)
 *		AVISaveOptionsFree	(AVIFILE.124)
 */
HRESULT WINAPI AVISaveOptionsFree(INT nStreams,LPAVICOMPRESSOPTIONS*ppOptions)
{
  TRACE("(%d,%p)\n", nStreams, ppOptions);

  if (nStreams < 0 || ppOptions == NULL)
    return AVIERR_BADPARAM;

  for (; nStreams > 0; nStreams--) {
    if (ppOptions[nStreams] != NULL) {
      ppOptions[nStreams]->dwFlags &= ~AVICOMPRESSF_VALID;

      if (ppOptions[nStreams]->lpParms != NULL) {
	HeapFree(GetProcessHeap(), 0, ppOptions[nStreams]->lpParms);
	ppOptions[nStreams]->lpParms = NULL;
	ppOptions[nStreams]->cbParms = 0;
      }
      if (ppOptions[nStreams]->lpFormat != NULL) {
	HeapFree(GetProcessHeap(), 0, ppOptions[nStreams]->lpFormat);
	ppOptions[nStreams]->lpFormat = NULL;
	ppOptions[nStreams]->cbFormat = 0;
      }
    }
  }

  return AVIERR_OK;
}

/***********************************************************************
 *		AVISaveVA		(AVIFIL32.@)
 */
HRESULT WINAPI AVISaveVA(LPCSTR szFile, CLSID *pclsidHandler,
			 AVISAVECALLBACK lpfnCallback, int nStream,
			 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *plpOptions)
{
  LPWSTR  wszFile = NULL;
  HRESULT hr;
  int     len;

  TRACE("%s,%p,%p,%d,%p,%p)\n", debugstr_a(szFile), pclsidHandler,
	lpfnCallback, nStream, ppavi, plpOptions);

  if (szFile == NULL || ppavi == NULL || plpOptions == NULL)
    return AVIERR_BADPARAM;

  /* convert ASCII string to Unicode and call Unicode function */
  len = MultiByteToWideChar(CP_ACP, 0, szFile, -1, NULL, 0);
  if (len <= 0)
    return AVIERR_BADPARAM;

  wszFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
  if (wszFile == NULL)
    return AVIERR_MEMORY;

  MultiByteToWideChar(CP_ACP, 0, szFile, -1, wszFile, len);

  hr = AVISaveVW(wszFile, pclsidHandler, lpfnCallback,
		 nStream, ppavi, plpOptions);

  HeapFree(GetProcessHeap(), 0, wszFile);

  return hr;
}

/***********************************************************************
 *		AVIFILE_AVISaveDefaultCallback	(internal)
 */
static BOOL WINAPI AVIFILE_AVISaveDefaultCallback(INT progress)
{
  TRACE("(%d)\n", progress);

  return FALSE;
}

/***********************************************************************
 *		AVISaveVW		(AVIFIL32.@)
 */
HRESULT WINAPI AVISaveVW(LPCWSTR szFile, CLSID *pclsidHandler,
			 AVISAVECALLBACK lpfnCallback, int nStreams,
			 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *plpOptions)
{
  LONG           lStart[MAX_AVISTREAMS];
  PAVISTREAM     pOutStreams[MAX_AVISTREAMS];
  PAVISTREAM     pInStreams[MAX_AVISTREAMS];
  AVIFILEINFOW   fInfo;
  AVISTREAMINFOW sInfo;

  PAVIFILE       pfile = NULL; /* the output AVI file */
  LONG           lFirstVideo = -1;
  int            curStream;

  /* for interleaving ... */
  DWORD          dwInterleave = 0; /* interleave rate */
  DWORD          dwFileInitialFrames;
  LONG           lFileLength;
  LONG           lSampleInc;

  /* for reading/writing the data ... */
  LPVOID         lpBuffer = NULL;
  LONG           cbBuffer;        /* real size of lpBuffer */
  LONG           lBufferSize;     /* needed bytes for format(s), etc. */
  LONG           lReadBytes;
  LONG           lReadSamples;
  HRESULT        hres;

  TRACE("(%s,%p,%p,%d,%p,%p)\n", debugstr_w(szFile), pclsidHandler,
	lpfnCallback, nStreams, ppavi, plpOptions);

  if (szFile == NULL || ppavi == NULL || plpOptions == NULL)
    return AVIERR_BADPARAM;
  if (nStreams >= MAX_AVISTREAMS) {
    WARN("Can't write AVI with %d streams only supports %d -- change MAX_AVISTREAMS!\n", nStreams, MAX_AVISTREAMS);
    return AVIERR_INTERNAL;
  }

  if (lpfnCallback == NULL)
    lpfnCallback = AVIFILE_AVISaveDefaultCallback;

  /* clear local variable(s) */
  for (curStream = 0; curStream < nStreams; curStream++) {
    pInStreams[curStream]  = NULL;
    pOutStreams[curStream] = NULL;
  }

  /* open output AVI file (create it if it doesn't exist) */
  hres = AVIFileOpenW(&pfile, szFile, OF_CREATE|OF_SHARE_EXCLUSIVE|OF_WRITE,
		      pclsidHandler);
  if (FAILED(hres))
    return hres;
  AVIFileInfoW(pfile, &fInfo, sizeof(fInfo)); /* for dwCaps */

  /* initialize our data structures part 1 */
  for (curStream = 0; curStream < nStreams; curStream++) {
    PAVISTREAM pCurStream = ppavi[curStream];

    hres = AVIStreamInfoW(pCurStream, &sInfo, sizeof(sInfo));
    if (FAILED(hres))
      goto error;

    /* search first video stream and check for interleaving */
    if (sInfo.fccType == streamtypeVIDEO) {
      /* remember first video stream -- needed for interleaving */
      if (lFirstVideo < 0)
	lFirstVideo = curStream;
    } else if (!dwInterleave && plpOptions != NULL) {
      /* check if any non-video stream wants to be interleaved */
      WARN("options.flags=0x%X options.dwInterleave=%u\n",plpOptions[curStream]->dwFlags,plpOptions[curStream]->dwInterleaveEvery);
      if (plpOptions[curStream] != NULL &&
	  plpOptions[curStream]->dwFlags & AVICOMPRESSF_INTERLEAVE)
	dwInterleave = plpOptions[curStream]->dwInterleaveEvery;
    }

    /* create de-/compressed stream interface if needed */
    pInStreams[curStream] = NULL;
    if (plpOptions != NULL && plpOptions[curStream] != NULL) {
      if (plpOptions[curStream]->fccHandler ||
	  plpOptions[curStream]->lpFormat != NULL) {
	DWORD dwKeySave = plpOptions[curStream]->dwKeyFrameEvery;

	if (fInfo.dwCaps & AVIFILECAPS_ALLKEYFRAMES)
	  plpOptions[curStream]->dwKeyFrameEvery = 1;

	hres = AVIMakeCompressedStream(&pInStreams[curStream], pCurStream,
				       plpOptions[curStream], NULL);
	plpOptions[curStream]->dwKeyFrameEvery = dwKeySave;
	if (FAILED(hres) || pInStreams[curStream] == NULL) {
	  pInStreams[curStream] = NULL;
	  goto error;
	}

	/* test stream interface and update stream-info */
	hres = AVIStreamInfoW(pInStreams[curStream], &sInfo, sizeof(sInfo));
	if (FAILED(hres))
	  goto error;
      }
    }

    /* now handle streams which will only be copied */
    if (pInStreams[curStream] == NULL) {
      pCurStream = pInStreams[curStream] = ppavi[curStream];
      AVIStreamAddRef(pCurStream);
    } else
      pCurStream = pInStreams[curStream];

    lStart[curStream] = sInfo.dwStart;
  } /* for all streams */

  /* check that first video stream is the first stream */
  if (lFirstVideo > 0) {
    PAVISTREAM pTmp = pInStreams[lFirstVideo];
    LONG lTmp = lStart[lFirstVideo];

    pInStreams[lFirstVideo] = pInStreams[0];
    pInStreams[0] = pTmp;
    lStart[lFirstVideo] = lStart[0];
    lStart[0] = lTmp;
    lFirstVideo = 0;
  }

  /* allocate buffer for formats, data, etc. of an initial size of 64 kBytes*/
  cbBuffer = 0x00010000;
  lpBuffer = HeapAlloc(GetProcessHeap(), 0, cbBuffer);
  if (lpBuffer == NULL) {
    hres = AVIERR_MEMORY;
    goto error;
  }

  AVIStreamInfoW(pInStreams[0], &sInfo, sizeof(sInfo));
  lFileLength = sInfo.dwLength;
  dwFileInitialFrames = 0;
  if (lFirstVideo >= 0) {
    /* check for correct version of the format
     *  -- need at least BITMAPINFOHEADER or newer
     */
    lSampleInc = 1;
    lBufferSize = cbBuffer;
    hres = AVIStreamReadFormat(pInStreams[lFirstVideo], AVIStreamStart(pInStreams[lFirstVideo]), lpBuffer, &lBufferSize);
    if (lBufferSize < (LONG)sizeof(BITMAPINFOHEADER))
      hres = AVIERR_INTERNAL;
    if (FAILED(hres))
      goto error;
  } else /* use one second blocks for interleaving if no video present */
    lSampleInc = AVIStreamTimeToSample(pInStreams[0], 1000000);

  /* create output streams */
  for (curStream = 0; curStream < nStreams; curStream++) {
    AVIStreamInfoW(pInStreams[curStream], &sInfo, sizeof(sInfo));

    sInfo.dwInitialFrames = 0;
    if (dwInterleave != 0 && curStream > 0 && sInfo.fccType != streamtypeVIDEO) {
      /* 750 ms initial frames for non-video streams */
      sInfo.dwInitialFrames = AVIStreamTimeToSample(pInStreams[0], 750);
    }

    hres = AVIFileCreateStreamW(pfile, &pOutStreams[curStream], &sInfo);
    if (pOutStreams[curStream] != NULL && SUCCEEDED(hres)) {
      /* copy initial format for this stream */
      lBufferSize = cbBuffer;
      hres = AVIStreamReadFormat(pInStreams[curStream], sInfo.dwStart,
				 lpBuffer, &lBufferSize);
      if (FAILED(hres))
	goto error;
      hres = AVIStreamSetFormat(pOutStreams[curStream], 0, lpBuffer, lBufferSize);
      if (FAILED(hres))
	goto error;

      /* try to copy stream handler data */
      lBufferSize = cbBuffer;
      hres = AVIStreamReadData(pInStreams[curStream], ckidSTREAMHANDLERDATA,
			       lpBuffer, &lBufferSize);
      if (SUCCEEDED(hres) && lBufferSize > 0) {
	hres = AVIStreamWriteData(pOutStreams[curStream],ckidSTREAMHANDLERDATA,
				  lpBuffer, lBufferSize);
	if (FAILED(hres))
	  goto error;
      }

      if (dwFileInitialFrames < sInfo.dwInitialFrames)
	dwFileInitialFrames = sInfo.dwInitialFrames;
      lReadBytes =
	AVIStreamSampleToSample(pOutStreams[0], pInStreams[curStream],
				sInfo.dwLength);
      if (lFileLength < lReadBytes)
	lFileLength = lReadBytes;
    } else {
      /* creation of de-/compression stream interface failed */
      WARN("creation of (de-)compression stream failed for stream %d\n",curStream);
      AVIStreamRelease(pInStreams[curStream]);
      if (curStream + 1 >= nStreams) {
	/* move the others one up */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -