/src/ffmpeg/libavcodec/mpeg12framerate.c
Line | Count | Source |
1 | | /* |
2 | | * This file is part of FFmpeg. |
3 | | * |
4 | | * FFmpeg is free software; you can redistribute it and/or |
5 | | * modify it under the terms of the GNU Lesser General Public |
6 | | * License as published by the Free Software Foundation; either |
7 | | * version 2.1 of the License, or (at your option) any later version. |
8 | | * |
9 | | * FFmpeg is distributed in the hope that it will be useful, |
10 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | | * Lesser General Public License for more details. |
13 | | * |
14 | | * You should have received a copy of the GNU Lesser General Public |
15 | | * License along with FFmpeg; if not, write to the Free Software |
16 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | | */ |
18 | | |
19 | | #include "libavutil/rational.h" |
20 | | |
21 | | #include "mpeg12.h" |
22 | | #include "mpeg12data.h" |
23 | | |
24 | | const AVRational ff_mpeg12_frame_rate_tab[16] = { |
25 | | { 0, 0}, |
26 | | {24000, 1001}, |
27 | | { 24, 1}, |
28 | | { 25, 1}, |
29 | | {30000, 1001}, |
30 | | { 30, 1}, |
31 | | { 50, 1}, |
32 | | {60000, 1001}, |
33 | | { 60, 1}, |
34 | | // Xing's 15fps: (9) |
35 | | { 15, 1}, |
36 | | // libmpeg3's "Unofficial economy rates": (10-13) |
37 | | { 5, 1}, |
38 | | { 10, 1}, |
39 | | { 12, 1}, |
40 | | { 15, 1}, |
41 | | { 0, 0}, |
42 | | }; |
43 | | |
44 | | void ff_mpeg12_find_best_frame_rate(AVRational frame_rate, |
45 | | int *code, int *ext_n, int *ext_d, |
46 | | int nonstandard) |
47 | 0 | { |
48 | 0 | int mpeg2 = ext_n && ext_d; |
49 | 0 | int max_code = nonstandard ? 12 : 8; |
50 | 0 | int c, n, d, best_c, best_n, best_d; |
51 | 0 | AVRational best_error = { INT_MAX, 1 }; |
52 | | |
53 | | // Default to NTSC if the inputs make no sense. |
54 | 0 | best_c = 4; |
55 | 0 | best_n = best_d = 1; |
56 | |
|
57 | 0 | for (c = 1; c <= max_code; c++) { |
58 | 0 | if (av_cmp_q(frame_rate, ff_mpeg12_frame_rate_tab[c]) == 0) { |
59 | 0 | best_c = c; |
60 | 0 | goto found; |
61 | 0 | } |
62 | 0 | } |
63 | | |
64 | 0 | for (c = 1; c <= max_code; c++) { |
65 | 0 | for (n = 1; n <= (mpeg2 ? 4 : 1); n++) { |
66 | 0 | for (d = 1; d <= (mpeg2 ? 32 : 1); d++) { |
67 | 0 | AVRational test, error; |
68 | 0 | int cmp; |
69 | |
|
70 | 0 | test = av_mul_q(ff_mpeg12_frame_rate_tab[c], |
71 | 0 | (AVRational) { n, d }); |
72 | |
|
73 | 0 | cmp = av_cmp_q(test, frame_rate); |
74 | 0 | if (cmp == 0) { |
75 | 0 | best_c = c; |
76 | 0 | best_n = n; |
77 | 0 | best_d = d; |
78 | 0 | goto found; |
79 | 0 | } |
80 | | |
81 | 0 | if (cmp < 0) |
82 | 0 | error = av_div_q(frame_rate, test); |
83 | 0 | else |
84 | 0 | error = av_div_q(test, frame_rate); |
85 | |
|
86 | 0 | cmp = av_cmp_q(error, best_error); |
87 | 0 | if (cmp < 0 || (cmp == 0 && n == 1 && d == 1)) { |
88 | 0 | best_c = c; |
89 | 0 | best_n = n; |
90 | 0 | best_d = d; |
91 | 0 | best_error = error; |
92 | 0 | } |
93 | 0 | } |
94 | 0 | } |
95 | 0 | } |
96 | | |
97 | 0 | found: |
98 | 0 | *code = best_c; |
99 | 0 | if (mpeg2) { |
100 | 0 | *ext_n = best_n - 1; |
101 | 0 | *ext_d = best_d - 1; |
102 | 0 | } |
103 | 0 | } |