X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmpegvideo_xvmc.c;h=2e50814ab1ecc13b65f8456499728e2a1d8e6aa9;hb=fe4be5dbd5f4645b01887aea4e24c0177f7d8440;hp=9b9150972bbd3554191019d169b53683827d3cad;hpb=f0a902ad8213eb547b01f2bbd5e9ac4126673973;p=ffmpeg diff --git a/libavcodec/mpegvideo_xvmc.c b/libavcodec/mpegvideo_xvmc.c index 9b9150972bb..2e50814ab1e 100644 --- a/libavcodec/mpegvideo_xvmc.c +++ b/libavcodec/mpegvideo_xvmc.c @@ -21,7 +21,6 @@ #include -//avcodec include #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" @@ -30,62 +29,64 @@ #include #include "xvmc.h" +#include "xvmc_internal.h" //set s->block void ff_xvmc_init_block(MpegEncContext *s) { - struct xvmc_render_state * render; - render = (struct xvmc_render_state*)s->current_picture.data[2]; + struct xvmc_render_state *render = (struct xvmc_render_state*)s->current_picture.data[2]; assert(render); - if (!render || (render->magic != AV_XVMC_RENDER_MAGIC)) { + if (!render || render->magic != AV_XVMC_RENDER_MAGIC) { assert(0); - return;//make sure that this is a render packet + return; // make sure that this is a render packet } - s->block = (DCTELEM *)(render->data_blocks+(render->next_free_data_block_num)*64); + s->block = (DCTELEM *)(render->data_blocks + render->next_free_data_block_num * 64); } void ff_xvmc_pack_pblocks(MpegEncContext *s, int cbp) { - int i,j; + int i, j = 0; const int mb_block_count = 4 + (1 << s->chroma_format); - j = 0; cbp <<= 12-mb_block_count; for (i = 0; i < mb_block_count; i++) { - if (cbp & (1<<11)) { + if (cbp & (1 << 11)) s->pblocks[i] = (short *)(&s->block[j++]); - }else{ + else s->pblocks[i] = NULL; - } cbp+=cbp; } } -//These functions should be called on every new field and/or frame. -//They should be safe if they are called a few times for the same field! +/** + * This function should be called for every new field and/or frame. + * It should be safe to call the function a few times for the same field. + */ int ff_xvmc_field_start(MpegEncContext*s, AVCodecContext *avctx) { - struct xvmc_render_state * render, * last, * next; + struct xvmc_render_state *last, *next, *render = (struct xvmc_render_state*)s->current_picture.data[2]; assert(avctx); - - render = (struct xvmc_render_state*)s->current_picture.data[2]; assert(render); - if (!render || (render->magic != AV_XVMC_RENDER_MAGIC)) - return -1;//make sure that this is render packet + if (!render || render->magic != AV_XVMC_RENDER_MAGIC) + return -1; // make sure that this is a render packet render->picture_structure = s->picture_structure; - render->flags = (s->first_field) ? 0 : XVMC_SECOND_FIELD; + render->flags = s->first_field ? 0 : XVMC_SECOND_FIELD; -//make sure that all data is drawn by XVMC_end_frame - assert(render->filled_mv_blocks_num == 0); + if (render->filled_mv_blocks_num) { + av_log(avctx, AV_LOG_ERROR, + "Rendering surface contains %i unprocessed blocks\n", + render->filled_mv_blocks_num); + return -1; + } render->p_future_surface = NULL; render->p_past_surface = NULL; - switch(s->pict_type){ + switch(s->pict_type) { case FF_I_TYPE: - return 0;// no prediction from other frames + return 0; // no prediction from other frames case FF_B_TYPE: next = (struct xvmc_render_state*)s->next_picture.data[2]; assert(next); @@ -94,11 +95,11 @@ int ff_xvmc_field_start(MpegEncContext*s, AVCodecContext *avctx) if (next->magic != AV_XVMC_RENDER_MAGIC) return -1; render->p_future_surface = next->p_surface; - //no return here, going to set forward prediction + // no return here, going to set forward prediction case FF_P_TYPE: last = (struct xvmc_render_state*)s->last_picture.data[2]; - if (!last)// && !s->first_field) - last = render;//predict second field from the first + if (!last) + last = render; // predict second field from the first if (last->magic != AV_XVMC_RENDER_MAGIC) return -1; render->p_past_surface = last->p_surface; @@ -110,19 +111,18 @@ return -1; void ff_xvmc_field_end(MpegEncContext *s) { - struct xvmc_render_state * render; - render = (struct xvmc_render_state*)s->current_picture.data[2]; + struct xvmc_render_state *render = (struct xvmc_render_state*)s->current_picture.data[2]; assert(render); if (render->filled_mv_blocks_num > 0) - ff_draw_horiz_band(s,0,0); + ff_draw_horiz_band(s, 0, 0); } void ff_xvmc_decode_mb(MpegEncContext *s) { - XvMCMacroBlock * mv_block; - struct xvmc_render_state * render; - int i,cbp,blocks_per_mb; + XvMCMacroBlock *mv_block; + struct xvmc_render_state *render; + int i, cbp, blocks_per_mb; const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; @@ -132,43 +132,42 @@ void ff_xvmc_decode_mb(MpegEncContext *s) return; } - //from MPV_decode_mb(), - /* update DC predictors for P macroblocks */ + // from MPV_decode_mb(), update DC predictors for P macroblocks if (!s->mb_intra) { s->last_dc[0] = s->last_dc[1] = s->last_dc[2] = 128 << s->intra_dc_precision; } - //MC doesn't skip blocks + // MC doesn't skip blocks s->mb_skipped = 0; - // Do I need to export quant when I could not perform postprocessing? - // Anyway, it doesn't hurt. + // Do I need to export quant when I could not perform postprocessing? + // Anyway, it doesn't hurt. s->current_picture.qscale_table[mb_xy] = s->qscale; -//START OF XVMC specific code + // start of XVMC-specific code render = (struct xvmc_render_state*)s->current_picture.data[2]; assert(render); - assert(render->magic==AV_XVMC_RENDER_MAGIC); + assert(render->magic == AV_XVMC_RENDER_MAGIC); assert(render->mv_blocks); - //take the next free macroblock + // take the next free macroblock mv_block = &render->mv_blocks[render->start_mv_blocks_num + - render->filled_mv_blocks_num ]; + render->filled_mv_blocks_num]; mv_block->x = s->mb_x; mv_block->y = s->mb_y; - mv_block->dct_type = s->interlaced_dct;//XVMC_DCT_TYPE_FRAME/FIELD; - if (s->mb_intra){ - mv_block->macroblock_type = XVMC_MB_TYPE_INTRA;//no MC, all done - }else{ + mv_block->dct_type = s->interlaced_dct; // XVMC_DCT_TYPE_FRAME/FIELD; + if (s->mb_intra) { + mv_block->macroblock_type = XVMC_MB_TYPE_INTRA; // no MC, all done + } else { mv_block->macroblock_type = XVMC_MB_TYPE_PATTERN; if (s->mv_dir & MV_DIR_FORWARD) { mv_block->macroblock_type |= XVMC_MB_TYPE_MOTION_FORWARD; - //pmv[n][dir][xy]=mv[dir][n][xy] + // PMV[n][dir][xy] = mv[dir][n][xy] mv_block->PMV[0][0][0] = s->mv[0][0][0]; mv_block->PMV[0][0][1] = s->mv[0][0][1]; mv_block->PMV[1][0][0] = s->mv[0][1][0]; @@ -182,7 +181,7 @@ void ff_xvmc_decode_mb(MpegEncContext *s) mv_block->PMV[1][1][1] = s->mv[1][1][1]; } - switch(s->mv_type){ + switch(s->mv_type) { case MV_TYPE_16X16: mv_block->motion_type = XVMC_PREDICTION_FRAME; break; @@ -202,21 +201,21 @@ void ff_xvmc_decode_mb(MpegEncContext *s) mv_block->motion_type = XVMC_PREDICTION_DUAL_PRIME; if (s->picture_structure == PICT_FRAME) { - mv_block->PMV[0][0][0] = s->mv[0][0][0];//top from top - mv_block->PMV[0][0][1] = s->mv[0][0][1]<<1; + mv_block->PMV[0][0][0] = s->mv[0][0][0]; // top from top + mv_block->PMV[0][0][1] = s->mv[0][0][1] << 1; - mv_block->PMV[0][1][0] = s->mv[0][0][0];//bottom from bottom - mv_block->PMV[0][1][1] = s->mv[0][0][1]<<1; + mv_block->PMV[0][1][0] = s->mv[0][0][0]; // bottom from bottom + mv_block->PMV[0][1][1] = s->mv[0][0][1] << 1; - mv_block->PMV[1][0][0] = s->mv[0][2][0];//dmv00, top from bottom - mv_block->PMV[1][0][1] = s->mv[0][2][1]<<1;//dmv01 + mv_block->PMV[1][0][0] = s->mv[0][2][0]; // dmv00, top from bottom + mv_block->PMV[1][0][1] = s->mv[0][2][1] << 1; // dmv01 - mv_block->PMV[1][1][0] = s->mv[0][3][0];//dmv10, bottom from top - mv_block->PMV[1][1][1] = s->mv[0][3][1]<<1;//dmv11 + mv_block->PMV[1][1][0] = s->mv[0][3][0]; // dmv10, bottom from top + mv_block->PMV[1][1][1] = s->mv[0][3][1] << 1; // dmv11 - }else{ - mv_block->PMV[0][1][0] = s->mv[0][2][0];//dmv00 - mv_block->PMV[0][1][1] = s->mv[0][2][1];//dmv01 + } else { + mv_block->PMV[0][1][0] = s->mv[0][2][0]; // dmv00 + mv_block->PMV[0][1][1] = s->mv[0][2][1]; // dmv01 } break; default: @@ -225,19 +224,15 @@ void ff_xvmc_decode_mb(MpegEncContext *s) mv_block->motion_vertical_field_select = 0; -//set correct field references + // set correct field references if (s->mv_type == MV_TYPE_FIELD || s->mv_type == MV_TYPE_16X8) { - if (s->field_select[0][0]) - mv_block->motion_vertical_field_select |= 1; - if (s->field_select[1][0]) - mv_block->motion_vertical_field_select |= 2; - if (s->field_select[0][1]) - mv_block->motion_vertical_field_select |= 4; - if (s->field_select[1][1]) - mv_block->motion_vertical_field_select |= 8; + mv_block->motion_vertical_field_select |= s->field_select[0][0]; + mv_block->motion_vertical_field_select |= s->field_select[1][0] << 1; + mv_block->motion_vertical_field_select |= s->field_select[0][1] << 2; + mv_block->motion_vertical_field_select |= s->field_select[1][1] << 3; } - }//!intra -//time to handle data blocks; + } // !intra + // time to handle data blocks mv_block->index = render->next_free_data_block_num; blocks_per_mb = 6; @@ -245,7 +240,7 @@ void ff_xvmc_decode_mb(MpegEncContext *s) blocks_per_mb = 4 + (1 << s->chroma_format); } -// calculate cbp + // calculate cbp cbp = 0; for (i = 0; i < blocks_per_mb; i++) { cbp += cbp; @@ -254,15 +249,15 @@ void ff_xvmc_decode_mb(MpegEncContext *s) } if (s->flags & CODEC_FLAG_GRAY) { - if (s->mb_intra){//intra frames are always full chroma block + if (s->mb_intra) { // intra frames are always full chroma blocks for (i = 4; i < blocks_per_mb; i++) { - memset(s->pblocks[i],0,sizeof(short)*8*8);//so we need to clear them + memset(s->pblocks[i], 0, sizeof(short)*64); // so we need to clear them if (!render->unsigned_intra) s->pblocks[i][0] = 1 << 10; } - }else{ + } else { cbp &= 0xf << (blocks_per_mb - 4); - blocks_per_mb = 4;//luminance blocks only + blocks_per_mb = 4; // luminance blocks only } } mv_block->coded_block_pattern = cbp; @@ -272,16 +267,19 @@ void ff_xvmc_decode_mb(MpegEncContext *s) for (i = 0; i < blocks_per_mb; i++) { if (s->block_last_index[i] >= 0) { // I do not have unsigned_intra MOCO to test, hope it is OK. - if ((s->mb_intra) && (render->idct || (!render->idct && !render->unsigned_intra))) + if (s->mb_intra && (render->idct || (!render->idct && !render->unsigned_intra))) s->pblocks[i][0] -= 1 << 10; if (!render->idct) { s->dsp.idct(s->pblocks[i]); - //!!TODO!clip!!! + /* It is unclear if MC hardware requires pixel diff values to be + * in the range [-255;255]. TODO: Clipping if such hardware is + * ever found. As of now it would only be an unnecessary + * slowdown. */ } -//copy blocks only if the codec doesn't support pblocks reordering + // copy blocks only if the codec doesn't support pblocks reordering if (s->avctx->xvmc_acceleration == 1) { memcpy(&render->data_blocks[render->next_free_data_block_num*64], - s->pblocks[i],sizeof(short)*8*8); + s->pblocks[i], sizeof(short)*64); } render->next_free_data_block_num++; } @@ -290,8 +288,11 @@ void ff_xvmc_decode_mb(MpegEncContext *s) assert(render->filled_mv_blocks_num <= render->total_number_of_mv_blocks); assert(render->next_free_data_block_num <= render->total_number_of_data_blocks); + /* The above conditions should not be able to fail as long as this function + * is used and the following 'if ()' automatically calls a callback to free + * blocks. */ if (render->filled_mv_blocks_num >= render->total_number_of_mv_blocks) - ff_draw_horiz_band(s,0,0); + ff_draw_horiz_band(s, 0, 0); }