open-h264: Fix frame parsing

pull/6/head
Andri Yngvason 2022-04-10 16:13:54 +00:00
parent 0b757d6623
commit 09c851750e
1 changed files with 21 additions and 6 deletions

View File

@ -89,8 +89,6 @@ static struct open_h264_context* open_h264_context_create(
if (!context->parser)
goto failure;
context->parser->flags = PARSER_FLAG_COMPLETE_FRAMES;
context->codec_ctx = avcodec_alloc_context3(codec);
if (!context->codec_ctx)
goto failure;
@ -176,6 +174,8 @@ void open_h264_destroy(struct open_h264* self)
static bool decode_frame(struct open_h264_context* context, AVFrame* frame,
AVPacket* packet)
{
av_frame_unref(frame);
int rc;
rc = avcodec_send_packet(context->codec_ctx, packet);
@ -204,6 +204,14 @@ static bool decode_frame(struct open_h264_context* context, AVFrame* frame,
return true;
}
static int parse_elementary_stream(struct open_h264_context* context,
AVPacket* packet, const uint8_t* src, uint32_t length)
{
return av_parser_parse2(context->parser, context->codec_ctx,
&packet->data, &packet->size, src, length,
AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
}
struct AVFrame* open_h264_decode_rect(struct open_h264* self,
rfbFramebufferUpdateRectHeader* msg)
{
@ -241,18 +249,25 @@ struct AVFrame* open_h264_decode_rect(struct open_h264* self,
if (!ReadFromRFBServer(self->client, data, length))
goto failure;
const uint8_t* dp = (const uint8_t*)data;
uint8_t* dp = (uint8_t*)data;
while (length > 0) {
int rc = av_parser_parse2(context->parser, context->codec_ctx,
&packet->data, &packet->size, dp, length,
AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
int rc = parse_elementary_stream(context, packet, dp, length);
if (rc < 0)
goto failure;
dp += rc;
length -= rc;
// The h264 elementary stream doesn't have end-markers, so the
// parser doesn't know where the frame ends. This flushes it:
if (packet->size == 0 && length == 0) {
int rc = parse_elementary_stream(context, packet, dp,
length);
if (rc < 0)
goto failure;
}
// If we get multiple frames per rect, there's no point in
// rendering them all, so we just return the last one.
if (packet->size != 0)