-
-
Save lu-zero/8340119adabb948adb1b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c | |
index 80bc46a..d651406 100644 | |
--- a/libavcodec/svq3.c | |
+++ b/libavcodec/svq3.c | |
@@ -75,6 +75,7 @@ typedef struct SVQ3Context { | |
H264Picture *cur_pic; | |
H264Picture *next_pic; | |
H264Picture *last_pic; | |
+ GetBitContext slice; | |
int halfpel_flag; | |
int thirdpel_flag; | |
int unknown_flag; | |
@@ -85,6 +86,8 @@ typedef struct SVQ3Context { | |
int h_edge_pos; | |
int v_edge_pos; | |
int last_frame_output; | |
+ int slice_size; | |
+ const uint8_t *slice_buf; | |
} SVQ3Context; | |
#define FULLPEL_MODE 1 | |
@@ -779,8 +782,11 @@ static int svq3_decode_slice_header(AVCodecContext *avctx) | |
const int mb_xy = sl->mb_xy; | |
int i, header; | |
unsigned slice_id; | |
+ int last_slice_size; | |
- header = get_bits(&h->gb, 8); | |
+ av_log(avctx, AV_LOG_INFO|AV_LOG_C(111), "slice start at %d/%d ", | |
+ get_bits_count(&s->slice) / 8, get_bits_count(&s->slice) % 8); | |
+ header = get_bits(&s->slice, 8); | |
if (((header & 0x9F) != 1 && (header & 0x9F) != 2) || (header & 0x60) == 0) { | |
/* TODO: what? */ | |
@@ -789,28 +795,35 @@ static int svq3_decode_slice_header(AVCodecContext *avctx) | |
} else { | |
int length = header >> 5 & 3; | |
- s->next_slice_index = get_bits_count(&h->gb) + | |
- 8 * show_bits(&h->gb, 8 * length) + | |
+ s->next_slice_index = get_bits_count(&s->slice) + | |
+ 8 * show_bits(&s->slice, 8 * length) + | |
8 * length; | |
+ av_log(avctx, AV_LOG_INFO|AV_LOG_C(121), "next %d/%d\n", s->next_slice_index / 8, s->next_slice_index % 8); | |
- if (s->next_slice_index > h->gb.size_in_bits) { | |
+ if (s->next_slice_index > s->slice.size_in_bits) { | |
av_log(avctx, AV_LOG_ERROR, "slice after bitstream end\n"); | |
return -1; | |
} | |
- h->gb.size_in_bits = s->next_slice_index - 8 * (length - 1); | |
- skip_bits(&h->gb, 8); | |
+ last_slice_size = s->slice_size; | |
+ s->slice_size = (s->next_slice_index - 8 * (length - 1)) >> 3; | |
+ skip_bits(&s->slice, 8); | |
+ | |
+ av_fast_malloc(&s->slice_buf, &last_slice_size, s->slice_size * 8 + AV_INPUT_BUFFER_PADDING_SIZE); | |
+ if(!s->slice_buf) | |
+ return AVERROR(ENOMEM); | |
+ memcpy((uint8_t *) s->slice_buf, (uint8_t *) &s->slice.buffer[get_bits_count(&s->slice) >> 3], s->slice_size); | |
if (s->watermark_key) { | |
- uint32_t header = AV_RL32(&h->gb.buffer[(get_bits_count(&h->gb) >> 3) + 1]); | |
- AV_WL32(&h->gb.buffer[(get_bits_count(&h->gb) >> 3) + 1], | |
- header ^ s->watermark_key); | |
+ uint32_t header = AV_RL32(&s->slice_buf[1]); | |
+ AV_WL32(&s->slice_buf[1], header ^ s->watermark_key); | |
} | |
if (length > 0) { | |
- memcpy((uint8_t *) &h->gb.buffer[get_bits_count(&h->gb) >> 3], | |
- &h->gb.buffer[h->gb.size_in_bits >> 3], length - 1); | |
+ memcpy((uint8_t *) &s->slice_buf[0], | |
+ &s->slice.buffer[s->slice_size], length - 1); | |
} | |
- skip_bits_long(&h->gb, 0); | |
+ init_get_bits(&h->gb, s->slice_buf, s->slice_size * 8 - 16); | |
+ skip_bits_long(&s->slice, 0); | |
} | |
if ((slice_id = svq3_get_ue_golomb(&h->gb)) >= 3) { | |
@@ -844,6 +857,7 @@ static int svq3_decode_slice_header(AVCodecContext *avctx) | |
while (get_bits1(&h->gb)) | |
skip_bits(&h->gb, 8); | |
+ skip_bits(&s->slice, get_bits_count(&h->gb)); | |
/* reset intra predictors and invalidate motion vector references */ | |
if (sl->mb_x > 0) { | |
@@ -890,6 +904,7 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) | |
if (!s->cur_pic->f || !s->last_pic->f || !s->next_pic->f) | |
return AVERROR(ENOMEM); | |
+ s->slice_size = 0; | |
if (ff_h264_decode_init(avctx) < 0) | |
return -1; | |
@@ -1152,8 +1167,8 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, | |
} | |
return 0; | |
} | |
- | |
- init_get_bits(&h->gb, buf, 8 * buf_size); | |
+ av_log(avctx, AV_LOG_INFO|AV_LOG_C(123), "Frame Start\n"); | |
+ init_get_bits(&s->slice, buf, 8 * buf_size); | |
sl->mb_x = sl->mb_y = sl->mb_xy = 0; | |
@@ -1269,19 +1284,23 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, | |
unsigned mb_type; | |
sl->mb_xy = sl->mb_x + sl->mb_y * h->mb_stride; | |
- if ((get_bits_count(&h->gb) + 7) >= h->gb.size_in_bits && | |
- ((get_bits_count(&h->gb) & 7) == 0 || | |
- show_bits(&h->gb, -get_bits_count(&h->gb) & 7) == 0)) { | |
- skip_bits(&h->gb, s->next_slice_index - get_bits_count(&h->gb)); | |
- h->gb.size_in_bits = 8 * buf_size; | |
+ if ((get_bits_left(&s->slice)) <= 7) { | |
+ av_log(avctx, AV_LOG_INFO|AV_LOG_C(143), "count %d left %d pad %d\n", | |
+ get_bits_count(&s->slice) & 7, get_bits_left(&s->slice), | |
+ show_bits(&s->slice, get_bits_left(&s->slice) & 7)); | |
- if (svq3_decode_slice_header(avctx)) | |
- return -1; | |
+ if (((get_bits_count(&s->slice) & 7) == 0 || | |
+ show_bits(&s->slice, get_bits_left(&s->slice) & 7) == 0)) { | |
+ skip_bits(&s->slice, s->next_slice_index - get_bits_count(&s->slice)); | |
+ | |
+ if (svq3_decode_slice_header(avctx)) | |
+ return -1; | |
+ } | |
/* TODO: support s->mb_skip_run */ | |
} | |
- mb_type = svq3_get_ue_golomb(&h->gb); | |
+ mb_type = svq3_get_ue_golomb(&s->slice); | |
if (h->pict_type == AV_PICTURE_TYPE_I) | |
mb_type += 8; | |
@@ -1323,6 +1342,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, | |
} else { | |
av_frame_unref(s->cur_pic->f); | |
} | |
+ av_log(avctx, AV_LOG_INFO|AV_LOG_C(123), "Frame End\n"); | |
return buf_size; | |
} | |
@@ -1341,6 +1361,7 @@ static av_cold int svq3_decode_end(AVCodecContext *avctx) | |
av_freep(&s->cur_pic); | |
av_freep(&s->next_pic); | |
av_freep(&s->last_pic); | |
+ av_freep(&s->slice_buf); | |
memset(&h->cur_pic, 0, sizeof(h->cur_pic)); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment