lisamelton / video_transcoding

Tools to transcode, inspect and convert videos.
MIT License
2.39k stars 160 forks source link

Sync Issue with Avid DNxHD/DNxHR Codecs [Handbrake 1.0.7/video_transcoding 0.17.3] #188

Closed abeason closed 6 years ago

abeason commented 6 years ago

Hey Don,

Let me start by saying we're big fans of your script and use it extensively. Great work.

We've got a little problem we were hoping you could take a look at: we noticed recently that whenever we run Avid DNxHD or DNxHR codecs through your script we end up with a file that is about 1 frame out of sync. Setting an explicit frame rate does not seem to correct the issue. The sync drift seems to creep up gradually and is generally most noticeable at the end of a file.

May very well be on Handbrake's end (https://github.com/HandBrake/HandBrake/issues/1120) but wanted to put in front of you just in case.

Here's a WeTransfer link to a test file (SYNCTEST_3MIN_111717_SASexport.mov) straight out of Avid that doesn't exhibit the issue and three different conversions we did off of it that do. Each has burned in timecode for reference and a series of beeps/flashes to diagnose sync drift. https://we.tl/F4x3ZzE6Wn

Any insight you could provide would be appreciated.

Thanks!

lisamelton commented 6 years ago

@abeason Thanks for the heads up. I suspect this is a HandBrake problem since I'm not doing anything strange with frame rates. You can verify that by executing the output of:

transcode-video --dry-run SYNCTEST_3MIN_111717_SASexport.mov

... which will bypass my code entirely.

I would try that myself but both the links in your message are invalid. Thanks.

lisamelton commented 6 years ago

@abeason I'm back from dinner and downloading the files now (which are huge). I'll let you know what I find out.

lisamelton commented 6 years ago

@abeason OK, I'm not sure what I'm supposed to be looking at. I honestly don't know how to tell the "good" source from the "bad" transcoding. Can you be much more specific about the problem?

Also, examining the source video in the .mov file shows it with a non-standard frame rate of 23976/1000 or 2997/125. This is not actually 23.976. That would be 24000/1001. This might be causing HandBrakeCLI some problems.

abeason commented 6 years ago

@donmelton Users report that the sound and video are out of sync by about a frame by the 01:03:00:00 mark. I don't have the eye to see it honestly.

I followed your advice and ran dry-run to see the handbrake arguments being used, then passed them to handbrakeCLI to run my own pass with your commands. That file seemed fine to me but I'm going to have to put it in front of more discerning eyes to be able to tell.

I mentioned before that we'd made a little script to go over top of yours and analyze the incoming file using ffprobe, then try to set the frame rate using handbrakeCLI arguments to see if that fixed the issue. According to the feedback we got it didn't. Here's a sample:

rem Check framerate
for /f %%i in ('ffprobe -v error -of flat^=s^=_ -select_streams v:0 -show_entries stream^=r_frame_rate %1') do set %%i
set ffprobe_framerate=%streams_stream_0_r_frame_rate%
echo %ffprobe_framerate%
rem FFprobe gives framerate in fractions. So convert to figures Melton expects.
if %ffprobe_framerate%=="2997/125" (
    set framerate="23.976"
) else (
    set framerate="29.97"
)
echo %framerate%
rem Run Melton with settings above.
call transcode-video --mp4 %1 --target 3000 -H width=1280 -H height=720 --force-rate %framerate% --pixel-aspect 1:1 --crop %cropval% --output C:\%homepath%\Desktop\BATCH_SCRIPTS\DON_MELTON_OUT_MQ
pause

But looking at your commands and reading some of the documentation it occurred to me that even though we're using --force-rate we're not using --cfr. Handbrake documentation says in the absence of an explicit declaration any framerate set with -r uses -pfr by default.

If we want our files to be 100% frame accurate (and I can see how there isn't such a stringent necessity for this in consumer video most of the time), could the fact that the frame rate is being allowed to vary slightly be causing this? I noticed the other day that even when I used --force-rate with handbrakeCLI that the resulting file showed as variable within a small margin in MediaInfo (ffprobe showed it as plain 23.976).

I noticed the 2997/125 thing too. Didn't realize it wasn't standard. Not sure why Avid/Quicktime are outputting files like this. It's corrected in their newer AMA File Export system - files exported in that manner come out 24000/1001 as you mentioned.

The loss of sync is so minute that it would almost never matter, so this probably isn't really a bug but more a difference in requirements (and maybe a lack of understanding of the underlying software on our part). Still, would be nice to get to the bottom of it for that 0.001% of cases where we need it.

Thanks for the help and for humoring us Don!

lisamelton commented 6 years ago

@abeason Sure, glad to humor a fellow video nerd! :)

I have no idea why HandBrake is doing that. Have the HandBrake developers responded to you in your bug report yet?

abeason commented 6 years ago

@donmelton Not yet. I'll let you know if/when they do chime in. Thanks again!

lisamelton commented 6 years ago

@abeason OK, I'll close this for now but feel free to comment here again. Or even open a new issue.

abeason commented 6 years ago

Hey Don, I rewrote our scripts today to try to include -H --cfr but it looks like --cfr is not a Handbrake argument video_transcoding allows to be passed to Handbrake. Is it possible to add the capability to set a constant frame rate in or will that break the rate limiting in your script?

Tell me if this is a stupid request or if you think I'm barking up the wrong tree looking at frame rate settings for sync.

lisamelton commented 6 years ago

@abeason If you want to pass an argument to HandBrakeCLI you need to use its option without the leading -- as the argument to -H. Like this: -H cfr.

But this is completely unnecessary since using my --force-rate option will do the same thing and in a much safer way. You can verify that with the --dry-run option to see what it would pass to HandBrakeCLI.

abeason commented 6 years ago

@donmelton I didn't think to use --dry-run with --force-rate. I see that you do include --cfr there. So I guess our problem lies elsewhere. I'll wait for the Handbrake crew to chime in.

Out of curiosity, does the --force-rate option have any impact on the efficiency of the overall rate limiting function of the script?

Thanks again for all your help!

lisamelton commented 6 years ago

@abeason Sorry I took so long to reply. I was out taking my wife shopping and getting lunch.

AFAIK, forcing or limiting to a specific frame rate does not impact efficiency. But forcing a constant frame rate when the output is to an MP4 file is not actually necessary since the MP4 format will not allow a variable frame rate for video anyway.