Use frame source trait in decoder

This commit is contained in:
Romain Vimont 2023-03-02 09:37:36 +01:00
parent 8dac37fff0
commit d19c03d015
3 changed files with 14 additions and 61 deletions

View file

@ -12,32 +12,6 @@
/** Downcast packet_sink to decoder */
#define DOWNCAST(SINK) container_of(SINK, struct sc_decoder, packet_sink)
static void
sc_decoder_close_first_sinks(struct sc_decoder *decoder, unsigned count) {
while (count) {
struct sc_frame_sink *sink = decoder->sinks[--count];
sink->ops->close(sink);
}
}
static inline void
sc_decoder_close_sinks(struct sc_decoder *decoder) {
sc_decoder_close_first_sinks(decoder, decoder->sink_count);
}
static bool
sc_decoder_open_sinks(struct sc_decoder *decoder, const AVCodecContext *ctx) {
for (unsigned i = 0; i < decoder->sink_count; ++i) {
struct sc_frame_sink *sink = decoder->sinks[i];
if (!sink->ops->open(sink, ctx)) {
sc_decoder_close_first_sinks(decoder, i);
return false;
}
}
return true;
}
static bool
sc_decoder_open(struct sc_decoder *decoder, const AVCodec *codec) {
decoder->codec_ctx = avcodec_alloc_context3(codec);
@ -77,7 +51,8 @@ sc_decoder_open(struct sc_decoder *decoder, const AVCodec *codec) {
return false;
}
if (!sc_decoder_open_sinks(decoder, decoder->codec_ctx)) {
if (!sc_frame_source_sinks_open(&decoder->frame_source,
decoder->codec_ctx)) {
av_frame_free(&decoder->frame);
avcodec_close(decoder->codec_ctx);
avcodec_free_context(&decoder->codec_ctx);
@ -89,24 +64,12 @@ sc_decoder_open(struct sc_decoder *decoder, const AVCodec *codec) {
static void
sc_decoder_close(struct sc_decoder *decoder) {
sc_decoder_close_sinks(decoder);
sc_frame_source_sinks_close(&decoder->frame_source);
av_frame_free(&decoder->frame);
avcodec_close(decoder->codec_ctx);
avcodec_free_context(&decoder->codec_ctx);
}
static bool
push_frame_to_sinks(struct sc_decoder *decoder, const AVFrame *frame) {
for (unsigned i = 0; i < decoder->sink_count; ++i) {
struct sc_frame_sink *sink = decoder->sinks[i];
if (!sink->ops->push(sink, frame)) {
return false;
}
}
return true;
}
static bool
sc_decoder_push(struct sc_decoder *decoder, const AVPacket *packet) {
bool is_config = packet->pts == AV_NOPTS_VALUE;
@ -135,7 +98,8 @@ sc_decoder_push(struct sc_decoder *decoder, const AVPacket *packet) {
}
// a frame was received
bool ok = push_frame_to_sinks(decoder, decoder->frame);
bool ok = sc_frame_source_sinks_push(&decoder->frame_source,
decoder->frame);
// A frame lost should not make the whole pipeline fail. The error, if
// any, is already logged.
(void) ok;
@ -168,7 +132,7 @@ sc_decoder_packet_sink_push(struct sc_packet_sink *sink,
void
sc_decoder_init(struct sc_decoder *decoder, const char *name) {
decoder->name = name; // statically allocated
decoder->sink_count = 0;
sc_frame_source_init(&decoder->frame_source);
static const struct sc_packet_sink_ops ops = {
.open = sc_decoder_packet_sink_open,
@ -178,11 +142,3 @@ sc_decoder_init(struct sc_decoder *decoder, const char *name) {
decoder->packet_sink.ops = &ops;
}
void
sc_decoder_add_sink(struct sc_decoder *decoder, struct sc_frame_sink *sink) {
assert(decoder->sink_count < SC_DECODER_MAX_SINKS);
assert(sink);
assert(sink->ops);
decoder->sinks[decoder->sink_count++] = sink;
}

View file

@ -3,22 +3,19 @@
#include "common.h"
#include "trait/frame_source.h"
#include "trait/packet_sink.h"
#include <stdbool.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#define SC_DECODER_MAX_SINKS 2
struct sc_decoder {
struct sc_packet_sink packet_sink; // packet sink trait
struct sc_frame_source frame_source; // frame source trait
const char *name; // must be statically allocated (e.g. a string literal)
struct sc_frame_sink *sinks[SC_DECODER_MAX_SINKS];
unsigned sink_count;
AVCodecContext *codec_ctx;
AVFrame *frame;
};
@ -27,7 +24,4 @@ struct sc_decoder {
void
sc_decoder_init(struct sc_decoder *decoder, const char *name);
void
sc_decoder_add_sink(struct sc_decoder *decoder, struct sc_frame_sink *sink);
#endif

View file

@ -681,11 +681,13 @@ aoa_hid_end:
}
screen_initialized = true;
sc_decoder_add_sink(&s->video_decoder, &s->screen.frame_sink);
sc_frame_source_add_sink(&s->video_decoder.frame_source,
&s->screen.frame_sink);
if (options->audio) {
sc_audio_player_init(&s->audio_player);
sc_decoder_add_sink(&s->audio_decoder, &s->audio_player.frame_sink);
sc_frame_source_add_sink(&s->audio_decoder.frame_source,
&s->audio_player.frame_sink);
}
}
@ -696,7 +698,8 @@ aoa_hid_end:
goto end;
}
sc_decoder_add_sink(&s->video_decoder, &s->v4l2_sink.frame_sink);
sc_frame_source_add_sink(&s->video_decoder.frame_source,
&s->v4l2_sink.frame_sink);
v4l2_sink_initialized = true;
}