stream: turn the highlight fields into mp_dvdnav_highlight
The highlight rectangle and palette were passed around as loose fields in three places. Bundle them into a struct, pass the whole nav state to the sd_lavc control.
This commit is contained in:
1 parent
c7859fe5b6
commit
c9422ff88f
5 files changed
+55
-72
No files matched your search
+5
-16
@@ -153,25 +153,13 @@ bool disc_nav_mouse_pos_to_src(struct MPContext *mpctx, int src_w, int src_h,
|
||||
}
|
||||
|
||||
// Push the current menu/highlight state to the dvd_subtitle decoders.
|
||||
static void push_dvd_overlay(struct MPContext *mpctx,
|
||||
struct stream_nav_state *nav, bool visible)
|
||||
static void push_dvd_overlay(struct MPContext *mpctx, struct stream_nav_state *nav)
|
||||
{
|
||||
struct mp_dvdnav_hli hli = {
|
||||
.show = visible,
|
||||
.change_id = nav->change_id,
|
||||
};
|
||||
if (visible) {
|
||||
hli.x = nav->hl_x;
|
||||
hli.y = nav->hl_y;
|
||||
hli.w = nav->hl_w;
|
||||
hli.h = nav->hl_h;
|
||||
memcpy(hli.palette, nav->hl_palette, sizeof(hli.palette));
|
||||
}
|
||||
for (int n = 0; n < mpctx->num_tracks; n++) {
|
||||
struct track *t = mpctx->tracks[n];
|
||||
if (!is_dvd_sub_track(t) || !t->d_sub)
|
||||
continue;
|
||||
sub_control(t->d_sub, SD_CTRL_APPLY_DVDNAV, &hli);
|
||||
sub_control(t->d_sub, SD_CTRL_APPLY_DVDNAV, nav);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,12 +482,13 @@ void disc_nav_update(struct MPContext *mpctx)
|
||||
sync_disc_track_selection(mpctx, s, &nav);
|
||||
|
||||
bool is_bd = strcmp(s->info->name, "bd") == 0 || strcmp(s->info->name, "bdmv/bluray") == 0;
|
||||
bool visible = nav.menu_active && (is_bd || (nav.hl_w > 0 && nav.hl_h > 0));
|
||||
bool visible = nav.menu_active &&
|
||||
(is_bd || (mp_rect_w(nav.hl.rect) > 0 && mp_rect_h(nav.hl.rect) > 0));
|
||||
|
||||
if (is_bd) {
|
||||
push_bd_overlay(mpctx, s, &nav, visible);
|
||||
} else {
|
||||
push_dvd_overlay(mpctx, &nav, visible);
|
||||
push_dvd_overlay(mpctx, &nav);
|
||||
ensure_menu_sub_selection(mpctx, nav.menu_active);
|
||||
}
|
||||
|
||||
|
||||
+9
-4
@@ -25,6 +25,7 @@
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "common/common.h"
|
||||
#include "misc/bstr.h"
|
||||
|
||||
// Minimum guaranteed buffer and seek-back size. For any reads <= of this size,
|
||||
@@ -142,6 +143,12 @@ static inline bool stream_nav_action_activates(enum stream_nav_action a)
|
||||
}
|
||||
}
|
||||
|
||||
// A DVD subpicture button highlight.
|
||||
struct mp_dvdnav_highlight {
|
||||
struct mp_rect rect; // button rectangle in SPU/source coords
|
||||
uint32_t palette[4]; // replacement colors for SPU pixel values 0..3
|
||||
};
|
||||
|
||||
// Snapshot of the stream's menu state.
|
||||
struct stream_nav_state {
|
||||
bool nav_active; // interactive disc navigation is enabled
|
||||
@@ -149,10 +156,8 @@ struct stream_nav_state {
|
||||
bool has_popup; // disc supports a popup menu (BD only)
|
||||
bool still_active; // holding an indefinite still frame
|
||||
int src_w, src_h; // dimensions of the coordinate space mouse uses
|
||||
// Highlight rectangle of the currently focused button (in src coords).
|
||||
int hl_x, hl_y, hl_w, hl_h;
|
||||
uint32_t hl_palette[4]; // BGRA highlight palette (0xAARRGGBB, straight)
|
||||
uint32_t change_id; // Bumped whenever any of the above changes
|
||||
struct mp_dvdnav_highlight hl; // focused button highlight (DVD only)
|
||||
uint32_t change_id; // Bumped whenever any of the above changes
|
||||
uint32_t discontinuity_id; // Bumped when the stream's source position jumps
|
||||
|
||||
// Disc-driven track selection.
|
||||
|
||||
+13
-25
@@ -79,8 +79,7 @@ struct priv {
|
||||
|
||||
bool in_menu;
|
||||
int current_button; // mirror of libdvdnav HL_BTNN_REG
|
||||
int btn_rect[4]; // x, y, w, h in source coords
|
||||
uint32_t hl_palette[4]; // 0xAARRGGBB for SPU pixel values 0..3
|
||||
struct mp_dvdnav_highlight hl; // focused button rect + palette
|
||||
uint32_t nav_change_id;
|
||||
uint32_t discontinuity_id; // bumped on actions that may jump
|
||||
bool pending_drain; // emit one EOF at the next jump boundary
|
||||
@@ -241,8 +240,7 @@ static bool in_menu_domain(dvdnav_t *dvdnav)
|
||||
|
||||
static void compute_button_rect(struct priv *priv, pci_t *pci, int btn)
|
||||
{
|
||||
priv->btn_rect[0] = priv->btn_rect[1] = 0;
|
||||
priv->btn_rect[2] = priv->btn_rect[3] = 0;
|
||||
priv->hl.rect = (struct mp_rect){0};
|
||||
if (btn <= 0 || btn > pci->hli.hl_gi.btn_ns)
|
||||
return;
|
||||
// btni_t is packed and full of bitfields, memcpy to ensure correct alignment.
|
||||
@@ -250,10 +248,11 @@ static void compute_button_rect(struct priv *priv, pci_t *pci, int btn)
|
||||
memcpy(&b, &pci->hli.btnit[btn - 1], sizeof(b));
|
||||
int xs = b.x_start, xe = b.x_end;
|
||||
int ys = b.y_start, ye = b.y_end;
|
||||
priv->btn_rect[0] = xs;
|
||||
priv->btn_rect[1] = ys;
|
||||
priv->btn_rect[2] = xe > xs ? xe - xs : 0;
|
||||
priv->btn_rect[3] = ye > ys ? ye - ys : 0;
|
||||
priv->hl.rect = (struct mp_rect){
|
||||
.x0 = xs, .y0 = ys,
|
||||
.x1 = xe > xs ? xe : xs,
|
||||
.y1 = ye > ys ? ye : ys,
|
||||
};
|
||||
}
|
||||
|
||||
// Resolve the 4-entry "select-state" highlight palette for the focused button.
|
||||
@@ -262,7 +261,7 @@ static void compute_button_rect(struct priv *priv, pci_t *pci, int btn)
|
||||
// alphas.
|
||||
static void compute_highlight_palette(struct priv *priv, pci_t *pci, int btn)
|
||||
{
|
||||
memset(priv->hl_palette, 0, sizeof(priv->hl_palette));
|
||||
memset(priv->hl.palette, 0, sizeof(priv->hl.palette));
|
||||
if (!priv->spu_clut_valid || btn <= 0 || btn > pci->hli.hl_gi.btn_ns)
|
||||
return;
|
||||
btni_t b;
|
||||
@@ -289,7 +288,7 @@ static void compute_highlight_palette(struct priv *priv, pci_t *pci, int btn)
|
||||
int c[3];
|
||||
mp_map_fixp_color(&cmatrix, 8, y, 8, c);
|
||||
uint32_t alpha = (a << 4) | a;
|
||||
priv->hl_palette[i] = (alpha << 24) | (c[0] << 16) | (c[1] << 8) | c[2];
|
||||
priv->hl.palette[i] = (alpha << 24) | (c[0] << 16) | (c[1] << 8) | c[2];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,11 +333,8 @@ static void refresh_video_resolution(struct priv *priv)
|
||||
static void update_highlight(struct priv *priv)
|
||||
{
|
||||
int prev_btn = priv->current_button;
|
||||
int prev_x = priv->btn_rect[0], prev_y = priv->btn_rect[1];
|
||||
int prev_w = priv->btn_rect[2], prev_h = priv->btn_rect[3];
|
||||
bool prev_menu = priv->in_menu;
|
||||
uint32_t prev_palette[4];
|
||||
memcpy(prev_palette, priv->hl_palette, sizeof(prev_palette));
|
||||
struct mp_dvdnav_highlight prev_hl = priv->hl;
|
||||
|
||||
priv->in_menu = in_menu_domain(priv->dvdnav);
|
||||
pci_t *pci = priv->in_menu ? dvdnav_get_current_nav_pci(priv->dvdnav) : NULL;
|
||||
@@ -362,9 +358,7 @@ static void update_highlight(struct priv *priv)
|
||||
|
||||
if (!highlight_live || btn <= 0 || btn > pci->hli.hl_gi.btn_ns) {
|
||||
priv->current_button = 0;
|
||||
priv->btn_rect[0] = priv->btn_rect[1] = 0;
|
||||
priv->btn_rect[2] = priv->btn_rect[3] = 0;
|
||||
memset(priv->hl_palette, 0, sizeof(priv->hl_palette));
|
||||
priv->hl = (struct mp_dvdnav_highlight){0};
|
||||
} else {
|
||||
priv->current_button = btn;
|
||||
compute_button_rect(priv, pci, btn);
|
||||
@@ -372,9 +366,7 @@ static void update_highlight(struct priv *priv)
|
||||
}
|
||||
|
||||
if (priv->in_menu != prev_menu || priv->current_button != prev_btn ||
|
||||
priv->btn_rect[0] != prev_x || priv->btn_rect[1] != prev_y ||
|
||||
priv->btn_rect[2] != prev_w || priv->btn_rect[3] != prev_h ||
|
||||
memcmp(prev_palette, priv->hl_palette, sizeof(prev_palette)) != 0)
|
||||
memcmp(&prev_hl, &priv->hl, sizeof(prev_hl)) != 0)
|
||||
{
|
||||
priv->nav_change_id++;
|
||||
}
|
||||
@@ -909,10 +901,7 @@ static int control(stream_t *stream, int cmd, void *arg)
|
||||
.still_active = priv->still_active,
|
||||
.src_w = priv->src_w,
|
||||
.src_h = priv->src_h,
|
||||
.hl_x = priv->btn_rect[0],
|
||||
.hl_y = priv->btn_rect[1],
|
||||
.hl_w = priv->btn_rect[2],
|
||||
.hl_h = priv->btn_rect[3],
|
||||
.hl = priv->hl,
|
||||
.change_id = priv->nav_change_id,
|
||||
.discontinuity_id = priv->discontinuity_id,
|
||||
.active_audio_id = dvd_physical_audio_to_substream(priv, priv->audio_physical),
|
||||
@@ -921,7 +910,6 @@ static int control(stream_t *stream, int cmd, void *arg)
|
||||
.angle = cur_angle,
|
||||
.num_angles = num_angles,
|
||||
};
|
||||
memcpy(st->hl_palette, priv->hl_palette, sizeof(st->hl_palette));
|
||||
return STREAM_OK;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-8
@@ -5,6 +5,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "player/core.h"
|
||||
#include "stream/stream.h"
|
||||
#include "osd.h"
|
||||
|
||||
struct sh_stream;
|
||||
@@ -21,14 +22,7 @@ enum sd_ctrl {
|
||||
SD_CTRL_SET_VIDEO_DEF_FPS,
|
||||
SD_CTRL_RESET_SOFT,
|
||||
SD_CTRL_UPDATE_OPTS,
|
||||
SD_CTRL_APPLY_DVDNAV, // struct mp_dvdnav_hli *
|
||||
};
|
||||
|
||||
struct mp_dvdnav_hli {
|
||||
bool show;
|
||||
int x, y, w, h; // button rect in SPU/source coords
|
||||
uint32_t palette[4]; // 0xAARRGGBB, straight alpha
|
||||
uint32_t change_id; // bumped on any visible change
|
||||
SD_CTRL_APPLY_DVDNAV, // const struct stream_nav_state *
|
||||
};
|
||||
|
||||
enum sd_text_type {
|
||||
|
||||
+26
-19
@@ -72,8 +72,9 @@ struct sd_lavc_priv {
|
||||
int num_seekpoints;
|
||||
struct bitmap_packer *packer;
|
||||
|
||||
// DVD-nav per-pixel highlight overlay state.
|
||||
struct mp_dvdnav_hli hli;
|
||||
// DVD-nav menu/highlight overlay state.
|
||||
bool menu_active; // in-menu: gates the highlight overlay
|
||||
struct mp_dvdnav_highlight hl; // focused button rect + palette
|
||||
uint32_t hli_change_id;
|
||||
};
|
||||
|
||||
@@ -300,21 +301,20 @@ static void read_sub_bitmaps(struct sd *sd, struct sub *sub)
|
||||
convert_pal(pal, 256, opts->sub_gray);
|
||||
|
||||
// DVD navigation highlight
|
||||
bool hli_active = priv->hli.show &&
|
||||
priv->hli.w > 0 && priv->hli.h > 0 &&
|
||||
r->x < priv->hli.x + priv->hli.w &&
|
||||
r->y < priv->hli.y + priv->hli.h &&
|
||||
r->x + r->w > priv->hli.x &&
|
||||
r->y + r->h > priv->hli.y;
|
||||
struct mp_rect hlr = priv->hl.rect;
|
||||
bool hli_active = priv->menu_active &&
|
||||
mp_rect_w(hlr) > 0 && mp_rect_h(hlr) > 0 &&
|
||||
r->x < hlr.x1 && r->y < hlr.y1 &&
|
||||
r->x + r->w > hlr.x0 && r->y + r->h > hlr.y0;
|
||||
uint32_t hli_pal[4] = {0};
|
||||
if (hli_active) {
|
||||
memcpy(hli_pal, priv->hli.palette, sizeof(hli_pal));
|
||||
memcpy(hli_pal, priv->hl.palette, sizeof(hli_pal));
|
||||
convert_pal(hli_pal, 4, opts->sub_gray);
|
||||
}
|
||||
int hli_x0 = priv->hli.x - r->x;
|
||||
int hli_y0 = priv->hli.y - r->y;
|
||||
int hli_x1 = hli_x0 + priv->hli.w;
|
||||
int hli_y1 = hli_y0 + priv->hli.h;
|
||||
int hli_x0 = hlr.x0 - r->x;
|
||||
int hli_y0 = hlr.y0 - r->y;
|
||||
int hli_x1 = hlr.x1 - r->x;
|
||||
int hli_y1 = hlr.y1 - r->y;
|
||||
|
||||
for (int y = -padding; y < b->h + padding; y++) {
|
||||
uint32_t *out = (uint32_t*)((char*)b->bitmap + y * b->stride);
|
||||
@@ -760,13 +760,20 @@ static int control(struct sd *sd, enum sd_ctrl cmd, void *arg)
|
||||
priv->video_params = *(struct mp_image_params *)arg;
|
||||
return CONTROL_OK;
|
||||
case SD_CTRL_APPLY_DVDNAV: {
|
||||
struct mp_dvdnav_hli *hli = arg;
|
||||
if (priv->hli_change_id == hli->change_id)
|
||||
return CONTROL_OK;
|
||||
priv->hli = *hli;
|
||||
priv->hli_change_id = hli->change_id;
|
||||
const struct stream_nav_state *nav = arg;
|
||||
bool menu_closed = priv->menu_active && !nav->menu_active;
|
||||
bool changed = priv->hli_change_id != nav->change_id;
|
||||
priv->menu_active = nav->menu_active;
|
||||
priv->hl = nav->hl;
|
||||
priv->hli_change_id = nav->change_id;
|
||||
// Don't let menu subpictures leak into title playback.
|
||||
if (menu_closed) {
|
||||
for (int n = 0; n < MAX_QUEUE; n++)
|
||||
clear_sub(&priv->subs[n]);
|
||||
}
|
||||
// Re-render any decoded subtitles, after style update.
|
||||
rerender_queued_subs(sd);
|
||||
if (changed)
|
||||
rerender_queued_subs(sd);
|
||||
return CONTROL_OK;
|
||||
}
|
||||
default:
|
||||
|
||||
Reference in new issue
Block a user