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
0eaa123b
Commit
0eaa123b
authored
Jan 16, 2012
by
Clément Bœsch
Committed by
Clément Bœsch
Feb 02, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavu: add public timecode API.
parent
b18ebcbe
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
338 additions
and
1 deletion
+338
-1
APIchanges
doc/APIchanges
+3
-0
Makefile
libavutil/Makefile
+2
-0
avutil.h
libavutil/avutil.h
+1
-1
timecode.c
libavutil/timecode.c
+194
-0
timecode.h
libavutil/timecode.h
+138
-0
No files found.
doc/APIchanges
View file @
0eaa123b
...
...
@@ -13,6 +13,9 @@ libavutil: 2011-04-18
API changes, most recent first:
2012-02-02 - xxxxxxx - lavu 51.37.100
Add public timecode helpers.
2012-01-24 - xxxxxxx - lavfi 2.60.100
Add avfilter_graph_dump.
...
...
libavutil/Makefile
View file @
0eaa123b
...
...
@@ -37,6 +37,7 @@ HEADERS = adler32.h \
rational.h
\
samplefmt.h
\
sha.h
\
timecode.h
\
BUILT_HEADERS
=
avconfig.h
...
...
@@ -71,6 +72,7 @@ OBJS = adler32.o \
rc4.o
\
samplefmt.o
\
sha.o
\
timecode.o
\
tree.o
\
utils.o
\
...
...
libavutil/avutil.h
View file @
0eaa123b
...
...
@@ -154,7 +154,7 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 51
#define LIBAVUTIL_VERSION_MINOR 3
6
#define LIBAVUTIL_VERSION_MINOR 3
7
#define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
...
...
libavutil/timecode.c
0 → 100644
View file @
0eaa123b
/*
* Copyright (c) 2006 Smartjog S.A.S, Baptiste Coudurier <baptiste.coudurier@gmail.com>
* Copyright (c) 2011-2012 Smartjog S.A.S, Clément Bœsch <clement.boesch@smartjog.com>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Timecode helpers
* A few references:
* https://en.wikipedia.org/wiki/SMPTE_time_code
* http://www.dropframetimecode.org
*/
#include <stdio.h>
#include "timecode.h"
#include "log.h"
#include "error.h"
int
av_timecode_adjust_ntsc_framenum
(
int
framenum
)
{
/* only works for NTSC 29.97 */
int
d
=
framenum
/
17982
;
int
m
=
framenum
%
17982
;
//if (m < 2) m += 2; /* not needed since -2,-1 / 1798 in C returns 0 */
return
framenum
+
18
*
d
+
2
*
((
m
-
2
)
/
1798
);
}
uint32_t
av_timecode_get_smpte_from_framenum
(
const
AVTimecode
*
tc
,
int
framenum
)
{
unsigned
fps
=
tc
->
fps
;
int
drop
=
!!
(
tc
->
flags
&
AV_TIMECODE_FLAG_DROPFRAME
);
int
hh
,
mm
,
ss
,
ff
;
framenum
+=
tc
->
start
;
if
(
drop
)
framenum
=
av_timecode_adjust_ntsc_framenum
(
framenum
);
ff
=
framenum
%
fps
;
ss
=
framenum
/
fps
%
60
;
mm
=
framenum
/
(
fps
*
60
)
%
60
;
hh
=
framenum
/
(
fps
*
3600
)
%
24
;
return
0
<<
31
|
// color frame flag (0: unsync mode, 1: sync mode)
drop
<<
30
|
// drop frame flag (0: non drop, 1: drop)
(
ff
/
10
)
<<
28
|
// tens of frames
(
ff
%
10
)
<<
24
|
// units of frames
0
<<
23
|
// PC (NTSC) or BGF0 (PAL)
(
ss
/
10
)
<<
20
|
// tens of seconds
(
ss
%
10
)
<<
16
|
// units of seconds
0
<<
15
|
// BGF0 (NTSC) or BGF2 (PAL)
(
mm
/
10
)
<<
12
|
// tens of minutes
(
mm
%
10
)
<<
8
|
// units of minutes
0
<<
7
|
// BGF2 (NTSC) or PC (PAL)
0
<<
6
|
// BGF1
(
hh
/
10
)
<<
4
|
// tens of hours
(
hh
%
10
);
// units of hours
}
char
*
av_timecode_make_string
(
const
AVTimecode
*
tc
,
char
*
buf
,
int
framenum
)
{
int
fps
=
tc
->
fps
;
int
drop
=
tc
->
flags
&
AV_TIMECODE_FLAG_DROPFRAME
;
int
hh
,
mm
,
ss
,
ff
,
neg
=
0
;
framenum
+=
tc
->
start
;
if
(
drop
)
framenum
=
av_timecode_adjust_ntsc_framenum
(
framenum
);
if
(
framenum
<
0
)
{
framenum
=
-
framenum
;
neg
=
tc
->
flags
&
AV_TIMECODE_FLAG_ALLOWNEGATIVE
;
}
ff
=
framenum
%
fps
;
ss
=
framenum
/
fps
%
60
;
mm
=
framenum
/
(
fps
*
60
)
%
60
;
hh
=
framenum
/
(
fps
*
3600
);
if
(
tc
->
flags
&
AV_TIMECODE_FLAG_24HOURSMAX
)
hh
=
hh
%
24
;
snprintf
(
buf
,
AV_TIMECODE_STR_SIZE
,
"%s%02d:%02d:%02d%c%02d"
,
neg
?
"-"
:
""
,
hh
,
mm
,
ss
,
drop
?
';'
:
':'
,
ff
);
return
buf
;
}
static
unsigned
bcd2uint
(
uint8_t
bcd
)
{
unsigned
low
=
bcd
&
0xf
;
unsigned
high
=
bcd
>>
4
;
if
(
low
>
9
||
high
>
9
)
return
0
;
return
low
+
10
*
high
;
}
char
*
av_timecode_make_smpte_tc_string
(
char
*
buf
,
uint32_t
tcsmpte
,
int
prevent_df
)
{
unsigned
hh
=
bcd2uint
(
tcsmpte
&
0x3f
);
// 6-bit hours
unsigned
mm
=
bcd2uint
(
tcsmpte
>>
8
&
0x7f
);
// 7-bit minutes
unsigned
ss
=
bcd2uint
(
tcsmpte
>>
16
&
0x7f
);
// 7-bit seconds
unsigned
ff
=
bcd2uint
(
tcsmpte
>>
24
&
0x3f
);
// 6-bit frames
unsigned
drop
=
tcsmpte
&
1
<<
30
&&
!
prevent_df
;
// 1-bit drop if not arbitrary bit
snprintf
(
buf
,
AV_TIMECODE_STR_SIZE
,
"%02u:%02u:%02u%c%02u"
,
hh
,
mm
,
ss
,
drop
?
';'
:
':'
,
ff
);
return
buf
;
}
char
*
av_timecode_make_mpeg_tc_string
(
char
*
buf
,
uint32_t
tc25bit
)
{
snprintf
(
buf
,
AV_TIMECODE_STR_SIZE
,
"%02u:%02u:%02u%c%02u"
,
tc25bit
>>
19
&
0x1f
,
// 5-bit hours
tc25bit
>>
13
&
0x3f
,
// 6-bit minutes
tc25bit
>>
6
&
0x3f
,
// 6-bit seconds
tc25bit
&
1
<<
24
?
';'
:
':'
,
// 1-bit drop flag
tc25bit
&
0x3f
);
// 6-bit frames
return
buf
;
}
static
int
check_timecode
(
void
*
log_ctx
,
AVTimecode
*
tc
)
{
if
(
tc
->
fps
<=
0
)
{
av_log
(
log_ctx
,
AV_LOG_ERROR
,
"Timecode frame rate must be specified
\n
"
);
return
AVERROR
(
EINVAL
);
}
if
((
tc
->
flags
&
AV_TIMECODE_FLAG_DROPFRAME
)
&&
tc
->
fps
!=
30
)
{
av_log
(
log_ctx
,
AV_LOG_ERROR
,
"Drop frame is only allowed with 30000/1001 FPS
\n
"
);
return
AVERROR
(
EINVAL
);
}
switch
(
tc
->
fps
)
{
case
24
:
case
25
:
case
30
:
return
0
;
default:
av_log
(
log_ctx
,
AV_LOG_ERROR
,
"Timecode frame rate not supported
\n
"
);
return
AVERROR_PATCHWELCOME
;
}
}
static
int
fps_from_frame_rate
(
AVRational
rate
)
{
if
(
!
rate
.
den
||
!
rate
.
num
)
return
-
1
;
return
(
rate
.
num
+
rate
.
den
/
2
)
/
rate
.
den
;
}
int
av_timecode_init
(
AVTimecode
*
tc
,
AVRational
rate
,
int
flags
,
int
frame_start
,
void
*
log_ctx
)
{
memset
(
tc
,
0
,
sizeof
(
*
tc
));
tc
->
start
=
frame_start
;
tc
->
flags
=
flags
;
tc
->
rate
=
rate
;
tc
->
fps
=
fps_from_frame_rate
(
rate
);
return
check_timecode
(
log_ctx
,
tc
);
}
int
av_timecode_init_from_string
(
AVTimecode
*
tc
,
AVRational
rate
,
const
char
*
str
,
void
*
log_ctx
)
{
char
c
;
int
hh
,
mm
,
ss
,
ff
,
ret
;
if
(
sscanf
(
str
,
"%d:%d:%d%c%d"
,
&
hh
,
&
mm
,
&
ss
,
&
c
,
&
ff
)
!=
5
)
{
av_log
(
log_ctx
,
AV_LOG_ERROR
,
"Unable to parse timecode, "
"syntax: hh:mm:ss[:;.]ff
\n
"
);
return
AVERROR_INVALIDDATA
;
}
memset
(
tc
,
0
,
sizeof
(
*
tc
));
tc
->
flags
=
c
!=
':'
?
AV_TIMECODE_FLAG_DROPFRAME
:
0
;
// drop if ';', '.', ...
tc
->
rate
=
rate
;
tc
->
fps
=
fps_from_frame_rate
(
rate
);
ret
=
check_timecode
(
log_ctx
,
tc
);
if
(
ret
<
0
)
return
ret
;
tc
->
start
=
(
hh
*
3600
+
mm
*
60
+
ss
)
*
tc
->
fps
+
ff
;
if
(
tc
->
flags
&
AV_TIMECODE_FLAG_DROPFRAME
)
{
/* adjust frame number */
int
tmins
=
60
*
hh
+
mm
;
tc
->
start
-=
2
*
(
tmins
-
tmins
/
10
);
}
return
0
;
}
libavutil/timecode.h
0 → 100644
View file @
0eaa123b
/*
* Copyright (c) 2006 Smartjog S.A.S, Baptiste Coudurier <baptiste.coudurier@gmail.com>
* Copyright (c) 2011-2012 Smartjog S.A.S, Clément Bœsch <clement.boesch@smartjog.com>
*
* This file is part of FFmpeg.
*
* FFmpeg 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.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Timecode helpers header
*/
#ifndef AVUTIL_TIMECODE_H
#define AVUTIL_TIMECODE_H
#include <stdint.h>
#include "rational.h"
#define AV_TIMECODE_STR_SIZE 16
#define AV_TIMECODE_OPTION(ctx, string_field, flags) \
"timecode", "set timecode value following hh:mm:ss[:;.]ff format, " \
"use ';' or '.' before frame number for drop frame", \
offsetof(ctx, string_field), \
AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, flags
enum
AVTimecodeFlag
{
AV_TIMECODE_FLAG_DROPFRAME
=
1
<<
0
,
///< timecode is drop frame
AV_TIMECODE_FLAG_24HOURSMAX
=
1
<<
1
,
///< timecode wraps after 24 hours
AV_TIMECODE_FLAG_ALLOWNEGATIVE
=
1
<<
2
,
///< negative time values are allowed
};
typedef
struct
{
int
start
;
///< timecode frame start (first base frame number)
uint32_t
flags
;
///< flags such as drop frame, +24 hours support, ...
AVRational
rate
;
///< frame rate in rational form
unsigned
fps
;
///< frame per second; must be consistent with the rate field
}
AVTimecode
;
/**
* Adjust frame number for NTSC drop frame time code.
*
* @param framenum frame number to adjust
* @return adjusted frame number
* @warning adjustment is only valid in NTSC 29.97
*/
int
av_timecode_adjust_ntsc_framenum
(
int
framenum
);
/**
* Convert frame number to SMPTE 12M binary representation.
*
* @param tc timecode data correctly initialized
* @param framenum frame number
* @return the SMPTE binary representation
*
* @note Frame number adjustment is automatically done in case of drop timecode,
* you do NOT have to call av_timecode_adjust_ntsc_framenum().
* @note The frame number is relative to tc->start.
* @note Color frame (CF), binary group flags (BGF) and biphase mark polarity
* correction (PC) bits are set to zero.
*/
uint32_t
av_timecode_get_smpte_from_framenum
(
const
AVTimecode
*
tc
,
int
framenum
);
/**
* Load timecode string in buf.
*
* @param buf destination buffer, must be at least AV_TIMECODE_STR_SIZE long
* @param tc timecode data correctly initialized
* @param framenum frame number
* @return the buf parameter
*
* @note Timecode representation can be a negative timecode and have more than
* 24 hours, but will only be honored if the flags are correctly set.
* @note The frame number is relative to tc->start.
*/
char
*
av_timecode_make_string
(
const
AVTimecode
*
tc
,
char
*
buf
,
int
framenum
);
/**
* Get the timecode string from the SMPTE timecode format.
*
* @param buf destination buffer, must be at least AV_TIMECODE_STR_SIZE long
* @param tcsmpte the 32-bit SMPTE timecode
* @param prevent_df prevent the use of a drop flag when it is known the DF bit
* is arbitrary
* @return the buf parameter
*/
char
*
av_timecode_make_smpte_tc_string
(
char
*
buf
,
uint32_t
tcsmpte
,
int
prevent_df
);
/**
* Get the timecode string from the 25-bit timecode format (MPEG GOP format).
*
* @param buf destination buffer, must be at least AV_TIMECODE_STR_SIZE long
* @param tc25bit the 25-bits timecode
* @return the buf parameter
*/
char
*
av_timecode_make_mpeg_tc_string
(
char
*
buf
,
uint32_t
tc25bit
);
/**
* Init a timecode struct with the passed parameters.
*
* @param log_ctx a pointer to an arbitrary struct of which the first field
* is a pointer to an AVClass struct (used for av_log)
* @param tc pointer to an allocated AVTimecode
* @param rate frame rate in rational form
* @param flags miscellaneous flags such as drop frame, +24 hours, ...
* (see AVTimecodeFlag)
* @param frame_start the first frame number
* @return 0 on success, AVERROR otherwise
*/
int
av_timecode_init
(
AVTimecode
*
tc
,
AVRational
rate
,
int
flags
,
int
frame_start
,
void
*
log_ctx
);
/**
* Parse timecode representation (hh:mm:ss[:;.]ff).
*
* @param log_ctx a pointer to an arbitrary struct of which the first field is a
* pointer to an AVClass struct (used for av_log).
* @param tc pointer to an allocated AVTimecode
* @param rate frame rate in rational form
* @param str timecode string which will determine the frame start
* @return 0 on success, AVERROR otherwise
*/
int
av_timecode_init_from_string
(
AVTimecode
*
tc
,
AVRational
rate
,
const
char
*
str
,
void
*
log_ctx
);
#endif
/* AVUTIL_TIMECODE_H */
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