* @param stride the number of MVs to get to the next row
* @param mv_step the number of MVs per row or column in a macroblock
*/
- static void set_mv_strides(ERContext *s, int *mv_step, int *stride)
+ static void set_mv_strides(ERContext *s, ptrdiff_t *mv_step, ptrdiff_t *stride)
{
if (s->avctx->codec_id == AV_CODEC_ID_H264) {
- assert(s->quarter_sample);
+ av_assert0(s->quarter_sample);
*mv_step = 4;
*stride = s->mb_width * 4;
} else {
* @param h height in 8 pixel blocks
*/
static void guess_dc(ERContext *s, int16_t *dc, int w,
- int h, int stride, int is_luma)
+ int h, ptrdiff_t stride, int is_luma)
{
int b_x, b_y;
+ int16_t (*col )[4] = av_malloc_array(stride, h*sizeof( int16_t)*4);
+ uint32_t (*dist)[4] = av_malloc_array(stride, h*sizeof(uint32_t)*4);
+
+ if(!col || !dist) {
+ av_log(s->avctx, AV_LOG_ERROR, "guess_dc() is out of memory\n");
+ goto fail;
+ }
+
+ for(b_y=0; b_y<h; b_y++){
+ int color= 1024;
+ int distance= -1;
+ for(b_x=0; b_x<w; b_x++){
+ int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
+ int error_j= s->error_status_table[mb_index_j];
+ int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
+ if(intra_j==0 || !(error_j&ER_DC_ERROR)){
+ color= dc[b_x + b_y*stride];
+ distance= b_x;
+ }
+ col [b_x + b_y*stride][1]= color;
+ dist[b_x + b_y*stride][1]= distance >= 0 ? b_x-distance : 9999;
+ }
+ color= 1024;
+ distance= -1;
+ for(b_x=w-1; b_x>=0; b_x--){
+ int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
+ int error_j= s->error_status_table[mb_index_j];
+ int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
+ if(intra_j==0 || !(error_j&ER_DC_ERROR)){
+ color= dc[b_x + b_y*stride];
+ distance= b_x;
+ }
+ col [b_x + b_y*stride][0]= color;
+ dist[b_x + b_y*stride][0]= distance >= 0 ? distance-b_x : 9999;
+ }
+ }
+ for(b_x=0; b_x<w; b_x++){
+ int color= 1024;
+ int distance= -1;
+ for(b_y=0; b_y<h; b_y++){
+ int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
+ int error_j= s->error_status_table[mb_index_j];
+ int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
+ if(intra_j==0 || !(error_j&ER_DC_ERROR)){
+ color= dc[b_x + b_y*stride];
+ distance= b_y;
+ }
+ col [b_x + b_y*stride][3]= color;
+ dist[b_x + b_y*stride][3]= distance >= 0 ? b_y-distance : 9999;
+ }
+ color= 1024;
+ distance= -1;
+ for(b_y=h-1; b_y>=0; b_y--){
+ int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
+ int error_j= s->error_status_table[mb_index_j];
+ int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
+ if(intra_j==0 || !(error_j&ER_DC_ERROR)){
+ color= dc[b_x + b_y*stride];
+ distance= b_y;
+ }
+ col [b_x + b_y*stride][2]= color;
+ dist[b_x + b_y*stride][2]= distance >= 0 ? distance-b_y : 9999;
+ }
+ }
for (b_y = 0; b_y < h; b_y++) {
for (b_x = 0; b_x < w; b_x++) {
}
}
+#define MV_FROZEN 8
+#define MV_CHANGED 4
+#define MV_UNCHANGED 2
+#define MV_LISTED 1
+static av_always_inline void add_blocklist(int (*blocklist)[2], int *blocklist_length, uint8_t *fixed, int mb_x, int mb_y, int mb_xy)
+{
+ if (fixed[mb_xy])
+ return;
+ fixed[mb_xy] = MV_LISTED;
+ blocklist[ *blocklist_length ][0] = mb_x;
+ blocklist[(*blocklist_length)++][1] = mb_y;
+}
+
static void guess_mv(ERContext *s)
{
- uint8_t *fixed = s->er_temp_buffer;
-#define MV_FROZEN 3
-#define MV_CHANGED 2
-#define MV_UNCHANGED 1
+ int (*blocklist)[2], (*next_blocklist)[2];
+ uint8_t *fixed;
- const int mb_stride = s->mb_stride;
+ const ptrdiff_t mb_stride = s->mb_stride;
const int mb_width = s->mb_width;
- const int mb_height = s->mb_height;
+ int mb_height = s->mb_height;
int i, depth, num_avail;
- int mb_x, mb_y, mot_step, mot_stride;
+ int mb_x, mb_y;
+ ptrdiff_t mot_step, mot_stride;
+ int blocklist_length, next_blocklist_length;
+
+ if (s->last_pic.f && s->last_pic.f->data[0])
+ mb_height = FFMIN(mb_height, (s->last_pic.f->height+15)>>4);
+ if (s->next_pic.f && s->next_pic.f->data[0])
+ mb_height = FFMIN(mb_height, (s->next_pic.f->height+15)>>4);
+
+ blocklist = (int (*)[2])s->er_temp_buffer;
+ next_blocklist = blocklist + s->mb_stride * s->mb_height;
+ fixed = (uint8_t *)(next_blocklist + s->mb_stride * s->mb_height);
set_mv_strides(s, &mot_step, &mot_stride);