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.
This commit is contained in:
Romain Vimont
2019-03-02 16:43:43 +01:00
parent e7b7b083aa
commit e6e011baaf
7 changed files with 388 additions and 312 deletions

View File

@@ -1,35 +1,22 @@
#ifndef DECODER_H
#define DECODER_H
#include <libavformat/avformat.h>
#include <SDL2/SDL_stdinc.h>
#include <SDL2/SDL_thread.h>
#include "common.h"
#include "net.h"
struct video_buffer;
struct frame_meta {
uint64_t pts;
struct frame_meta *next;
};
struct decoder {
struct video_buffer *video_buffer;
socket_t video_socket;
SDL_Thread *thread;
struct recorder *recorder;
struct receiver_state {
// meta (in order) for frames not consumed yet
struct frame_meta *frame_meta_queue;
size_t remaining; // remaining bytes to receive for the current frame
} receiver_state;
AVCodecContext *codec_ctx;
};
void decoder_init(struct decoder *decoder, struct video_buffer *vb,
socket_t video_socket, struct recorder *recoder);
SDL_bool decoder_start(struct decoder *decoder);
void decoder_stop(struct decoder *decoder);
void decoder_join(struct decoder *decoder);
void decoder_init(struct decoder *decoder, struct video_buffer *vb);
SDL_bool decoder_open(struct decoder *decoder, AVCodec *codec);
void decoder_close(struct decoder *decoder);
SDL_bool decoder_push(struct decoder *decoder, AVPacket *packet);
void decoder_interrupt(struct decoder *decoder);
#endif