mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-10 10:08:52 +00:00
Detect frame size mismatch in decoder
Warn if the size of a decoded video frame does not match the session metadata.
This commit is contained in:
parent
fe0bda4bc7
commit
02047ff102
2 changed files with 40 additions and 0 deletions
|
@ -25,6 +25,15 @@ sc_decoder_open(struct sc_decoder *decoder, AVCodecContext *ctx,
|
||||||
|
|
||||||
decoder->ctx = ctx;
|
decoder->ctx = ctx;
|
||||||
|
|
||||||
|
// A video stream must have a session
|
||||||
|
assert(session || ctx->codec_type != AVMEDIA_TYPE_VIDEO);
|
||||||
|
|
||||||
|
if (session) {
|
||||||
|
decoder->session = *session;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&decoder->frame_size, 0, sizeof(decoder->frame_size));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +71,32 @@ sc_decoder_push(struct sc_decoder *decoder, const AVPacket *packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// a frame was received
|
// a frame was received
|
||||||
|
|
||||||
|
if (decoder->ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||||
|
assert(decoder->frame->width >= 0);
|
||||||
|
assert(decoder->frame->height >= 0);
|
||||||
|
struct sc_size frame_size = {
|
||||||
|
.width = decoder->frame->width,
|
||||||
|
.height = decoder->frame->height,
|
||||||
|
};
|
||||||
|
if (decoder->frame_size.width != frame_size.width
|
||||||
|
|| decoder->frame_size.height != frame_size.height) {
|
||||||
|
// The frame size has changed, check if it matches the session
|
||||||
|
uint32_t sw = decoder->session.video.width;
|
||||||
|
uint32_t sh = decoder->session.video.height;
|
||||||
|
if (frame_size.width != sw || frame_size.height != sh) {
|
||||||
|
LOGW("Unexpected video size: %" PRIu32 "x%" PRIu32
|
||||||
|
" (expected %" PRIu32 "x%" PRIu32 ")",
|
||||||
|
frame_size.width, frame_size.height, sw, sh);
|
||||||
|
|
||||||
|
LOGW("The encoder did not respect the requested size, "
|
||||||
|
"please retry with a lower resolution (-m/--max-size)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder->frame_size = frame_size;
|
||||||
|
}
|
||||||
|
|
||||||
bool ok = sc_frame_source_sinks_push(&decoder->frame_source,
|
bool ok = sc_frame_source_sinks_push(&decoder->frame_source,
|
||||||
decoder->frame);
|
decoder->frame);
|
||||||
av_frame_unref(decoder->frame);
|
av_frame_unref(decoder->frame);
|
||||||
|
@ -77,6 +112,7 @@ sc_decoder_push(struct sc_decoder *decoder, const AVPacket *packet) {
|
||||||
static bool
|
static bool
|
||||||
sc_decoder_push_session(struct sc_decoder *decoder,
|
sc_decoder_push_session(struct sc_decoder *decoder,
|
||||||
const struct sc_stream_session *session) {
|
const struct sc_stream_session *session) {
|
||||||
|
decoder->session = *session;
|
||||||
return sc_frame_source_sinks_push_session(&decoder->frame_source, session);
|
return sc_frame_source_sinks_push_session(&decoder->frame_source, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
|
|
||||||
|
#include "coords.h"
|
||||||
#include "trait/frame_source.h"
|
#include "trait/frame_source.h"
|
||||||
#include "trait/packet_sink.h"
|
#include "trait/packet_sink.h"
|
||||||
|
|
||||||
|
@ -16,6 +17,9 @@ struct sc_decoder {
|
||||||
|
|
||||||
AVCodecContext *ctx;
|
AVCodecContext *ctx;
|
||||||
AVFrame *frame;
|
AVFrame *frame;
|
||||||
|
|
||||||
|
struct sc_stream_session session; // only initialized for video stream
|
||||||
|
struct sc_size frame_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The name must be statically allocated (e.g. a string literal)
|
// The name must be statically allocated (e.g. a string literal)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue