Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   [решено] звук из AVI (http://forum.oszone.net/showthread.php?t=122710)

pva 12-11-2008 12:51 950469

звук из AVI
 
Как достать (проиграть) звуковую дорожку из AVI?
делаю так:
Код:

class AviStream
{
public:
    ~AviStream();
    AviStream(PAVIFILE avi_file, unsigned long fcc);
    void process();

protected:
    char* bufferInfo() {return &_buffer_info[0];}
    virtual void render(unsigned frame_index, std::vector<char>& data) = 0;

private:
    PAVISTREAM          _pstream;
    std::vector<char>  _buffer_info;
    std::vector<char>  _buffer;
    unsigned            _frame_no;
};

void AviStream::process()
{
    long size1 = 0; //байт на буфер
    long size2 = 0; //сэмплов на буфер

    AVIStreamRead(_pstream, _frame_no, AVISTREAMREAD_CONVENIENT, 0, 0, &size1, &size2);
    _buffer.resize(size1);

    AVIStreamRead(_pstream, _frame_no, size2, &_buffer[0], _buffer.size(), &size1, &size2);
    render(_frame_no, _buffer);

    ++_frame_no;
}

дорожку видео читает, звук - нет, возвращает байт на буфер 0, сэмплов на буфер 0.

pva 12-11-2008 15:39 950634

Странно... на некоторых роликах звук работает. А на некоторых слетает видео-поток в кодеке. Почему?

Delirium 13-11-2008 01:06 951176

Цитата:

Цитата pva
на некоторых роликах звук работает. А на некоторых слетает видео-поток в кодеке »

А какие кодеки используют рабочий и нерабочий ролики? Может дело в этом?

pva 13-11-2008 23:33 952071

я думал, что он сам поднимает нужный кодек. Оказывается ошибался. Для видео поднимает, для аудио - не очень. Нашёл пример кода, где поднимается всё как надо. Всем пасиба :)

Delirium 14-11-2008 01:01 952131

pva, ну а отметить тему решенной? Да и примерчик кода бы тоже не помешал, для законченности темы.

pva 17-11-2008 16:14 954967

ссылку не помню, да простят меня авторы текста
Код:


static int nWaveOutHeadersCount = 0;

void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
  if (uMsg != WOM_DONE)
    return;
  LPWAVEHDR pwh = (LPWAVEHDR)dwParam1;
  char* pData = pwh->lpData;
  waveOutUnprepareHeader(hwo, pwh, sizeof(WAVEHDR));
  nWaveOutHeadersCount--;
  free(pwh);
  free(pData);
}

void PlayAviAudio(LPCSTR pszFile)
{
  AVIFileInit();
  PAVIFILE paf;
  AVIFileOpen(&paf, pszFile, OF_READ, 0);
  AVIFILEINFO afi;
  AVIFileInfo(paf, &afi, sizeof(AVIFILEINFO));
  PAVISTREAM pasAudio;
  AVIFileGetStream(paf, &pasAudio, streamtypeAUDIO, 0);
  AVISTREAMINFO asiAudio;
  AVIStreamInfo(pasAudio, &asiAudio, sizeof(AVISTREAMINFO));
  long nFormatSize;
  AVIStreamReadFormat(pasAudio, asiAudio.dwStart, NULL, &nFormatSize);
  WAVEFORMATEX* pwfxIn = (WAVEFORMATEX*)malloc(nFormatSize);
  AVIStreamReadFormat(pasAudio, asiAudio.dwStart, pwfxIn, &nFormatSize);
  WAVEFORMATEX wfxDec;
  memcpy(&wfxDec, pwfxIn, min(nFormatSize, sizeof(WAVEFORMATEX)));
  wfxDec.wFormatTag = WAVE_FORMAT_PCM;
  wfxDec.wBitsPerSample = 16;
  wfxDec.nBlockAlign = wfxDec.nChannels * wfxDec.wBitsPerSample / 8;
  wfxDec.nAvgBytesPerSec = wfxDec.nSamplesPerSec * wfxDec.nBlockAlign;
  HACMSTREAM has;
  acmStreamOpen(&has, NULL, pwfxIn, &wfxDec, NULL, NULL, 0, ACM_STREAMOPENF_NONREALTIME);
  HWAVEOUT hwo;
  waveOutOpen(&hwo, WAVE_MAPPER, &wfxDec, (DWORD_PTR)waveOutProc, 0, CALLBACK_FUNCTION);
  BYTE *pInData = NULL, *pDecData;
  long nInBufSize = 0, nSampleSize = 0, nBytesCount = 0, nSamplesCount = 1;
  DWORD nDecBufSize;
  for (int nSample = asiAudio.dwStart; nSample <= asiAudio.dwStart + asiAudio.dwLength; nSample += nSamplesCount)
  {
    if (asiAudio.dwSampleSize == 0)
    {
      AVIStreamSampleSize(pasAudio, nSample, &nSampleSize);
      nBytesCount = nSampleSize;
      if (nBytesCount > nInBufSize)
      {
        pInData = (BYTE*)realloc(pInData, nBytesCount);
        nInBufSize = nBytesCount;
      }
      AVIStreamRead(pasAudio, nSample, 1, pInData, nInBufSize, NULL, NULL);
    }
    else
    {
      nSamplesCount = 1152;
      nBytesCount = nSamplesCount * asiAudio.dwSampleSize;
      if (nBytesCount > nInBufSize)
      {
        pInData = (BYTE*)realloc(pInData, nBytesCount);
        nInBufSize = nBytesCount;
      }
      AVIStreamRead(pasAudio, nSample, nSamplesCount, pInData, nInBufSize, &nBytesCount, &nSamplesCount);
    }
    acmStreamSize(has, nBytesCount, &nDecBufSize, ACM_STREAMSIZEF_SOURCE);
    pDecData = (BYTE*)malloc(nDecBufSize);
    ACMSTREAMHEADER ash;
    memset(&ash, 0, sizeof(ACMSTREAMHEADER));
    ash.cbStruct = sizeof(ACMSTREAMHEADER);
    ash.pbSrc = pInData;
    ash.cbSrcLength = nBytesCount;
    ash.pbDst = pDecData;
    ash.cbDstLength = nDecBufSize;
    acmStreamPrepareHeader(has, &ash, 0);
    acmStreamConvert(has, &ash, 0);
    WAVEHDR* pwh = (WAVEHDR*)malloc(sizeof(WAVEHDR));
    memset(pwh, 0, sizeof(WAVEHDR));
    pwh->lpData = (LPSTR)ash.pbDst;
    pwh->dwBufferLength = ash.cbDstLengthUsed;
    waveOutPrepareHeader(hwo, pwh, sizeof(WAVEHDR));
    waveOutWrite(hwo, pwh, sizeof(WAVEHDR));
    nWaveOutHeadersCount++;
    acmStreamUnprepareHeader(has, &ash, 0);
    while (nWaveOutHeadersCount > 1)
    {
      MSG msg;
      if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
      {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
      }
      Sleep(10);
    }
  }
  waveOutReset(hwo);
  waveOutClose(hwo);
  acmStreamClose(has, 0);
  AVIStreamRelease(pasAudio);
  AVIFileRelease(paf);
  AVIFileExit();
}











#include <vfw.h>

#ifndef DIBSIZE
#define WIDTHBYTES(bits) ((DWORD)(((bits)+31) & (~31)) / 8)
#define DIBWIDTHBYTES(bi) (DWORD)WIDTHBYTES((DWORD)(bi).biWidth * (DWORD)(bi).biBitCount)
#define _DIBSIZE(bi) (DIBWIDTHBYTES(bi) * (DWORD)(bi).biHeight)
#define DIBSIZE(bi) ((bi).biHeight < 0 ? (-1)*(_DIBSIZE(bi)) : _DIBSIZE(bi))
#endif

void PlayAvi(LPCSTR pszFile, HWND hWndOutput)
{
  AVIFileInit();
  PAVIFILE paf;
  AVIFileOpen(&paf, pszFile, OF_READ, 0);
  AVIFILEINFO afi;
  AVIFileInfo(paf, &afi, sizeof(AVIFILEINFO));
  PAVISTREAM pas;
  AVIFileGetStream(paf, &pas, streamtypeVIDEO, 0);
  AVISTREAMINFO asi;
  AVIStreamInfo(pas, &asi, sizeof(AVISTREAMINFO));
  long nFormatSize;
  AVIStreamReadFormat(pas, asi.dwStart, NULL, &nFormatSize);
  BITMAPINFOHEADER* pbihIn = (BITMAPINFOHEADER*)malloc(nFormatSize);
  AVIStreamReadFormat(pas, asi.dwStart, pbihIn, &nFormatSize);
  BITMAPINFOHEADER bihDec;
  memcpy(&bihDec, pbihIn, sizeof(BITMAPINFOHEADER));
  bihDec.biCompression = BI_RGB;
  bihDec.biBitCount = 24;
  bihDec.biSizeImage = DIBSIZE(bihDec);
  BYTE* pDecData = (BYTE*)malloc(bihDec.biSizeImage);
  memset(pDecData, 0, bihDec.biSizeImage);
  HIC hic = ICDecompressOpen(ICTYPE_VIDEO, pbihIn->biCompression, pbihIn, &bihDec);
  ICDecompressBegin(hic, pbihIn, &bihDec);
  HDC hdc = GetDC(hWndOutput);
  RECT rc;
  GetClientRect(hWndOutput, &rc);
  HDRAWDIB hdd = DrawDibOpen();
  BYTE* pInData = NULL;
  long nBufSize = 0, nSampleSize = 0;
  for (int nSample = asi.dwStart; nSample <= asi.dwStart + asi.dwLength; nSample++)
  {
    AVIStreamSampleSize(pas, nSample, &nSampleSize);
    if (nSampleSize > nBufSize)
    {
      pInData = (BYTE*)realloc(pInData, nSampleSize);
      nBufSize = nSampleSize;
    }
    AVIStreamRead(pas, nSample, 1, pInData, nBufSize, NULL, NULL);
    ICDecompress(hic, 0, pbihIn, pInData, &bihDec, pDecData);
    // сейчас в pDecData текущий кадр в виде битмапки, рисуем его
    DrawDibDraw(hdd, hdc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, &bihDec, pDecData, 0, 0, bihDec.biWidth, bihDec.biHeight, 0);
  }
  DrawDibClose(hdd);
  ReleaseDC(hWndOutput, hdc);
  ICDecompressEnd(hic);
  ICClose(hic);
  AVIStreamRelease(pas);
  AVIFileRelease(paf);
  AVIFileExit();
  free(pInData);
  free(pDecData);
  free(pbihIn);
}



Время: 16:51.

Время: 16:51.
© OSzone.net 2001-