Skip to content

MediaSession artwork only uses the first item in the artwork array#30598

Merged
webkit-commit-queue merged 1 commit intoWebKit:mainfrom
jyavenard:eng/MediaSession-artwork-only-uses-the-first-item-in-the-artwork-array
Jul 10, 2024
Merged

MediaSession artwork only uses the first item in the artwork array#30598
webkit-commit-queue merged 1 commit intoWebKit:mainfrom
jyavenard:eng/MediaSession-artwork-only-uses-the-first-item-in-the-artwork-array

Conversation

@jyavenard
Copy link
Copy Markdown
Member

@jyavenard jyavenard commented Jul 9, 2024

cbbcae6

MediaSession artwork only uses the first item in the artwork array
https://bugs.webkit.org/show_bug.cgi?id=276351
rdar://81160539

Reviewed by Youenn Fablet.

If `sizes` metadata artwork attribute is provided we will use them to determine the "best"
image to select. We do so by giving each resolution a score between 0 and 1. We aim to download
an image that is 512x512 with an aspect ratio of 1.
If the `sizes` attribute contains invalid content or if not provided, we will iterate through
all the available images and download them. We will then either select the one with the highest
score, or the first one found with a resolution greater than 512 pixels.

Test will be added once https://bugs.webkit.org/show_bug.cgi?id=276133 lands as it adds some
internal APIs to check which URL was selected with Now Playing.
For now, manually tested.

* Source/WebCore/Modules/mediasession/MediaMetadata.cpp:
(WebCore::MediaMetadata::imageDimensionsScore const):
(WebCore::MediaMetadata::refreshArtworkImage):
(WebCore::MediaMetadata::tryNextArtworkImage):
* Source/WebCore/Modules/mediasession/MediaMetadata.h:

Canonical link: https://commits.webkit.org/280804@main

515c507

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 wincairo
✅ 🧪 bindings ✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2 ✅ 🧪 wincairo-tests
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe
✅ 🧪 ios-wk2-wpt ✅ 🧪 mac-wk1 ✅ 🛠 wpe-cairo
🧪 api-ios ✅ 🧪 mac-wk2 ✅ 🛠 gtk
✅ 🛠 vision ✅ 🧪 mac-AS-debug-wk2 ✅ 🧪 gtk-wk2
✅ 🛠 vision-sim ✅ 🧪 mac-wk2-stress ✅ 🧪 api-gtk
✅ 🛠 🧪 merge ✅ 🧪 vision-wk2
🛠 tv
✅ 🛠 tv-sim
🛠 watch
✅ 🛠 watch-sim

@jyavenard jyavenard self-assigned this Jul 9, 2024
@jyavenard jyavenard added the Media Bugs related to the HTML 5 Media elements. label Jul 9, 2024
@jyavenard jyavenard requested a review from a team July 9, 2024 08:24
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
for (auto element : stringView.split(' ')) {
for (auto element : StringView(sizes).split(' ')) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also do we handle the case of multiple spaces like 192x192 320x320?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Also do we handle the case of multiple spaces like 192x192 320x320?

Hmm I didn't think of that. If spaces are correct then we take the biggest of the series

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
Vector<std::optional<uint32_t>> numbers;
Vector<std::optional<uint32_t>, 2> numbers;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

removed that code altogether

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can probably use findIgnoringASCIICase("x"_s) to remove this string allocation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I prefer the old version of checking whether image is null upfront.
The current version is ok I think for that case, but somehow convoluted.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I prefer the old version of checking whether image is null upfront. The current version is ok I think for that case, but somehow convoluted.

we don't want to exit early when it's null anymore, we want to try the other artwork

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sure, wouldn't the following just work:

if (!image) {
    tryNextArtworkImage(index + 1);
    return;
}
m_artworkImageSrc = artworkImageSrc;
setArtworkImage(image);
metadataUpdated();
// Maybe we should also free m_artworkLoader, need to check how this loader is implemented.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

s/iterate/shouldIterate/

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

removed that code

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
if (!iterate || index + 1 < m_metadata.artwork.size())
if (!iterate || ++index < m_metadata.artwork.size())

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this would require to make the entire lambda mutable

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
IntSize newSize = { int(*numbers[0]), int(*numbers[1]) };
IntSize newSize { int(*numbers[0]), int(*numbers[1]) };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would it be simpler to have a Vector of image srcs, sorted by the image score.
Then, start with the first image src (the one with the best score) and only iterate if there is no image?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

If we can sort the src, then we only retrieve one image. There's no need to keep sorted vector anymore.

Otherwise we can't sort until we have downloaded all the images.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

yeah, it ended up being nicer that way. and it simplifies the logic as we don't need to distinguish the case where we do need to iterate for those we don't

@jyavenard jyavenard force-pushed the eng/MediaSession-artwork-only-uses-the-first-item-in-the-artwork-array branch from 51d7516 to b068ce2 Compare July 9, 2024 11:34
@jyavenard jyavenard requested a review from youennf July 9, 2024 11:37
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Theoretically, it would be possible for m_idealSize and m_minimumSize to be the same.
Given they are static, we should probably rename them as s_...
Or maybe make this method a free function and have const variables for ideal/minimum sizes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I added a static_assert

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
m_sortedSrc.clear();
m_sortedSrces.clear();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sure, wouldn't the following just work:

if (!image) {
    tryNextArtworkImage(index + 1);
    return;
}
m_artworkImageSrc = artworkImageSrc;
setArtworkImage(image);
metadataUpdated();
// Maybe we should also free m_artworkLoader, need to check how this loader is implemented.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
float imageScore = size.isEmpty() ? -1.0 : imageDimensionsScore(size.width(), size.height());
float imageScore = imageDimensionsScore(size.width(), size.height());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
tryNextArtworkImage(index + 1);
tryNextArtworkImage(index);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would tend to do the following:

Suggested change
void MediaMetadata::tryNextArtworkImage(uint32_t index)
void MediaMetadata::tryNextArtworkImage(Vector<Pair>&&, uint32_t index = 0)

And have the lambda capture the Vector.
Also m_sortedSrcand m_artworkLoader are useless once we finished loading. If it was captured in the lambda, it would be freed automatically by freeing m_artworkLoader

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
static constexpr int m_minimumSize = 128;
static constexpr int s_minimumSize = 128;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
static constexpr int m_idealSize = 512;
static constexpr int s_idealSize = 512;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would it be possible to directly create m_sortedSrc without creating this sizes vector?

@youennf
Copy link
Copy Markdown
Contributor

youennf commented Jul 9, 2024

Test will be added once https://bugs.webkit.org/show_bug.cgi?id=276133 lands as it adds some
internal APIs to check which URL was selected with Now Playing.

Let's not forget to add some edge cases like 192x X56, multiple spaces...

Copy link
Copy Markdown
Contributor

@youennf youennf left a comment

Choose a reason for hiding this comment

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

LGTM.
Some further improvements added in comments.

@jyavenard jyavenard force-pushed the eng/MediaSession-artwork-only-uses-the-first-item-in-the-artwork-array branch from b068ce2 to 515c507 Compare July 10, 2024 00:52
@jyavenard jyavenard added the merge-queue Applied to send a pull request to merge-queue label Jul 10, 2024
@webkit-commit-queue webkit-commit-queue force-pushed the eng/MediaSession-artwork-only-uses-the-first-item-in-the-artwork-array branch from 515c507 to bbeb5ef Compare July 10, 2024 03:25
https://bugs.webkit.org/show_bug.cgi?id=276351
rdar://81160539

Reviewed by Youenn Fablet.

If `sizes` metadata artwork attribute is provided we will use them to determine the "best"
image to select. We do so by giving each resolution a score between 0 and 1. We aim to download
an image that is 512x512 with an aspect ratio of 1.
If the `sizes` attribute contains invalid content or if not provided, we will iterate through
all the available images and download them. We will then either select the one with the highest
score, or the first one found with a resolution greater than 512 pixels.

Test will be added once https://bugs.webkit.org/show_bug.cgi?id=276133 lands as it adds some
internal APIs to check which URL was selected with Now Playing.
For now, manually tested.

* Source/WebCore/Modules/mediasession/MediaMetadata.cpp:
(WebCore::MediaMetadata::imageDimensionsScore const):
(WebCore::MediaMetadata::refreshArtworkImage):
(WebCore::MediaMetadata::tryNextArtworkImage):
* Source/WebCore/Modules/mediasession/MediaMetadata.h:

Canonical link: https://commits.webkit.org/280804@main
@webkit-commit-queue webkit-commit-queue force-pushed the eng/MediaSession-artwork-only-uses-the-first-item-in-the-artwork-array branch from bbeb5ef to cbbcae6 Compare July 10, 2024 03:27
@webkit-commit-queue
Copy link
Copy Markdown
Collaborator

Committed 280804@main (cbbcae6): https://commits.webkit.org/280804@main

Reviewed commits have been landed. Closing PR #30598 and removing active labels.

@webkit-commit-queue webkit-commit-queue merged commit cbbcae6 into WebKit:main Jul 10, 2024
@webkit-commit-queue webkit-commit-queue removed the merge-queue Applied to send a pull request to merge-queue label Jul 10, 2024
@jyavenard jyavenard deleted the eng/MediaSession-artwork-only-uses-the-first-item-in-the-artwork-array branch November 27, 2024 23:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Media Bugs related to the HTML 5 Media elements.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants