Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions lib/upipe-framers/upipe_h264_framer.c
Original file line number Diff line number Diff line change
Expand Up @@ -2402,6 +2402,16 @@ static void upipe_h264f_work_annexb(struct upipe *upipe, struct upump **upump_p)
break;
size_t start_size = !prev ? 5 : 4;

if (unlikely(upipe_h264f->au_size < start_size)) {
/* The start code overlaps a previously flushed boundary (stale
* scan context): discard it and rescan from a clean state. */
upipe_warn(upipe, "discarding start code spanning a flush");
upipe_h264f->au_size = 0;
upipe_h264f->au_last_nal_offset = -1;
upipe_h264f->scan_context = UINT32_MAX;
continue;
}

upipe_h264f->au_size -= start_size;
upipe_h264f_end_annexb(upipe, upump_p);

Expand All @@ -2421,12 +2431,16 @@ static void upipe_h264f_work_annexb(struct upipe *upipe, struct upump **upump_p)
upipe_h264f_begin_annexb(upipe, upump_p);
}

if (!upipe_h264f->complete_input || !upipe_h264f->au_size)
if (!upipe_h264f->complete_input || !upipe_h264f->au_size ||
upipe_h264f->next_uref == NULL)
return;

upipe_h264f_end_annexb(upipe, upump_p);
upipe_h264f_output_annexb(upipe, upump_p);
upipe_h264f->au_last_nal_offset = -1;
/* The flush consumes up to the end of the stream, so the scan context
* must not be carried over to the next input uref. */
upipe_h264f->scan_context = UINT32_MAX;
}

/** @internal @This prepares a raw access unit.
Expand Down Expand Up @@ -2868,7 +2882,8 @@ static void upipe_h264f_free(struct upipe *upipe)

/* Output any buffered frame. */
if (upipe_h264f->encaps_input == UREF_H26X_ENCAPS_ANNEXB &&
!upipe_h264f->complete_input && upipe_h264f->au_size) {
!upipe_h264f->complete_input && upipe_h264f->au_size &&
upipe_h264f->next_uref != NULL) {
upipe_h264f_end_annexb(upipe, NULL);
upipe_h264f_output_annexb(upipe, NULL);
}
Expand Down
19 changes: 17 additions & 2 deletions lib/upipe-framers/upipe_h265_framer.c
Original file line number Diff line number Diff line change
Expand Up @@ -2602,6 +2602,16 @@ static void upipe_h265f_work_annexb(struct upipe *upipe, struct upump **upump_p)
break;
size_t start_size = !prev ? 6 : 5;

if (unlikely(upipe_h265f->au_size < start_size)) {
/* The start code overlaps a previously flushed boundary (stale
* scan context): discard it and rescan from a clean state. */
upipe_warn(upipe, "discarding start code spanning a flush");
upipe_h265f->au_size = 0;
upipe_h265f->au_last_nal_offset = -1;
upipe_h265f->scan_context = UINT32_MAX;
continue;
}

upipe_h265f->au_size -= start_size;
upipe_h265f_end_annexb(upipe, upump_p);

Expand All @@ -2621,12 +2631,16 @@ static void upipe_h265f_work_annexb(struct upipe *upipe, struct upump **upump_p)
upipe_h265f_begin_annexb(upipe, upump_p);
}

if (!upipe_h265f->complete_input || !upipe_h265f->au_size)
if (!upipe_h265f->complete_input || !upipe_h265f->au_size ||
upipe_h265f->next_uref == NULL)
return;

upipe_h265f_end_annexb(upipe, upump_p);
upipe_h265f_output_annexb(upipe, upump_p);
upipe_h265f->au_last_nal_offset = -1;
/* The flush consumes up to the end of the stream, so the scan context
* must not be carried over to the next input uref. */
upipe_h265f->scan_context = UINT32_MAX;
}

/** @internal @This works on incoming frames in NALU format (supposedly
Expand Down Expand Up @@ -2990,7 +3004,8 @@ static void upipe_h265f_free(struct upipe *upipe)

/* Output any buffered frame. */
if (upipe_h265f->encaps_input == UREF_H26X_ENCAPS_ANNEXB &&
!upipe_h265f->complete_input && upipe_h265f->au_size) {
!upipe_h265f->complete_input && upipe_h265f->au_size &&
upipe_h265f->next_uref != NULL) {
upipe_h265f_end_annexb(upipe, NULL);
upipe_h265f_output_annexb(upipe, NULL);
}
Expand Down
26 changes: 23 additions & 3 deletions lib/upipe-framers/upipe_mpgv_framer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1082,10 +1082,17 @@ static struct uref *upipe_mpgvf_handle_frame(struct upipe *upipe)
return NULL;
}

if (unlikely(upipe_mpgvf->next_frame_offset == -1)) {
/* No picture start code was found (e.g. a trailing sequence or GOP
* header flushed at end of stream): this is not a decodable frame. */
upipe_mpgvf_consume_uref_stream(upipe, upipe_mpgvf->next_frame_size);
return NULL;
}

/* The PTS can be updated up to the first octet of the picture start code,
* so any preceding structure must be extracted before, so that the PTS
* can be properly promoted and taken into account. */
if (upipe_mpgvf->next_frame_offset) {
if (upipe_mpgvf->next_frame_offset > 0) {
uref = upipe_mpgvf_extract_uref_stream(upipe,
upipe_mpgvf->next_frame_offset);
if (unlikely(uref == NULL)) {
Expand Down Expand Up @@ -1270,6 +1277,16 @@ static void upipe_mpgvf_work(struct upipe *upipe, struct upump **upump_p)
if (!upipe_mpgvf_find(upipe, &start, &next))
break;

if (unlikely(upipe_mpgvf->next_frame_size < 4)) {
/* The start code overlaps a previously flushed boundary (stale
* scan context): discard it and rescan from a clean state. */
upipe_warn(upipe, "discarding start code spanning a flush");
upipe_mpgvf->next_frame_size = 0;
upipe_mpgvf->scan_context = UINT32_MAX;
upipe_mpgvf_reset(upipe);
continue;
}

if (unlikely(!upipe_mpgvf->acquired)) {
bool discard = upipe_mpgvf->next_frame_size > 4;
if (discard) {
Expand Down Expand Up @@ -1386,12 +1403,15 @@ static void upipe_mpgvf_work(struct upipe *upipe, struct upump **upump_p)
upipe_mpgvf_output_frame(upipe, uref, upump_p);
}

if (!upipe_mpgvf->complete_input || !upipe_mpgvf->next_frame_size)
if (!upipe_mpgvf->complete_input || !upipe_mpgvf->next_frame_size || upipe_mpgvf->next_uref == NULL)
return;

struct uref *uref = upipe_mpgvf_handle_frame(upipe);
upipe_mpgvf_reset(upipe);
upipe_mpgvf->next_frame_size = 0;
/* The flush consumes up to the end of the stream, so the scan context
* must not be carried over to the next input uref. */
upipe_mpgvf->scan_context = UINT32_MAX;

if (uref == NULL)
return;
Expand Down Expand Up @@ -1606,7 +1626,7 @@ static void upipe_mpgvf_free(struct upipe *upipe)
struct upipe_mpgvf *upipe_mpgvf = upipe_mpgvf_from_upipe(upipe);

/* Output any buffered frame. */
if (upipe_mpgvf->next_frame_size) {
if (upipe_mpgvf->next_frame_size && upipe_mpgvf->next_uref != NULL) {
struct uref *uref = upipe_mpgvf_handle_frame(upipe);
if (uref != NULL)
upipe_mpgvf_output_frame(upipe, uref, NULL);
Expand Down
Loading