2012-02-02 3 views
0

Я пытаюсь записать в AVI-файл с помощью AVIStreamWrite, но полученный файл avi немного испорчен. Изображения в avi содержат правильное изображение и цвета, но продолжительность и скорость видео отключены. Я записал видео, которое должно было быть около 7 секунд, и посмотрев на свойства файла в проводнике Windows, он показал, что он длился около 2 секунд. Когда я играл в Media Player, он был слишком коротким и, казалось, играл очень быстро (движение в видео было похоже на быструю перемотку вперед). Я также не могу искать в видео с помощью Media Player. Вот что я делаю ...AVI, созданный с AVIStreamWrite, имеет неправильную длину и скорость воспроизведения

// инициализация

HRESULT AVIWriter::Init() 
{ 
HRESULT hr = S_OK; 
_hAVIFile = NULL; 
_videoStream = NULL; 


_frameCount = 0; 
AVIFileInit(); 

::DeleteFileW(_filename); 

hr = AVIFileOpen(&_hAVIFile,_filename,OF_WRITE|OF_CREATE, NULL); 
if (hr != AVIERR_OK) 
{ 
    ::cout << "AVI ERROR"; 
    return 0; 
} 
/**************************************/ 
// Create a raw video stream in the file 
::ZeroMemory(&_streamInfo, sizeof(_streamInfo)); 
_streamInfo.fccType    = streamtypeVIDEO; // stream type 
_streamInfo.fccHandler    = 0;     // No compressor 
_streamInfo.dwScale    = 1;          
_streamInfo.dwRate     = _aviFps; //this is 30 
_streamInfo.dwSuggestedBufferSize = 0; 
_streamInfo.dwSampleSize = 0; 
SetRect(&_streamInfo.rcFrame, 0, 0,_bmi.biWidth , _bmi.biHeight); 

hr = AVIFileCreateStream( _hAVIFile,  // file pointer 
          &_videoStream,// returned stream pointer 
          &_streamInfo); // stream header 

hr = AVIStreamSetFormat(_videoStream, 0, 
          &_bmi, 
          sizeof(_bmi)); 

return hr; 
} 

// называем это, когда я получаю кадр из моей камеры

HRESULT AVIWriter::AddFrameToAVI(BYTE* buffer) 
{ 
HRESULT hr; 
long size = _bmi.biHeight * _bmi.biWidth * 3; 

hr = AVIStreamWrite(_videoStream,   // stream pointer 
       _frameCount++,    // time of this frame 
       1,      // number to write 
       buffer, // pointer to data 
       size,// size of this frame 
       AVIIF_KEYFRAME,   // flags.... 
       NULL, 
       NULL); 

return hr; 

}

// назовите это, когда я закончил

void AVIWriter::CloseAVI() 

    { 
    AVIStreamClose(_videoStream); 
    AVIFileClose(_hAVIFile); 
    AVIFileExit(); 

    } 

Теперь в качестве теста я использовал GraphEdit DirectShow для создания графика, состоящего из фильтра VideoCapture для этой же камеры и мультиплекса AVI, и создал AVI-файл. В результате получился файл AVI. Частота кадров составляла 30 кадров в секунду, что я использую. Я запросил оба файла avi (мой «плохой» и «хороший», созданные с помощью GraphEdit), используя вызов в AVIStreamInfo, и информация о потоке была практически такой же для обоих файлов. Я бы ожидал, что выборки в секунду или количество кадров будут отключены для моего «плохого» avi, но это не так. Я делаю что-то неправильно, что может привести к тому, что мой AVI будет иметь неправильную длину и, похоже, будет воспроизводиться с повышенной скоростью? Я новичок в использовании VFW, поэтому любая помощь приветствуется. Спасибо

+0

Итак, сколько кадров вы на самом деле там писали? Что такое '_frameCount', когда вы закрываете файл? Это не «150», не так ли? –

+0

Хммм ... Так что я просто запустил его снова, я записал около 14 секунд и закончил видео с частотой около 4 секунд. _frameCount - это 141 кадр, который при 30 кадрах в секунду составляет около 4,7 секунды. Кажется, я должен куда-то сбрасывать кадры. В основном, что я сделал, я создал график DirectShow для подключения к моей веб-камере ноутбуков, используя ISampleGrabberCB. Я хватаю каждый кадр, а затем публикую его своим подписчикам, одним из которых является мой писатель. Я предполагаю, что я теряю примерно один из каждых четырех кадров либо в моем примереGrabberCB, либо в моей публикации кадров. – mash

ответ

1

Время кадра в завещании будет в конечном итоге _frameCount/_aviFps, так что либо вы отбрасываете свои кадры, и они не достигают AVIStreamWrite, либо, если вы предпочитаете пропустить несколько кадров в файле, вам нужно увеличить _frameCount соответственно, чтобы перепрыгнуть через кадры, чтобы пропустить.

+0

Спасибо за вход Roman. Кажется, что вы правы, все мои рамки не доходят до AVIStreamWrite! – mash

 Смежные вопросы

  • Нет связанных вопросов^_^