If true, this skips the for loop at the beginning of avpriv_find_start_code().
If the state/start_code input is a local variable and only one buffer is used, then no history is needed. In loops and inline functions: if ignoring history, don't initialize start_code, so it isn't reset twice each time. cbs_mpeg2.c needs further changes to use output_only = true. Use output_only = 0 for no functional change. For example, if the state/start_code is passed into the function calling avpriv_find_start_code(). --- libavcodec/cavsdec.c | 2 +- libavcodec/cbs_mpeg2.c | 4 ++-- libavcodec/extract_extradata_bsf.c | 4 ++-- libavcodec/h264_parser.c | 2 +- libavcodec/internal.h | 9 ++++++++- libavcodec/mpeg12.c | 2 +- libavcodec/mpeg12dec.c | 9 ++++----- libavcodec/mpeg4_unpack_bframes_bsf.c | 3 +-- libavcodec/mpegvideo_parser.c | 5 ++--- libavcodec/remove_extradata_bsf.c | 8 ++++---- libavcodec/utils.c | 14 +++++++++++++- libavcodec/vc1_common.h | 4 ++-- libavformat/avidec.c | 6 +++--- libavformat/avs2dec.c | 2 +- libavformat/avs3dec.c | 2 +- libavformat/cavsvideodec.c | 2 +- libavformat/mpegtsenc.c | 4 ++-- libavformat/mpegvideodec.c | 2 +- libavformat/mxfenc.c | 2 +- libavformat/rtpenc_mpv.c | 4 ++-- 20 files changed, 53 insertions(+), 37 deletions(-) diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index a62177d520..c4c78cd534 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -1248,7 +1248,7 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, buf_ptr = buf; buf_end = buf + buf_size; for(;;) { - buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &stc); + buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &stc, 1); if (!avpriv_start_code_is_valid(stc) || buf_ptr == buf_end) { if (!h->stc) av_log(h->avctx, AV_LOG_WARNING, "no frame decoded\n"); diff --git a/libavcodec/cbs_mpeg2.c b/libavcodec/cbs_mpeg2.c index eb45929132..d41477620e 100644 --- a/libavcodec/cbs_mpeg2.c +++ b/libavcodec/cbs_mpeg2.c @@ -151,7 +151,7 @@ static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx, int err, i, final = 0; start = avpriv_find_start_code(frag->data, frag->data + frag->data_size, - &start_code); + &start_code, 1); if (!avpriv_start_code_is_valid(start_code)) { // No start code found. return AVERROR_INVALIDDATA; @@ -169,7 +169,7 @@ static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx, } end = avpriv_find_start_code(start--, frag->data + frag->data_size, - &start_code); + &start_code, 0); // start points to the byte containing the start_code_identifier // (may be the last byte of fragment->data); end points to the byte diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c index 4df1c97139..1a3ddceff2 100644 --- a/libavcodec/extract_extradata_bsf.c +++ b/libavcodec/extract_extradata_bsf.c @@ -237,7 +237,7 @@ static int extract_extradata_vc1(AVBSFContext *ctx, AVPacket *pkt, int has_extradata = 0, extradata_size = 0; while (ptr < end) { - ptr = avpriv_find_start_code(ptr, end, &state); + ptr = avpriv_find_start_code(ptr, end, &state, 1); if (state == VC1_CODE_SEQHDR || state == VC1_CODE_ENTRYPOINT) { has_extradata = 1; } else if (has_extradata && avpriv_start_code_is_valid(state)) { @@ -300,7 +300,7 @@ static int extract_extradata_mpeg4(AVBSFContext *ctx, AVPacket *pkt, uint32_t state = UINT32_MAX; while (ptr < end) { - ptr = avpriv_find_start_code(ptr, end, &state); + ptr = avpriv_find_start_code(ptr, end, &state, 1); if (state == 0x1B3 || state == 0x1B6) { if (ptr - pkt->data > 4) { *size = ptr - 4 - pkt->data; diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index 4002bcad77..0ca411c592 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -72,7 +72,7 @@ static int find_start_code(const uint8_t *buf, int buf_size, { uint32_t state = -1; - buf_index = avpriv_find_start_code(buf + buf_index, buf + next_avc + 1, &state) - buf - 1; + buf_index = avpriv_find_start_code(buf + buf_index, buf + next_avc + 1, &state, 1) - buf - 1; return FFMIN(buf_index, buf_size); } diff --git a/libavcodec/internal.h b/libavcodec/internal.h index dadd8d4a10..57e2816a95 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -309,6 +309,9 @@ static av_always_inline int avpriv_start_code_is_valid(uint32_t start_code) { * By preserving the <b>@p start_code</b> value between subsequent calls, the caller can * detect start codes across buffer boundaries. * + * If <b>@p output_only</b> is true, <b>@p start_code</b> is reset to <b>@c ~0 </b> + * if @f$ p - end < 4 @f$. + * * @param[in] p A pointer to the start of the memory buffer to scan. * @param[in] end A pointer to the past-the-end memory address for the buffer * given by @p p. <b>@p p</b> must be ≤ <b>@p end</b>. @@ -321,12 +324,16 @@ static av_always_inline int avpriv_start_code_is_valid(uint32_t start_code) { * start code (the 4 bytes prior to the returned value, * using the input history if @f$ p - end < 4 @f$). * + * @param[in] output_only Boolean that if true makes <b>@p start_code</b> an + * output only parameter. + * * @return A pointer to the memory address following the found start code, or <b>@p end</b> * if no start code was found. */ const uint8_t *avpriv_find_start_code(const uint8_t *p, const uint8_t * const end, - uint32_t * const start_code); + uint32_t * const start_code, + int output_only); int avpriv_codec_get_cap_skip_frame_fill_param(const AVCodec *codec); diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index e45bc74479..d788aeb9e2 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -203,7 +203,7 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, } state++; } else { - i = avpriv_find_start_code(buf + i, buf + buf_size, &state) - buf - 1; + i = avpriv_find_start_code(buf + i, buf + buf_size, &state, 0) - buf - 1; if (pc->frame_start_found == 0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE) { i++; pc->frame_start_found = 4; diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index 6b0b84ae64..cad17d1b1a 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -1771,7 +1771,7 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y, if (avctx->hwaccel && avctx->hwaccel->decode_slice) { const uint8_t *buf_end, *buf_start = *buf - 4; /* include start_code */ uint32_t start_code = ~0; - buf_end = avpriv_find_start_code(buf_start + 2, *buf + buf_size, &start_code); + buf_end = avpriv_find_start_code(buf_start + 2, *buf + buf_size, &start_code, 1); if (buf_end < *buf + buf_size) buf_end -= 4; s->mb_y = mb_y; @@ -2020,8 +2020,7 @@ static int slice_decode_thread(AVCodecContext *c, void *arg) if (s->mb_y == s->end_mb_y) return 0; - start_code = -1; - buf = avpriv_find_start_code(buf, s->gb.buffer_end, &start_code); + buf = avpriv_find_start_code(buf, s->gb.buffer_end, &start_code, 1); if (start_code < SLICE_MIN_START_CODE || start_code > SLICE_MAX_START_CODE) return AVERROR_INVALIDDATA; mb_y = start_code - SLICE_MIN_START_CODE; @@ -2475,8 +2474,8 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture, for (;;) { /* find next start code */ - uint32_t start_code = -1; - buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &start_code); + uint32_t start_code; + buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &start_code, 1); if (!avpriv_start_code_is_valid(start_code)) { if (!skip_frame) { if (HAVE_THREADS && diff --git a/libavcodec/mpeg4_unpack_bframes_bsf.c b/libavcodec/mpeg4_unpack_bframes_bsf.c index 6f8595713d..37fb0e4b66 100644 --- a/libavcodec/mpeg4_unpack_bframes_bsf.c +++ b/libavcodec/mpeg4_unpack_bframes_bsf.c @@ -36,8 +36,7 @@ static void scan_buffer(const uint8_t *buf, int buf_size, const uint8_t *end = buf + buf_size, *pos = buf; while (pos < end) { - startcode = -1; - pos = avpriv_find_start_code(pos, end, &startcode); + pos = avpriv_find_start_code(pos, end, &startcode, 1); if (startcode == USER_DATA_STARTCODE && pos_p) { /* check if the (DivX) userdata string ends with 'p' (packed) */ diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c index f0897e7e2c..14e350eaea 100644 --- a/libavcodec/mpegvideo_parser.c +++ b/libavcodec/mpegvideo_parser.c @@ -68,7 +68,7 @@ static int mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, } state++; } else { - i = avpriv_find_start_code(buf + i, buf + buf_size, &state) - buf - 1; + i = avpriv_find_start_code(buf + i, buf + buf_size, &state, 0) - buf - 1; if (pc->frame_start_found == 0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE) { i++; pc->frame_start_found = 4; @@ -120,8 +120,7 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, s->repeat_pict = 0; while (buf < buf_end) { - start_code= -1; - buf= avpriv_find_start_code(buf, buf_end, &start_code); + buf = avpriv_find_start_code(buf, buf_end, &start_code, 1); bytes_left = buf_end - buf; switch(start_code) { case PICTURE_START_CODE: diff --git a/libavcodec/remove_extradata_bsf.c b/libavcodec/remove_extradata_bsf.c index 0e42174912..46e914053d 100644 --- a/libavcodec/remove_extradata_bsf.c +++ b/libavcodec/remove_extradata_bsf.c @@ -70,7 +70,7 @@ static int h264_split(const uint8_t *buf, int buf_size) int nalu_type; while (ptr < end) { - ptr = avpriv_find_start_code(ptr, end, &state); + ptr = avpriv_find_start_code(ptr, end, &state, 1); if (!avpriv_start_code_is_valid(state)) break; nalu_type = state & 0x1F; @@ -108,7 +108,7 @@ static int hevc_split(const uint8_t *buf, int buf_size) int nut; while (ptr < end) { - ptr = avpriv_find_start_code(ptr, end, &state); + ptr = avpriv_find_start_code(ptr, end, &state, 1); if (!avpriv_start_code_is_valid(state)) break; nut = (state >> 1) & 0x3F; @@ -151,7 +151,7 @@ static int mpeg4video_split(const uint8_t *buf, int buf_size) uint32_t state = -1; while (ptr < end) { - ptr = avpriv_find_start_code(ptr, end, &state); + ptr = avpriv_find_start_code(ptr, end, &state, 1); if (state == 0x1B3 || state == 0x1B6) return ptr - 4 - buf; } @@ -166,7 +166,7 @@ static int vc1_split(const uint8_t *buf, int buf_size) int charged = 0; while (ptr < end) { - ptr = avpriv_find_start_code(ptr, end, &state); + ptr = avpriv_find_start_code(ptr, end, &state, 1); if (state == VC1_CODE_SEQHDR || state == VC1_CODE_ENTRYPOINT) { charged = 1; } else if (charged && avpriv_start_code_is_valid(state)) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index cf92d29f67..da057bad3e 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -942,9 +942,20 @@ void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, in const uint8_t *avpriv_find_start_code(const uint8_t *av_restrict p, const uint8_t * const end, - uint32_t * const av_restrict start_code) + uint32_t * const av_restrict start_code, + const int output_only) { av_assert0(p <= end); + if (output_only) { + // minimum length for a start code + if (p + 4 > end) { + *start_code = ~0; // set to an invalid start code + return end; + } + + p += 3; // offset for negative indices in while loop + } + else { if (p >= end) return end; @@ -958,6 +969,7 @@ const uint8_t *avpriv_find_start_code(const uint8_t *av_restrict p, return p; } // p is now properly incremented for the negative indices in the while loop + } /* with memory address increasing left to right, we are looking for (in hexadecimal): * 00 00 01 XX diff --git a/libavcodec/vc1_common.h b/libavcodec/vc1_common.h index 483f86a4ee..453dec34c6 100644 --- a/libavcodec/vc1_common.h +++ b/libavcodec/vc1_common.h @@ -57,8 +57,8 @@ enum Profile { static av_always_inline const uint8_t* find_next_marker(const uint8_t *src, const uint8_t *end) { if (end - src >= 4) { - uint32_t mrk = 0xFFFFFFFF; - src = avpriv_find_start_code(src, end, &mrk); + uint32_t mrk; + src = avpriv_find_start_code(src, end, &mrk, 1); if (avpriv_start_code_is_valid(mrk)) return src - 4; } diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 86f857b1e3..674f313e84 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -1530,12 +1530,12 @@ resync: if (index >= 0 && e->timestamp == ast->frame_offset) { if (index == sti->nb_index_entries-1) { int key=1; - uint32_t state=-1; if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4) { const uint8_t *ptr = pkt->data, *end = ptr + FFMIN(size, 256); while (ptr < end) { - ptr = avpriv_find_start_code(ptr, end, &state); - if (state == 0x1B6 && ptr < end) { + uint32_t start_code; + ptr = avpriv_find_start_code(ptr, end, &start_code, 1); + if (start_code == 0x1B6 && ptr < end) { key = !(*ptr & 0xC0); break; } diff --git a/libavformat/avs2dec.c b/libavformat/avs2dec.c index bdeb746fc7..f2349dde45 100644 --- a/libavformat/avs2dec.c +++ b/libavformat/avs2dec.c @@ -41,7 +41,7 @@ static int avs2_probe(const AVProbeData *p) } while (ptr < end) { - ptr = avpriv_find_start_code(ptr, end, &code); + ptr = avpriv_find_start_code(ptr, end, &code, 1); if (avpriv_start_code_is_valid(code)) { state = code & 0xFF; if (AVS2_ISUNIT(state)) { diff --git a/libavformat/avs3dec.c b/libavformat/avs3dec.c index 2daccd3d15..2238193ff4 100644 --- a/libavformat/avs3dec.c +++ b/libavformat/avs3dec.c @@ -35,7 +35,7 @@ static int avs3video_probe(const AVProbeData *p) int ret = 0; while (ptr < end) { - ptr = avpriv_find_start_code(ptr, end, &code); + ptr = avpriv_find_start_code(ptr, end, &code, 1); if (avpriv_start_code_is_valid(code)) { state = code & 0xFF; if (state < AVS3_SEQ_START_CODE) { diff --git a/libavformat/cavsvideodec.c b/libavformat/cavsvideodec.c index 1d007708cc..8f4004acea 100644 --- a/libavformat/cavsvideodec.c +++ b/libavformat/cavsvideodec.c @@ -37,7 +37,7 @@ static int cavsvideo_probe(const AVProbeData *p) const uint8_t *ptr = p->buf, *end = p->buf + p->buf_size; while (ptr < end) { - ptr = avpriv_find_start_code(ptr, end, &code); + ptr = avpriv_find_start_code(ptr, end, &code, 1); if (avpriv_start_code_is_valid(code)) { if(code < CAVS_SEQ_START_CODE) { /* slices have to be consecutive */ diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 92b4cc8087..483c65be17 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -1881,7 +1881,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) extradd = 0; do { - p = avpriv_find_start_code(p, buf_end, &state); + p = avpriv_find_start_code(p, buf_end, &state, 1); av_log(s, AV_LOG_TRACE, "nal %"PRId32"\n", state & 0x1f); if ((state & 0x1f) == 7) extradd = 0; @@ -1947,7 +1947,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) extradd = 0; do { - p = avpriv_find_start_code(p, buf_end, &state); + p = avpriv_find_start_code(p, buf_end, &state, 1); av_log(s, AV_LOG_TRACE, "nal %"PRId32"\n", (state & 0x7e)>>1); if ((state & 0x7e) == 2*32) extradd = 0; diff --git a/libavformat/mpegvideodec.c b/libavformat/mpegvideodec.c index a9829dc1df..840d3565af 100644 --- a/libavformat/mpegvideodec.c +++ b/libavformat/mpegvideodec.c @@ -43,7 +43,7 @@ static int mpegvideo_probe(const AVProbeData *p) int j; while (ptr < end) { - ptr = avpriv_find_start_code(ptr, end, &code); + ptr = avpriv_find_start_code(ptr, end, &code, 1); if (avpriv_start_code_is_valid(code)) { switch(code){ case SEQ_START_CODE: diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 5e068c8220..8cec44e89c 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -2242,7 +2242,7 @@ static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st, int i, frame_size, slice_type, has_sps = 0, intra_only = 0, ret; for (;;) { - buf = avpriv_find_start_code(buf, buf_end, &state); + buf = avpriv_find_start_code(buf, buf_end, &state, 1); if (buf >= buf_end) break; diff --git a/libavformat/rtpenc_mpv.c b/libavformat/rtpenc_mpv.c index 91c07574bb..3c7168c482 100644 --- a/libavformat/rtpenc_mpv.c +++ b/libavformat/rtpenc_mpv.c @@ -54,8 +54,8 @@ void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size) r1 = buf1; while (1) { - uint32_t start_code = ~0; - r = avpriv_find_start_code(r1, end, &start_code); + uint32_t start_code; + r = avpriv_find_start_code(r1, end, &start_code, 1); if (avpriv_start_code_is_valid(start_code)) { /* New start code found */ if (start_code == 0x100) { -- 2.32.0 _______________________________________________ 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".