Skip to content

Commit

Permalink
Update Device Profile for correct h264 level (#699)
Browse files Browse the repository at this point in the history
  • Loading branch information
neilsb authored Jul 17, 2022
1 parent d00ad94 commit e44c4ab
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 16 deletions.
18 changes: 11 additions & 7 deletions components/JFVideo.brs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,17 @@ sub onState(msg)
m.bufferCheckTimer.control = "start"
m.bufferCheckTimer.ObserveField("fire", "bufferCheck")
else if m.top.state = "error"
' If an error was encountered, Display dialog
dialog = createObject("roSGNode", "Dialog")
dialog.title = tr("Error During Playback")
dialog.buttons = [tr("OK")]
dialog.message = tr("An error was encountered while playing this item.")
dialog.observeField("buttonSelected", "dialogClosed")
m.top.getScene().dialog = dialog
if not m.playReported and m.top.transcodeAvailable
m.top.retryWithTranscoding = true ' If playback was not reported, retry with transcoding
else
' If an error was encountered, Display dialog
dialog = createObject("roSGNode", "Dialog")
dialog.title = tr("Error During Playback")
dialog.buttons = [tr("OK")]
dialog.message = tr("An error was encountered while playing this item.")
dialog.observeField("buttonSelected", "dialogClosed")
m.top.getScene().dialog = dialog
end if

' Stop playback and exit player
m.top.control = "stop"
Expand Down
2 changes: 2 additions & 0 deletions components/JFVideo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
<field id="showID" type="string" />

<field id="transcodeParams" type="assocarray" />
<field id="transcodeAvailable" type="boolean" value="false" />
<field id="retryWithTranscoding" type="boolean" value="false" />
<field id="isTranscoded" type="boolean" />
<field id="transcodeReasons" type="array" />

Expand Down
2 changes: 1 addition & 1 deletion manifest
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title=Jellyfin
major_version=1
minor_version=4
build_version=12
build_version=14

### Main Menu Icons / Channel Poster Artwork
mm_icon_focus_fhd=pkg:/images/channel-poster_fhd.png
Expand Down
7 changes: 7 additions & 0 deletions settings/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
"settingName": "playback.mpeg2",
"type": "bool",
"default": "false"
},
{
"title": "Attempt Direct Play (Profile Lvl)",
"description": "Attempt Direct Play for h264 media with unsupported profile levels (> 4.2) before falling back to trancoding if it fails.",
"settingName": "playback.tryDirect.h264ProfileLevel",
"type": "bool",
"default": "true"
}
]
},
Expand Down
10 changes: 9 additions & 1 deletion source/Main.brs
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,15 @@ sub Main (args as dynamic) as void
node = msg.getRoSGNode()
if node.state = "finished"
node.control = "stop"
if node.showID = invalid

' If node allows retrying using Transcode Url, give that shot
if node.retryWithTranscoding
retryVideo = CreateVideoPlayerGroup(node.Id, invalid, node.audioIndex, true)
m.global.sceneManager.callFunc("popScene")
if retryVideo <> invalid
m.global.sceneManager.callFunc("pushScene", retryVideo)
end if
else if node.showID = invalid
sceneManager.callFunc("popScene")
else
autoPlayNextEpisode(node.id, node.showID)
Expand Down
4 changes: 2 additions & 2 deletions source/ShowScenes.brs
Original file line number Diff line number Diff line change
Expand Up @@ -362,9 +362,9 @@ sub CreateSidePanel(buttons, options)
group.options = options
end sub

function CreateVideoPlayerGroup(video_id, mediaSourceId = invalid, audio_stream_idx = 1)
function CreateVideoPlayerGroup(video_id, mediaSourceId = invalid, audio_stream_idx = 1, forceTranscoding = false)
' Video is Playing
video = VideoPlayer(video_id, mediaSourceId, audio_stream_idx, defaultSubtitleTrackFromVid(video_id))
video = VideoPlayer(video_id, mediaSourceId, audio_stream_idx, defaultSubtitleTrackFromVid(video_id), forceTranscoding)
if video = invalid then return invalid
video.observeField("selectSubtitlePressed", m.port)
video.observeField("state", m.port)
Expand Down
21 changes: 18 additions & 3 deletions source/VideoPlayer.brs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
function VideoPlayer(id, mediaSourceId = invalid, audio_stream_idx = 1, subtitle_idx = -1)
function VideoPlayer(id, mediaSourceId = invalid, audio_stream_idx = 1, subtitle_idx = -1, forceTranscoding = false)

' Get video controls and UI
video = CreateObject("roSGNode", "JFVideo")
video.id = id
AddVideoContent(video, mediaSourceId, audio_stream_idx, subtitle_idx)
AddVideoContent(video, mediaSourceId, audio_stream_idx, subtitle_idx, -1, forceTranscoding)

if video.content = invalid
return invalid
Expand All @@ -16,7 +16,7 @@ function VideoPlayer(id, mediaSourceId = invalid, audio_stream_idx = 1, subtitle
return video
end function

sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -1, playbackPosition = -1)
sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -1, playbackPosition = -1, forceTranscoding = false)

video.content = createObject("RoSGNode", "ContentNode")
meta = ItemMetaData(video.id)
Expand Down Expand Up @@ -187,6 +187,21 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -

video.directPlaySupported = playbackInfo.MediaSources[0].SupportsDirectPlay
fully_external = false


' For h264 video, Roku spec states that it supports and Encoding level 4.1 and 4.2.
' The device can decode content with a Higher Encoding level but may play it back with certain
' artifacts. If the user preference is set, and the only reason the server says we need to
' transcode is that the Envoding Level is not supported, then try to direct play but silently
' fall back to the transcode if that fails.
if get_user_setting("playback.tryDirect.h264ProfileLevel") = "true" and playbackInfo.MediaSources[0].TranscodingUrl <> invalid and forceTranscoding = false and playbackInfo.MediaSources[0].MediaStreams[0].codec = "h264"
transcodingReasons = getTranscodeReasons(playbackInfo.MediaSources[0].TranscodingUrl)
if transcodingReasons.Count() = 1 and transcodingReasons[0] = "VideoLevelNotSupported"
video.directPlaySupported = true
video.transcodeAvailable = true
end if
end if

if video.directPlaySupported
protocol = LCase(playbackInfo.MediaSources[0].Protocol)
if protocol <> "file"
Expand Down
22 changes: 20 additions & 2 deletions source/utils/deviceCapabilities.brs
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,31 @@ function getDeviceProfile() as object
{
"Condition": "EqualsAny",
"Property": "VideoProfile",
"Value": "high|main|baseline|constrained baseline",
"Value": "high|main",
"IsRequired": false
},
{
"Condition": "LessThanEqual",
"Property": "VideoLevel",
"Value": "51",
"Value": "41",
"IsRequired": false
}
]
},
{
"Type": "Video",
"Codec": "hevc",
"Conditions": [
{
"Condition": "EqualsAny",
"Property": "VideoProfile",
"Value": "main",
"IsRequired": false
},
{
"Condition": "LessThanEqual",
"Property": "VideoLevel",
"Value": StrI(120 * 5.1),
"IsRequired": false
}
]
Expand Down

0 comments on commit e44c4ab

Please sign in to comment.