32 |
* |
* |
33 |
* History: |
* History: |
34 |
* |
* |
35 |
|
* 22.04.2002 add some B-frame decode support; chenm001 <chenm001@163.com> |
36 |
* 29.03.2002 interlacing fix - compensated block wasn't being used when |
* 29.03.2002 interlacing fix - compensated block wasn't being used when |
37 |
* reconstructing blocks, thus artifacts |
* reconstructing blocks, thus artifacts |
38 |
* interlacing speedup - used transfers to re-interlace |
* interlacing speedup - used transfers to re-interlace |
96 |
return XVID_ERR_MEMORY; |
return XVID_ERR_MEMORY; |
97 |
} |
} |
98 |
|
|
99 |
if (image_create(&dec->refn, dec->edged_width, dec->edged_height)) |
if (image_create(&dec->refn[0], dec->edged_width, dec->edged_height)) |
100 |
{ |
{ |
101 |
image_destroy(&dec->cur, dec->edged_width, dec->edged_height); |
image_destroy(&dec->cur, dec->edged_width, dec->edged_height); |
102 |
xvid_free(dec); |
xvid_free(dec); |
103 |
return XVID_ERR_MEMORY; |
return XVID_ERR_MEMORY; |
104 |
} |
} |
105 |
|
// add by chenm001 <chenm001@163.com> |
106 |
|
// for support B-frame to reference last 2 frame |
107 |
|
if (image_create(&dec->refn[1], dec->edged_width, dec->edged_height)) |
108 |
|
{ |
109 |
|
image_destroy(&dec->cur, dec->edged_width, dec->edged_height); |
110 |
|
image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height); |
111 |
|
xvid_free(dec); |
112 |
|
return XVID_ERR_MEMORY; |
113 |
|
} |
114 |
|
|
115 |
dec->mbs = xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height, CACHE_LINE); |
dec->mbs = xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height, CACHE_LINE); |
116 |
if (dec->mbs == NULL) |
if (dec->mbs == NULL) |
129 |
int decoder_destroy(DECODER * dec) |
int decoder_destroy(DECODER * dec) |
130 |
{ |
{ |
131 |
xvid_free(dec->mbs); |
xvid_free(dec->mbs); |
132 |
image_destroy(&dec->refn, dec->edged_width, dec->edged_height); |
image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height); |
133 |
image_destroy(&dec->cur, dec->edged_width, dec->edged_height); |
image_destroy(&dec->cur, dec->edged_width, dec->edged_height); |
134 |
xvid_free(dec); |
xvid_free(dec); |
135 |
|
|
309 |
} |
} |
310 |
|
|
311 |
start_timer(); |
start_timer(); |
312 |
interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x_pos, 16*y_pos , pMB->mvs[0].x, pMB->mvs[0].y, stride, rounding); |
interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos, 16*y_pos , pMB->mvs[0].x, pMB->mvs[0].y, stride, rounding); |
313 |
interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x_pos + 8, 16*y_pos , pMB->mvs[1].x, pMB->mvs[1].y, stride, rounding); |
interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos + 8, 16*y_pos , pMB->mvs[1].x, pMB->mvs[1].y, stride, rounding); |
314 |
interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x_pos, 16*y_pos + 8, pMB->mvs[2].x, pMB->mvs[2].y, stride, rounding); |
interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos, 16*y_pos + 8, pMB->mvs[2].x, pMB->mvs[2].y, stride, rounding); |
315 |
interpolate8x8_switch(dec->cur.y, dec->refn.y, 16*x_pos + 8, 16*y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride, rounding); |
interpolate8x8_switch(dec->cur.y, dec->refn[0].y, 16*x_pos + 8, 16*y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride, rounding); |
316 |
interpolate8x8_switch(dec->cur.u, dec->refn.u, 8*x_pos, 8*y_pos, uv_dx, uv_dy, stride2, rounding); |
interpolate8x8_switch(dec->cur.u, dec->refn[0].u, 8*x_pos, 8*y_pos, uv_dx, uv_dy, stride2, rounding); |
317 |
interpolate8x8_switch(dec->cur.v, dec->refn.v, 8*x_pos, 8*y_pos, uv_dx, uv_dy, stride2, rounding); |
interpolate8x8_switch(dec->cur.v, dec->refn[0].v, 8*x_pos, 8*y_pos, uv_dx, uv_dy, stride2, rounding); |
318 |
stop_comp_timer(); |
stop_comp_timer(); |
319 |
|
|
320 |
for (i = 0; i < 6; i++) |
for (i = 0; i < 6; i++) |
481 |
|
|
482 |
uint32_t x, y; |
uint32_t x, y; |
483 |
|
|
|
image_swap(&dec->cur, &dec->refn); |
|
|
|
|
484 |
start_timer(); |
start_timer(); |
485 |
image_setedges(&dec->refn, dec->edged_width, dec->edged_height, dec->width, dec->height, dec->interlacing); |
image_setedges(&dec->refn[0], dec->edged_width, dec->edged_height, dec->width, dec->height, dec->interlacing); |
486 |
stop_edges_timer(); |
stop_edges_timer(); |
487 |
|
|
488 |
for (y = 0; y < dec->mb_height; y++) |
for (y = 0; y < dec->mb_height; y++) |
598 |
start_timer(); |
start_timer(); |
599 |
|
|
600 |
transfer8x8_copy(dec->cur.y + (16*y)*dec->edged_width + (16*x), |
transfer8x8_copy(dec->cur.y + (16*y)*dec->edged_width + (16*x), |
601 |
dec->refn.y + (16*y)*dec->edged_width + (16*x), |
dec->refn[0].y + (16*y)*dec->edged_width + (16*x), |
602 |
dec->edged_width); |
dec->edged_width); |
603 |
|
|
604 |
transfer8x8_copy(dec->cur.y + (16*y)*dec->edged_width + (16*x+8), |
transfer8x8_copy(dec->cur.y + (16*y)*dec->edged_width + (16*x+8), |
605 |
dec->refn.y + (16*y)*dec->edged_width + (16*x+8), |
dec->refn[0].y + (16*y)*dec->edged_width + (16*x+8), |
606 |
dec->edged_width); |
dec->edged_width); |
607 |
|
|
608 |
transfer8x8_copy(dec->cur.y + (16*y+8)*dec->edged_width + (16*x), |
transfer8x8_copy(dec->cur.y + (16*y+8)*dec->edged_width + (16*x), |
609 |
dec->refn.y + (16*y+8)*dec->edged_width + (16*x), |
dec->refn[0].y + (16*y+8)*dec->edged_width + (16*x), |
610 |
dec->edged_width); |
dec->edged_width); |
611 |
|
|
612 |
transfer8x8_copy(dec->cur.y + (16*y+8)*dec->edged_width + (16*x+8), |
transfer8x8_copy(dec->cur.y + (16*y+8)*dec->edged_width + (16*x+8), |
613 |
dec->refn.y + (16*y+8)*dec->edged_width + (16*x+8), |
dec->refn[0].y + (16*y+8)*dec->edged_width + (16*x+8), |
614 |
dec->edged_width); |
dec->edged_width); |
615 |
|
|
616 |
transfer8x8_copy(dec->cur.u + (8*y)*dec->edged_width/2 + (8*x), |
transfer8x8_copy(dec->cur.u + (8*y)*dec->edged_width/2 + (8*x), |
617 |
dec->refn.u + (8*y)*dec->edged_width/2 + (8*x), |
dec->refn[0].u + (8*y)*dec->edged_width/2 + (8*x), |
618 |
dec->edged_width/2); |
dec->edged_width/2); |
619 |
|
|
620 |
transfer8x8_copy(dec->cur.v + (8*y)*dec->edged_width/2 + (8*x), |
transfer8x8_copy(dec->cur.v + (8*y)*dec->edged_width/2 + (8*x), |
621 |
dec->refn.v + (8*y)*dec->edged_width/2 + (8*x), |
dec->refn[0].v + (8*y)*dec->edged_width/2 + (8*x), |
622 |
dec->edged_width/2); |
dec->edged_width/2); |
623 |
|
|
624 |
stop_transfer_timer(); |
stop_transfer_timer(); |
635 |
uint32_t quant; |
uint32_t quant; |
636 |
uint32_t fcode; |
uint32_t fcode; |
637 |
uint32_t intra_dc_threshold; |
uint32_t intra_dc_threshold; |
638 |
|
uint32_t vop_type; |
639 |
|
|
640 |
start_global_timer(); |
start_global_timer(); |
641 |
|
|
642 |
BitstreamInit(&bs, frame->bitstream, frame->length); |
BitstreamInit(&bs, frame->bitstream, frame->length); |
643 |
|
|
644 |
switch (BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode, &intra_dc_threshold)) |
// add by chenm001 <chenm001@163.com> |
645 |
|
// for support B-frame to reference last 2 frame |
646 |
|
vop_type=BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode, &intra_dc_threshold); |
647 |
|
|
648 |
|
if (vop_type==I_VOP || vop_type==P_VOP){ |
649 |
|
image_swap(&dec->refn[0], &dec->refn[1]); |
650 |
|
image_swap(&dec->cur, &dec->refn[0]); |
651 |
|
} |
652 |
|
|
653 |
|
switch (vop_type) |
654 |
{ |
{ |
655 |
case P_VOP : |
case P_VOP : |
656 |
decoder_pframe(dec, &bs, rounding, quant, fcode, intra_dc_threshold); |
decoder_pframe(dec, &bs, rounding, quant, fcode, intra_dc_threshold); |