Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
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