Mercurial > mplayer.hg
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; |