Wrap receiver state into separate struct
For readability, wrap the state of the receiver in a separate struct receiver_state.
This commit is contained in:
parent
e562837c0b
commit
70579dc709
2 changed files with 42 additions and 24 deletions
|
@ -22,36 +22,49 @@
|
|||
|
||||
static int read_packet(void *opaque, uint8_t *buf, int buf_size) {
|
||||
struct decoder *decoder = opaque;
|
||||
struct receiver_state *state = &decoder->receiver_state;
|
||||
|
||||
// The video stream contains raw packets, without time information. When we
|
||||
// record, we retrieve the timestamps separately, from a "meta" header
|
||||
// added by the server before each raw packet.
|
||||
//
|
||||
// The "meta" header length is 12 bytes:
|
||||
// [. . . . . . . .|. . . .]. . . . . . . . . . . . . . . ...
|
||||
// <-------------> <-----> <-----------------------------...
|
||||
// PTS packet raw packet
|
||||
// size
|
||||
//
|
||||
// It is followed by <packet_size> bytes containing the packet/frame.
|
||||
|
||||
if (!state->remaining) {
|
||||
// the next PTS is now for the current frame
|
||||
state->pts = state->next_pts;
|
||||
|
||||
#define HEADER_SIZE 12
|
||||
uint8_t header[HEADER_SIZE];
|
||||
int remaining;
|
||||
int ret;
|
||||
|
||||
remaining = decoder->remaining;
|
||||
if (remaining == 0) {
|
||||
// the previous PTS read is now for the current frame
|
||||
decoder->pts = decoder->next_pts;
|
||||
|
||||
ret = net_recv_all(decoder->video_socket, header, HEADER_SIZE);
|
||||
if (ret <= 0)
|
||||
ssize_t ret = net_recv_all(decoder->video_socket, header, HEADER_SIZE);
|
||||
if (ret <= 0) {
|
||||
return ret;
|
||||
|
||||
}
|
||||
// no partial read (net_recv_all())
|
||||
SDL_assert_release(ret == HEADER_SIZE);
|
||||
|
||||
// read the PTS for the next frame
|
||||
decoder->next_pts = buffer_read64be(header);
|
||||
remaining = buffer_read32be(&header[8]);
|
||||
state->next_pts = buffer_read64be(header);
|
||||
state->remaining = buffer_read32be(&header[8]);
|
||||
}
|
||||
|
||||
if (buf_size > remaining)
|
||||
buf_size = remaining;
|
||||
SDL_assert(state->remaining);
|
||||
|
||||
ret = net_recv(decoder->video_socket, buf, buf_size);
|
||||
if (ret <= 0)
|
||||
if (buf_size > state->remaining)
|
||||
buf_size = state->remaining;
|
||||
|
||||
ssize_t ret = net_recv(decoder->video_socket, buf, buf_size);
|
||||
if (ret <= 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
remaining -= ret;
|
||||
decoder->remaining = remaining;
|
||||
SDL_assert(state->remaining >= ret);
|
||||
state->remaining -= ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -107,6 +120,9 @@ static int run_decoder(void *data) {
|
|||
goto run_finally_free_format_ctx;
|
||||
}
|
||||
|
||||
// initialize the receiver state
|
||||
decoder->receiver_state.remaining = 0;
|
||||
|
||||
AVIOContext *avio_ctx = avio_alloc_context(buffer, BUFSIZE, 0, decoder, read_packet, NULL, NULL);
|
||||
if (!avio_ctx) {
|
||||
LOGC("Could not allocate avio context");
|
||||
|
@ -170,8 +186,8 @@ static int run_decoder(void *data) {
|
|||
#endif
|
||||
|
||||
if (decoder->recorder) {
|
||||
packet.pts = decoder->pts;
|
||||
packet.dts = decoder->pts;
|
||||
packet.pts = decoder->receiver_state.pts;
|
||||
packet.dts = decoder->receiver_state.pts;
|
||||
|
||||
// no need to rescale with av_packet_rescale_ts(), the timestamps
|
||||
// are in microseconds both in input and output
|
||||
|
|
|
@ -15,9 +15,11 @@ struct decoder {
|
|||
SDL_Thread *thread;
|
||||
SDL_mutex *mutex;
|
||||
struct recorder *recorder;
|
||||
struct receiver_state {
|
||||
uint64_t next_pts;
|
||||
uint64_t pts;
|
||||
int remaining;
|
||||
size_t remaining; // remaining bytes to receive for the current frame
|
||||
} receiver_state;
|
||||
};
|
||||
|
||||
void decoder_init(struct decoder *decoder, struct frames *frames,
|
||||
|
|
Loading…
Reference in a new issue