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_NEW_LOCATION libvlc_media_new_location_;
|
||||||
LIBVLC_MEDIA_ADD_OPTION libvlc_media_add_option_;
|
LIBVLC_MEDIA_ADD_OPTION libvlc_media_add_option_;
|
||||||
LIBVLC_MEDIA_RELEASE libvlc_media_release_;
|
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_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 */
|
||||||
LIBVLC_MEDIA_PLAYER_NEW libvlc_media_player_new_;
|
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_release);
|
||||||
LOAD_VLC_FUNC(libvlc_media_retain);
|
LOAD_VLC_FUNC(libvlc_media_retain);
|
||||||
LOAD_VLC_FUNC(libvlc_media_get_meta);
|
LOAD_VLC_FUNC(libvlc_media_get_meta);
|
||||||
|
LOAD_VLC_FUNC(libvlc_media_tracks_get);
|
||||||
|
LOAD_VLC_FUNC(libvlc_media_tracks_release);
|
||||||
|
|
||||||
/* libvlc media player */
|
/* libvlc media player */
|
||||||
LOAD_VLC_FUNC(libvlc_media_player_new);
|
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 void (*LIBVLC_MEDIA_RELEASE)(libvlc_media_t *p_md);
|
||||||
typedef char *(*LIBVLC_MEDIA_GET_META)(libvlc_media_t *p_md,
|
typedef char *(*LIBVLC_MEDIA_GET_META)(libvlc_media_t *p_md,
|
||||||
libvlc_meta_t e_meta);
|
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 */
|
/* libvlc media player */
|
||||||
typedef libvlc_media_player_t *(*LIBVLC_MEDIA_PLAYER_NEW)(
|
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_RELEASE libvlc_media_release_;
|
||||||
extern LIBVLC_MEDIA_RETAIN libvlc_media_retain_;
|
extern LIBVLC_MEDIA_RETAIN libvlc_media_retain_;
|
||||||
extern LIBVLC_MEDIA_GET_META libvlc_media_get_meta_;
|
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 */
|
/* libvlc media player */
|
||||||
extern LIBVLC_MEDIA_PLAYER_NEW libvlc_media_player_new_;
|
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);
|
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,
|
static unsigned vlcs_video_format(void **p_data, char *chroma, unsigned *width,
|
||||||
unsigned *height, unsigned *pitches,
|
unsigned *height, unsigned *pitches,
|
||||||
unsigned *lines)
|
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);
|
new_format = convert_vlc_video_format(chroma, &new_range);
|
||||||
|
|
||||||
/* This is used because VLC will by default try to use a different
|
/* The width and height passed from VLC are the buffer size rather than
|
||||||
* scaling than what the file uses (probably for optimization reasons).
|
* the correct video display size, and may be the next multiple of 32
|
||||||
* For example, if the file is 1920x1080, it will try to render it by
|
* up from the original dimension, e.g. 1080 would become 1088. VLC 4.0
|
||||||
* 1920x1088, which isn't what we want. Calling libvlc_video_get_size
|
* will pass the correct display size in *(width+1) and *(height+1) but
|
||||||
* gets the actual video file's size, and thus fixes the problem.
|
* for now we need to calculate it ourselves. */
|
||||||
* However this doesn't work with URLs, so if it returns a 0 value, it
|
calculate_display_size(c, width, height);
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* don't allocate a new frame if format/width/height hasn't changed */
|
/* don't allocate a new frame if format/width/height hasn't changed */
|
||||||
if (c->frame.format != new_format || c->frame.width != *width ||
|
if (c->frame.format != new_format || c->frame.width != *width ||
|
||||||
|
Loading…
x
Reference in New Issue
Block a user