Commit Graph

37 Commits (master)

Author SHA1 Message Date
Romain Vimont 4bdf632dfa Pass AVCodecContext to packet sinks
Create the codec context from the demuxer, so that it can fill context
data for the decoder and recorder.
1 year ago
Romain Vimont 974227a3fc Use frame source trait in decoder 1 year ago
Romain Vimont 05f0e35d2a Give a name to decoder instances
This will be useful in logs.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
1 year ago
Romain Vimont 0080d0b0ff Use sc_ prefix for decoder 2 years ago
Bernhard Rosenkränzer 5e8fa56e7a Fix build with ffmpeg 5.0
PR #2948 <https://github.com/Genymobile/scrcpy/pull/2948>

Signed-off-by: Bernhard Rosenkränzer <bero@lindev.ch>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2 years ago
Marco Martinelli d39161f753 Add support for v4l2loopback
It allows to send the video stream to /dev/videoN, so that it can be
captured (like a webcam) by any v4l2-capable tool.

PR #2232 <https://github.com/Genymobile/scrcpy/pull/2232>
PR #2233 <https://github.com/Genymobile/scrcpy/pull/2233>
PR #2268 <https://github.com/Genymobile/scrcpy/pull/2268>

Co-authored-by: Romain Vimont <rom@rom1v.com>
3 years ago
Romain Vimont 6f5ad21f57 Make decoder push frames to sinks
Now that screen implements the packet sink trait, make decoder push
packets to the sinks without depending on the concrete sink types.
3 years ago
Romain Vimont f7a1b67d66 Make stream push packets to sinks
Now that decoder and recorder implement the packet sink trait, make
stream push packets to the sinks without depending on the concrete sink
types.
3 years ago
Romain Vimont cbed38799e Expose decoder as packet sink
Make decoder implement the packet sink trait.

This will allow the stream to push packets without depending on the
concrete sink type.
3 years ago
Romain Vimont 2ddf760c09 Make video_buffer more generic
The video buffer took ownership of the producer frame (so that it could
swap frames quickly).

In order to support multiple sinks plugged to the decoder, the decoded
frame must not be consumed by the display video buffer.

Therefore, move the producer and consumer frames out of the video
buffer, and use FFmpeg AVFrame refcounting to share ownership while
avoiding copies.
3 years ago
Romain Vimont 55806e7d31 Remove option --render-expired-frames
This flag forced the decoder to wait for the previous frame to be
consumed by the display.

It was initially implemented as a compilation flag for testing, not
intended to be exposed at runtime. But to remove ifdefs and to allow
users to test this flag easily, it had finally been exposed by commit
ebccb9f6cc.

In practice, it turned out to be useless: it had no practical impact,
and it did not solve or mitigate any performance issues causing frame
skipping.

But that added some complexity to the codebase: it required an
additional condition variable, and made video buffer calls possibly
blocking, which in turn required code to interrupt it on exit.

To prepare support for multiple sinks plugged to the decoder (display
and v4l2 for example), the blocking call used for pacing the decoder
output becomes unacceptable, so just remove this useless "feature".
3 years ago
Romain Vimont cb9c42bdcb Use a callback to notify frame skip
A skipped frame is detected when the producer offers a frame while the
current pending frame has not been consumed.

However, the producer (in practice the decoder) is not interested in the
fact that a frame has been skipped, only the consumer (the renderer) is.

Therefore, notify frame skip via a consumer callback. This allows to
manage the skipped and rendered frames count at the same place, and
remove fps_counter from decoder.
3 years ago
Romain Vimont cb197ee3a2 Move fps counter out of video buffer
In order to make video buffer more generic, move out its specific
responsibility to count the fps between the decoder and the renderer.
3 years ago
Romain Vimont ab912c23e7 Define feature test macros in common.h
This enables necessary functions once for all.

As a consequence, define common.h before any other header.
3 years ago
Romain Vimont 59feb2a15c Group common includes into common.h
Include config.h and compat.h in common.h, and include common.h from all
source files.
3 years ago
Romain Vimont 1f8ba1ca79 Include config.h everywhere
Ref: <https://github.com/Genymobile/scrcpy/issues/829>

Suggested-by: Louis Kruger <louisk@gmail.com>
5 years ago
Romain Vimont a7b3901c31 Add more consts
Some decoder and recorder functions must not write to AVCodec and
AVPacket.
5 years ago
Romain Vimont dfed1b250e Replace SDL types by C99 standard types
Scrcpy is a C11 project. Use the C99 standard types instead of the
SDL-specific types:

    SDL_bool -> bool
    SintXX   -> intXX_t
    UintXX   -> uintXX_t
5 years ago
Romain Vimont aeda583a2c Update code style
Limit source code to 80 chars, and declare functions return type and
modifiers on a separate line.

This allows to avoid very long lines, and all function names are
aligned.

(We do this on VLC, and I like it.)
5 years ago
Romain Vimont e6e011baaf Add stream layer
The decoder initially read from the socket, decoded the video and sent
the decoded frames to the screen:

              +---------+      +----------+
  socket ---> | decoder | ---> |  screen  |
              +---------+      +----------+

The design was simple, but the decoder had several responsabilities.

Then we added the recording feature, so we added a recorder, which
reused the packets received from the socket managed by the decoder:

                                    +----------+
                               ---> |  screen  |
              +---------+     /     +----------+
  socket ---> | decoder | ----
              +---------+     \     +----------+
                               ---> | recorder |
                                    +----------+

This lack of separation of concerns now have concrete implications: we
could not (properly) disable the decoder/display to only record the
video.

Therefore, split the decoder to extract the stream:

                                    +----------+      +----------+
                               ---> | decoder  | ---> |  screen  |
              +---------+     /     +----------+      +----------+
  socket ---> | stream  | ----
              +---------+     \     +----------+
                               ---> | recorder |
                                    +----------+

This will allow to record the stream without decoding the video.
5 years ago
Romain Vimont fff87095d9 Rename "frames" to "video_buffer"
It better describes the purpose of the structure.
5 years ago
Romain Vimont aacb09a3d6 Remove unused mutex field in decoder 5 years ago
Romain Vimont 60afb46c8d Store queue of PTS for pending frames
Several frames may be read by read_packet() before they are consumed
(returned by av_read_frame()), so we need to store the PTS of frames in
order, so that the right PTS is assigned to the right frame.
6 years ago
Romain Vimont 70579dc709 Wrap receiver state into separate struct
For readability, wrap the state of the receiver in a separate struct
receiver_state.
6 years ago
Romain Vimont 475912a39c Do not transmit MediaCodec flags
Since PTS handling has been fixed, the recorder do not associate a PTS
to a wrong frame anymore, so PTS of "configuration packets" (which never
produce a frame), are never read by the recorder. Therefore, there is no
need to ignore them explicitly, so we can remove the MediaCodec flags
completely.
6 years ago
Romain Vimont 27e8a9a79d Assign PTS to the right frame
The PTS was read from the socket and set as the current one even before
the frame was consumed, so it could be assigned to the previous frame
"in advance".

Store the PTS for the current frame and the last PTS read from the
packet header of the next frame in separate fields.

As a side-effect, this fixes the warning on quit:

> Application provided invalid, non monotonically increasing dts to
> muxer in stream 0: 17164020 >= 17164020
6 years ago
Romain Vimont 2cd99e7205 Only set valid PTS/DTS
When the PTS is valid, set both PTS and DTS to avoid FFmpeg warnings.

Since configuration packets have no PTS, do not record these packets.
6 years ago
Romain Vimont 27686e9361 Add recorder
Implement recording in a separate "class".
6 years ago
Ivan Gorinov d706c5df39 Enable video output file, with pts set by server 6 years ago
Romain Vimont 9b056f5091 Replace SDL_net by custom implementation
SDL_net is not very suitable for scrcpy.

For example, SDLNet_TCP_Accept() is non-blocking, so we have to wrap it
by calling many SDL_Net-specific functions to make it blocking.

But above all, SDLNet_TCP_Open() is a server socket only when no IP is
provided; otherwise, it's a client socket. Therefore, it is not possible
to create a server socket bound to localhost, so it accepts connections
from anywhere.

This is a problem for scrcpy, because on start, the application listens
for nearly 1 second until it accepts the first connection, supposedly
from the device. If someone on the local network manages to connect to
the server socket first, then they can stream arbitrary H.264 video.
This may be troublesome, for example during a public presentation ;-)

Provide our own simplified API (net.h) instead, implemented for the
different platforms.
6 years ago
Romain Vimont 523097eadf Provide decoder_init()
Expose an initializer so that the caller does not have to guess what
fields must be initialized.
6 years ago
Romain Vimont 127e56780a Fix deadlock on exit if SKIP_FRAMES disabled
On exit, the renderer will not consume frames anymore, so signal the
condition variable to wake up the decoder.
6 years ago
Romain Vimont 8d30d40b79 Make SKIP_FRAMES a compilation flag
The skip_frames flag was a non-configurable runtime flag. Since it is
not exposed to the user, there is no need for a (possible) runtime cost.

For testing purpose, we still want it to be configurable, so make it a
compilation flag.
6 years ago
Romain Vimont d972a88c1a Optimize includes
Only include SDL_stdinc.h for SDL_bool, not the whole SDL.h.
7 years ago
Romain Vimont a9b276aa67 Remove useless forward declarations
The required headers are included anyway.
7 years ago
Romain Vimont 37d88b8a6a Use SDL_bool return type instead of int
Many functions returned an int to indicate their success. For clarity,
use SDL_bool instead.
7 years ago
Romain Vimont 54d9148a36 Initial commit
Start a new clean history from here.
7 years ago