lavd video: removed parser

This effectively reverts recent commit d70e2fb3 (from 15th Aug).

The use of parser seems to be a problem for UG workflow, in the end -
the point is that it may cache a packet until arival of next packet
(commit 6e9a4142), so in that commit, as a solution flushing with EOF
was added.

However, it seems to produce problems with simple (but not with H.264 parser):
```
uv -d gl -t  testcard -c libavcodec:encoder=libx265
```
because the parser seems to be confused when parsing frames after EOF
so for the subsequent frames it consumes 1 byte producing 1 byte output. This
is mostly harmless (it is actually '\0', part of the start code), but
it produces errors:
```
[lavc hevc @ 0x68216c0055c0] missing picture in access unit with size 1
```

Possible solution would be to re-create the parser for every frame
(sic!) but it is unclear the overhead (which applies also to parsing the
frames, anyways). Anyways, as piggy-backed frames should not occur since
the commit c57f2fc5, it is perhaps best to remove this stuff altogether.
This commit is contained in:
Martin Pulec
2023-08-23 16:40:21 +02:00
parent 09488b085e
commit e2f0bb34d7

View File

@@ -69,11 +69,10 @@
#define MOD_NAME "[lavd] "
struct state_libavcodec_decompress {
AVCodecContext *codec_ctx;
AVCodecParserContext *parser;
AVFrame *frame;
AVFrame *tmp_frame;
AVPacket *pkt;
AVCodecContext *codec_ctx;
AVFrame *frame;
AVFrame *tmp_frame;
AVPacket *pkt;
struct video_desc desc;
int pitch;
@@ -105,8 +104,6 @@ static enum AVPixelFormat get_format_callback(struct AVCodecContext *s, const en
static void deconfigure(struct state_libavcodec_decompress *s)
{
av_parser_close(s->parser);
s->parser = NULL;
if(s->codec_ctx) {
lavd_flush(s->codec_ctx);
avcodec_free_context(&s->codec_ctx);
@@ -352,10 +349,6 @@ static bool configure_with(struct state_libavcodec_decompress *s,
if (dec->codec_callback) {
dec->codec_callback();
}
s->parser = av_parser_init(dec->avcodec_id);
if (s->parser == NULL) {
log_msg(LOG_LEVEL_WARNING, MOD_NAME "Cannot create parser!\n");
}
// priority list of decoders that can be used for the codec
const AVCodec *usable_decoders[DEC_LEN] = { NULL };
@@ -977,60 +970,28 @@ static bool
decode_frame(struct state_libavcodec_decompress *s, unsigned char *src,
int src_len)
{
int ret = 0;
bool frame_decoded = false;
const char *dec_err_pref = MOD_NAME;
while (true) {
const bool eof = src_len == 0;
if (s->parser == NULL) {
s->pkt->data = src;
s->pkt->size = src_len;
ret = src_len;
} else {
ret = av_parser_parse2(s->parser, s->codec_ctx,
&s->pkt->data, &s->pkt->size,
src, src_len, AV_NOPTS_VALUE,
AV_NOPTS_VALUE, 0);
if (ret < 0) {
dec_err_pref = MOD_NAME "av_parser_parse2 - ";
break;
}
}
src += ret;
src_len -= ret;
if (s->pkt->size == 0) {
if (eof) {
break;
}
continue;
}
ret = avcodec_send_packet(s->codec_ctx, s->pkt);
if (ret != 0 && ret != AVERROR(EAGAIN)) {
dec_err_pref = MOD_NAME "send - ";
break;
}
// we output to tmp_frame because even if receive fails,
// it overrides previous potentially valid frame
while ((ret = avcodec_receive_frame(s->codec_ctx,
s->tmp_frame)) == 0) {
if (frame_decoded) {
log_msg(LOG_LEVEL_WARNING, MOD_NAME
"Multiple frames decoded at once!\n");
}
frame_decoded = true;
SWAP_PTR(s->frame, s->tmp_frame);
}
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
continue;
bool frame_decoded = false;
s->pkt->data = src;
s->pkt->size = src_len;
int ret = avcodec_send_packet(s->codec_ctx, s->pkt);
if (ret != 0 && ret != AVERROR(EAGAIN)) {
handle_lavd_error(MOD_NAME "send - ", s, ret);
return false;
}
// we output to tmp_frame because even if receive fails,
// it overrides previous potentially valid frame
while ((ret = avcodec_receive_frame(s->codec_ctx, s->tmp_frame)) == 0) {
if (frame_decoded) {
log_msg(LOG_LEVEL_WARNING,
MOD_NAME "Multiple frames decoded at once!\n");
}
frame_decoded = true;
SWAP_PTR(s->frame, s->tmp_frame);
}
if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
handle_lavd_error(MOD_NAME "recv - ", s, ret);
}
if (frame_decoded) {
return true;
}
handle_lavd_error(dec_err_pref, s, ret);
return false;
return frame_decoded;
}
static decompress_status libavcodec_decompress(void *state, unsigned char *dst, unsigned char *src,
@@ -1065,11 +1026,7 @@ static decompress_status libavcodec_decompress(void *state, unsigned char *dst,
time_ns_t t0 = get_time_in_ns();
if (!decode_frame(s, src, src_len)) {
if (s->parser) {
log_msg(LOG_LEVEL_DEBUG,
MOD_NAME "Parsed %c frame but not decoded.\n",
av_get_picture_type_char(s->parser->pict_type));
}
log_msg(LOG_LEVEL_DEBUG, MOD_NAME "No frame was decoded!\n");
return DECODER_NO_FRAME;
}
s->consecutive_failed_decodes = 0;