vlc-video: Fix video rotation and aspect ratio
Fixes #5250 and #3843. Gets dimensions, aspect ratio and orientation/rotation from source video track.
This commit is contained in:
parent
8bd4ef61a0
commit
59bdac1569
@ -24,8 +24,10 @@ LIBVLC_MEDIA_NEW_PATH libvlc_media_new_path_;
|
||||
LIBVLC_MEDIA_NEW_LOCATION libvlc_media_new_location_;
|
||||
LIBVLC_MEDIA_ADD_OPTION libvlc_media_add_option_;
|
||||
LIBVLC_MEDIA_RELEASE libvlc_media_release_;
|
||||
LIBVLC_MEDIA_RELEASE libvlc_media_retain_;
|
||||
LIBVLC_MEDIA_RETAIN libvlc_media_retain_;
|
||||
LIBVLC_MEDIA_GET_META libvlc_media_get_meta_;
|
||||
LIBVLC_MEDIA_TRACKS_GET libvlc_media_tracks_get_;
|
||||
LIBVLC_MEDIA_TRACKS_RELEASE libvlc_media_tracks_release_;
|
||||
|
||||
/* libvlc media player */
|
||||
LIBVLC_MEDIA_PLAYER_NEW libvlc_media_player_new_;
|
||||
@ -104,6 +106,8 @@ static bool load_vlc_funcs(void)
|
||||
LOAD_VLC_FUNC(libvlc_media_release);
|
||||
LOAD_VLC_FUNC(libvlc_media_retain);
|
||||
LOAD_VLC_FUNC(libvlc_media_get_meta);
|
||||
LOAD_VLC_FUNC(libvlc_media_tracks_get);
|
||||
LOAD_VLC_FUNC(libvlc_media_tracks_release);
|
||||
|
||||
/* libvlc media player */
|
||||
LOAD_VLC_FUNC(libvlc_media_player_new);
|
||||
|
@ -38,6 +38,10 @@ typedef void (*LIBVLC_MEDIA_RETAIN)(libvlc_media_t *p_md);
|
||||
typedef void (*LIBVLC_MEDIA_RELEASE)(libvlc_media_t *p_md);
|
||||
typedef char *(*LIBVLC_MEDIA_GET_META)(libvlc_media_t *p_md,
|
||||
libvlc_meta_t e_meta);
|
||||
typedef unsigned (*LIBVLC_MEDIA_TRACKS_GET)(libvlc_media_t *p_md,
|
||||
libvlc_media_track_t ***pp_es);
|
||||
typedef void (*LIBVLC_MEDIA_TRACKS_RELEASE)(libvlc_media_track_t **p_tracks,
|
||||
unsigned i_count);
|
||||
|
||||
/* libvlc media player */
|
||||
typedef libvlc_media_player_t *(*LIBVLC_MEDIA_PLAYER_NEW)(
|
||||
@ -125,6 +129,8 @@ extern LIBVLC_MEDIA_ADD_OPTION libvlc_media_add_option_;
|
||||
extern LIBVLC_MEDIA_RELEASE libvlc_media_release_;
|
||||
extern LIBVLC_MEDIA_RETAIN libvlc_media_retain_;
|
||||
extern LIBVLC_MEDIA_GET_META libvlc_media_get_meta_;
|
||||
extern LIBVLC_MEDIA_TRACKS_GET libvlc_media_tracks_get_;
|
||||
extern LIBVLC_MEDIA_TRACKS_RELEASE libvlc_media_tracks_release_;
|
||||
|
||||
/* libvlc media player */
|
||||
extern LIBVLC_MEDIA_PLAYER_NEW libvlc_media_player_new_;
|
||||
|
@ -382,6 +382,62 @@ static void vlcs_video_display(void *data, void *picture)
|
||||
UNUSED_PARAMETER(picture);
|
||||
}
|
||||
|
||||
static void calculate_display_size(struct vlc_source *c, unsigned *width,
|
||||
unsigned *height)
|
||||
{
|
||||
libvlc_media_t *media = libvlc_media_player_get_media_(c->media_player);
|
||||
|
||||
if (!media)
|
||||
return;
|
||||
|
||||
libvlc_media_track_t **tracks;
|
||||
|
||||
unsigned count = libvlc_media_tracks_get_(media, &tracks);
|
||||
|
||||
if (count > 0) {
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
libvlc_media_track_t *track = tracks[i];
|
||||
|
||||
if (track->i_type != libvlc_track_video)
|
||||
continue;
|
||||
|
||||
int display_width = track->video->i_width;
|
||||
int display_height = track->video->i_height;
|
||||
|
||||
if (display_width == 0 || display_height == 0)
|
||||
continue;
|
||||
|
||||
/* Adjust for Sample Aspect Ratio (SAR) */
|
||||
if (track->video->i_sar_num > 0 &&
|
||||
track->video->i_sar_den > 0) {
|
||||
display_width = display_width *
|
||||
track->video->i_sar_num /
|
||||
track->video->i_sar_den;
|
||||
}
|
||||
|
||||
switch (track->video->i_orientation) {
|
||||
case libvlc_video_orient_left_top:
|
||||
case libvlc_video_orient_left_bottom:
|
||||
case libvlc_video_orient_right_top:
|
||||
case libvlc_video_orient_right_bottom:
|
||||
/* orientation swaps height and width */
|
||||
*width = display_height;
|
||||
*height = display_width;
|
||||
break;
|
||||
default:
|
||||
/* height and width not swapped */
|
||||
*width = display_width;
|
||||
*height = display_height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
libvlc_media_tracks_release_(tracks, count);
|
||||
}
|
||||
|
||||
libvlc_media_release_(media);
|
||||
}
|
||||
|
||||
static unsigned vlcs_video_format(void **p_data, char *chroma, unsigned *width,
|
||||
unsigned *height, unsigned *pitches,
|
||||
unsigned *lines)
|
||||
@ -396,19 +452,12 @@ static unsigned vlcs_video_format(void **p_data, char *chroma, unsigned *width,
|
||||
|
||||
new_format = convert_vlc_video_format(chroma, &new_range);
|
||||
|
||||
/* This is used because VLC will by default try to use a different
|
||||
* scaling than what the file uses (probably for optimization reasons).
|
||||
* For example, if the file is 1920x1080, it will try to render it by
|
||||
* 1920x1088, which isn't what we want. Calling libvlc_video_get_size
|
||||
* gets the actual video file's size, and thus fixes the problem.
|
||||
* However this doesn't work with URLs, so if it returns a 0 value, it
|
||||
* shouldn't be used. */
|
||||
libvlc_video_get_size_(c->media_player, 0, &new_width, &new_height);
|
||||
|
||||
if (new_width && new_height) {
|
||||
*width = new_width;
|
||||
*height = new_height;
|
||||
}
|
||||
/* The width and height passed from VLC are the buffer size rather than
|
||||
* the correct video display size, and may be the next multiple of 32
|
||||
* up from the original dimension, e.g. 1080 would become 1088. VLC 4.0
|
||||
* will pass the correct display size in *(width+1) and *(height+1) but
|
||||
* for now we need to calculate it ourselves. */
|
||||
calculate_display_size(c, width, height);
|
||||
|
||||
/* don't allocate a new frame if format/width/height hasn't changed */
|
||||
if (c->frame.format != new_format || c->frame.width != *width ||
|
||||
|
Loading…
x
Reference in New Issue
Block a user