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

WebM Movie Player (VP9/Opus) #458

Merged
merged 16 commits into from Dec 26, 2014
Merged

WebM Movie Player (VP9/Opus) #458

merged 16 commits into from Dec 26, 2014

Conversation

@Mystler
Copy link
Contributor

Mystler commented Oct 29, 2014

Now, this is what I call a collaboration.
This, finally, implements our movie player. It can play webm containers that include vp9 video and opus audio. As a bonus, it supports multiple tracks and tries to select the track that matches the game language, if possible.

// TODO: Figure out video and audio based on current language
// For now... just take the first one.
const mkvparser::Tracks* tracks = fSegment->GetTracks();
for (uint32_t i = 0; i < tracks->GetTracksCount(); ++i)

This comment has been minimized.

Copy link
@branan

branan Oct 29, 2014

Member

Just so I can make sure I understand this: This will use the first audio and video tracks, UNLESS a later one happens to match the current language?

This comment has been minimized.

Copy link
@Mystler

Mystler Oct 29, 2014

Author Contributor

Correct.

SAFE_OP(seg->Load(), "load segment from webm");
fSegment.reset(seg);

// TODO: Figure out video and audio based on current language

This comment has been minimized.

Copy link
@branan

branan Oct 29, 2014

Member

This comment is out of date

This comment has been minimized.

Copy link
@Mystler

Mystler Oct 29, 2014

Author Contributor

Thanks for catching that. Updated.

@Mystler Mystler force-pushed the Mystler:webm branch from 8604479 to de60e16 Oct 29, 2014
VPX() { }

public:
#ifdef VIDEO_AVAILABLE

This comment has been minimized.

Copy link
@dpogue

dpogue Oct 30, 2014

Member

Should this ifdef be one line higher? Currently you'd end up with the following if VIDEO_AVAILABLE were not defined:

class VPX
{
    VPX() { }

public:
}
@Mystler Mystler force-pushed the Mystler:webm branch from de60e16 to c1b8377 Oct 30, 2014
@Mystler
Copy link
Contributor Author

Mystler commented Oct 30, 2014

Moved that ifdef. Also, the last libwebm release is over a year old, so I took the latest files from master and updated the TrackMgr to respect the CodecDelay (libwebm supports that now, see mkv specs). This means that our track synchronization should be a few ms more exact, now. The specific change is a one-liner squashed into 2d990ae.

Mystler added 7 commits Oct 26, 2014
Includes some reorganization and cleanup
*sigh* This happens when you copy the formula from somewhere else... Let's do it correctly now and fix the source in plVoiceChat as well.
Also:
Do not start the video again if it is already playing.
Update files from libwebm
Also, do not show the plate before there is anything on it.
Scale plate using pixels and limit it to viewport size
@Mystler Mystler force-pushed the Mystler:webm branch from c1b8377 to 639819a Oct 30, 2014
@Mystler
Copy link
Contributor Author

Mystler commented Oct 31, 2014

As I mentioned in the IRC, it looks like URU sometimes doesn't like it if we decode our audio frames on-demand. I added a new commit that changes it to preload them when we start the video. I haven't experienced any noticeable delay with this change and it fixes old record player like crackling problems in release mode.

if (!(mov->GetCmd() & plMovieMsg::kMake))
{
for (i = 0; i < fMovies.GetCount(); i++)
for (i = 0; i < fMovies.size(); i++)

This comment has been minimized.

Copy link
@Hoikas

Hoikas Nov 1, 2014

Member

It would be super awesome if this were a range-based for instead

This comment has been minimized.

Copy link
@Mystler

Mystler Nov 1, 2014

Author Contributor

Uhm... i is used outside the loop, so I didn't touch it.

This comment has been minimized.

Copy link
@Hoikas

Hoikas Nov 1, 2014

Member

Hmm... crazy code. This can be addressed later.

@@ -42,25 +42,417 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com

#include "plMoviePlayer.h"

#ifdef VIDEO_AVAILABLE

This comment has been minimized.

Copy link
@Hoikas

Hoikas Nov 1, 2014

Member

This is kind of ambiguous--are we referring to vpx+opus or just vpx?

This comment has been minimized.

Copy link
@Mystler

Mystler Nov 1, 2014

Author Contributor

In your original version it was VPX_AVAILABLE which I found misleading. VIDEO should represent both libs, but I can change it to MOVIE_AVAILABLE, if you prefer that.

public:
vpx_codec_ctx_t codec;

~VPX() {

This comment has been minimized.

Copy link
@Hoikas

Hoikas Nov 1, 2014

Member

code style nitpick

This comment has been minimized.

Copy link
@Mystler

Mystler Nov 1, 2014

Author Contributor

Guess who wrote that. :p

for (int32_t i = 0; i < block->GetFrameCount(); i++)
{
const mkvparser::Block::Frame data = block->GetFrame(i);
uint8_t* buf = new uint8_t[data.len];

This comment has been minimized.

Copy link
@Hoikas

Hoikas Nov 1, 2014

Member

potential optimization: move the allocation step out of the loop and only (re-)allocate if the existing buffer is not big enough

This comment has been minimized.

Copy link
@Mystler

Mystler Nov 1, 2014

Author Contributor

I could use a std::vector to do that, I assume.

This comment has been minimized.

Copy link
@Mystler

Mystler Nov 1, 2014

Author Contributor

Actually, I'm not sure how to approach this, since that buffer is going into the frames container as a unique pointer.

This comment has been minimized.

Copy link
@Hoikas

Hoikas Nov 1, 2014

Member

Oh, I thought this was a buffer that did not have a long life span. Whoops!

std::vector<int16_t> decoded;
decoded.reserve(frames.size() * audio->GetChannels() * maxFrameSize);

for (auto it = frames.begin(); it != frames.end(); ++it)

This comment has been minimized.

Copy link
@Hoikas

Hoikas Nov 1, 2014

Member

range based for would be super awesome

const std::unique_ptr<uint8_t>& buf = std::get<0>(*it);
int32_t size = std::get<1>(*it);

int16_t* pcm = new int16_t[maxFrameSize * audio->GetChannels()];

This comment has been minimized.

Copy link
@Hoikas

Hoikas Nov 1, 2014

Member

we could optimize this by moving the allocation outside of the loop. (heap alloc is slow)

vpx_image_t* img = nullptr;

// We have to decode all the frames, but we only want to display the most recent one to the user.
for (auto it = frames.begin(); it != frames.end(); ++it)

This comment has been minimized.

Copy link
@Hoikas

Hoikas Nov 1, 2014

Member

range based for?

const mkvparser::VideoTrack* video = static_cast<const mkvparser::VideoTrack*>(fVideoTrack->GetTrack());
if (strcmp(video->GetCodecId(), WEBM_CODECID_VP9) != 0)
{
hsAssert(false, "Not a VP9 video track!");

This comment has been minimized.

Copy link
@Hoikas

Hoikas Nov 1, 2014

Member

this should probably be a log message--people who embed videos in ages they are creating probably won't be using a debug client. therefore, they will not see this assert

This comment has been minimized.

Copy link
@Mystler

Mystler Nov 1, 2014

Author Contributor

I assume the same goes for the audio track? Where would you recommend to log that message to?

EDIT: In my WIP, I replaced the hsAssert with a log entry to a movie.log file.

This comment has been minimized.

Copy link
@Hoikas

Hoikas Nov 1, 2014

Member

That sounds good

if (fPlate)
fPlate->SetVisible(false);

for (int i = 0; i < fCallbacks.size(); i++)

This comment has been minimized.

Copy link
@Hoikas

Hoikas Nov 1, 2014

Member

range based for?

@Hoikas
Copy link
Member

Hoikas commented Nov 1, 2014

I know I wrote the original code here, and it's probably awful that I'm going to say this, but I've since changed my mind about how our code formatting should look. It would be really awesome if we could get this to use the same style as DirtSand. My newer additions, such as pfPatcher sort of do this. The most relevant change here is that class and method definitions have a newline before the opening braces, but loops and conditional statements do not.

Also, I believe congratulations are in order for getting this to work!

@Mystler
Copy link
Contributor Author

Mystler commented Nov 1, 2014

Heh, I definitely agree. The Plasma code style is really annoying. In fact, when writing on this I sometimes had to fight with my VS editor, because it didn't like how I wrote. Neither did I.

If you say that it's time for a revolution, I'm going to jump right into the front lines.

@Deledrius
Copy link
Member

Deledrius commented Nov 1, 2014

It can be hard to decide how to write any given thing, since there's no consistent style through the entire codebase (which given its size and the length of time it was worked on, isn't surprising), or sometimes even in within the same project.

So, is it finally time to merge this: 8590ba4?

@Mystler
Copy link
Contributor Author

Mystler commented Nov 1, 2014

Updated. One commit addresses what you pointed out, the other one changes the code style.

@Hoikas

This comment has been minimized.

wait... why not simply auto?

This comment has been minimized.

Copy link
Owner Author

Mystler replied Nov 2, 2014

Becaust const and because reference. ;)

@Hoikas

This comment has been minimized.

same as 290

@Lunanne
Copy link
Member

Lunanne commented Nov 26, 2014

Tested it and seems to work fine.
The only issue I found is that when you pres the escape key more than once to exit the intro video (because you're impatient and there is a slight delay) you can get the help gui to show up more than once. You can just click them away so I don't think this is a huge issue. The screen did flicker for me sometimes during the intro video, but that might be on my end.

@Deledrius
Copy link
Member

Deledrius commented Dec 23, 2014

👍

Hoikas added a commit that referenced this pull request Dec 26, 2014
WebM Movie Player (VP9/Opus)
@Hoikas Hoikas merged commit 990f42c into H-uru:master Dec 26, 2014
@Mystler Mystler deleted the Mystler:webm branch Dec 26, 2014
FelixWolf pushed a commit to openuruunofficial/CWE-ou that referenced this pull request Mar 20, 2019
and reenable as much USE_BINK_SDK stuff as empirically needed to get the Yeesha intro movie cave to disappear on its own, as before merging Cyan's Build 918.

Not the cleanest way, but I'm trying to minimize effort spent on this until we can get the proper solution, VP9 video support, from H-uru/Plasma#458 .

--HG--
branch : bink-stub-2
FelixWolf pushed a commit to openuruunofficial/CWE-ou that referenced this pull request Mar 20, 2019
Fix stuck-in-intro-cave bug

This reintroduces the plBinkPlayer stub removed in 8a1346b in order to fix the bug where a new player is stuck in the intro cave with the rotating wall until it occurs to them to press the esc key.

I have not spent much effort on checking that this is the correct and minimal change but it appears to work for me.

This is a quick fix, the definitive solution will be to port VP9/Opus support from H-uru/Plasma#458.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

6 participants
You can’t perform that action at this time.