Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
b5859e0b
Commit
b5859e0b
authored
Sep 12, 2017
by
Mark Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mpeg12: Move finding the best frame rate to common code
Previously in the mpeg2_metadata filter. Also adds a test.
parent
a41b69b5
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
166 additions
and
53 deletions
+166
-53
Makefile
libavcodec/Makefile
+1
-0
mpeg12.h
libavcodec/mpeg12.h
+4
-0
mpeg12framerate.c
libavcodec/mpeg12framerate.c
+64
-0
mpeg2_metadata_bsf.c
libavcodec/mpeg2_metadata_bsf.c
+5
-53
mpeg12framerate.c
libavcodec/tests/mpeg12framerate.c
+87
-0
libavcodec.mak
tests/fate/libavcodec.mak
+5
-0
No files found.
libavcodec/Makefile
View file @
b5859e0b
...
...
@@ -824,6 +824,7 @@ TESTPROGS-$(CONFIG_FFT) += fft fft-fixed
TESTPROGS-$(CONFIG_GOLOMB)
+=
golomb
TESTPROGS-$(CONFIG_IDCTDSP)
+=
dct
TESTPROGS-$(CONFIG_IIRFILTER)
+=
iirfilter
TESTPROGS-$(CONFIG_MPEGVIDEO)
+=
mpeg12framerate
TESTPROGS-$(CONFIG_RANGECODER)
+=
rangecoder
TESTOBJS
=
dctref.o
...
...
libavcodec/mpeg12.h
View file @
b5859e0b
...
...
@@ -64,4 +64,8 @@ void ff_mpeg1_encode_mb(MpegEncContext *s, int16_t block[8][64],
void
ff_mpeg1_encode_init
(
MpegEncContext
*
s
);
void
ff_mpeg1_encode_slice_header
(
MpegEncContext
*
s
);
void
ff_mpeg12_find_best_frame_rate
(
AVRational
frame_rate
,
int
*
code
,
int
*
ext_n
,
int
*
ext_d
,
int
nonstandard
);
#endif
/* AVCODEC_MPEG12_H */
libavcodec/mpeg12framerate.c
View file @
b5859e0b
...
...
@@ -18,6 +18,9 @@
#include "libavutil/rational.h"
#include "mpeg12.h"
#include "mpeg12data.h"
const
AVRational
ff_mpeg12_frame_rate_tab
[
16
]
=
{
{
0
,
0
},
{
24000
,
1001
},
...
...
@@ -37,3 +40,64 @@ const AVRational ff_mpeg12_frame_rate_tab[16] = {
{
15
,
1
},
{
0
,
0
},
};
void
ff_mpeg12_find_best_frame_rate
(
AVRational
frame_rate
,
int
*
code
,
int
*
ext_n
,
int
*
ext_d
,
int
nonstandard
)
{
int
mpeg2
=
ext_n
&&
ext_d
;
int
max_code
=
nonstandard
?
12
:
8
;
int
c
,
n
,
d
,
best_c
,
best_n
,
best_d
;
AVRational
best_error
=
{
INT_MAX
,
1
};
// Default to NTSC if the inputs make no sense.
best_c
=
4
;
best_n
=
best_d
=
1
;
for
(
c
=
1
;
c
<=
max_code
;
c
++
)
{
if
(
av_cmp_q
(
frame_rate
,
ff_mpeg12_frame_rate_tab
[
c
])
==
0
)
{
best_c
=
c
;
goto
found
;
}
}
for
(
c
=
1
;
c
<=
max_code
;
c
++
)
{
for
(
n
=
1
;
n
<=
(
mpeg2
?
4
:
1
);
n
++
)
{
for
(
d
=
1
;
d
<=
(
mpeg2
?
32
:
1
);
d
++
)
{
AVRational
test
,
error
;
int
cmp
;
test
=
av_mul_q
(
ff_mpeg12_frame_rate_tab
[
c
],
(
AVRational
)
{
n
,
d
});
cmp
=
av_cmp_q
(
test
,
frame_rate
);
if
(
cmp
==
0
)
{
best_c
=
c
;
best_n
=
n
;
best_d
=
d
;
goto
found
;
}
if
(
cmp
<
0
)
error
=
av_div_q
(
frame_rate
,
test
);
else
error
=
av_div_q
(
test
,
frame_rate
);
cmp
=
av_cmp_q
(
error
,
best_error
);
if
(
cmp
<
0
||
(
cmp
==
0
&&
n
==
1
&&
d
==
1
))
{
best_c
=
c
;
best_n
=
n
;
best_d
=
d
;
best_error
=
error
;
}
}
}
}
found:
*
code
=
best_c
;
if
(
mpeg2
)
{
*
ext_n
=
best_n
-
1
;
*
ext_d
=
best_d
-
1
;
}
}
libavcodec/mpeg2_metadata_bsf.c
View file @
b5859e0b
...
...
@@ -23,6 +23,7 @@
#include "bsf.h"
#include "cbs.h"
#include "cbs_mpeg2.h"
#include "mpeg12.h"
typedef
struct
MPEG2MetadataContext
{
const
AVClass
*
class
;
...
...
@@ -99,63 +100,14 @@ static int mpeg2_metadata_update_fragment(AVBSFContext *bsf,
}
if
(
ctx
->
frame_rate
.
num
&&
ctx
->
frame_rate
.
den
)
{
// Table 6-4.
static
AVRational
frame_rate_table
[]
=
{
{
0
,
0
},
{
24000
,
1001
},
{
24
,
1
},
{
25
,
1
},
{
30000
,
1001
},
{
30
,
1
},
{
50
,
1
},
{
60000
,
1001
},
{
60
,
1
},
};
int
code
,
ext_n
,
ext_d
;
AVRational
best_error
=
{
INT_MAX
,
1
};
for
(
i
=
1
;
i
<
FF_ARRAY_ELEMS
(
frame_rate_table
);
i
++
)
{
if
(
av_cmp_q
(
ctx
->
frame_rate
,
frame_rate_table
[
i
])
==
0
)
{
code
=
i
;
ext_n
=
1
;
ext_d
=
1
;
goto
found_frame_rate
;
}
}
for
(
i
=
1
;
i
<
FF_ARRAY_ELEMS
(
frame_rate_table
);
i
++
)
{
AVRational
fr
,
error
;
int
n
,
d
,
cmp
;
for
(
n
=
1
;
n
<=
4
;
n
++
)
{
for
(
d
=
1
;
d
<=
32
;
d
++
)
{
fr
=
av_mul_q
(
frame_rate_table
[
i
],
(
AVRational
)
{
n
,
d
});
cmp
=
av_cmp_q
(
fr
,
ctx
->
frame_rate
);
if
(
cmp
==
0
)
{
code
=
i
;
ext_n
=
n
;
ext_d
=
d
;
goto
found_frame_rate
;
}
if
(
cmp
<
0
)
error
=
av_div_q
(
ctx
->
frame_rate
,
fr
);
else
error
=
av_div_q
(
fr
,
ctx
->
frame_rate
);
cmp
=
av_cmp_q
(
error
,
best_error
);
if
(
cmp
<
0
||
(
cmp
==
0
&&
n
==
1
&&
d
==
1
))
{
code
=
i
;
ext_n
=
n
;
ext_d
=
d
;
best_error
=
error
;
}
}
}
}
ff_mpeg12_find_best_frame_rate
(
ctx
->
frame_rate
,
&
code
,
&
ext_n
,
&
ext_d
,
0
);
found_frame_rate:
sh
->
frame_rate_code
=
code
;
se
->
frame_rate_extension_n
=
ext_n
-
1
;
se
->
frame_rate_extension_d
=
ext_d
-
1
;
se
->
frame_rate_extension_n
=
ext_n
;
se
->
frame_rate_extension_d
=
ext_d
;
}
if
(
ctx
->
video_format
>=
0
||
...
...
libavcodec/tests/mpeg12framerate.c
0 → 100644
View file @
b5859e0b
/*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavcodec/mpeg12.h"
#include "libavcodec/mpeg12data.h"
int
main
(
void
)
{
int
i
;
#define TEST_MATCH(frame_rate, code, ext_n, ext_d) do { \
AVRational fr = frame_rate; \
int c, n, d; \
ff_mpeg12_find_best_frame_rate(fr, &c, &n, &d, 0); \
if (c != code || n != ext_n || d != ext_d) { \
av_log(NULL, AV_LOG_ERROR, "Failed to match %d/%d: " \
"code = %d, ext_n = %d, ext_d = %d.\n", \
fr.num, fr.den, c, n, d); \
return 1; \
} \
} while (0)
#define TEST_EXACT(frn, frd) do { \
AVRational fr = (AVRational) { frn, frd }; \
int c, n, d; \
ff_mpeg12_find_best_frame_rate(fr, &c, &n, &d, 0); \
if (av_cmp_q(fr, av_mul_q(ff_mpeg12_frame_rate_tab[c], \
(AVRational) { n + 1, d + 1 })) != 0) { \
av_log(NULL, AV_LOG_ERROR, "Failed to find exact %d/%d: " \
"code = %d, ext_n = %d, ext_d = %d.\n", \
fr.num, fr.den, c, n, d); \
return 1; \
} \
} while (0)
// Framerates in the table must be chosen exactly.
for
(
i
=
1
;
i
<=
8
;
i
++
)
TEST_MATCH
(
ff_mpeg12_frame_rate_tab
[
i
],
i
,
0
,
0
);
// As should the same ones with small perturbations.
// (1/1000 used here to be smaller than half the difference
// between 24 and 24000/1001.)
for
(
i
=
1
;
i
<=
8
;
i
++
)
{
TEST_MATCH
(
av_sub_q
(
ff_mpeg12_frame_rate_tab
[
i
],
(
AVRational
)
{
1
,
1000
}),
i
,
0
,
0
);
TEST_MATCH
(
av_add_q
(
ff_mpeg12_frame_rate_tab
[
i
],
(
AVRational
)
{
1
,
1000
}),
i
,
0
,
0
);
}
// Exactly constructable framerates should be exact. Note that some
// values can be made in multiple ways (e.g. 12 = 24 / 2 == 60 / 5),
// and there is no reason to favour any particular choice.
TEST_EXACT
(
1
,
1
);
TEST_EXACT
(
2
,
1
);
TEST_EXACT
(
12
,
1
);
TEST_EXACT
(
15000
,
1001
);
TEST_EXACT
(
15
,
1
);
TEST_EXACT
(
120
,
1
);
TEST_EXACT
(
120000
,
1001
);
TEST_EXACT
(
200
,
1
);
TEST_EXACT
(
240
,
1
);
// Values higher than 240 (the highest representable, as 60 * 4 / 1)
// should be mapped to 240.
for
(
i
=
240
;
i
<
1000
;
i
+=
10
)
TEST_MATCH
(((
AVRational
)
{
i
,
1
}),
8
,
3
,
0
);
// Values lower than 24000/32032 (the lowest representable, as
// 24000/1001 * 1 / 32) should be mapped to 24000/32032.
for
(
i
=
74
;
i
>
0
;
i
--
)
TEST_MATCH
(((
AVRational
)
{
i
,
100
}),
1
,
0
,
31
);
return
0
;
}
tests/fate/libavcodec.mak
View file @
b5859e0b
...
...
@@ -12,6 +12,11 @@ FATE_LIBAVCODEC-$(CONFIG_IIRFILTER) += fate-iirfilter
fate-iirfilter: libavcodec/tests/iirfilter$(EXESUF)
fate-iirfilter: CMD = run libavcodec/tests/iirfilter
FATE_LIBAVCODEC-$(CONFIG_MPEGVIDEO) += fate-mpeg12framerate
fate-mpeg12framerate: libavcodec/tests/mpeg12framerate$(EXESUF)
fate-mpeg12framerate: CMD = run libavcodec/tests/mpeg12framerate
fate-mpeg12framerate: CMP = null
FATE_LIBAVCODEC-$(CONFIG_RANGECODER) += fate-rangecoder
fate-rangecoder: libavcodec/tests/rangecoder$(EXESUF)
fate-rangecoder: CMD = run libavcodec/tests/rangecoder
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment