Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Video Encode API: Output File has 1000 fps? #15

Closed
Xaymar opened this issue Aug 30, 2016 · 17 comments
Closed

Video Encode API: Output File has 1000 fps? #15

Xaymar opened this issue Aug 30, 2016 · 17 comments

Comments

@Xaymar
Copy link
Contributor

Xaymar commented Aug 30, 2016

I am unsure as to why this happens. I know that with Media SDK it did not happen, am I forgetting to set something per frame?

Encoder Parameters (in the order they were assigned):

AMF_VIDEO_ENCODER_USAGE = Transcoding
AMF_VIDEO_ENCODER_QUALITY_PRESET = Speed
AMF_VIDEO_ENCODER_PROFILE = High
AMF_VIDEO_ENCODER_PROFILE_LEVEL = 5.2
AMF_VIDEO_ENCODER_FRAMESIZE = 1920x1080
AMF_VIDEO_ENCODER_FRAMERATE = 60/1
AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD = CQP
AMF_VIDEO_ENCODER_FILLER_DATA_ENABLE = False
AMF_VIDEO_ENCODER_RATE_CONTROL_SKIP_FRAME_ENABLE = False
AMF_VIDEO_ENCODER_VBV_BUFFER_SIZE = 65535000
AMF_VIDEO_ENCODER_INITIAL_VBV_BUFFER_FULLNESS = 64
AMF_VIDEO_ENCODER_MIN_QP = 11
AMF_VIDEO_ENCODER_MAX_QP = 41
AMF_VIDEO_ENCODER_QP_I = 27
AMF_VIDEO_ENCODER_QP_P = 29
AMF_VIDEO_ENCODER_QP_B = 31
AMF_VIDEO_ENCODER_ENFORCE_HRD = False
AMF_VIDEO_ENCODER_IDR_PERIOD = 60
AMF_VIDEO_ENCODER_DE_BLOCKING_FILTER = False
AMF_VIDEO_ENCODER_B_PIC_PATTERN = 3
AMF_VIDEO_ENCODER_B_REFERENCE_ENABLE = False
AMF_VIDEO_ENCODER_B_PIC_DELTA_QP = 2
AMF_VIDEO_ENCODER_REF_B_PIC_DELTA_QP = 1
AMF_VIDEO_ENCODER_MOTION_HALF_PIXEL = True
AMF_VIDEO_ENCODER_MOTION_QUARTERPIXEL = True
AMF_VIDEO_ENCODER_FRAMESIZE = 1920x1080
AMF_VIDEO_ENCODER_FRAMERATE = 60/1

Submission Parameters (in the order they were assigned):

PTS = Frame Index converted to real time
Frame = Frame Index

Here is a file which won't support skipping in decoders that don't automatically fix this: 2016-08-30 08-40-44.zip

@MikhailAMD
Copy link
Collaborator

The file looks correct to me. I checked all properties by MediaInfo app - advanced mode. The seeking works in VLC and both MSFT players. In general, all skipping or seeking relays solely on I-frames and on PTS which is not part of encoder but belong to container.
Where did you get 1000 fps? And what is the actual problem in details?

@Xaymar
Copy link
Contributor Author

Xaymar commented Aug 30, 2016

You can see the 1000 FPS being listed if you right-click on the file in Windows Explorer and select Properties, it should be in the Details tab. A properly encoded file (Media SDK) shows 60 frames/second here for a 60/1 setting, not 1000 frames/second. Additionally the output packet stream is near impossible to correctly stream or use: MPC-HC, Windows Media Player, Movies & TV app, DirectShow assisted playback, Intel HW Decoder and NVidia HW Decoder will all fail to play it back correctly if they weren't present at the start of playback.

VLC will take a bit to skip to any point, but will play it back "fine" due to it's automatic correction.
MPC-HC will start flickering - this is the correct behaviour as observed with StreamEye.
Windows Media Player refuses to skip, same with Movies & TV app and DirectShow assisted playback.
MFT Decoding is unaffected, plays it back fine - most likely uses the GPU to decode anyway.
Intel and NVidias HW Decoder try, but will fail as there is just not enough frames for the correct stream: the result is either green or almost pure black. I have reproduced this on a remote machine myself.
FFMPEG handles it just fine again.

Twitch and Beam will occasionally refuse the stream, while YouTube and HitBox will accept it just fine - with some additional delay. Uploading the raw mkv file to YouTube will have it be in processing for much longer than it normally should be. It's really hit and miss with what software accepts it and what software flips out.

@MikhailAMD
Copy link
Collaborator

Hey,
I just tried to record MKV with these settings and then MP4 with the same settings.
MKV file does show 1000 fps in properties while MP4 does not. Both files are play-able and seek-able in VLC, WMP and Movies&TV players. The elementary streams are fully valid - verified by Vega analyzer .
Please try MP4 and compare.

@Xaymar
Copy link
Contributor Author

Xaymar commented Aug 31, 2016

Did that now, exactly the same issue. The file is unwatchable in Windows Media Player and Movies & TV, seeking is broken in MPC-HC (flickering) - only VLC and ffmpeg have no issues, probably because these two apply an automatic correction to the stream.

Here is an archive with two high quality 1920x1080p60 recordings using settings very similar to the ones listed in the initial issue: AMFIssue15.7z (1.19 GB, contains mkv and mp4 file).

I can provide the trace output of a recording if it is needed to track the issue down. Like I said before, in Media SDK 1.1 with the updated binaries it worked fine.

@MikhailAMD
Copy link
Collaborator

the link doesn't work

@Xaymar
Copy link
Contributor Author

Xaymar commented Aug 31, 2016

This one should work, forgot the http:// part: http://cdn.xaymar.com/private/2016/08/AMFIssue15.7z

@MikhailAMD
Copy link
Collaborator

OK, these clips fail to play in WMP on Win7 (plays but show black screen) but play with wrong frame order on WMP Win10. The elementary H.264 stream is correct (Vega analyzer). I believe that container (MP4, MKV) must have DTS set to decode order and PTS to present order. Currently AMF encoder returns PTS (->GetPts()) in decode order. The plug-ins sets it to PTS and DTS. The plug-in has code that set present time PTS on surface as a private property L"Frame". You should use it to set DTS in the output packet. please try,
Also please try to disable B-frames - for test only. it should produce the playable files.
My dev machine is borrowed so I cannot try it myself right now.
thanks,

@Xaymar
Copy link
Contributor Author

Xaymar commented Sep 1, 2016

Applied the changes, no differences in the result: http://cdn.xaymar.com/private/2016/09/2016-09-01%2010-14-34.mp4

Edit: File can't even be fixed using ffmpeg.
Edit 2: I can't really figure out what is wrong and why it won't play back/decode properly in these players. MPC-HC is considered one of the best players.

@MikhailAMD
Copy link
Collaborator

I fixed the file you sent me with FFMPEG just by extracting elementary stream and putting back to the container. The BAT file would look like:
ffmpeg.exe -i %1 -vcodec copy -bsf h264_mp4toannexb %1.h264
ffmpeg.exe -i %1.h264 -vcodec copy %1.h264.mp4
Annexb is important.
Please share your command lines.
This experiment points toward container.
Also did you try to disable B-frames?

@Xaymar
Copy link
Contributor Author

Xaymar commented Sep 1, 2016

I fixed the file you sent me with FFMPEG just by extracting elementary stream and putting back to the container. The BAT file would look like:
ffmpeg.exe -i %1 -vcodec copy -bsf h264_mp4toannexb %1.h264
ffmpeg.exe -i %1.h264 -vcodec copy %1.h264.mp4
Annexb is important.
Please share your command lines.
This experiment points toward container.

My command line is this (didn't help much, obviously):

ffmpeg -i "%~1" -an -vcodec copy -r 60hz -s 1920x1080 "%~dpf1_fixed.mp4"

And your command line actually fixes it. The question is now why is it broken in the first place.

Also did you try to disable B-frames?

Yes, that new file is without B-Frames and with the changes you mentioned.

@Xaymar
Copy link
Contributor Author

Xaymar commented Sep 1, 2016

This is the code that creates the surface being submitted:

amf::AMFSurfacePtr Plugin::AMD::VCEEncoder::CreateSurfaceFromFrame(struct encoder_frame*& frame) {

...

        // Convert Frame Index to Nanoseconds.
        amf_pts amfPts = (int64_t)ceil((double_t)frame->pts * (m_FrameRateReverseDivisor * 10000000.0));
        // Example for the above:
        // amfPts = frame * ((1.0 / 60.0) * 10000000.0);
        // amfPts = 23 * ((1.0 / 60.0) * 10000000.0);
        // amfPts = 23 * (0.016' * 10000000.0);
        // amfPts = 23 * 166666.6'
        // amfPts = 3833333.3' amf_pts(100 ns) = 383.333 µs = 383.333 ms = 0.383 s
        pSurface->SetPts(amfPts);
        pSurface->SetProperty(L"Frame", frame->pts);
    }

    return pSurface;
}

And the code that does the reverse operation, converting from real time back to frames:

void Plugin::AMD::VCEEncoder::OutputThreadLogic() {
    // Thread Loop that handles Querying
    uint64_t lastFrameIndex = 0;
    double_t frameRateDivisor = (m_FrameRateReverseDivisor * 10000000.0);

    std::unique_lock<std::mutex> lock(m_ThreadedOutput.mutex);
    do {

...

        // Update divisor.
        frameRateDivisor = (m_FrameRateReverseDivisor * 10000000.0);

...

                AMF_LOG_INFO("out: %d pts", pData->GetPts());
                pkt.dts = (uint64_t)((double_t)pData->GetPts() / frameRateDivisor);
                pData->GetProperty(L"Frame", &pkt.pts);

...

}

@MikhailAMD
Copy link
Collaborator

Yes, I saw this code. I don't see any problem here. I am guessing but there is something between plug-in and libav. When we released AMF 1.3 the hope was that applications will switch the existing code, make it working and then continue development. Now we have two moving targets: AMF and the plug-in.
I will download the latest MP4 file, and check. The server is very slow. I will look into OBS code and integration with libav but probably next week.
Meanwhile you may want to check AMF sample code with FFMpeg integration: TranscodeHW sample and ComponentsFFMPEG project. It may give you a clue.

@Xaymar
Copy link
Contributor Author

Xaymar commented Sep 1, 2016

I will download the latest MP4 file, and check. The server is very slow.

That could be because the server is located in Germany and will only serve users in Europa and USA with really high speeds. Can't really fix this for a while, contract runs until the end of the next year. :/

Meanwhile you may want to check AMF sample code with FFMpeg integration: TranscodeHW sample and ComponentsFFMPEG project. It may give you a clue.

I will. Hopefully I can track down where things go wrong after understanding it.

@Xaymar
Copy link
Contributor Author

Xaymar commented Sep 1, 2016

Alright, so some change i did seems to have fixed it. I'm not sure what I did, but it works now - so I'm not complaining. mkv still shows 1000 fps in VLC and Properties, but I think that is actually an issue in VLC and windows.

If only I knew what fixed it.

Xaymar pushed a commit to obsproject/obs-amd-encoder that referenced this issue Sep 1, 2016
… ::SetFrameRate to only increase timer precision while encoding and apparently fix the wrong order of frames in streams and recorded files. (GPUOpen-LibrariesAndSDKs/AMF#15)
@MikhailAMD
Copy link
Collaborator

Yes, sounds weird. Shell we close issues: this one and about CPU usage?

Mikhail

From: Michael Fabian Dirks [mailto:notifications@github.com]
Sent: September 1, 2016 2:41 PM
To: GPUOpen-LibrariesAndSDKs/AMF AMF@noreply.github.com
Cc: Mironov, Mikhail Mikhail.Mironov@amd.com; Comment comment@noreply.github.com
Subject: Re: [GPUOpen-LibrariesAndSDKs/AMF] Video Encode API: Output File has 1000 fps? (#15)

Alright, I'm confused now. I changed absolutely nothing, still on driver 16.8.2 and it suddenly works? Huh?!


You are receiving this because you commented.
Reply to this email directly, view it on GitHubhttps://github.com//issues/15#issuecomment-244172463, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AOcWv1DEFyOVL88q30TyxSi1gjn7FY0Pks5qlxxDgaJpZM4JwNKV.

@Xaymar
Copy link
Contributor Author

Xaymar commented Sep 1, 2016

I figured out what happened. I was using the Advanced Interface which was still using the Media SDK order - which didn't work with AMF SDK. I'll close this one now.

@Xaymar Xaymar closed this as completed Sep 1, 2016
@MikhailAMD
Copy link
Collaborator

Cool, thanks,

Mikhail

From: Michael Fabian Dirks [mailto:notifications@github.com]
Sent: September 1, 2016 4:32 PM
To: GPUOpen-LibrariesAndSDKs/AMF AMF@noreply.github.com
Cc: Mironov, Mikhail Mikhail.Mironov@amd.com; Comment comment@noreply.github.com
Subject: Re: [GPUOpen-LibrariesAndSDKs/AMF] Video Encode API: Output File has 1000 fps? (#15)

I figured out what happened. I was using the Advanced Interface which was still using the Media SDK order - which didn't work with AMF SDK. I'll close this one now.


You are receiving this because you commented.
Reply to this email directly, view it on GitHubhttps://github.com//issues/15#issuecomment-244202874, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AOcWv7EQBFjPAVE3Ky-DN997QyXw0gAiks5qlzY4gaJpZM4JwNKV.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants