locked
Output video bitrate is unexpected when convert video using MFT RRS feed

  • Question

  • When we convert a fast motion video with some parameters as following:

    - video codec: H264

    - video frame rate: 30 frame/s

    - video bitrate: 128000 bps

    The output video bitrate is un expected (128kbps)

    We have implemented fast motion video encode using CODECAPI_AVEncCommonRateControlMode with two values eAVEncCommonRateControlMode_CBR and eAVEncCommonRateControlMode_PeakConstrainedVBR. However, the video output still does not receive the expected bitrate setting.

    Video input: https://drive.google.com/drive/folders/1MJrv5VOKqbEvWHAOkwTH1ZfB9w6FiPRA?usp=sharing

    Q: Can you explain the problem, is there something wrong with the codecAPI of MS?


    Tuesday, June 9, 2020 9:39 AM

All replies

  • Hi DinhChuyen,

    Thanks for posting here.

    Q: Can you explain the problem, is there something wrong with the codecAPI of MS?

    Can you provide a code sample that can reproduce this problem?

    Best regards,

    Strive


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, June 10, 2020 10:09 AM
  • Hi Strive,

    Program details as below:
    ---------------------------------------

    #include <windows.h>
    #include <windowsx.h>
    #include <comdef.h>
    #include <stdio.h>
    #include <mfapi.h>
    #include <mfidl.h>
    #include <mfreadwrite.h>
    #include <Mferror.h>
    #include <mfplay.h>
    #include <codecapi.h>
    #include <atlcomcli.h>
    #pragma comment(lib, "ole32")
    #pragma comment(lib, "mfplat")
    #pragma comment(lib, "mfreadwrite")
    #pragma comment(lib, "mfuuid")

    int main()
    {
    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    hr = MFStartup(MF_VERSION);

    IMFMediaType *pMediaType;
    IMFMediaType *pMediaTypeOut;
    IMFSourceReader *pSourceReader;
    IMFAttributes *pAttributes;
    IMFSinkWriter *pSinkWriter;
    IMFMediaType *pCurrentMediaType;
    LONGLONG nDruration = 37200000;

    hr = MFCreateSourceReaderFromURL(L"Black_bird.mp4", NULL, &pSourceReader);
    pSourceReader->SetStreamSelection(MF_SOURCE_READER_FIRST_VIDEO_STREAM, TRUE);

    IMFMediaType *pPartialType;
    MFCreateMediaType(&pPartialType);
    hr = pPartialType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
    hr = pPartialType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
    hr = pSourceReader->SetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM, nullptr, pPartialType);
    hr = pSourceReader->GetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM, &pPartialType);
    hr = pSourceReader->SetStreamSelection(MF_SOURCE_READER_FIRST_VIDEO_STREAM, TRUE);

    hr = MFCreateMediaType(&pMediaTypeOut);
    hr = pMediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
    hr = pMediaTypeOut->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
    hr = pMediaTypeOut->SetUINT32(MF_MT_AVG_BITRATE, 128000);
    hr = pMediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
    hr = MFSetAttributeRatio(pMediaTypeOut, MF_MT_FRAME_RATE, 30, 1);
    hr = MFSetAttributeSize(pMediaTypeOut, MF_MT_FRAME_SIZE, 1920, 1080);
    hr = MFSetAttributeRatio(pMediaTypeOut, MF_MT_PIXEL_ASPECT_RATIO, 16, 9);

    DWORD nWriterStreamIndex = -1;
    hr = MFCreateSinkWriterFromURL(L"output.mp4", NULL, NULL, &pSinkWriter);
    hr = pSinkWriter->AddStream(pMediaTypeOut, &nWriterStreamIndex);
    hr = pSinkWriter->BeginWriting();

    LONGLONG SampleDuration = 0L;
    //Sets the input format for a stream on the sink writer.
    hr = pSinkWriter->AddStream(pMediaTypeOut, &nWriterStreamIndex);
    hr = pSinkWriter->SetInputMediaType(nWriterStreamIndex, pPartialType, NULL);

    // Using codecapi #begin
    CComPtr<ICodecAPI> pCodecApi;
    hr = pSinkWriter->GetServiceForStream(nWriterStreamIndex, GUID_NULL, __uuidof(ICodecAPI), (void**)&pCodecApi);
    if (pCodecApi)
    {
    VARIANT var;
    VariantInit(&var);
    var.vt = VT_UI4;
    var.ulVal = eAVEncCommonRateControlMode_CBR; // or eAVEncCommonRateControlMode_UnconstrainedVBR
    hr = pCodecApi->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var);
    VariantClear(&var);
    }
    // Using codecapi #end

    for (;;)
    {
    DWORD nStreamIndex, nStreamFlags;
    LONGLONG nTime;
    IMFSample *pSample;

    hr = pSourceReader->ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM,
    0,
    &nStreamIndex,
    &nStreamFlags,
    &nTime,
    &pSample);
    printf("%d\n", nStreamFlags);
    printf("%d\n", nTime);

    //Update media type, when current media tye changed.
    if (nStreamFlags & MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED) {
    pSourceReader->GetNativeMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM, MF_SOURCE_READER_CURRENT_TYPE_INDEX, &pCurrentMediaType);
    pSourceReader->SetStreamSelection(MF_SOURCE_READER_FIRST_VIDEO_STREAM, TRUE);
    hr = pSinkWriter->SetInputMediaType(nWriterStreamIndex, pCurrentMediaType, NULL);
    continue;
    }
    pSample->GetSampleDuration(&SampleDuration);

    if (nTime >= nDruration)
    {
    break;
    }
    // Calculate new timestamp of sample when this sample is written on output file
    if (nTime + SampleDuration >= nDruration)
    {
    SampleDuration = nDruration - nTime;
    pSample->SetSampleDuration(SampleDuration);
    }
    pSample->SetSampleTime(nTime);

    if (FAILED(hr)) {
    printf("ReadSample Error...\n");
    return 0;
    }

    //write sample
    if (pSample)
    {
    OutputDebugString(L"Write sample...\n");
    hr = pSinkWriter->WriteSample(
    nWriterStreamIndex,
    pSample
    );
    if (FAILED(hr)) {
    printf("WriteSample Error...\n");
    return 0;
    }
    }

    if (nStreamFlags & MF_SOURCE_READERF_ENDOFSTREAM)
    {
    break;
    }
    }
    hr = pSinkWriter->Finalize();
    return 0;
    }

    The output is set 128kbps bit rate. However regardless of whether we use codecapi CODECAPI_AVEncCommonRateControlMode or not, the results are not as expected

    However regardless of whether we use codecapi CODECAPI_AVEncCommonRateControlMode or not, the results are not as expected

    • Edited by DinhChuyen Wednesday, July 15, 2020 9:43 AM
    Tuesday, June 30, 2020 4:38 AM