I am writing the program which encodes RGBA frames to the mp4 video with Microsoft Media Foundation. But, probably because a frame rate and the duration are not correct, a result video plays quickly than actual time.
How should I fix the problem that not reflect a correct play time according to the frame rate?
IMFMediaType *mediaout = NULL; MFCreateMediaType(&mediaout); mediaout->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); mediaout->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); mediaout->SetUINT32(MF_MT_AVG_BITRATE, vbitrate); mediaout->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive); MFSetAttributeSize(mediaout, MF_MT_FRAME_SIZE, owidth, oheight); MFSetAttributeRatio(mediaout, MF_MT_FRAME_RATE, fps, 1); // ex) fps=15,60 MFSetAttributeRatio(mediaout, MF_MT_PIXEL_ASPECT_RATIO, 1, 1); HRESULT hr = writer->AddStream(mediaout, &vindex); MFCreateMediaType(&mediain); mediain->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); mediain->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_ARGB32); mediain->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive); MFSetAttributeSize(mediain, MF_MT_FRAME_SIZE, width, height); //MFSetAttributeRatio(mediain, MF_MT_FRAME_RATE, fps, 1); MFSetAttributeRatio(mediain, MF_MT_PIXEL_ASPECT_RATIO, 1, 1); hr = writer->SetInputMediaType(vindex, mediain, NULL);
MFFrameRateToAverageTimePerFrame(fps, 1, &duration);DWORD EncodeVideo() { HRESULT hr; ULONGLONG wait = 1000 / fps; while (true){ if (exit == true) break; ULONGLONG st = GetTickCount64(); int stride = width * 4; IMFMediaBuffer *buffer; int buflen = height * width * 4; hr = MFCreateMemoryBuffer(buflen, &buffer); IMFSample *sample; MFCreateSample(&sample); sample->AddBuffer(buffer); UpdateFrame(); BYTE *p; buffer->Lock(&p, NULL, NULL); hr = MFCopyImage(p, stride, GetBits(), stride, stride, height); buffer->Unlock(); buffer->SetCurrentLength(buflen); sample->SetSampleTime(nvtime); sample->SetSampleDuration(duration); hr = writer->WriteSample(vindex, sample); if(SUCCEEDED(hr)) nvtime += duration; sample->Release(); buffer->Release(); ULONGLONG et = GetTickCount64() - st; if (wait > et){ Sleep((DWORD)(wait - et)); } } return S_OK; }