| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * MJPEG encoder | ||
| 3 | * Copyright (c) 2016 William Ma, Ted Ying, Jerry Jiang | ||
| 4 | * | ||
| 5 | * This file is part of FFmpeg. | ||
| 6 | * | ||
| 7 | * FFmpeg is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU Lesser General Public | ||
| 9 | * License as published by the Free Software Foundation; either | ||
| 10 | * version 2.1 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * FFmpeg is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * Lesser General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public | ||
| 18 | * License along with FFmpeg; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <string.h> | ||
| 23 | #include <stdint.h> | ||
| 24 | #include "libavutil/avassert.h" | ||
| 25 | #include "libavutil/qsort.h" | ||
| 26 | #include "mjpegenc_huffman.h" | ||
| 27 | |||
| 28 | /** | ||
| 29 | * Used to assign a occurrence count or "probability" to an input value | ||
| 30 | */ | ||
| 31 | typedef struct PTable { | ||
| 32 | int value; ///< input value | ||
| 33 | int prob; ///< number of occurrences of this value in input | ||
| 34 | } PTable; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * Used to store intermediate lists in the package merge algorithm | ||
| 38 | */ | ||
| 39 | typedef struct PackageMergerList { | ||
| 40 | int nitems; ///< number of items in the list and probability ex. 4 | ||
| 41 | int item_idx[515]; ///< index range for each item in items 0, 2, 5, 9, 13 | ||
| 42 | int probability[514]; ///< probability of each item 3, 8, 18, 46 | ||
| 43 | int items[257 * 16]; ///< chain of all individual values that make up items A, B, A, B, C, A, B, C, D, C, D, D, E | ||
| 44 | } PackageMergerList; | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Comparison function for two PTables by prob | ||
| 48 | * | ||
| 49 | * @param a First PTable to compare | ||
| 50 | * @param b Second PTable to compare | ||
| 51 | * @return < 0 for less than, 0 for equals, > 0 for greater than | ||
| 52 | */ | ||
| 53 | 332812 | static int compare_by_prob(const void *a, const void *b) | |
| 54 | { | ||
| 55 | 332812 | PTable a_val = *(PTable *) a; | |
| 56 | 332812 | PTable b_val = *(PTable *) b; | |
| 57 | 332812 | return a_val.prob - b_val.prob; | |
| 58 | } | ||
| 59 | |||
| 60 | /** | ||
| 61 | * Computes the length of the Huffman encoding for each distinct input value. | ||
| 62 | * Uses package merge algorithm as follows: | ||
| 63 | * 1. start with an empty list, lets call it list(0), set i = 0 | ||
| 64 | * 2. add 1 entry to list(i) for each symbol we have and give each a score equal to the probability of the respective symbol | ||
| 65 | * 3. merge the 2 symbols of least score and put them in list(i+1), and remove them from list(i). The new score will be the sum of the 2 scores | ||
| 66 | * 4. if there is more than 1 symbol left in the current list(i), then goto 3 | ||
| 67 | * 5. i++ | ||
| 68 | * 6. if i < 16 goto 2 | ||
| 69 | * 7. select the n-1 elements in the last list with the lowest score (n = the number of symbols) | ||
| 70 | * 8. the length of the huffman code for symbol s will be equal to the number of times the symbol occurs in the select elements | ||
| 71 | * Go to guru.multimedia.cx/small-tasks-for-ffmpeg/ for more details | ||
| 72 | * | ||
| 73 | * All probabilities should be nonnegative integers. | ||
| 74 | * | ||
| 75 | * @param prob_table[in,out] array of a PTable for each distinct input value, | ||
| 76 | * will be sorted according to ascending probability | ||
| 77 | * @param counts[out] the number of values of a given length | ||
| 78 | * @param size number of elements of the prob_table array | ||
| 79 | * @param max_length max length of a code | ||
| 80 | */ | ||
| 81 | 3360 | static void mjpegenc_huffman_compute_bits(PTable *prob_table, | |
| 82 | uint8_t counts[/* max_length + 1 */], | ||
| 83 | int size, int max_length) | ||
| 84 | { | ||
| 85 | 3360 | PackageMergerList list_a, list_b, *to = &list_a, *from = &list_b, *temp; | |
| 86 | |||
| 87 | int times, i, j, k; | ||
| 88 | |||
| 89 | 3360 | int nbits[257] = {0}; | |
| 90 | |||
| 91 | int min; | ||
| 92 | |||
| 93 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3360 times.
|
3360 | av_assert0(max_length > 0); |
| 94 | |||
| 95 | 3360 | to->nitems = 0; | |
| 96 | 3360 | from->nitems = 0; | |
| 97 | 3360 | to->item_idx[0] = 0; | |
| 98 | 3360 | from->item_idx[0] = 0; | |
| 99 |
44/44✓ Branch 0 taken 29909 times.
✓ Branch 1 taken 10481 times.
✓ Branch 3 taken 12701 times.
✓ Branch 4 taken 17208 times.
✓ Branch 6 taken 2763 times.
✓ Branch 7 taken 9938 times.
✓ Branch 9 taken 3709 times.
✓ Branch 10 taken 13499 times.
✓ Branch 12 taken 13505 times.
✓ Branch 13 taken 16404 times.
✓ Branch 14 taken 5926 times.
✓ Branch 15 taken 23983 times.
✓ Branch 16 taken 111820 times.
✓ Branch 17 taken 6758 times.
✓ Branch 19 taken 57483 times.
✓ Branch 20 taken 54337 times.
✓ Branch 21 taken 107651 times.
✓ Branch 22 taken 17591 times.
✓ Branch 24 taken 64147 times.
✓ Branch 25 taken 43504 times.
✓ Branch 26 taken 17591 times.
✓ Branch 27 taken 43504 times.
✓ Branch 28 taken 61095 times.
✓ Branch 29 taken 23983 times.
✓ Branch 30 taken 6065 times.
✓ Branch 31 taken 17918 times.
✓ Branch 32 taken 4184 times.
✓ Branch 33 taken 1881 times.
✓ Branch 34 taken 1844 times.
✓ Branch 35 taken 2340 times.
✓ Branch 36 taken 13133 times.
✓ Branch 37 taken 1592 times.
✓ Branch 39 taken 11000 times.
✓ Branch 40 taken 2133 times.
✓ Branch 41 taken 1592 times.
✓ Branch 42 taken 2133 times.
✓ Branch 43 taken 9679 times.
✓ Branch 44 taken 12712 times.
✓ Branch 46 taken 4068 times.
✓ Branch 47 taken 6413 times.
✓ Branch 48 taken 40390 times.
✓ Branch 49 taken 7752 times.
✓ Branch 50 taken 25751 times.
✓ Branch 51 taken 3360 times.
|
269210 | AV_QSORT(prob_table, size, PTable, compare_by_prob); |
| 100 | |||
| 101 |
2/2✓ Branch 0 taken 57107 times.
✓ Branch 1 taken 3360 times.
|
60467 | for (times = 0; times <= max_length; times++) { |
| 102 | 57107 | to->nitems = 0; | |
| 103 | 57107 | to->item_idx[0] = 0; | |
| 104 | |||
| 105 | 57107 | j = 0; | |
| 106 | 57107 | k = 0; | |
| 107 | |||
| 108 |
2/2✓ Branch 0 taken 53747 times.
✓ Branch 1 taken 3360 times.
|
57107 | if (times < max_length) { |
| 109 | 53747 | i = 0; | |
| 110 | } | ||
| 111 |
4/4✓ Branch 0 taken 2163484 times.
✓ Branch 1 taken 302520 times.
✓ Branch 2 taken 245413 times.
✓ Branch 3 taken 57107 times.
|
2466004 | while (i < size || j + 1 < from->nitems) { |
| 112 | 2408897 | to->nitems++; | |
| 113 | 2408897 | to->item_idx[to->nitems] = to->item_idx[to->nitems - 1]; | |
| 114 |
2/2✓ Branch 0 taken 2163484 times.
✓ Branch 1 taken 245413 times.
|
2408897 | if (i < size && |
| 115 |
2/2✓ Branch 0 taken 2083928 times.
✓ Branch 1 taken 79556 times.
|
2163484 | (j + 1 >= from->nitems || |
| 116 | 2083928 | prob_table[i].prob < | |
| 117 |
2/2✓ Branch 0 taken 1185275 times.
✓ Branch 1 taken 898653 times.
|
2083928 | from->probability[j] + from->probability[j + 1])) { |
| 118 | 1264831 | to->items[to->item_idx[to->nitems]++] = prob_table[i].value; | |
| 119 | 1264831 | to->probability[to->nitems - 1] = prob_table[i].prob; | |
| 120 | 1264831 | i++; | |
| 121 | } else { | ||
| 122 |
2/2✓ Branch 0 taken 7005287 times.
✓ Branch 1 taken 1144066 times.
|
8149353 | for (k = from->item_idx[j]; k < from->item_idx[j + 2]; k++) { |
| 123 | 7005287 | to->items[to->item_idx[to->nitems]++] = from->items[k]; | |
| 124 | } | ||
| 125 | 1144066 | to->probability[to->nitems - 1] = | |
| 126 | 1144066 | from->probability[j] + from->probability[j + 1]; | |
| 127 | 1144066 | j += 2; | |
| 128 | } | ||
| 129 | } | ||
| 130 | 57107 | temp = to; | |
| 131 | 57107 | to = from; | |
| 132 | 57107 | from = temp; | |
| 133 | } | ||
| 134 | |||
| 135 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3360 times.
|
3360 | min = (size - 1 < from->nitems) ? size - 1 : from->nitems; |
| 136 |
2/2✓ Branch 0 taken 591753 times.
✓ Branch 1 taken 3360 times.
|
595113 | for (i = 0; i < from->item_idx[min]; i++) { |
| 137 | 591753 | nbits[from->items[i]]++; | |
| 138 | } | ||
| 139 | // we don't want to return the 256 bit count (it was just in here to prevent | ||
| 140 | // all 1s encoding) | ||
| 141 | 3360 | memset(counts, 0, sizeof(counts[0]) * (max_length + 1)); | |
| 142 |
2/2✓ Branch 0 taken 860160 times.
✓ Branch 1 taken 3360 times.
|
863520 | for (int i = 0; i < 256; ++i) |
| 143 | 860160 | counts[nbits[i]]++; | |
| 144 | 3360 | } | |
| 145 | |||
| 146 | 3356 | void ff_mjpeg_encode_huffman_init(MJpegEncHuffmanContext *s) | |
| 147 | { | ||
| 148 | 3356 | memset(s->val_count, 0, sizeof(s->val_count)); | |
| 149 | 3356 | } | |
| 150 | |||
| 151 | /** | ||
| 152 | * Produces a Huffman encoding with a given input | ||
| 153 | * | ||
| 154 | * @param s input to encode | ||
| 155 | * @param bits output array where the ith character represents how many input values have i length encoding | ||
| 156 | * @param val output array of input values sorted by their encoded length | ||
| 157 | * @param max_nval maximum number of distinct input values | ||
| 158 | */ | ||
| 159 | 3356 | void ff_mjpeg_encode_huffman_close(MJpegEncHuffmanContext *s, uint8_t bits[17], | |
| 160 | uint8_t val[], int max_nval) | ||
| 161 | { | ||
| 162 | PTable val_counts[257]; | ||
| 163 | |||
| 164 | av_assert1(max_nval <= FF_ARRAY_ELEMS(val_counts) - 1); | ||
| 165 | |||
| 166 | 3356 | int nval = 0; | |
| 167 |
2/2✓ Branch 0 taken 859136 times.
✓ Branch 1 taken 3356 times.
|
862492 | for (int i = 0; i < 256; i++) { |
| 168 |
2/2✓ Branch 0 taken 75178 times.
✓ Branch 1 taken 783958 times.
|
859136 | if (s->val_count[i]) { |
| 169 | 75178 | val_counts[nval].value = i; | |
| 170 | 75178 | val_counts[nval].prob = s->val_count[i]; | |
| 171 | 75178 | nval++; | |
| 172 | av_assert2(nval <= max_nval); | ||
| 173 | } | ||
| 174 | } | ||
| 175 | 3356 | val_counts[nval].value = 256; | |
| 176 | 3356 | val_counts[nval].prob = 0; | |
| 177 | |||
| 178 | 3356 | mjpegenc_huffman_compute_bits(val_counts, bits, nval + 1, 16); | |
| 179 | |||
| 180 | // val_counts[0] is the fake element we added earlier. | ||
| 181 | av_assert1(val_counts[0].prob == 0 && val_counts[0].value == 256); | ||
| 182 | // The following loop puts the values with higher occurrence first, | ||
| 183 | // ensuring that they get the shorter codes. | ||
| 184 |
2/2✓ Branch 0 taken 75178 times.
✓ Branch 1 taken 3356 times.
|
78534 | for (int i = 0; i < nval; ++i) |
| 185 | 75178 | val[i] = val_counts[nval - i].value; | |
| 186 | 3356 | } | |
| 187 |