diff --git a/libavcodec/h263_parser.c b/libavcodec/h263_parser.c index e05b8a4ac4..7a742caa80 100644 --- a/libavcodec/h263_parser.c +++ b/libavcodec/h263_parser.c @@ -25,9 +25,16 @@ */ #include "parser.h" +#if FF_API_FLAG_TRUNCATED +/* Nuke this header when removing FF_API_FLAG_TRUNCATED */ #include "h263_parser.h" int ff_h263_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){ +#else + +static int h263_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) +{ +#endif int vop_found, i; uint32_t state; @@ -73,7 +80,11 @@ static int h263_parse(AVCodecParserContext *s, if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { next = buf_size; } else { +#if FF_API_FLAG_TRUNCATED next= ff_h263_find_frame_end(pc, buf, buf_size); +#else + next = h263_find_frame_end(pc, buf, buf_size); +#endif if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { *poutbuf = NULL; diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 1aacd07e41..58e03c05d4 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -168,6 +168,7 @@ av_cold void ff_mpeg12_init_vlcs(void) ff_thread_once(&init_static_once, mpeg12_init_vlcs); } +#if FF_API_FLAG_TRUNCATED /** * Find the end of the current frame in the bitstream. * @return the position of the first byte of the next frame, or -1 @@ -231,6 +232,7 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, pc->state = state; return END_NOT_FOUND; } +#endif #define MAX_INDEX (64 - 1) diff --git a/libavcodec/mpeg12.h b/libavcodec/mpeg12.h index a7b94c132a..fb2b37e7c8 100644 --- a/libavcodec/mpeg12.h +++ b/libavcodec/mpeg12.h @@ -70,7 +70,9 @@ int ff_mpeg1_decode_block_intra(GetBitContext *gb, int16_t *block, int index, int qscale); void ff_mpeg1_clean_buffers(MpegEncContext *s); +#if FF_API_FLAG_TRUNCATED int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s); +#endif void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number); void ff_mpeg1_encode_mb(MpegEncContext *s, int16_t block[8][64], diff --git a/libavcodec/mpeg4video_parser.c b/libavcodec/mpeg4video_parser.c index 1b0e2555da..c68c966259 100644 --- a/libavcodec/mpeg4video_parser.c +++ b/libavcodec/mpeg4video_parser.c @@ -26,7 +26,10 @@ #include "parser.h" #include "mpegvideo.h" #include "mpeg4video.h" +#if FF_API_FLAG_TRUNCATED +/* Nuke this header when removing FF_API_FLAG_TRUNCATED */ #include "mpeg4video_parser.h" +#endif struct Mp4vParseContext { ParseContext pc; @@ -34,7 +37,15 @@ struct Mp4vParseContext { int first_picture; }; +#if FF_API_FLAG_TRUNCATED int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) +#else +/** + * Find the end of the current frame in the bitstream. + * @return the position of the first byte of the next frame, or -1 + */ +static int mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) +#endif { int vop_found, i; uint32_t state; @@ -138,7 +149,11 @@ static int mpeg4video_parse(AVCodecParserContext *s, if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { next = buf_size; } else { +#if FF_API_FLAG_TRUNCATED next = ff_mpeg4_find_frame_end(pc, buf, buf_size); +#else + next = mpeg4_find_frame_end(pc, buf, buf_size); +#endif if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { *poutbuf = NULL; diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 8dfa904577..e90669b776 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -49,7 +49,9 @@ #include "pixblockdsp.h" #include "put_bits.h" #include "ratecontrol.h" +#if FF_API_FLAG_TRUNCATED #include "parser.h" +#endif #include "mpegutils.h" #include "mpeg12data.h" #include "qpeldsp.h" diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c index 7864224643..39b9f2e43a 100644 --- a/libavcodec/mpegvideo_parser.c +++ b/libavcodec/mpegvideo_parser.c @@ -31,6 +31,72 @@ struct MpvParseContext { int width, height; }; +#if !FF_API_FLAG_TRUNCATED +/** + * Find the end of the current frame in the bitstream. + * @return the position of the first byte of the next frame, or -1 + */ +static int mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, + int buf_size, AVCodecParserContext *s) +{ + int i; + uint32_t state = pc->state; + + /* EOF considered as end of frame */ + if (buf_size == 0) + return 0; + +/* + 0 frame start -> 1/4 + 1 first_SEQEXT -> 0/2 + 2 first field start -> 3/0 + 3 second_SEQEXT -> 2/0 + 4 searching end +*/ + + for (i = 0; i < buf_size; i++) { + av_assert1(pc->frame_start_found >= 0 && pc->frame_start_found <= 4); + if (pc->frame_start_found & 1) { + if (state == EXT_START_CODE && (buf[i] & 0xF0) != 0x80) + pc->frame_start_found--; + else if (state == EXT_START_CODE + 2) { + if ((buf[i] & 3) == 3) + pc->frame_start_found = 0; + else + pc->frame_start_found = (pc->frame_start_found + 1) & 3; + } + state++; + } else { + i = avpriv_find_start_code(buf + i, buf + buf_size, &state) - buf - 1; + if (pc->frame_start_found == 0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE) { + i++; + pc->frame_start_found = 4; + } + if (state == SEQ_END_CODE) { + pc->frame_start_found = 0; + pc->state = -1; + return i + 1; + } + if (pc->frame_start_found == 2 && state == SEQ_START_CODE) + pc->frame_start_found = 0; + if (pc->frame_start_found < 4 && state == EXT_START_CODE) + pc->frame_start_found++; + if (pc->frame_start_found == 4 && (state & 0xFFFFFF00) == 0x100) { + if (state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE) { + pc->frame_start_found = 0; + pc->state = -1; + return i - 3; + } + } + if (pc->frame_start_found == 0 && s && state == PICTURE_START_CODE) { + ff_fetch_timestamp(s, i - 3, 1, i > 3); + } + } + } + pc->state = state; + return END_NOT_FOUND; +} +#endif static void mpegvideo_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx, @@ -192,7 +258,11 @@ static int mpegvideo_parse(AVCodecParserContext *s, if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ next= buf_size; }else{ +#if FF_API_FLAG_TRUNCATED next= ff_mpeg1_find_frame_end(pc, buf, buf_size, s); +#else + next = mpeg1_find_frame_end(pc, buf, buf_size, s); +#endif if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { *poutbuf = NULL;