[go: up one dir, main page]

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

Always set ffmpeg flag +genpts when video stream is being copied #977

Merged
merged 3 commits into from
Feb 27, 2019
Merged

Conversation

Lynxy
Copy link
Contributor
@Lynxy Lynxy commented Feb 22, 2019

Changes
Ensure ffmpeg flag +genpts is set if target codec is copy.

Issues
Transcoding fails on video streams that lack PTS data. When ffmpeg is copying a video stream which lacks PTS data or for some other reason PTS is not passed along correctly, the ffmpeg decoder is bypassed and PTS data is not ever generated, resulting in a stream that never plays.

Output of ffmpeg in such a case:

[NULL @ 0x5bfc8c0] Failed to parse extradata
[segment @ 0x5c20900] Timestamps are unset in a packet for stream 0. This is deprecated and will stop working in the future. Fix your code to set the timestamps properly
[mpegts @ 0x5c2b140] Timestamps are unset in a packet for stream 0. This is deprecated and will stop working in the future. Fix your code to set the timestamps properly
[mpegts @ 0x5c2b140] first pts value must be set
av_interleaved_write_frame(): Invalid data found when processing input
[mpegts @ 0x5c2b140] first pts value must be set
[segment @ 0x5c20900] Opening '/var/lib/jellyfin/transcoding-temp/e0cc15376cab26c8563e0be01117a4cd.m3u8.tmp' for writing
Error writing trailer of /var/lib/jellyfin/transcoding-temp/e0cc15376cab26c8563e0be01117a4cd%d.ts: Invalid data found when processing input

The +genpts flag will generate missing PTS if DTS is present. Relevant Stack Exchange answer: https://superuser.com/questions/710008/how-to-get-rid-of-ffmpeg-pts-has-no-value-error

@cvium
Copy link
Member
cvium commented Feb 22, 2019

Would be helpful if you could paste the actual command before and after the changes.

Also, I'm not convinced this actually places the flag before -i, which according to the ffmpeg devs is necessary.

Copy link
Contributor
@JustAMan JustAMan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look okay-ish, but I second @cvium - please provide pre- and post-change ffmpeg command lines.

@Lynxy
Copy link
Contributor Author
Lynxy commented Feb 22, 2019

Sure thing. Here are the commands taken from /var/log/jellyfin/ (with media path replaced for privacy).

Before patch:

/usr/local/bin/ffmpeg-4.0.3-64bit-static/ffmpeg -f avi -i file:"/path/to/media/file.avi" -map_metadata -1 -map_chapters -1 -threads 8 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -copyts -vsync -1 -codec:a:0 aac -strict experimental -ac 2 -ab 117512 -f segment -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -segment_time 6 -individual_header_trailer 0 -segment_format mpegts -segment_list_type m3u8 -segment_start_number 0 -segment_list "/var/lib/jellyfin/transcoding-temp/48b5614998dd85b101d4612dcd7ec15a.m3u8" -y "/var/lib/jellyfin/transcoding-temp/48b5614998dd85b101d4612dcd7ec15a%d.ts"

After patch:

/usr/local/bin/ffmpeg-4.0.3-64bit-static/ffmpeg -fflags +genpts -f avi -i file:"/path/to/media/file.avi" -map_metadata -1 -map_chapters -1 -threads 8 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -copyts -vsync -1 -codec:a:0 aac -strict experimental -ac 2 -ab 117512 -f segment -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -segment_time 6 -individual_header_trailer 0 -segment_format mpegts -segment_list_type m3u8 -segment_start_number 0 -segment_list "/var/lib/jellyfin/transcoding-temp/f5f73d0b4df185cb317b36fc1b98cf.m3u8" -y "/var/lib/jellyfin/transcoding-temp/f5f73d0b4df185cb317b36fc1b98cf%d.ts"

I believe the flags are placed in the correct location because of the code at MediaBrowser.Api/Playback/Hls/BaseHlsService.cs:268. Under this line it even asks the question if +genpts should be added while copying.

@Lynxy
Copy link
Contributor Author
Lynxy commented Feb 22, 2019

@cvium, this pull requests addresses EncodingHelper.cs:2453; it is moved up to line 2439 to read clearer.

As for EncodedRecorder.cs:152, what exactly needs fixing? I do not use the Live TV feature so I would not be able to test any changes, so I wouldn't feel comfortable doing any work to that.

Copy link
Contributor
@JustAMan JustAMan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
Please add yourself to CONTRIBUTORS.md!

@Lynxy
Copy link
Contributor Author
Lynxy commented Feb 23, 2019

Hah alright, will do!

@cvium
Copy link
Member
cvium commented Feb 23, 2019

@cvium, this pull requests addresses EncodingHelper.cs:2453; it is moved up to line 2439 to read clearer.

As for EncodedRecorder.cs:152, what exactly needs fixing? I do not use the Live TV feature so I would not be able to test any changes, so I wouldn't feel comfortable doing any work to that.

The problem with EncodingHelper.cs:2453 is that the function is called here

GetProgressiveVideoArguments(state, encodingOptions, videoCodec, defaultH264Preset),
, which is after the -i flag.

Regarding EncodedRecorder.cs:152, it's a similar problem in that it's used here after -i:

var commandLineArgs = string.Format("-i \"{0}\"{5} {2} -map_metadata -1 -threads 0 {3}{4}{6} -y \"{1}\"",

@Lynxy
Copy link
Contributor Author
Lynxy commented Feb 23, 2019

@cvium, I provided a before/after log showing the issued ffmpeg command having +genpts before the -i switch as you requested. I would be happy to provide a .avi file that does not transcode without +genpts so you could test this patch yourself.

Here is how +genpts gets before -i.

EncodingHelper.cs:2453 is called from 4 locations:

  1. MediaBrowser.Api.Playback.Hls.BaseHlsService.GetCommandLineArguments()
  2. MediaBrowser.Api.Playback.Hls.DynamicHlsService.GetCommandLineArguments()
  3. MediaBrowser.Controller.MediaEncoding.EncodingHelper.GetProgressiveAudioFullCommandLine()
  4. MediaBrowser.Controller.MediaEncoding.EncodingHelper.GetProgressiveVideoFullCommandLine()

Number 1 and 2 from my list are similar so we'll examine those together. Look at the return string.Format() call in both of them. It formats the string with {0} coming first, which is inputModifier, a variable containing the output of EncodingHelper.GetInputModifier(), the function I modified. Next up is {1}, which is the output from EncodingHelper.GetInputArgument; it is within this function that the -i switch is added. It is quite clear how +genpts ends up before -i here.

Number 3 are 4 are similar as well. The return string.Format() call formats with {0} first, which is inputModifier, a variable containing the output of EncodingHelper.GetInputModifier(), the function I modified. Next comes {1} which is the output from this.GetInputArgument() which provides the -i switch. In these cases it is clear to see how +genpts ends up before -i.

You are right about the call to GetProgressiveVideoArguments() coming after the -i switch so I will revert the code there as that seems be intended to apply to the output file.

@Lynxy
Copy link
Contributor Author
Lynxy commented Feb 23, 2019

In regards to @cvium's second point, I do not know why you are asking me to fix EncodedRecorder.cs:152. This patch does not touch that file at all. The code you are referencing is existing code; Jellyfin will behave exactly the same with or without my patch. It is also for a completely different aspect (LiveTV) so should probably be it's own PR.

@joshuaboniface
Copy link
Member

@cvium Does @Lynxy's last commit address your concerns?

Copy link
Member
@joshuaboniface joshuaboniface left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved pending feedback from @cvium.

@cvium
Copy link
Member
cvium commented Feb 27, 2019

No, fflags only works on inputs according to the response we got from the ffmpeg mailing list. But it's fine, we'll deal with it separately.

Copy link
Member
@cvium cvium left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved

@joshuaboniface joshuaboniface merged commit 9651a78 into jellyfin:master Feb 27, 2019
brianjmurrell added a commit to brianjmurrell/jellyfin that referenced this pull request Feb 28, 2019
brianjmurrell added a commit to brianjmurrell/jellyfin that referenced this pull request Mar 1, 2019
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

Successfully merging this pull request may close these issues.

4 participants