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
070a40f1
Commit
070a40f1
authored
Dec 06, 2011
by
Matthieu Bouron
Committed by
Michael Niedermayer
Dec 07, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gxfenc: support timecode option
Reviewed-by: Baptiste Coudurier
parent
a99dbe01
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
86 additions
and
20 deletions
+86
-20
gxfenc.c
libavformat/gxfenc.c
+85
-19
gxf
tests/ref/lavf/gxf
+1
-1
No files found.
libavformat/gxfenc.c
View file @
070a40f1
...
...
@@ -20,7 +20,9 @@
*/
#include "libavutil/intfloat_readwrite.h"
#include "libavutil/opt.h"
#include "libavutil/mathematics.h"
#include "libavcodec/timecode.h"
#include "avformat.h"
#include "internal.h"
#include "gxf.h"
...
...
@@ -29,6 +31,19 @@
#define GXF_AUDIO_PACKET_SIZE 65536
#define GXF_TIMECODE(c, d, h, m, s, f) \
((c) << 30 | (d) << 29 | (h) << 24 | (m) << 16 | (s) << 8 | (f))
typedef
struct
GXFTimecode
{
int
hh
;
int
mm
;
int
ss
;
int
ff
;
int
color
;
int
drop
;
char
*
str
;
}
GXFTimecode
;
typedef
struct
GXFStreamContext
{
AudioInterleaveContext
aic
;
uint32_t
track_type
;
...
...
@@ -49,6 +64,7 @@ typedef struct GXFStreamContext {
}
GXFStreamContext
;
typedef
struct
GXFContext
{
AVClass
*
av_class
;
uint32_t
nb_fields
;
uint16_t
audio_tracks
;
uint16_t
mpeg_tracks
;
...
...
@@ -67,6 +83,7 @@ typedef struct GXFContext {
uint64_t
*
map_offsets
;
///< offset of map packets
unsigned
map_offsets_nb
;
unsigned
packet_count
;
GXFTimecode
tc
;
}
GXFContext
;
static
const
struct
{
...
...
@@ -200,19 +217,21 @@ static int gxf_write_mpeg_auxiliary(AVIOContext *pb, AVStream *st)
return
size
+
3
;
}
static
int
gxf_write_timecode_auxiliary
(
AVIOContext
*
pb
,
GXF
StreamContext
*
sc
)
static
int
gxf_write_timecode_auxiliary
(
AVIOContext
*
pb
,
GXF
Context
*
gxf
)
{
avio_w8
(
pb
,
0
);
/* fields */
avio_w8
(
pb
,
0
);
/* seconds */
avio_w8
(
pb
,
0
);
/* minutes */
avio_w8
(
pb
,
0
);
/* flags + hours */
uint32_t
timecode
=
GXF_TIMECODE
(
gxf
->
tc
.
color
,
gxf
->
tc
.
drop
,
gxf
->
tc
.
hh
,
gxf
->
tc
.
mm
,
gxf
->
tc
.
ss
,
gxf
->
tc
.
ff
);
avio_wl32
(
pb
,
timecode
);
/* reserved */
avio_w
b
32
(
pb
,
0
);
avio_w
l
32
(
pb
,
0
);
return
8
;
}
static
int
gxf_write_track_description
(
AVFormatContext
*
s
,
GXFStreamContext
*
sc
,
int
index
)
{
GXFContext
*
gxf
=
s
->
priv_data
;
AVIOContext
*
pb
=
s
->
pb
;
int64_t
pos
;
int
mpeg
=
sc
->
track_type
==
4
||
sc
->
track_type
==
9
;
...
...
@@ -236,7 +255,7 @@ static int gxf_write_track_description(AVFormatContext *s, GXFStreamContext *sc,
avio_w8
(
pb
,
TRACK_AUX
);
avio_w8
(
pb
,
8
);
if
(
sc
->
track_type
==
3
)
gxf_write_timecode_auxiliary
(
pb
,
sc
);
gxf_write_timecode_auxiliary
(
pb
,
gxf
);
else
avio_wl64
(
pb
,
0
);
}
...
...
@@ -398,7 +417,9 @@ static int gxf_write_umf_material_description(AVFormatContext *s)
int
timecode_base
=
gxf
->
time_base
.
den
==
60000
?
60
:
50
;
int64_t
timestamp
=
0
;
AVDictionaryEntry
*
t
;
uint32_t
timecode
;
uint64_t
nb_fields
;
uint32_t
timecode_in
;
// timecode at mark in
uint32_t
timecode_out
;
// timecode at mark out
#if FF_API_TIMESTAMP
if
(
s
->
timestamp
)
...
...
@@ -408,20 +429,29 @@ static int gxf_write_umf_material_description(AVFormatContext *s)
if
(
t
=
av_dict_get
(
s
->
metadata
,
"creation_time"
,
NULL
,
0
))
timestamp
=
ff_iso8601_to_unix_time
(
t
->
value
);
// XXX drop frame
timecode
=
gxf
->
nb_fields
/
(
timecode_base
*
3600
)
%
24
<<
24
|
// hours
gxf
->
nb_fields
/
(
timecode_base
*
60
)
%
60
<<
16
|
// minutes
gxf
->
nb_fields
/
timecode_base
%
60
<<
8
|
// seconds
gxf
->
nb_fields
%
timecode_base
;
// fields
timecode_in
=
GXF_TIMECODE
(
gxf
->
tc
.
color
,
gxf
->
tc
.
drop
,
gxf
->
tc
.
hh
,
gxf
->
tc
.
mm
,
gxf
->
tc
.
ss
,
gxf
->
tc
.
ff
);
nb_fields
=
gxf
->
nb_fields
+
gxf
->
tc
.
hh
*
(
timecode_base
*
3600
)
+
gxf
->
tc
.
mm
*
(
timecode_base
*
60
)
+
gxf
->
tc
.
ss
*
timecode_base
+
gxf
->
tc
.
ff
;
timecode_out
=
GXF_TIMECODE
(
gxf
->
tc
.
color
,
gxf
->
tc
.
drop
,
nb_fields
/
(
timecode_base
*
3600
)
%
24
,
nb_fields
/
(
timecode_base
*
60
)
%
60
,
nb_fields
/
timecode_base
%
60
,
nb_fields
%
timecode_base
);
avio_wl32
(
pb
,
gxf
->
flags
);
avio_wl32
(
pb
,
gxf
->
nb_fields
);
/* length of the longest track */
avio_wl32
(
pb
,
gxf
->
nb_fields
);
/* length of the shortest track */
avio_wl32
(
pb
,
0
);
/* mark in */
avio_wl32
(
pb
,
gxf
->
nb_fields
);
/* mark out */
avio_wl32
(
pb
,
0
);
/* timecode mark in */
avio_wl32
(
pb
,
timecode
);
/* timecode mark out */
avio_wl32
(
pb
,
timecode_in
);
/* timecode mark in */
avio_wl32
(
pb
,
timecode
_out
);
/* timecode mark out */
avio_wl64
(
pb
,
timestamp
);
/* modification time */
avio_wl64
(
pb
,
timestamp
);
/* creation time */
avio_wl16
(
pb
,
0
);
/* reserved */
...
...
@@ -496,9 +526,9 @@ static int gxf_write_umf_media_mpeg(AVIOContext *pb, AVStream *st)
return
32
;
}
static
int
gxf_write_umf_media_timecode
(
AVIOContext
*
pb
,
GXFStreamContext
*
sc
)
static
int
gxf_write_umf_media_timecode
(
AVIOContext
*
pb
,
int
drop
)
{
avio_wl32
(
pb
,
1
);
/* non
drop frame */
avio_wl32
(
pb
,
drop
);
/*
drop frame */
avio_wl32
(
pb
,
0
);
/* reserved */
avio_wl32
(
pb
,
0
);
/* reserved */
avio_wl32
(
pb
,
0
);
/* reserved */
...
...
@@ -578,7 +608,7 @@ static int gxf_write_umf_media_description(AVFormatContext *s)
avio_wl32
(
pb
,
0
);
/* reserved */
if
(
sc
==
&
gxf
->
timecode_track
)
gxf_write_umf_media_timecode
(
pb
,
sc
);
/* 8 0bytes */
gxf_write_umf_media_timecode
(
pb
,
gxf
->
tc
.
drop
);
else
{
AVStream
*
st
=
s
->
streams
[
i
];
switch
(
st
->
codec
->
codec_id
)
{
...
...
@@ -641,6 +671,25 @@ static void gxf_init_timecode_track(GXFStreamContext *sc, GXFStreamContext *vsc)
sc
->
fields
=
vsc
->
fields
;
}
static
int
gxf_init_timecode
(
AVFormatContext
*
s
,
GXFTimecode
*
tc
,
int
fields
)
{
char
c
;
if
(
sscanf
(
tc
->
str
,
"%d:%d:%d%c%d"
,
&
tc
->
hh
,
&
tc
->
mm
,
&
tc
->
ss
,
&
c
,
&
tc
->
ff
)
!=
5
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"unable to parse timecode, "
"syntax: hh:mm:ss[:;.]ff
\n
"
);
return
-
1
;
}
tc
->
color
=
0
;
tc
->
drop
=
c
!=
':'
;
if
(
fields
==
2
)
tc
->
ff
=
tc
->
ff
*
2
;
return
0
;
}
static
int
gxf_write_header
(
AVFormatContext
*
s
)
{
AVIOContext
*
pb
=
s
->
pb
;
...
...
@@ -759,6 +808,10 @@ static int gxf_write_header(AVFormatContext *s)
if
(
ff_audio_interleave_init
(
s
,
GXF_samples_per_frame
,
(
AVRational
){
1
,
48000
})
<
0
)
return
-
1
;
if
(
gxf
->
tc
.
str
)
{
gxf_init_timecode
(
s
,
&
gxf
->
tc
,
vsc
->
fields
);
}
gxf_init_timecode_track
(
&
gxf
->
timecode_track
,
vsc
);
gxf
->
flags
|=
0x200000
;
// time code track is non-drop frame
...
...
@@ -946,6 +999,18 @@ static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pk
av_interleave_packet_per_dts
,
gxf_compare_field_nb
);
}
static
const
AVOption
options
[]
=
{
{
TIMECODE_OPT
(
GXFContext
,
AV_OPT_FLAG_ENCODING_PARAM
)
},
{
NULL
}
};
static
const
AVClass
gxf_muxer_class
=
{
.
class_name
=
"GXF muxer"
,
.
item_name
=
av_default_item_name
,
.
option
=
options
,
.
version
=
LIBAVUTIL_VERSION_INT
,
};
AVOutputFormat
ff_gxf_muxer
=
{
.
name
=
"gxf"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"GXF format"
),
...
...
@@ -957,4 +1022,5 @@ AVOutputFormat ff_gxf_muxer = {
.
write_packet
=
gxf_write_packet
,
.
write_trailer
=
gxf_write_trailer
,
.
interleave_packet
=
gxf_interleave_packet
,
.
priv_class
=
&
gxf_muxer_class
,
};
tests/ref/lavf/gxf
View file @
070a40f1
346d38d330ab5cb0caa6b5537167bc0d
*./tests/data/lavf/lavf.gxf
1c1693cf2358025f1e37ac76e1da925a
*./tests/data/lavf/lavf.gxf
796392 ./tests/data/lavf/lavf.gxf
./tests/data/lavf/lavf.gxf CRC=0x102918fd
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