Hi,
This patch is trying to fix #6869.
The ticket has a h264 stream NOT starting with IDR, and all frames are I
frames.
And the mp4toannexb filter insert SPS/PPS before IDR, so leads to the
result that the output has no SPS/PPS.
The fix is just simply insert SPS/PPS before first picture, no matter what
type it is. Thanks.
Best Regards
-Jun
From 052674e9d4e2e6cf29141858b6cdc707fb75ecb1 Mon Sep 17 00:00:00 2001
From: Jun Li
Date: Fri, 16 Aug 2019 15:08:23 -0700
Subject: [PATCH v1] avcodec/h264_mp4toannexb_bsf: force sps/pps writing before
the first pict
Fix #6869, write sps/pps before the first picture nal, no matter what type
of picture it is.
---
libavcodec/h264_mp4toannexb_bsf.c | 15 ---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c
index fb3f24ea40..e616c4c210 100644
--- a/libavcodec/h264_mp4toannexb_bsf.c
+++ b/libavcodec/h264_mp4toannexb_bsf.c
@@ -36,6 +36,7 @@ typedef struct H264BSFContext {
uint8_t idr_sps_seen;
uint8_t idr_pps_seen;
int extradata_parsed;
+int first_pict;
} H264BSFContext;
static int alloc_and_copy(AVPacket *out,
@@ -160,6 +161,7 @@ static int h264_mp4toannexb_init(AVBSFContext *ctx)
s->idr_sps_seen = 0;
s->idr_pps_seen = 0;
s->extradata_parsed = 1;
+s->first_pict = 0;
} else {
av_log(ctx, AV_LOG_ERROR, "Invalid extradata size: %d\n", extra_size);
return AVERROR_INVALIDDATA;
@@ -207,6 +209,9 @@ static int h264_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *out)
buf += s->length_size;
unit_type = *buf & 0x1f;
+if (!s->first_pict && (unit_type == H264_NAL_IDR_SLICE || unit_type == H264_NAL_SLICE))
+s->first_pict = 1;
+
if (nal_size > buf_end - buf || nal_size < 0)
goto fail;
@@ -236,15 +241,15 @@ static int h264_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *out)
if (!s->new_idr && unit_type == H264_NAL_IDR_SLICE && (buf[1] & 0x80))
s->new_idr = 1;
-/* prepend only to the first type 5 NAL unit of an IDR picture, if no sps/pps are already present */
-if (s->new_idr && unit_type == H264_NAL_IDR_SLICE && !s->idr_sps_seen && !s->idr_pps_seen) {
+/* prepend only to the first type 5 NAL unit of an IDR picture or the first pict NAL of the entire stream, if no sps/pps are already present */
+if ((s->new_idr && unit_type == H264_NAL_IDR_SLICE || s->first_pict == 1) && !s->idr_sps_seen && !s->idr_pps_seen) {
if ((ret=alloc_and_copy(out,
ctx->par_out->extradata, ctx->par_out->extradata_size,
buf, nal_size, 1)) < 0)
goto fail;
s->new_idr = 0;
/* if only SPS has been seen, also insert PPS */
-} else if (s->new_idr && unit_type == H264_NAL_IDR_SLICE && s->idr_sps_seen && !s->idr_pps_seen) {
+} else if ((s->new_idr && unit_type == H264_NAL_IDR_SLICE || s->first_pict == 1) && s->idr_sps_seen && !s->idr_pps_seen) {
if (s->pps_offset == -1) {
av_log(ctx, AV_LOG_WARNING, "PPS not present in the stream, nor in AVCC, stream may be unreadable\n");
if ((ret = alloc_and_copy(out, NULL, 0, buf, nal_size, 0)) < 0)
@@ -263,6 +268,10 @@ static int h264_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *out)
}
}
+/* first picture has been found, set the flag to -1 */
+if (s->first_pict == 1)
+s->first_pict = -1;
+
next_nal:
buf+= nal_size;
cumul_size += nal_size + s->length_size;
--
2.17.1
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".