[FFmpeg-devel] [PATCH v1] avcodec/h264_mp4toannexb_bsf: force sps/pps writing before the first pict
Jun Li
junli1026 at gmail.com
Sat Aug 17 02:13:22 EEST 2019
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
More information about the ffmpeg-devel
mailing list