📄 vp3.c
字号:
int decode_partial_blocks = 0;
int first_c_fragment_seen;
int i, j;
int current_fragment;
debug_vp3(" vp3: unpacking superblock coding\n");
if (s->keyframe) {
debug_vp3(" keyframe-- all superblocks are fully coded\n");
memset(s->superblock_coding, SB_FULLY_CODED, s->superblock_count);
} else {
/* unpack the list of partially-coded superblocks */
bit = get_bits1(gb);
/* toggle the bit because as soon as the first run length is
* fetched the bit will be toggled again */
bit ^= 1;
while (current_superblock < s->superblock_count) {
if (current_run-- == 0) {
bit ^= 1;
current_run = get_vlc2(gb,
s->superblock_run_length_vlc.table, 6, 2);
if (current_run == 33)
current_run += get_bits(gb, 12);
debug_block_coding(" setting superblocks %d..%d to %s\n",
current_superblock,
current_superblock + current_run - 1,
(bit) ? "partially coded" : "not coded");
/* if any of the superblocks are not partially coded, flag
* a boolean to decode the list of fully-coded superblocks */
if (bit == 0) {
decode_fully_flags = 1;
} else {
/* make a note of the fact that there are partially coded
* superblocks */
decode_partial_blocks = 1;
}
}
s->superblock_coding[current_superblock++] = bit;
}
/* unpack the list of fully coded superblocks if any of the blocks were
* not marked as partially coded in the previous step */
if (decode_fully_flags) {
current_superblock = 0;
current_run = 0;
bit = get_bits1(gb);
/* toggle the bit because as soon as the first run length is
* fetched the bit will be toggled again */
bit ^= 1;
while (current_superblock < s->superblock_count) {
/* skip any superblocks already marked as partially coded */
if (s->superblock_coding[current_superblock] == SB_NOT_CODED) {
if (current_run-- == 0) {
bit ^= 1;
current_run = get_vlc2(gb,
s->superblock_run_length_vlc.table, 6, 2);
if (current_run == 33)
current_run += get_bits(gb, 12);
}
debug_block_coding(" setting superblock %d to %s\n",
current_superblock,
(bit) ? "fully coded" : "not coded");
s->superblock_coding[current_superblock] = 2*bit;
}
current_superblock++;
}
}
/* if there were partial blocks, initialize bitstream for
* unpacking fragment codings */
if (decode_partial_blocks) {
current_run = 0;
bit = get_bits1(gb);
/* toggle the bit because as soon as the first run length is
* fetched the bit will be toggled again */
bit ^= 1;
}
}
/* figure out which fragments are coded; iterate through each
* superblock (all planes) */
s->coded_fragment_list_index = 0;
s->next_coeff= s->coeffs + s->fragment_count;
s->first_coded_y_fragment = s->first_coded_c_fragment = 0;
s->last_coded_y_fragment = s->last_coded_c_fragment = -1;
first_c_fragment_seen = 0;
memset(s->macroblock_coding, MODE_COPY, s->macroblock_count);
for (i = 0; i < s->superblock_count; i++) {
/* iterate through all 16 fragments in a superblock */
for (j = 0; j < 16; j++) {
/* if the fragment is in bounds, check its coding status */
current_fragment = s->superblock_fragments[i * 16 + j];
if (current_fragment >= s->fragment_count) {
av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_superblocks(): bad fragment number (%d >= %d)\n",
current_fragment, s->fragment_count);
return 1;
}
if (current_fragment != -1) {
if (s->superblock_coding[i] == SB_NOT_CODED) {
/* copy all the fragments from the prior frame */
s->all_fragments[current_fragment].coding_method =
MODE_COPY;
} else if (s->superblock_coding[i] == SB_PARTIALLY_CODED) {
/* fragment may or may not be coded; this is the case
* that cares about the fragment coding runs */
if (current_run-- == 0) {
bit ^= 1;
current_run = get_vlc2(gb,
s->fragment_run_length_vlc.table, 5, 2);
}
if (bit) {
/* default mode; actual mode will be decoded in
* the next phase */
s->all_fragments[current_fragment].coding_method =
MODE_INTER_NO_MV;
s->all_fragments[current_fragment].next_coeff= s->coeffs + current_fragment;
s->coded_fragment_list[s->coded_fragment_list_index] =
current_fragment;
if ((current_fragment >= s->fragment_start[1]) &&
(s->last_coded_y_fragment == -1) &&
(!first_c_fragment_seen)) {
s->first_coded_c_fragment = s->coded_fragment_list_index;
s->last_coded_y_fragment = s->first_coded_c_fragment - 1;
first_c_fragment_seen = 1;
}
s->coded_fragment_list_index++;
s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV;
debug_block_coding(" superblock %d is partially coded, fragment %d is coded\n",
i, current_fragment);
} else {
/* not coded; copy this fragment from the prior frame */
s->all_fragments[current_fragment].coding_method =
MODE_COPY;
debug_block_coding(" superblock %d is partially coded, fragment %d is not coded\n",
i, current_fragment);
}
} else {
/* fragments are fully coded in this superblock; actual
* coding will be determined in next step */
s->all_fragments[current_fragment].coding_method =
MODE_INTER_NO_MV;
s->all_fragments[current_fragment].next_coeff= s->coeffs + current_fragment;
s->coded_fragment_list[s->coded_fragment_list_index] =
current_fragment;
if ((current_fragment >= s->fragment_start[1]) &&
(s->last_coded_y_fragment == -1) &&
(!first_c_fragment_seen)) {
s->first_coded_c_fragment = s->coded_fragment_list_index;
s->last_coded_y_fragment = s->first_coded_c_fragment - 1;
first_c_fragment_seen = 1;
}
s->coded_fragment_list_index++;
s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV;
debug_block_coding(" superblock %d is fully coded, fragment %d is coded\n",
i, current_fragment);
}
}
}
}
if (!first_c_fragment_seen)
/* only Y fragments coded in this frame */
s->last_coded_y_fragment = s->coded_fragment_list_index - 1;
else
/* end the list of coded C fragments */
s->last_coded_c_fragment = s->coded_fragment_list_index - 1;
debug_block_coding(" %d total coded fragments, y: %d -> %d, c: %d -> %d\n",
s->coded_fragment_list_index,
s->first_coded_y_fragment,
s->last_coded_y_fragment,
s->first_coded_c_fragment,
s->last_coded_c_fragment);
return 0;
}
/*
* This function unpacks all the coding mode data for individual macroblocks
* from the bitstream.
*/
static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb)
{
int i, j, k;
int scheme;
int current_macroblock;
int current_fragment;
int coding_mode;
debug_vp3(" vp3: unpacking encoding modes\n");
if (s->keyframe) {
debug_vp3(" keyframe-- all blocks are coded as INTRA\n");
for (i = 0; i < s->fragment_count; i++)
s->all_fragments[i].coding_method = MODE_INTRA;
} else {
/* fetch the mode coding scheme for this frame */
scheme = get_bits(gb, 3);
debug_modes(" using mode alphabet %d\n", scheme);
/* is it a custom coding scheme? */
if (scheme == 0) {
debug_modes(" custom mode alphabet ahead:\n");
for (i = 0; i < 8; i++)
ModeAlphabet[scheme][get_bits(gb, 3)] = i;
}
for (i = 0; i < 8; i++)
debug_modes(" mode[%d][%d] = %d\n", scheme, i,
ModeAlphabet[scheme][i]);
/* iterate through all of the macroblocks that contain 1 or more
* coded fragments */
for (i = 0; i < s->u_superblock_start; i++) {
for (j = 0; j < 4; j++) {
current_macroblock = s->superblock_macroblocks[i * 4 + j];
if ((current_macroblock == -1) ||
(s->macroblock_coding[current_macroblock] == MODE_COPY))
continue;
if (current_macroblock >= s->macroblock_count) {
av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_modes(): bad macroblock number (%d >= %d)\n",
current_macroblock, s->macroblock_count);
return 1;
}
/* mode 7 means get 3 bits for each coding mode */
if (scheme == 7)
coding_mode = get_bits(gb, 3);
else
coding_mode = ModeAlphabet[scheme]
[get_vlc2(gb, s->mode_code_vlc.table, 3, 3)];
s->macroblock_coding[current_macroblock] = coding_mode;
for (k = 0; k < 6; k++) {
current_fragment =
s->macroblock_fragments[current_macroblock * 6 + k];
if (current_fragment == -1)
continue;
if (current_fragment >= s->fragment_count) {
av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_modes(): bad fragment number (%d >= %d)\n",
current_fragment, s->fragment_count);
return 1;
}
if (s->all_fragments[current_fragment].coding_method !=
MODE_COPY)
s->all_fragments[current_fragment].coding_method =
coding_mode;
}
debug_modes(" coding method for macroblock starting @ fragment %d = %d\n",
s->macroblock_fragments[current_macroblock * 6], coding_mode);
}
}
}
return 0;
}
/*
* This function unpacks all the motion vectors for the individual
* macroblocks from the bitstream.
*/
static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb)
{
int i, j, k;
int coding_mode;
int motion_x[6];
int motion_y[6];
int last_motion_x = 0;
int last_motion_y = 0;
int prior_last_motion_x = 0;
int prior_last_motion_y = 0;
int current_macroblock;
int current_fragment;
debug_vp3(" vp3: unpacking motion vectors\n");
if (s->keyframe) {
debug_vp3(" keyframe-- there are no motion vectors\n");
} else {
memset(motion_x, 0, 6 * sizeof(int));
memset(motion_y, 0, 6 * sizeof(int));
/* coding mode 0 is the VLC scheme; 1 is the fixed code scheme */
coding_mode = get_bits1(gb);
debug_vectors(" using %s scheme for unpacking motion vectors\n",
(coding_mode == 0) ? "VLC" : "fixed-length");
/* iterate through all of the macroblocks that contain 1 or more
* coded fragments */
for (i = 0; i < s->u_superblock_start; i++) {
for (j = 0; j < 4; j++) {
current_macroblock = s->superblock_macroblocks[i * 4 + j];
if ((current_macroblock == -1) ||
(s->macroblock_coding[current_macroblock] == MODE_COPY))
continue;
if (current_macroblock >= s->macroblock_count) {
av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_vectors(): bad macroblock number (%d >= %d)\n",
current_macroblock, s->macroblock_count);
return 1;
}
current_fragment = s->macroblock_fragments[current_macroblock * 6];
if (current_fragment >= s->fragment_count) {
av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_vectors(): bad fragment number (%d >= %d\n",
current_fragment, s->fragment_count);
return 1;
}
switch (s->macroblock_coding[current_macroblock]) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -