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

QML: second video in playlist is stretched to the size of first played #41

Closed
alanvice opened this issue Oct 15, 2015 · 10 comments
Closed
Assignees
Labels

Comments

@alanvice
Copy link

First video 1920x1080, second video 1920x768
The second video is played in the viewport size of the first one when fillMode: Image.PreserveAspectFit is selected.

@penguinest
Copy link

Try it with fillMode:VideoOutput.PreserveAspectFit. It seems you use the Image version.

@alanvice
Copy link
Author

just tried it , same behavior.

I forgot to say I'm using the v5.0.0 tag.
As you can see it's the same value:
console.log("VideoOutput.PreserveAspectFit",VideoOutput.PreserveAspectFit);
console.log("Image.PreserveAspectFit",Image.PreserveAspectFit);
Output:
qml: VideoOutput.PreserveAspectFit 1
qml: Image.PreserveAspectFit 1

This is a really bad workaround I tried but seems it hangs after a few hours of running.
Main.qml:
import QtQuick 2.0
import QtMultimedia 5.0

Rectangle {
    id: root
    width: 1920
    height: 1080
    color: "black"
    property var object

    property int index:0
    property string folder: "/folder/to/videos/"
    property var playlist: [
        "Video1.mp4",
        "Video2.mp4",
        "Video3.mp4"
    ];

    function startVideo(sourceFile)
    {
        var component = Qt.createComponent("Video.qml");
        if(component.status == Component.Ready)
        {
            object = component.createObject(root);
            object.fillMode=VideoOutput.PreserveAspectFit
            object.anchors.fill=root
            object.autoPlay=true
            object.source=folder+sourceFile
            object.onRealStopped.connect(nextVideo)
        }
    }

    function nextVideo()
    {
        object.destroy();
        index++
        if(index>=playlist.length)
             index=0
    startVideo(playlist[index])
    }

    Component.onCompleted: {
    startVideo(playlist[index])
    }
}

Video.qml:
import QtQuick 2.0
import QtMultimedia 5.0

Video {
// signal realStopped is necessary to skip the initial State changing from 
// STATE_INACTIVE to STATE_STOPPED...
    signal realStopped
    property bool hasPlayed: false
    onStatusChanged: {
        if(status == MediaPlayer.EndOfMedia) 
            hasPlayed = true;
    }
    onStopped: { if(hasPlayed) realStopped(); }
}

@penguinest
Copy link

You can use metadata information.

Video{
       id:video
       source: base.source;
        onStatusChanged: {
            if(status === MediaPlayer.Loaded){
                // If not recognized, use fullscreen
                if(metaData.resolution === undefined) loaded(video.parent.width,video.parent.height);
                // else, use native
                else loaded(metaData.resolution.width,metaData.resolution.height);
            }
        }
    function loaded(w,h){
        video.width = w;
        video.height = h;
    }
}

@alanvice
Copy link
Author

I set the Video component dimensions with:
object.anchors.fill=root
so it takes the root dimensions, and shows correctly on screen

11:21:54.377 DEBUG: MetaData request for key: Resolution.
11:21:54.378 DEBUG: MetaData request for key: Resolution.
qml: metaData.resolution undefined

@penguinest
Copy link

If you use anchor.fill you are going to get always fullscreen size. Use metadata or fixed value.
Metadata.resolution will always be found as long as you wait the content to be loaded and be referenced to a Video/Image object.
Anyway, I do not thing these is a problem related PiOmxTexture.
Did you make your code work on windows?

PD: The above code was used on one of my project and works like a charm (tested on windows only).

@alanvice
Copy link
Author

My project works well on windows and linux, even on arm utilite, now i'm trying to make it work on Raspberry.
Your project is fantastic but if you try to play different resolution videos with the flag fillMode:VideoOutput.PreserveAspectFit to keep the right aspect, the viewport will remain the size of the first ever video played. Obviously you don't have to close the program.

Try this over a raspberry in egl platform (not xcb):
Start your POC player, select a 4/3 aspect ratio video. On a 16/9 screen the video will be resized the right way leaving 2 bands on the sides. Now stop it without closing the player and open a 16/9 video. The second video (that should be played fullscreen) will be played in the viewport of the first one.
If you invert the order you will see the 16/9 video well displayed, then the 4/3 video stretched to fullscreen.

I'm saying it is a problem in libs, maybe in OMXVideo.cpp, where it should change the viewport dimensions/ratio.

@penguinest
Copy link

Ok, my bad.
The code I posted do not work(at least that's what I guess after a quick review) because "resolution" in not into OMX_MetaDataProvider::onUpdateRequested function.
Could you try something? Try to anchor your "object" item as centerIn: parent. Then, manually insert 1920x1080 at the first video and 1920x768 at the second.
Let's see if at least this work manually.

@carlonluca carlonluca added the bug label Oct 20, 2015
@alanvice
Copy link
Author

OK, I will try to manually insert dimensions...
Now i have taken some screenshots from my raspberry using pocplayer:
First execution, first video 1920x768, second video 1920x1080
video1-first
video2-second
As you can see the second video (FullHD) should be fullscreen instead it is in the size of the first one.

Now trying the reverse order, first video 1920x1080, second video 1920x768:
video2-first
video1-second
Now the problem is that the smaller video played as second is stretched to the size of the first one.

Meanwhile i found another bug, the first video is player ok, the second,third etc... video will start playing at 5 seconds +- skipping the very first part of the video (I will investigate today if I can).

@alanvice
Copy link
Author

I've done the test resizing the Video component manually to the video native size.
All video tested are mp4/h264-aac.
Don't look at the DIVX logo because I re-encoded all the videos.

Code used:
import QtQuick 2.0
import QtMultimedia 5.0

Rectangle {
    id: root
    width: 1920
    height: 1080
    color: "black"
    property var object

    property int index:0
    property string prefix: "/folder/to/videos/"
    property var playlist: [
//    prefix + "Video1920x1080.mp4",
    prefix + "Video1920x768.mp4",
    prefix + "Video1920x1080.mp4"
    ];
    property var dimensions: [
//            [1920,1080],
            [1920,768],
            [1920,1080]
    ];

    function nextVideo()
    {
        index++;
        if(index>=playlist.length)
             index=0;

        video.source=playlist[index];
        console.log("Setting size:",dimensions[index]);
        video.width=dimensions[index][0]
        video.height=dimensions[index][1]
        video.play();
    }

    Video {
        id: video
        //anchors.fill: parent
        anchors.centerIn: parent
        autoPlay: false //true
        fillMode: VideoOutput.PreserveAspectFit
        onStopped: nextVideo();
    }

    Component.onCompleted: {
        video.source=playlist[index];
        console.log("Setting size:",dimensions[index]);
        video.width=dimensions[index][0]
        video.height=dimensions[index][1]
        video.play();
    }
}

First execution, first video 1920x768, second video 1920x1080:
bike1
forte2
The second video is small even if the qml Video component is sized to 1920x1080.

Reverse order, first video 1920x1080, second video 1920x768:
forte1
bike2
In this case reducing the height of the second video makes the qml squeeze the video (look the wheels) because it thinks it is still a fullhd video.

Also confirming the second bug: the second video starts from a random time between the 5th and the 11th second even if doing a seek(0) before play().
Only doing a play(), stop(), play() ti will start from the beginning of the video.
Hope my tests will help you.

@carlonluca carlonluca self-assigned this Oct 23, 2015
@carlonluca
Copy link
Owner

You should find the fix for this in the next release. For the start position issue please file another report with a description on how to reproduce (I tried to reproduce but I failed). Reopen if you find a wrong behavior also in the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants