Index: source/libvpx/vp9/common/vp9_implicit_segmentation.c |
=================================================================== |
--- source/libvpx/vp9/common/vp9_implicit_segmentation.c (revision 0) |
+++ source/libvpx/vp9/common/vp9_implicit_segmentation.c (revision 0) |
@@ -0,0 +1,255 @@ |
+/* |
+ * Copyright (c) 2012 The WebM project authors. All Rights Reserved. |
+ * |
+ * Use of this source code is governed by a BSD-style license |
+ * that can be found in the LICENSE file in the root of the source |
+ * tree. An additional intellectual property rights grant can be found |
+ * in the file PATENTS. All contributing project authors may |
+ * be found in the AUTHORS file in the root of the source tree. |
+ */ |
+ |
+#include "vp9/common/vp9_onyxc_int.h" |
+ |
+#define MAX_REGIONS 24000 |
+#ifndef NULL |
+#define NULL 0 |
+#endif |
+ |
+#define min_mbs_in_region 3 |
+ |
+// this linked list structure holds equivalences for connected |
+// component labeling |
+struct list_el { |
+ int label; |
+ int seg_value; |
+ int count; |
+ struct list_el *next; |
+}; |
+typedef struct list_el item; |
+ |
+// connected colorsegments |
+typedef struct { |
+ int min_x; |
+ int min_y; |
+ int max_x; |
+ int max_y; |
+ long long sum_x; |
+ long long sum_y; |
+ int pixels; |
+ int seg_value; |
+ int label; |
+} segment_info; |
+ |
+ |
+typedef enum { |
+ SEGMENT_MODE, |
+ SEGMENT_MV, |
+ SEGMENT_REFFRAME, |
+ SEGMENT_SKIPPED |
+} SEGMENT_TYPE; |
+ |
+ |
+// this merges the two equivalence lists and |
+// then makes sure that every label points to the same |
+// equivalence list |
+void merge(item *labels, int u, int v) { |
+ item *a = labels[u].next; |
+ item *b = labels[v].next; |
+ item c; |
+ item *it = &c; |
+ int count; |
+ |
+ // check if they are already merged |
+ if (u == v || a == b) |
+ return; |
+ |
+ count = a->count + b->count; |
+ |
+ // merge 2 sorted linked lists. |
+ while (a != NULL && b != NULL) { |
+ if (a->label < b->label) { |
+ it->next = a; |
+ a = a->next; |
+ } else { |
+ it->next = b; |
+ b = b->next; |
+ } |
+ |
+ it = it->next; |
+ } |
+ |
+ if (a == NULL) |
+ it->next = b; |
+ else |
+ it->next = a; |
+ |
+ it = c.next; |
+ |
+ // make sure every equivalence in the linked list points to this new ll |
+ while (it != NULL) { |
+ labels[it->label].next = c.next; |
+ it = it->next; |
+ } |
+ c.next->count = count; |
+ |
+} |
+ |
+void segment_via_mode_info(VP9_COMMON *oci, int how) { |
+ MODE_INFO *mi = oci->mi; |
+ int i, j; |
+ int mb_index = 0; |
+ |
+ int label = 1; |
+ int pitch = oci->mb_cols; |
+ |
+ // holds linked list equivalences |
+ // the max should probably be allocated at a higher level in oci |
+ item equivalences[MAX_REGIONS]; |
+ int eq_ptr = 0; |
+ item labels[MAX_REGIONS]; |
+ segment_info segments[MAX_REGIONS]; |
+ int label_count = 1; |
+ int labeling[400 * 300]; |
+ int *lp = labeling; |
+ |
+ label_count = 1; |
+ memset(labels, 0, sizeof(labels)); |
+ memset(segments, 0, sizeof(segments)); |
+ |
+ /* Go through each macroblock first pass labelling */ |
+ for (i = 0; i < oci->mb_rows; i++, lp += pitch) { |
+ for (j = 0; j < oci->mb_cols; j++) { |
+ // int above seg_value, left seg_value, this seg_value... |
+ int a = -1, l = -1, n = -1; |
+ |
+ // above label, left label |
+ int al = -1, ll = -1; |
+ if (i) { |
+ al = lp[j - pitch]; |
+ a = labels[al].next->seg_value; |
+ } |
+ if (j) { |
+ ll = lp[j - 1]; |
+ l = labels[ll].next->seg_value; |
+ } |
+ |
+ // what setting are we going to do the implicit segmentation on |
+ switch (how) { |
+ case SEGMENT_MODE: |
+ n = mi[mb_index].mbmi.mode; |
+ break; |
+ case SEGMENT_MV: |
+ n = mi[mb_index].mbmi.mv[0].as_int; |
+ if (mi[mb_index].mbmi.ref_frame == INTRA_FRAME) |
+ n = -9999999; |
+ break; |
+ case SEGMENT_REFFRAME: |
+ n = mi[mb_index].mbmi.ref_frame; |
+ break; |
+ case SEGMENT_SKIPPED: |
+ n = mi[mb_index].mbmi.mb_skip_coeff; |
+ break; |
+ } |
+ |
+ // above and left both have the same seg_value |
+ if (n == a && n == l) { |
+ // pick the lowest label |
+ lp[j] = (al < ll ? al : ll); |
+ labels[lp[j]].next->count++; |
+ |
+ // merge the above and left equivalencies |
+ merge(labels, al, ll); |
+ } |
+ // this matches above seg_value |
+ else if (n == a) { |
+ // give it the same label as above |
+ lp[j] = al; |
+ labels[al].next->count++; |
+ } |
+ // this matches left seg_value |
+ else if (n == l) { |
+ // give it the same label as above |
+ lp[j] = ll; |
+ labels[ll].next->count++; |
+ } else { |
+ // new label doesn't match either |
+ item *e = &labels[label]; |
+ item *nl = &equivalences[eq_ptr++]; |
+ lp[j] = label; |
+ nl->label = label; |
+ nl->next = 0; |
+ nl->seg_value = n; |
+ nl->count = 1; |
+ e->next = nl; |
+ label++; |
+ } |
+ mb_index++; |
+ } |
+ mb_index++; |
+ } |
+ lp = labeling; |
+ |
+ // give new labels to regions |
+ for (i = 1; i < label; i++) |
+ if (labels[i].next->count > min_mbs_in_region && labels[labels[i].next->label].label == 0) { |
+ segment_info *cs = &segments[label_count]; |
+ cs->label = label_count; |
+ labels[labels[i].next->label].label = label_count++; |
+ labels[labels[i].next->label].seg_value = labels[i].next->seg_value; |
+ cs->seg_value = labels[labels[i].next->label].seg_value; |
+ cs->min_x = oci->mb_cols; |
+ cs->min_y = oci->mb_rows; |
+ cs->max_x = 0; |
+ cs->max_y = 0; |
+ cs->sum_x = 0; |
+ cs->sum_y = 0; |
+ cs->pixels = 0; |
+ |
+ } |
+ lp = labeling; |
+ |
+ // this is just to gather stats... |
+ for (i = 0; i < oci->mb_rows; i++, lp += pitch) { |
+ for (j = 0; j < oci->mb_cols; j++) { |
+ segment_info *cs; |
+ int oldlab = labels[lp[j]].next->label; |
+ int lab = labels[oldlab].label; |
+ lp[j] = lab; |
+ |
+ cs = &segments[lab]; |
+ |
+ cs->min_x = (j < cs->min_x ? j : cs->min_x); |
+ cs->max_x = (j > cs->max_x ? j : cs->max_x); |
+ cs->min_y = (i < cs->min_y ? i : cs->min_y); |
+ cs->max_y = (i > cs->max_y ? i : cs->max_y); |
+ cs->sum_x += j; |
+ cs->sum_y += i; |
+ cs->pixels++; |
+ |
+ lp[j] = lab; |
+ mb_index++; |
+ } |
+ mb_index++; |
+ } |
+ |
+ { |
+ lp = labeling; |
+ printf("labelling \n"); |
+ mb_index = 0; |
+ for (i = 0; i < oci->mb_rows; i++, lp += pitch) { |
+ for (j = 0; j < oci->mb_cols; j++) { |
+ printf("%4d", lp[j]); |
+ } |
+ printf(" "); |
+ for (j = 0; j < oci->mb_cols; j++, mb_index++) { |
+ // printf("%3d",mi[mb_index].mbmi.mode ); |
+ printf("%4d:%4d", mi[mb_index].mbmi.mv[0].as_mv.row, |
+ mi[mb_index].mbmi.mv[0].as_mv.col); |
+ } |
+ printf("\n"); |
+ ++mb_index; |
+ } |
+ printf("\n"); |
+ } |
+} |
+ |
Property changes on: source/libvpx/vp9/common/vp9_implicit_segmentation.c |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |