comparison libmpcodecs/pullup.c @ 11628:6fc547235443

simplified frame decision logic and reduced the occurrance of length=1 frames in output. this will make it easier for the caller to do timing or framerate regulation.
author rfelker
date Thu, 11 Dec 2003 07:52:57 +0000
parents 7737584af47a
children c7d65edff534
comparison
equal deleted inserted replaced
11627:7737584af47a 11628:6fc547235443
213 } 213 }
214 } 214 }
215 215
216 struct pullup_buffer *pullup_lock_buffer(struct pullup_buffer *b, int parity) 216 struct pullup_buffer *pullup_lock_buffer(struct pullup_buffer *b, int parity)
217 { 217 {
218 if (!b) return 0;
218 if (parity+1 & 1) b->lock[0]++; 219 if (parity+1 & 1) b->lock[0]++;
219 if (parity+1 & 2) b->lock[1]++; 220 if (parity+1 & 2) b->lock[1]++;
220 return b; 221 return b;
221 } 222 }
222 223
223 void pullup_release_buffer(struct pullup_buffer *b, int parity) 224 void pullup_release_buffer(struct pullup_buffer *b, int parity)
224 { 225 {
226 if (!b) return;
225 if (parity+1 & 1) b->lock[0]--; 227 if (parity+1 & 1) b->lock[0]--;
226 if (parity+1 & 2) b->lock[1]--; 228 if (parity+1 & 2) b->lock[1]--;
227 } 229 }
228 230
229 struct pullup_buffer *pullup_get_buffer(struct pullup_context *c, int parity) 231 struct pullup_buffer *pullup_get_buffer(struct pullup_context *c, int parity)
474 } 476 }
475 } 477 }
476 478
477 static int decide_frame_length(struct pullup_context *c) 479 static int decide_frame_length(struct pullup_context *c)
478 { 480 {
479 int n;
480 struct pullup_field *f0 = c->first; 481 struct pullup_field *f0 = c->first;
481 struct pullup_field *f1 = f0->next; 482 struct pullup_field *f1 = f0->next;
482 struct pullup_field *f2 = f1->next; 483 struct pullup_field *f2 = f1->next;
483 struct pullup_field *f3 = f2->next; 484 struct pullup_field *f3 = f2->next;
484 struct pullup_field *f4 = f3->next;
485 struct pullup_field *f5 = f4->next;
486 485
487 if (queue_length(c->first, c->last) < 6) return 0; 486 if (queue_length(c->first, c->last) < 6) return 0;
488 foo(c); 487 foo(c);
489 488
490 n = find_first_break(f0, 3);
491
492 if (f0->affinity == -1) return 1; 489 if (f0->affinity == -1) return 1;
493 490
494 switch (n) { 491 switch (find_first_break(f0, 3)) {
495 case 1: 492 case 1:
496 return 1; 493 return 1;
497 case 2: 494 case 2:
498 if (f1->affinity == 1) return 1; 495 if (f1->affinity == 1) return 1;
499 else return 2; 496 else return 2;
500 case 3: 497 case 3:
501 if (f1->affinity == -1) return 2; 498 if (f1->affinity == 1) {
502 else if (f1->affinity == 1) return 1; 499 if (f0->affinity == 1 && f2->affinity == -1) return 3;
500 else return 1;
501 }
502 else if (f2->affinity == 1) return 2;
503 else return 3; 503 else return 3;
504 default: 504 default:
505 if (f1->affinity == 1) return 1; 505 /* 9 possibilities covered before switch */
506 else if (f1->affinity == -1) return 2; 506 if (f1->affinity == 1) return 1; /* covers 6 */
507 else if (f2->affinity == 1) return 2; 507 else if (f1->affinity == -1) return 2; /* covers 6 */
508 else if (f0->affinity == 1 && f2->affinity == -1) return 3; 508 else if (f2->affinity == -1) { /* covers 2 */
509 else if (f2->affinity == -1) return 1; 509 if (f0->affinity == 1) return 3;
510 else if (f0->affinity == 1) return 2; 510 else return 1;
511 else if (f2->affinity == 0 && f3->affinity == 1) return 3; 511 }
512 else return 2; 512 else return 2; /* the remaining 6 */
513 } 513 }
514 } 514 }
515 515
516 516
517 static void print_aff_and_breaks(struct pullup_context *c, struct pullup_field *f) 517 static void print_aff_and_breaks(struct pullup_context *c, struct pullup_field *f)
541 struct pullup_frame *pullup_get_frame(struct pullup_context *c) 541 struct pullup_frame *pullup_get_frame(struct pullup_context *c)
542 { 542 {
543 int i; 543 int i;
544 struct pullup_frame *fr = c->frame; 544 struct pullup_frame *fr = c->frame;
545 int n = decide_frame_length(c); 545 int n = decide_frame_length(c);
546 int aff = c->first->next->affinity;
546 547
547 if (!n) return 0; 548 if (!n) return 0;
548 if (fr->lock) return 0; 549 if (fr->lock) return 0;
549 550
550 if (c->verbose) { 551 if (c->verbose) {
556 fr->length = n; 557 fr->length = n;
557 fr->parity = c->first->parity; 558 fr->parity = c->first->parity;
558 fr->buffer = 0; 559 fr->buffer = 0;
559 for (i = 0; i < n; i++) { 560 for (i = 0; i < n; i++) {
560 /* We cheat and steal the buffer without release+relock */ 561 /* We cheat and steal the buffer without release+relock */
561 fr->fields[i] = c->first->buffer; 562 fr->ifields[i] = c->first->buffer;
562 c->first->buffer = 0; 563 c->first->buffer = 0;
563 c->first = c->first->next; 564 c->first = c->first->next;
564 } 565 }
565 /* Export the entire frame as one buffer, if possible! */ 566
566 if (n == 2 && fr->fields[0] == fr->fields[1]) { 567 if (n == 1) {
567 fr->buffer = fr->fields[0]; 568 fr->ofields[fr->parity] = fr->ifields[0];
569 fr->ofields[fr->parity^1] = 0;
570 } else if (n == 2) {
571 fr->ofields[fr->parity] = fr->ifields[0];
572 fr->ofields[fr->parity^1] = fr->ifields[1];
573 } else if (n == 3) {
574 if (aff == 0)
575 aff = (fr->ifields[0] == fr->ifields[1]) ? -1 : 1;
576 /* else if (c->verbose) printf("forced aff: %d \n", aff); */
577 fr->ofields[fr->parity] = fr->ifields[1+aff];
578 fr->ofields[fr->parity^1] = fr->ifields[1];
579 }
580 pullup_lock_buffer(fr->ofields[0], 0);
581 pullup_lock_buffer(fr->ofields[1], 1);
582
583 if (fr->ofields[0] == fr->ofields[1]) {
584 fr->buffer = fr->ofields[0];
568 pullup_lock_buffer(fr->buffer, 2); 585 pullup_lock_buffer(fr->buffer, 2);
569 return fr; 586 return fr;
570 }
571 /* (loop is in case we ever support frames longer than 3 fields) */
572 for (i = 1; i < n-1; i++) {
573 if (fr->fields[i] == fr->fields[i-1]
574 || fr->fields[i] == fr->fields[i+1]) {
575 fr->buffer = fr->fields[i];
576 pullup_lock_buffer(fr->buffer, 2);
577 break;
578 }
579 } 587 }
580 return fr; 588 return fr;
581 } 589 }
582 590
583 static void copy_field(struct pullup_context *c, struct pullup_buffer *dest, 591 static void copy_field(struct pullup_context *c, struct pullup_buffer *dest,
600 { 608 {
601 int i; 609 int i;
602 int par = fr->parity; 610 int par = fr->parity;
603 if (fr->buffer) return; 611 if (fr->buffer) return;
604 if (fr->length < 2) return; /* FIXME: deal with this */ 612 if (fr->length < 2) return; /* FIXME: deal with this */
613 for (i = 0; i < 2; i++)
614 {
615 if (fr->ofields[i]->lock[i^1]) continue;
616 fr->buffer = fr->ofields[i];
617 pullup_lock_buffer(fr->buffer, 2);
618 copy_field(c, fr->buffer, fr->ofields[i^1], i^1);
619 return;
620 }
621 fr->buffer = pullup_get_buffer(c, 2);
622 copy_field(c, fr->buffer, fr->ofields[0], 0);
623 copy_field(c, fr->buffer, fr->ofields[1], 1);
624 }
625
626 void pullup_release_frame(struct pullup_frame *fr)
627 {
628 int i;
605 for (i = 0; i < fr->length; i++) 629 for (i = 0; i < fr->length; i++)
606 { 630 pullup_release_buffer(fr->ifields[i], fr->parity ^ (i&1));
607 if (fr->fields[i]->lock[par ^ (i&1) ^ 1]) continue; 631 pullup_release_buffer(fr->ofields[0], 0);
608 fr->buffer = fr->fields[i]; 632 pullup_release_buffer(fr->ofields[1], 1);
609 pullup_lock_buffer(fr->buffer, 2);
610 copy_field(c, fr->buffer, fr->fields[i+(i>0?-1:1)], par^(i&1)^1);
611 return;
612 }
613 fr->buffer = pullup_get_buffer(c, 2);
614 copy_field(c, fr->buffer, fr->fields[0], par);
615 copy_field(c, fr->buffer, fr->fields[1], par^1);
616 }
617
618 void pullup_release_frame(struct pullup_frame *fr)
619 {
620 int i;
621 for (i = 0; i < fr->length; i++)
622 pullup_release_buffer(fr->fields[i], fr->parity ^ (i&1));
623 if (fr->buffer) pullup_release_buffer(fr->buffer, 2); 633 if (fr->buffer) pullup_release_buffer(fr->buffer, 2);
624 fr->lock--; 634 fr->lock--;
625 } 635 }
626 636
627 637
659 c->metric_len = c->metric_w * c->metric_h; 669 c->metric_len = c->metric_w * c->metric_h;
660 670
661 c->head = make_field_queue(c, 8); 671 c->head = make_field_queue(c, 8);
662 672
663 c->frame = calloc(1, sizeof (struct pullup_frame)); 673 c->frame = calloc(1, sizeof (struct pullup_frame));
664 c->frame->fields = calloc(3, sizeof (struct pullup_buffer *)); 674 c->frame->ifields = calloc(3, sizeof (struct pullup_buffer *));
665 675
666 switch(c->format) { 676 switch(c->format) {
667 case PULLUP_FMT_Y: 677 case PULLUP_FMT_Y:
668 c->diff = diff_y; 678 c->diff = diff_y;
669 c->comb = licomb_y; 679 c->comb = licomb_y;