mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-21 09:40:18 +00:00
lavd video: removed parser
This effectively reverts recent commitd70e2fb3(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 (commit6e9a4142), 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 commitc57f2fc5, it is perhaps best to remove this stuff altogether.
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user