Войти
ПрограммированиеФорумОбщее

Запись изображения и звука в avi файл, с помощью API MS Windows (комментарии)

#0
23:35, 21 июня 2009

Запись изображения и звука в avi файл, с помощью API MS Windows (комментарии)

Это сообщение сгенерировано автоматически.

#1
23:35, 21 июня 2009

Еще интересно было бы рассказать о записи отдельных кадров.
Вот это http://www.gamedev.ru/flame/forum/?id=95416 было сделано с помощью AviCap отдельными кадрами. Может кому-то пригодиться

#2
23:11, 22 июня 2009

Booster
Спасибо... Интересно... Хотя не нуждаюсь в данный момент в таком, но на будущее учту с чего начать... :)

#3
14:08, 23 июня 2009

libavcodec круче.

Прошло более 10 месяцев
#4
13:10, 3 мая 2010
  //Если предыдущий вызов AVIStreamSetFormat завершился неудачей,
  //то пытаемся установить другой формат. 16 бит на пиксель.
  bi.bmiHeader.biBitCount = 16;
  if(AVIERR_OK==AVIMakeCompressedStream(ppCompressedStreamVideo,
     pStreamVideo, pVideoOptions, NULL) )
  {

      //Устанавливаем формат.
      if (AVIERR_OK == AVIStreamSetFormat(*ppCompressedStreamVideo, 0, &bi,
             ((LPBYTE)pBits) - ((LPBYTE) &bi)))
             return true;
      
      //В случае неуспеха удаляем поток.
      AVIStreamRelease(*ppCompressedStreamVideo);
      pCompressedStreamVideo = 0;
  }

  //Если предыдущий вызов AVIStreamSetFormat завершился неудачей,
  //то пытаемся установить другой формат. 8 бит на пиксель.
  bi.bmiHeader.biBitCount = 8;
  if(AVIERR_OK==AVIMakeCompressedStream(ppCompressedStreamVideo,
     pStreamVideo, pVideoOptions, NULL) )
  {

      //Устанавливаем формат.
      if (AVIERR_OK == AVIStreamSetFormat(*ppCompressedStreamVideo, 0, &bi,
             ((LPBYTE)pBits) - ((LPBYTE) &bi)))
             return true;
      
      //В случае неуспеха удаляем поток.
      AVIStreamRelease(*ppCompressedStreamVideo);
      pCompressedStreamVideo = 0;
  }

если мы это делаем, то мы должны и позаботится о буфере который мы пишем, а в примере:

  const DWORD sizeVideoFrame = WidthFrame * HeightFrame * 3;
  void *pVideo = malloc(sizeVideoFrame + sizeof(BITMAPINFOHEADER));
  BITMAPINFOHEADER *pBitm = (BITMAPINFOHEADER*)pVideo;
  ZeroMemory(pBitm, sizeof(BITMAPINFOHEADER));
  pBitm->biWidth = WidthFrame;
  pBitm->biHeight = HeightFrame;
  pBitm->biBitCount = 24;
  pBitm->biPlanes = 1;
  pBitm->biSize = sizeof(BITMAPINFOHEADER);
  pBitm->biCompression = BI_RGB;
  pBitm->biSizeImage = sizeVideoFrame;

  char *pBits = (char*)pVideo + sizeof(BITMAPINFOHEADER);

  int CountSoundInFrame = wf.nAvgBytesPerSec / FrameRate;
  DWORD *pSound = (DWORD*)malloc(CountSoundInFrame);

  printf("Recording ");

  for (int i = 0; i<CountFrames; i++)
  {
    //Video frame
    for (int i2 = 0; i2<(WidthFrame * HeightFrame); i2++)
    {
       unsigned int color = (((float)rand())/RAND_MAX)*0xffffff;
       pBits[i2*3] = ((char*)&color)[0];
       pBits[i2*3+1] = ((char*)&color)[1];
       pBits[i2*3+2] = ((char*)&color)[2];
    }

    //Audio frame
    for (int i3=0; i3<CountSoundInFrame/4; i3++)
    {
      unsigned short x = (((float)rand())/RAND_MAX)*AmplitudeSound;
      unsigned short y = (((float)rand())/RAND_MAX)*AmplitudeSound;
      ((WORD*)pSound)[i3*2] = x;
      ((WORD*)pSound)[i3*2+1] = y;
    }

    if (!WriteFrameVideoCompress(pCompressedStreamVideo, (BITMAPINFO*)pBitm, i))
      break;
    if (!WriteFrameAudio(pStreamAudio, pSound, CountSoundInFrame, i))
      break;

    if (!(i%FrameRate))
      printf(".");
  }

этого не делают, что неверно. Чтобы убедится в этом достаточно поменять

       pBits[i2*3] = ((char*)&color)[0];
       pBits[i2*3+1] = ((char*)&color)[1];
       pBits[i2*3+2] = ((char*)&color)[2];

на

       pBits[i2*3] = 0;
       pBits[i2*3+1] = 0;
       pBits[i2*3+2] = ((char*)&color)[2];

т.е. попытаться получить только "красный шум", и поэксперементировать с компрессорами. Например для Microsoft RLE будет НЕ красный шум. Попробуйте.

Так же утверждение в статье в пункте 7. Запись видео данных:
>>lpBuffer - указатель на буфер с данными кадра. Обратите внимание, что впереди этих данных обязательно должен быть корректно заполненный заголовок BITMAPINFOHEADER, иначе запись не произойдёт.
Неверно. Не должен там быть BITMAPINFOHEADER. Достаточно только указатель на буфер с самими данными, и размер этого самого буфера, НО буфер должен АБСОЛЮТНО соответствовать формату который мы выставили в пункте 5. Создание видео потока с компрессией через AVIStreamSetFormat.

ПрограммированиеФорумОбщее

Тема в архиве.