Homebrew Homebrew app [Release] Video player for 3DS

AleronIves

Well-Known Member
Member
Joined
Nov 17, 2016
Messages
460
Trophies
0
Age
36
Location
California
XP
2,250
Country
United States
I was using an anime fansub video to test with, so I don't think I'm allowed to upload it here. I tried encoding another video using similar x264 settings, and MVD_Services was able to play it, so I don't know why the anime video is causing the error. Does the video player support ASS subtitles? 🤔
 
  • Like
Reactions: Core_2_Extreme

Core_2_Extreme

Well-Known Member
OP
Member
Joined
Feb 11, 2019
Messages
153
Trophies
0
Age
22
XP
1,163
Country
Japan
I was using an anime fansub video to test with, so I don't think I'm allowed to upload it here. I tried encoding another video using similar x264 settings, and MVD_Services was able to play it, so I don't know why the anime video is causing the error. Does the video player support ASS subtitles? 🤔
No, it supports subrip, subviewer and movtext (has no style support).
Well, I didn't think about subtitle codec, I think your (and others) error came from subtitle decoder initialization.
To confirm that, open log window by pressying the SELECT button on main menu then try to play a video which will fail.
Then you should see something like "Util_subtitle_decoder_init()...[Error ]...avcodec_find_decoder() failed.".

How your "similar x264 settings video (I think that contains B-frames)" was played?
 

AleronIves

Well-Known Member
Member
Joined
Nov 17, 2016
Messages
460
Trophies
0
Age
36
Location
California
XP
2,250
Country
United States
Then you should see something like "Util_subtitle_decoder_init()...[Error ]...avcodec_find_decoder() failed.".
Yep, that's the error. The video player doesn't like the subtitle stream.

How your "similar x264 settings video (I think that contains B-frames)" was played?
Playback with B-frames seems smoother now. It looks like there might still be some stuttering that is most visible during camera pans, but it's much less noticeable than before.

I remuxed the anime video without subtitles, and it plays now. :) It's much smoother than the last time I tried to play it with MVD_Services.

Since MVD_Services sometimes outputs the same frame twice and other times skips frames, how did you get it to work? Maybe B-frame decoding isn't 100% perfect, but it's maybe 90% correct now.
 
  • Like
Reactions: Core_2_Extreme

Core_2_Extreme

Well-Known Member
OP
Member
Joined
Feb 11, 2019
Messages
153
Trophies
0
Age
22
XP
1,163
Country
Japan
Playback with B-frames seems smoother now. It looks like there might still be some stuttering that is most visible during camera pans, but it's much less noticeable than before.

I remuxed the anime video without subtitles, and it plays now. :) It's much smoother than the last time I tried to play it with MVD_Services.
ok, I'll continue investigating.

Since MVD_Services sometimes outputs the same frame twice and other times skips frames, how did you get it to work? Maybe B-frame decoding isn't 100% perfect, but it's maybe 90% correct now.

Actually mvd service does NOT return the same frame more than once, it will not return the frame at all OR return the next frame (with many combinations as below)
There is a good news, I confirmed that MVD_Services DOES output every frames even a video contains B-frames, BUT in a strange way.

Usually I call these 2 functions for hardware decoding :
C:
mvdstdProcessVideoFrame();
mvdstdRenderVideoFrame();
Because of function name, I thought that I need to use mvdstdProcessVideoFrame() to process video then call mvdstdRenderVideoFrame() to get a video frame but it wasn't.

Actually, If videos do NOT contain b-frames, it always :
(let's say I'm playing a video that shows "0" then "1" then "2" then "3" then "4"... on the screen)
mvdstdProcessVideoFrame() will process video and write output to the buffer. (frame that shows "0")
mvdstdRenderVideoFrame() does nothing (at least won't write anything to the output buffer)
call it again, then mvdstdRenderVideoFrame() does nothing (at least won't write anything to the output buffer)
(so only 1 output)

and if videos DO contain b-frames,
(let's say I'm playing a video that shows "0" then "1" then "2" then "3" then "4"... on the screen)
case 1 (same as without b-frames videos)
mvdstdProcessVideoFrame() will process video and write output to the buffer. (frame that shows "0")
mvdstdRenderVideoFrame() does nothing (at least won't write anything to the output buffer)
call it again, then mvdstdRenderVideoFrame() does nothing (at least won't write anything to the output buffer)
(so only 1 output)

case 2
mvdstdProcessVideoFrame() will process video (only processing, no outputs).
mvdstdRenderVideoFrame() will write output to the buffer (frame that shows "0")
call it again, then mvdstdRenderVideoFrame() does nothing (at least won't write anything to the output buffer)
(so only 1 output)

case 3
mvdstdProcessVideoFrame() will process video (only processing, no outputs).
mvdstdRenderVideoFrame() does nothing (at least won't write anything to the output buffer)
call it again, then mvdstdRenderVideoFrame() does nothing (at least won't write anything to the output buffer)
(so no outputs at all)

case 4
mvdstdProcessVideoFrame() will process video (only processing, no outputs).
mvdstdRenderVideoFrame() will write output to the buffer (frame that shows "0")
call it again, then mvdstdRenderVideoFrame() will write output to the buffer (frame that shows "1")
(so more than 1 outputs)

case 5
mvdstdProcessVideoFrame() will process video and write output to the buffer. (frame that shows "0")
mvdstdRenderVideoFrame() will write output to the buffer (frame that shows "1")
call it again, then mvdstdRenderVideoFrame() will write output to the buffer (frame that shows "2")
(so more than 1 outputs)

About case 4 and case 5, it seems completely random that how many frames are written.
Maybe related to max B-frames in encoding settings?
But in the same video, sometimes it writes 3 frames but sometimes 2 frames.
(so maybe 2 frames, 3 frames or even 5 frames, no prediction is available)

Finally, the big problem is, no matter it wrote a frame to the buffer or not, mvdstdProcessVideoFrame() WILL return
MVD_STATUS_FRAMEREADY(0x17003) and no matter it wrote a frame to the buffer or not, mvdstdRenderVideoFrame() WILL return MVD_STATUS_OK(0x17000) or MVD_STATUS_BUSY(0x17002).

Edit :
So if I play a video that shows "0" then "1" then "2" then "3" then "4"... on the screen, which contains B-frames :
and let's say "case 2 -> case 3 -> case 4" happen, (let's say case 4 writes 2 frames)
then you'll see "0" -> "0" -> "2" on the screen.

So what I'm doing now is write something to top-left (start of the output buffer) and bottom-right (end of the output buffer) before calling mvdstdProcessVideoFrame().
(Zoom the picture a lot to see it)
mvd_workarounds.png


(simplified version)
After calling mvdstdProcessVideoFrame(), check if any of them got changed and if so return that frame without calling mvdstdRenderVideoFrame().
If not, call mvdstdRenderVideoFrame() and check if any of them got changed and if so return that frame.

I'm currently using 2 pixel, but I'll change it so that it uses 4 pixel to detect if mvd service output the frame or not.
So misdetection is possible but with low possibility.
 

AleronIves

Well-Known Member
Member
Joined
Nov 17, 2016
Messages
460
Trophies
0
Age
36
Location
California
XP
2,250
Country
United States
Actually mvd service does NOT return the same frame more than once, it will not return the frame at all OR return the next frame (with many combinations as below)
How can you display all the frames if MVDS will sometimes not return certain frames? You're asking MVDS to render the same frame multiple times until you see that the 2 pixels in the corners of the screen got changed, and then you know MVDS finally rendered the frame properly, so now you can display it?

So if I play a video that shows "0" then "1" then "2" then "3" then "4"... on the screen, which contains B-frames :
and let's say "case 2 -> case 3 -> case 4" happen, (let's say case 4 writes 2 frames)
then you'll see "0" -> "0" -> "2" on the screen.
Since you see "0" twice, "2" once, and "1" and "3", are missing, I interpreted this as MVDS will return the same frame more than once (in this case, the frame that says "0").
 
  • Like
Reactions: Core_2_Extreme

Core_2_Extreme

Well-Known Member
OP
Member
Joined
Feb 11, 2019
Messages
153
Trophies
0
Age
22
XP
1,163
Country
Japan
Since you see "0" twice, "2" once, and "1" and "3", are missing, I interpreted this as MVDS will return the same frame more than once (in this case, the frame that says "0").
This is "if I call mvdstdProcessVideoFrame() and mvdstdRenderVideoFrame() no matter if it returns a frame or not".

How can you display all the frames if MVDS will sometimes not return certain frames? You're asking MVDS to render the same frame multiple times until you see that the 2 pixels in the corners of the screen got changed, and then you know MVDS finally rendered the frame properly, so now you can display it?
But here I'm doing is that, as soon as I got a frame, don't call the next function and return it.
And if case 3 (no outputs) happen, consider it as kind of an error and ignore it.

You can see debug log (after playing a video for a few seconds, press SELECT button on main menu) for more info.

"-------------------------------" in log indicates start of function.

There are var_debug_bool[1], [2] and [3].
var_debug_bool[1] is set when : got a frame for any reasons
var_debug_bool[2] is set when : got a frame after mvdstdProcessVideoFrame
var_debug_bool[3] is set when : got a frame after mvdstdProcessVideoFrame (same as var_debug_bool[2])

var_debug_bool[1] is unset when : start of function
var_debug_bool[2] is unset when : got no frames
var_debug_bool[3] is unset when : start of function
 
Last edited by Core_2_Extreme,

AleronIves

Well-Known Member
Member
Joined
Nov 17, 2016
Messages
460
Trophies
0
Age
36
Location
California
XP
2,250
Country
United States
I don't really understand, but if you think you can get MVDS to display every B-frame, then that will be a big improvement for the next release. :)

Since you can't display ASS subtitles, can you ignore ASS streams so that the audio and video are playable without subtitles, instead of rejecting the video?
 
  • Like
Reactions: Core_2_Extreme

lizzie

Member
Newcomer
Joined
Aug 29, 2022
Messages
8
Trophies
0
Age
21
Location
Somewhere in France
XP
65
Country
France
Hi everyone, did anyone ever get the 3d function working? I used @T0biasCZe 's ffmpeg script and it does output a viewable movie.avi, however the 3d is all over the place, when I turn it on I just see 2 pictures but they do not merge to make a 3d pic. any help greatly appreciated!
 
  • Like
Reactions: Core_2_Extreme

Core_2_Extreme

Well-Known Member
OP
Member
Joined
Feb 11, 2019
Messages
153
Trophies
0
Age
22
XP
1,163
Country
Japan
I don't really understand, but if you think you can get MVDS to display every B-frame, then that will be a big improvement for the next release. :)
I think mvd service outputs all frames for video that has B-frames, is your video played smoother if you use software decoder?

Since you can't display ASS subtitles, can you ignore ASS streams so that the audio and video are playable without subtitles, instead of rejecting the video?
I'll change it so.
 

T0biasCZe

Well-Known Member
Member
Joined
Oct 4, 2019
Messages
219
Trophies
0
Age
18
XP
939
Country
Czech Republic
i have issues with sound, its not playing (with neither mp3 or aac codec)
and i have dumped asp1
hough, i may know why its not working. on home screen, when i open luma menu, go to system configuration, and software volume control, and ajdust the slider, the vol value changed. but when i do the same in the video player, the vol is always on zero. and there is also "your volume slider is right at the edge, so it cant be adjusted by software. if its physically stuck you man need to solder to fix the volume" even when the slider is at middle.
and on home menu, when its at edge, it says "your volume slider is at edge, so output range is limited. if you can, move the slider to the edge to get better software range"
(but idk if this is somewhat related)

NVM it started working sudenly
 
Last edited by T0biasCZe,
  • Like
Reactions: Core_2_Extreme

withthelemons

Member
Newcomer
Joined
Sep 11, 2022
Messages
5
Trophies
0
Age
28
Location
Prague
XP
36
Country
Czech Republic
I want to expand on Tobias' 3D encoding guide. While it provides a good starting point, encoding the video in three steps (downsample, split, merge) is quite wasteful, both in the time it takes and the quality loss.

Instead, it is possible to do it all in one go:
Code:
ffmpeg -i INPUT -filter_complex "split[l][r];[l]stereo3d=sbsl:ml[left];[r]stereo3d=sbsl:mr[right];[left]scale=400:240:flags=neighbor[left];[right]scale=400:240:flags=neighbor[right]" -map [left] -map [right] -map 0:a:0 -vcodec mjpeg -b:v 3M -ac 2 movie.avi

This results in better speed, 37.1s vs 116.3s to encode 10m34s movie (tested on Big Buck Bunny).
Quality is also a little bit better since it doesn't have to go through unnecessary h264 encode in the middle.

But we can do even better.
  • MJPEG compression is really bad, both in terms of quality and size
  • using 240px height is sub-optimal since it results in stretched image (assuming input is 16:9)
  • while nearest neighbor scaling is fast, it results in poor image quality

Using h264, 224px height, and lanczos scaling will give us much higher quality and lower filesize.
Code:
ffmpeg -i INPUT -filter_complex "split[l][r];[l]stereo3d=sbsl:ml[left];[r]stereo3d=sbsl:mr[right];[left]scale=400:224:flags=lanczos[left];[right]scale=400:224:flags=lanczos[right]" -map [left] -map [right] -map 0:a:0 -c:a copy -c:v libx264 -crf 18 -bf 0 movie.mp4


The quality can be adjusted by changing CRF, the value of 18 produces good quality with relatively low filesize, but if you prefer higher quality, you can change it to lower number (eg. 16, 14). If you want/need smaller filesize, you can reduce the quality by setting a higher number (eg. 20, 21, 22). This doesn't impact encoding speed.
Encoding speed is impacted by the preset (eg. fast, slow, veryslow, default is medium). Slower encoding results in higher quality/lower filesize.
B frames cause issues with the player (artifacts) which is why they are disabled. If you don't mind the problems or you don't run into them, you can re-enable B frames by deleting "-bf 0"

The command asumes that the video is in side-by-side (sbs) format. If your video is above-below (abl), replace the two instances of "sbsl" in the command with "abl".
It also assumes that the first audio track is the correct one and it's in stereo. If it's not the case, change "-map 0:a:0 -c:a copy" to "-map 0:a:[audio track number] -c:a libvorbis -qscale:a 10 -ac 2"

I think that lanczos scaling provides best quality, but this can be subjective. You can experiment with other scaling algorithms, eg. bilinear, bicubic, neighbor, spline, sinc. Just replace "lanczos" in the command with your preferred option. There's also the option of using accurate rounding flag by adding "+accurate_rnd" (eg. lanczos+accurate_rnd), but this reduces encoding speed quite a bit and doesn't add much extra quality.

I wanted to post an example of an encoded file, but gbatemp doesn't let me to post links, so you will have to try it for yourself.
 

withthelemons

Member
Newcomer
Joined
Sep 11, 2022
Messages
5
Trophies
0
Age
28
Location
Prague
XP
36
Country
Czech Republic
i used very high bitrate for the middle files, so there were no visible loses in the output

Yes, the difference is not big, it mostly gets masked by the MJPEG compression, but it's still visible and it's not advisable to re-encode video multiple times, since each encode takes time and decreases quality (even if not by a huge margin).
 
  • Like
Reactions: Core_2_Extreme

withthelemons

Member
Newcomer
Joined
Sep 11, 2022
Messages
5
Trophies
0
Age
28
Location
Prague
XP
36
Country
Czech Republic
After more testing of H264 3D video playback, I've found that the image for left eye is one frame ahead of the right eye (only in player, the video file itself is in sync). It can be fixed by delaying left image by one frame by adding ";
tpad=start=1
" to the end of the filter.

I haven't noticed it before, because on movies with no fast movement one frame difference is not always very visible.​
 
  • Like
Reactions: Core_2_Extreme

Core_2_Extreme

Well-Known Member
OP
Member
Joined
Feb 11, 2019
Messages
153
Trophies
0
Age
22
XP
1,163
Country
Japan
v1.5.2 release

Changes​

Ignore unsupported codec so that you can play supported codec only
(e.g. You can now play videos that contain unsupported subtitles/audio)

Fixed bugs​

Hardware decoder won't play videos that contain B-frames smoothly has been fixed
(It means you don't have to care about B-frames when encoding to H.264 videos)

On NEW 3(2)DS, it is recommended to use patched Luma3DS for better performance.​


Download : https://github.com/Core-2-Extreme/Video_player_for_3DS/releases/tag/v1.5.2
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    I @ I-need-help-with-wup-wiiu: i have an issue with loading games on usb with usbloadergx on vwii. Is there anyone that can...