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
76a8c3b5
Commit
76a8c3b5
authored
Oct 12, 2018
by
Josh de Kock
Committed by
Kieran Kunhya
Oct 23, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
h264/pic_timing: support multiple timecodes
parent
4241e44a
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
65 additions
and
43 deletions
+65
-43
h264_sei.c
libavcodec/h264_sei.c
+12
-9
h264_sei.h
libavcodec/h264_sei.h
+20
-8
h264_slice.c
libavcodec/h264_slice.c
+33
-26
No files found.
libavcodec/h264_sei.c
View file @
76a8c3b5
...
@@ -84,8 +84,10 @@ static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb,
...
@@ -84,8 +84,10 @@ static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb,
return
AVERROR_INVALIDDATA
;
return
AVERROR_INVALIDDATA
;
num_clock_ts
=
sei_num_clock_ts_table
[
h
->
pic_struct
];
num_clock_ts
=
sei_num_clock_ts_table
[
h
->
pic_struct
];
h
->
timecode_cnt
=
0
;
for
(
i
=
0
;
i
<
num_clock_ts
;
i
++
)
{
for
(
i
=
0
;
i
<
num_clock_ts
;
i
++
)
{
if
(
get_bits
(
gb
,
1
))
{
/* clock_timestamp_flag */
if
(
get_bits
(
gb
,
1
))
{
/* clock_timestamp_flag */
H264SEITimeCode
*
tc
=
&
h
->
timecode
[
h
->
timecode_cnt
++
];
unsigned
int
full_timestamp_flag
;
unsigned
int
full_timestamp_flag
;
unsigned
int
counting_type
,
cnt_dropped_flag
;
unsigned
int
counting_type
,
cnt_dropped_flag
;
h
->
ct_type
|=
1
<<
get_bits
(
gb
,
2
);
h
->
ct_type
|=
1
<<
get_bits
(
gb
,
2
);
...
@@ -95,20 +97,21 @@ static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb,
...
@@ -95,20 +97,21 @@ static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb,
skip_bits
(
gb
,
1
);
/* discontinuity_flag */
skip_bits
(
gb
,
1
);
/* discontinuity_flag */
cnt_dropped_flag
=
get_bits
(
gb
,
1
);
/* cnt_dropped_flag */
cnt_dropped_flag
=
get_bits
(
gb
,
1
);
/* cnt_dropped_flag */
if
(
cnt_dropped_flag
&&
counting_type
>
1
&&
counting_type
<
7
)
if
(
cnt_dropped_flag
&&
counting_type
>
1
&&
counting_type
<
7
)
h
->
tc_
dropframe
=
1
;
tc
->
dropframe
=
1
;
h
->
tc_frames
=
get_bits
(
gb
,
8
);
/* n_frames */
tc
->
frame
=
get_bits
(
gb
,
8
);
/* n_frames */
if
(
full_timestamp_flag
)
{
if
(
full_timestamp_flag
)
{
h
->
fulltc_received
=
1
;
tc
->
full
=
1
;
h
->
tc_
seconds
=
get_bits
(
gb
,
6
);
/* seconds_value 0..59 */
tc
->
seconds
=
get_bits
(
gb
,
6
);
/* seconds_value 0..59 */
h
->
tc_
minutes
=
get_bits
(
gb
,
6
);
/* minutes_value 0..59 */
tc
->
minutes
=
get_bits
(
gb
,
6
);
/* minutes_value 0..59 */
h
->
tc_
hours
=
get_bits
(
gb
,
5
);
/* hours_value 0..23 */
tc
->
hours
=
get_bits
(
gb
,
5
);
/* hours_value 0..23 */
}
else
{
}
else
{
tc
->
seconds
=
tc
->
minutes
=
tc
->
hours
=
tc
->
full
=
0
;
if
(
get_bits
(
gb
,
1
))
{
/* seconds_flag */
if
(
get_bits
(
gb
,
1
))
{
/* seconds_flag */
h
->
tc_
seconds
=
get_bits
(
gb
,
6
);
tc
->
seconds
=
get_bits
(
gb
,
6
);
if
(
get_bits
(
gb
,
1
))
{
/* minutes_flag */
if
(
get_bits
(
gb
,
1
))
{
/* minutes_flag */
h
->
tc_
minutes
=
get_bits
(
gb
,
6
);
tc
->
minutes
=
get_bits
(
gb
,
6
);
if
(
get_bits
(
gb
,
1
))
/* hours_flag */
if
(
get_bits
(
gb
,
1
))
/* hours_flag */
h
->
tc_minute
s
=
get_bits
(
gb
,
5
);
tc
->
hour
s
=
get_bits
(
gb
,
5
);
}
}
}
}
}
}
...
...
libavcodec/h264_sei.h
View file @
76a8c3b5
...
@@ -67,6 +67,17 @@ typedef enum {
...
@@ -67,6 +67,17 @@ typedef enum {
H264_SEI_FPA_TYPE_2D
=
6
,
H264_SEI_FPA_TYPE_2D
=
6
,
}
H264_SEI_FpaType
;
}
H264_SEI_FpaType
;
typedef
struct
H264SEITimeCode
{
/* When not continuously receiving full timecodes, we have to reference
the previous timecode received */
int
full
;
int
frame
;
int
seconds
;
int
minutes
;
int
hours
;
int
dropframe
;
}
H264SEITimeCode
;
typedef
struct
H264SEIPictureTiming
{
typedef
struct
H264SEIPictureTiming
{
int
present
;
int
present
;
H264_SEI_PicStructType
pic_struct
;
H264_SEI_PicStructType
pic_struct
;
...
@@ -88,14 +99,15 @@ typedef struct H264SEIPictureTiming {
...
@@ -88,14 +99,15 @@ typedef struct H264SEIPictureTiming {
*/
*/
int
cpb_removal_delay
;
int
cpb_removal_delay
;
/* When not continuously receiving full timecodes, we have to reference
/**
the previous timecode received */
* Maximum three timecodes in a pic_timing SEI.
int
fulltc_received
;
*/
int
tc_frames
;
H264SEITimeCode
timecode
[
3
];
int
tc_seconds
;
int
tc_minutes
;
/**
int
tc_hours
;
* Number of timecode in use
int
tc_dropframe
;
*/
int
timecode_cnt
;
}
H264SEIPictureTiming
;
}
H264SEIPictureTiming
;
typedef
struct
H264SEIAFD
{
typedef
struct
H264SEIAFD
{
...
...
libavcodec/h264_slice.c
View file @
76a8c3b5
...
@@ -1287,42 +1287,49 @@ static int h264_export_frame_props(H264Context *h)
...
@@ -1287,42 +1287,49 @@ static int h264_export_frame_props(H264Context *h)
h
->
avctx
->
properties
|=
FF_CODEC_PROPERTY_CLOSED_CAPTIONS
;
h
->
avctx
->
properties
|=
FF_CODEC_PROPERTY_CLOSED_CAPTIONS
;
}
}
if
(
h
->
sei
.
picture_timing
.
fulltc_received
)
{
if
(
h
->
sei
.
picture_timing
.
timecode_cnt
>
0
)
{
uint32_t
tc
=
0
;
uint32_t
tc
=
0
;
uint32_t
frames
;
uint32_t
*
tc_sd
;
AVFrameSideData
*
tcside
=
av_frame_new_side_data
(
cur
->
f
,
AVFrameSideData
*
tcside
=
av_frame_new_side_data
(
cur
->
f
,
AV_FRAME_DATA_S12M_TIMECODE
,
AV_FRAME_DATA_S12M_TIMECODE
,
sizeof
(
uint32_t
));
sizeof
(
uint32_t
)
*
4
);
if
(
!
tcside
)
if
(
!
tcside
)
return
AVERROR
(
ENOMEM
);
return
AVERROR
(
ENOMEM
);
/* For SMPTE 12-M timecodes, frame count is a special case if > 30 FPS.
tc_sd
=
(
uint32_t
*
)
tcside
->
data
;
See SMPTE ST 12-1:2014 Sec 12.1 for more info. */
tc_sd
[
0
]
=
h
->
sei
.
picture_timing
.
timecode_cnt
;
if
(
av_cmp_q
(
h
->
avctx
->
framerate
,
(
AVRational
)
{
30
,
1
})
==
1
)
{
frames
=
h
->
sei
.
picture_timing
.
tc_frames
/
2
;
for
(
int
i
=
0
;
i
<
tc_sd
[
0
];
i
++
)
{
if
(
h
->
sei
.
picture_timing
.
tc_frames
%
2
==
1
)
{
uint32_t
frames
;
if
(
av_cmp_q
(
h
->
avctx
->
framerate
,
(
AVRational
)
{
50
,
1
})
==
0
)
tc
|=
(
1
<<
7
);
/* For SMPTE 12-M timecodes, frame count is a special case if > 30 FPS.
else
See SMPTE ST 12-1:2014 Sec 12.1 for more info. */
tc
|=
(
1
<<
23
);
if
(
av_cmp_q
(
h
->
avctx
->
framerate
,
(
AVRational
)
{
30
,
1
})
==
1
)
{
frames
=
h
->
sei
.
picture_timing
.
timecode
[
i
].
frame
/
2
;
if
(
h
->
sei
.
picture_timing
.
timecode
[
i
].
frame
%
2
==
1
)
{
if
(
av_cmp_q
(
h
->
avctx
->
framerate
,
(
AVRational
)
{
50
,
1
})
==
0
)
tc
|=
(
1
<<
7
);
else
tc
|=
(
1
<<
23
);
}
}
else
{
frames
=
h
->
sei
.
picture_timing
.
timecode
[
i
].
frame
;
}
}
}
else
{
frames
=
h
->
sei
.
picture_timing
.
tc_frames
;
}
tc
|=
h
->
sei
.
picture_timing
.
tc_
dropframe
<<
30
;
tc
|=
h
->
sei
.
picture_timing
.
timecode
[
i
].
dropframe
<<
30
;
tc
|=
(
frames
/
10
)
<<
28
;
tc
|=
(
frames
/
10
)
<<
28
;
tc
|=
(
frames
%
10
)
<<
24
;
tc
|=
(
frames
%
10
)
<<
24
;
tc
|=
(
h
->
sei
.
picture_timing
.
tc_
seconds
/
10
)
<<
20
;
tc
|=
(
h
->
sei
.
picture_timing
.
timecode
[
i
].
seconds
/
10
)
<<
20
;
tc
|=
(
h
->
sei
.
picture_timing
.
tc_
seconds
%
10
)
<<
16
;
tc
|=
(
h
->
sei
.
picture_timing
.
timecode
[
i
].
seconds
%
10
)
<<
16
;
tc
|=
(
h
->
sei
.
picture_timing
.
tc_
minutes
/
10
)
<<
12
;
tc
|=
(
h
->
sei
.
picture_timing
.
timecode
[
i
].
minutes
/
10
)
<<
12
;
tc
|=
(
h
->
sei
.
picture_timing
.
tc_
minutes
%
10
)
<<
8
;
tc
|=
(
h
->
sei
.
picture_timing
.
timecode
[
i
].
minutes
%
10
)
<<
8
;
tc
|=
(
h
->
sei
.
picture_timing
.
tc_
hours
/
10
)
<<
4
;
tc
|=
(
h
->
sei
.
picture_timing
.
timecode
[
i
].
hours
/
10
)
<<
4
;
tc
|=
(
h
->
sei
.
picture_timing
.
tc_
hours
%
10
);
tc
|=
(
h
->
sei
.
picture_timing
.
timecode
[
i
].
hours
%
10
);
memcpy
(
tcside
->
data
,
&
tc
,
sizeof
(
uint32_t
));
tc_sd
[
i
+
1
]
=
tc
;
h
->
sei
.
picture_timing
.
fulltc_received
=
0
;
}
h
->
sei
.
picture_timing
.
timecode_cnt
=
0
;
}
}
if
(
h
->
sei
.
alternative_transfer
.
present
&&
if
(
h
->
sei
.
alternative_transfer
.
present
&&
...
...
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