The o key lists the directory of the input, local or remote, in the
list. Enter or a click lists the chosen directory or plays the chosen
file instead of the input once it opened, so a file that is no media
leaves the input playing. Directories come first, hidden entries are
left out, and the popup of a file shows its size.
Assisted-by: Claude
The audio device is opened once the audio decoder is set up, and a
failure to start the audio output closes the audio stream again.
Assisted-by: Claude
avformat_open_input() replaces the dictionary it is given with the
options it did not use, which left the global format options without
the recognized ones after the first input. Each input is opened with a
copy now.
Assisted-by: Claude
stream_open() replaced the -volume percentage with the SDL volume it
computed from it, so a second stream would compute its volume from the
first stream's.
Assisted-by: Claude
The window title taken from the input's metadata, seeking by bytes and
the unlimited buffering of realtime inputs were decided once into
globals; they are kept per VideoState now, so that another input
decides them anew. The title string is freed with the stream.
Assisted-by: Claude
The list becomes a ListView in ffplay_list.c, which shows entries with
title, artist, length and metadata and reports the entry the user
chooses; ffplay builds the entries from the chapters and seeks to the
chosen one. The sort order moves from globals into the ListView.
Assisted-by: Claude
When the list scrolls, the pixels of the rows that stay visible are
moved together with their strips, so only the rows scrolling in and
those whose content changed are rendered. Rows the popup covered are
rendered anew, as their pixels moved with the popup's.
Assisted-by: Claude
The event loop slept up to REFRESH_RATE between refreshes while input
waited in the queue; waiting for an event with the same timeout handles
input as soon as it arrives.
Assisted-by: Claude
The rows are rebuilt and sorted whenever the list is shown; moving the
selection by key or wheel within the visible list only needs the new
selection, not another rebuild over all chapters.
Assisted-by: Claude
Input handlers only ask for a render, which happens once the pending
events are handled, so a burst of wheel clicks or key presses renders
the list once instead of once per event.
Assisted-by: Claude
The list is kept in one bitmap made of horizontal strips: the header,
each row, the bottom padding and each line of the metadata popup. A
strip is rendered through libass on a strip sized canvas, over its
background filled by the color source, only when its script, place or
background changed or when it lies on something cleared or redrawn
before it. Only the changed part of the bitmap is uploaded, on the next
refresh. Moving the mouse across the list thus renders and uploads the
two rows whose highlight changed instead of the whole list on a window
wide canvas.
The popup over the rows of a narrow window now covers them instead of
letting their text show through.
Assisted-by: Claude
A chapter length near INT64_MAX overflowed the rounding, the hour count
was also truncated to int.
Fixes: signed integer overflow
Fixes: 7JHyBJsQ7bNE
Regression since: 80a55704b7
Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24589
Signed integer overflow Replicated through UnModified FFmpeg with UBSAN
A symbol at the right of each entry pops up every tag of the chapter
beside the list, or over its rows when the window leaves no room there.
Clicking the symbol does not seek.
Assisted-by: Claude
A shuffle button orders the list by a pseudo-random rank of each
chapter derived from a seed, so the order is reproducible and the
other keys still resolve ties. Clicking the left half of the button
lowers the seed, the right half raises it, either way giving a new
order.
Assisted-by: Claude
The position of the mouse is kept from its motion events and every
render of the list looks up what lies under it, so the highlight always
matches the rows being drawn even after they were rebuilt. Mouse motion
only asks for a render when the hovered row or button changes, and the
render happens once the pending events are handled, so sweeping the
mouse across the list renders once instead of once per row. Leaving
the window drops the highlight.
Assisted-by: Claude
While the list is pinned it owns the keyboard: typed text narrows the
entries to those whose artist or title contains it, backspace erases,
escape closes the list. The list is pinned on the release of its key so
that the key's own text input does not start the search, and the
canvas keeps its full size so a changing row count does not alter the
script resolution libass scales to.
Assisted-by: Claude
Buttons above the list order it by chapter number, artist, title or
duration. Clicking a column makes it the first sort key ahead of the
ones clicked before, which still resolve ties, so # then Title orders
by title with equal titles in chapter order. Clicking the first key
again flips its order, shown by an arrow on its button.
The rows become an array in display order, rebuilt whenever the list is
shown, so the selection can survive a re-sort and chapters a demuxer
adds during playback are picked up. The length of each chapter is kept
with its row for the display and the sort to share; the sort compares
the exact length while the display rounds it to seconds.
Assisted-by: Claude
Page up/down fade in a list of the chapters around the current one and
fade it out again half a second after the last key press, "l" keeps it
on screen, and while it is kept down/up move the selection. Enter seeks
to the selected chapter and the mouse wheel moves the selection whenever
the list is visible. Each entry shows the chapter's number, its title
with the artist beneath it, both clipped to their column, and its
length; a bar at the left edge marks the chapter being played and moves
along with playback.
The ass filter renders the list onto a transparent canvas the size of
the panel, only when its content changes, and SDL composites the result
as a texture whose alpha modulation does the fading. The video path is
untouched and nothing is drawn while the list is hidden. The list is not
available with the Vulkan renderer, which bypasses SDL rendering.
Assisted-by: Claude
The callers pass the index relative to the current chapter themselves,
so the function can serve seeks to an arbitrary chapter too.
Assisted-by: Claude
The chapter lookup left the index one past the end when the position
lay inside the last chapter, so page down restarted that chapter
instead of moving to the previous one like it does everywhere else.
Assisted-by: Claude
sigterm_handler() called exit(123) directly, bypassing
avformat_close_input() and therefore any protocol level shutdown, such as
the RTSP TEARDOWN. Set a flag instead and let the event loop leave
through do_exit(), which keeps the 123 exit status.
Add a hard exit on the 4th sigterm, similar to ffmpeg.
Signed-off-by: Thomas Devoogdt <thomas@devoogdt.com>
Both fall-throughs are deliberate: SDL_MOUSEBUTTONDOWN shares the cursor
and seek handling of SDL_MOUSEMOTION, and a resize also needs the refresh
done by SDL_WINDOWEVENT_EXPOSED. Silences -Wimplicit-fallthrough.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
Clarify the behavior of seek keyboard shortcuts in both the
documentation and command-line help text. Specifically:
- left/right: mention custom interval option support
- page down/up: improve wording for chapter seeking fallback
And add the missing goto fail. This should ensure the alpha mode is set and remove
bogus warnings printed by ffplay.
Signed-off-by: James Almer <jamrial@gmail.com>
When vulkan rendering is requested by the user and fails, ffplay should
exit graciously instead of crash due to a null pointer deref.
Signed-off-by: Leandro Santiago <leandrosansilva@gmail.com>
Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
This function creates AND initializes a filter, so setting any filter
options after it is wrong. It happens to work when the filter's init
function does not touch the options in question, but is forbidden by the
API and is not guaranteed to remain functional.
Instead, use avfilter_graph_alloc_filter(), followed by setting the
options, and avfilter_init_dict().