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
9ea91e41
Commit
9ea91e41
authored
Sep 08, 2016
by
Aman Gupta
Committed by
Rick Kern
Oct 17, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavc/videotoolboxenc: implement a53cc
Signed-off-by:
Rick Kern
<
kernrj@gmail.com
>
parent
656feb64
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
68 additions
and
9 deletions
+68
-9
videotoolboxenc.c
libavcodec/videotoolboxenc.c
+68
-9
No files found.
libavcodec/videotoolboxenc.c
View file @
9ea91e41
...
@@ -32,6 +32,8 @@
...
@@ -32,6 +32,8 @@
#include "libavutil/pixdesc.h"
#include "libavutil/pixdesc.h"
#include "internal.h"
#include "internal.h"
#include <pthread.h>
#include <pthread.h>
#include "h264.h"
#include "h264_sei.h"
#if !CONFIG_VT_BT2020
#if !CONFIG_VT_BT2020
# define kCVImageBufferColorPrimaries_ITU_R_2020 CFSTR("ITU_R_2020")
# define kCVImageBufferColorPrimaries_ITU_R_2020 CFSTR("ITU_R_2020")
...
@@ -55,8 +57,14 @@ typedef enum VTH264Entropy{
...
@@ -55,8 +57,14 @@ typedef enum VTH264Entropy{
static
const
uint8_t
start_code
[]
=
{
0
,
0
,
0
,
1
};
static
const
uint8_t
start_code
[]
=
{
0
,
0
,
0
,
1
};
typedef
struct
ExtraSEI
{
void
*
data
;
size_t
size
;
}
ExtraSEI
;
typedef
struct
BufNode
{
typedef
struct
BufNode
{
CMSampleBufferRef
cm_buffer
;
CMSampleBufferRef
cm_buffer
;
ExtraSEI
*
sei
;
struct
BufNode
*
next
;
struct
BufNode
*
next
;
int
error
;
int
error
;
}
BufNode
;
}
BufNode
;
...
@@ -94,6 +102,7 @@ typedef struct VTEncContext {
...
@@ -94,6 +102,7 @@ typedef struct VTEncContext {
bool
flushing
;
bool
flushing
;
bool
has_b_frames
;
bool
has_b_frames
;
bool
warned_color_range
;
bool
warned_color_range
;
bool
a53_cc
;
}
VTEncContext
;
}
VTEncContext
;
static
int
vtenc_populate_extradata
(
AVCodecContext
*
avctx
,
static
int
vtenc_populate_extradata
(
AVCodecContext
*
avctx
,
...
@@ -136,7 +145,7 @@ static void set_async_error(VTEncContext *vtctx, int err)
...
@@ -136,7 +145,7 @@ static void set_async_error(VTEncContext *vtctx, int err)
pthread_mutex_unlock
(
&
vtctx
->
lock
);
pthread_mutex_unlock
(
&
vtctx
->
lock
);
}
}
static
int
vtenc_q_pop
(
VTEncContext
*
vtctx
,
bool
wait
,
CMSampleBufferRef
*
buf
)
static
int
vtenc_q_pop
(
VTEncContext
*
vtctx
,
bool
wait
,
CMSampleBufferRef
*
buf
,
ExtraSEI
**
sei
)
{
{
BufNode
*
info
;
BufNode
*
info
;
...
@@ -173,6 +182,12 @@ static int vtenc_q_pop(VTEncContext *vtctx, bool wait, CMSampleBufferRef *buf)
...
@@ -173,6 +182,12 @@ static int vtenc_q_pop(VTEncContext *vtctx, bool wait, CMSampleBufferRef *buf)
pthread_mutex_unlock
(
&
vtctx
->
lock
);
pthread_mutex_unlock
(
&
vtctx
->
lock
);
*
buf
=
info
->
cm_buffer
;
*
buf
=
info
->
cm_buffer
;
if
(
sei
&&
*
buf
)
{
*
sei
=
info
->
sei
;
}
else
if
(
info
->
sei
)
{
if
(
info
->
sei
->
data
)
av_free
(
info
->
sei
->
data
);
av_free
(
info
->
sei
);
}
av_free
(
info
);
av_free
(
info
);
vtctx
->
frame_ct_out
++
;
vtctx
->
frame_ct_out
++
;
...
@@ -180,7 +195,7 @@ static int vtenc_q_pop(VTEncContext *vtctx, bool wait, CMSampleBufferRef *buf)
...
@@ -180,7 +195,7 @@ static int vtenc_q_pop(VTEncContext *vtctx, bool wait, CMSampleBufferRef *buf)
return
0
;
return
0
;
}
}
static
void
vtenc_q_push
(
VTEncContext
*
vtctx
,
CMSampleBufferRef
buffer
)
static
void
vtenc_q_push
(
VTEncContext
*
vtctx
,
CMSampleBufferRef
buffer
,
ExtraSEI
*
sei
)
{
{
BufNode
*
info
=
av_malloc
(
sizeof
(
BufNode
));
BufNode
*
info
=
av_malloc
(
sizeof
(
BufNode
));
if
(
!
info
)
{
if
(
!
info
)
{
...
@@ -190,6 +205,7 @@ static void vtenc_q_push(VTEncContext *vtctx, CMSampleBufferRef buffer)
...
@@ -190,6 +205,7 @@ static void vtenc_q_push(VTEncContext *vtctx, CMSampleBufferRef buffer)
CFRetain
(
buffer
);
CFRetain
(
buffer
);
info
->
cm_buffer
=
buffer
;
info
->
cm_buffer
=
buffer
;
info
->
sei
=
sei
;
info
->
next
=
NULL
;
info
->
next
=
NULL
;
pthread_mutex_lock
(
&
vtctx
->
lock
);
pthread_mutex_lock
(
&
vtctx
->
lock
);
...
@@ -420,6 +436,7 @@ static void vtenc_output_callback(
...
@@ -420,6 +436,7 @@ static void vtenc_output_callback(
{
{
AVCodecContext
*
avctx
=
ctx
;
AVCodecContext
*
avctx
=
ctx
;
VTEncContext
*
vtctx
=
avctx
->
priv_data
;
VTEncContext
*
vtctx
=
avctx
->
priv_data
;
ExtraSEI
*
sei
=
sourceFrameCtx
;
if
(
vtctx
->
async_error
)
{
if
(
vtctx
->
async_error
)
{
if
(
sample_buffer
)
CFRelease
(
sample_buffer
);
if
(
sample_buffer
)
CFRelease
(
sample_buffer
);
...
@@ -440,7 +457,7 @@ static void vtenc_output_callback(
...
@@ -440,7 +457,7 @@ static void vtenc_output_callback(
}
}
}
}
vtenc_q_push
(
vtctx
,
sample_buffer
);
vtenc_q_push
(
vtctx
,
sample_buffer
,
sei
);
}
}
static
int
get_length_code_size
(
static
int
get_length_code_size
(
...
@@ -1258,7 +1275,8 @@ static int copy_replace_length_codes(
...
@@ -1258,7 +1275,8 @@ static int copy_replace_length_codes(
static
int
vtenc_cm_to_avpacket
(
static
int
vtenc_cm_to_avpacket
(
AVCodecContext
*
avctx
,
AVCodecContext
*
avctx
,
CMSampleBufferRef
sample_buffer
,
CMSampleBufferRef
sample_buffer
,
AVPacket
*
pkt
)
AVPacket
*
pkt
,
ExtraSEI
*
sei
)
{
{
VTEncContext
*
vtctx
=
avctx
->
priv_data
;
VTEncContext
*
vtctx
=
avctx
->
priv_data
;
...
@@ -1269,6 +1287,7 @@ static int vtenc_cm_to_avpacket(
...
@@ -1269,6 +1287,7 @@ static int vtenc_cm_to_avpacket(
size_t
header_size
=
0
;
size_t
header_size
=
0
;
size_t
in_buf_size
;
size_t
in_buf_size
;
size_t
out_buf_size
;
size_t
out_buf_size
;
size_t
sei_nalu_size
=
0
;
int64_t
dts_delta
;
int64_t
dts_delta
;
int64_t
time_base_num
;
int64_t
time_base_num
;
int
nalu_count
;
int
nalu_count
;
...
@@ -1298,9 +1317,14 @@ static int vtenc_cm_to_avpacket(
...
@@ -1298,9 +1317,14 @@ static int vtenc_cm_to_avpacket(
if
(
status
)
if
(
status
)
return
status
;
return
status
;
if
(
sei
)
{
sei_nalu_size
=
sizeof
(
start_code
)
+
3
+
sei
->
size
+
1
;
}
in_buf_size
=
CMSampleBufferGetTotalSampleSize
(
sample_buffer
);
in_buf_size
=
CMSampleBufferGetTotalSampleSize
(
sample_buffer
);
out_buf_size
=
header_size
+
out_buf_size
=
header_size
+
in_buf_size
+
in_buf_size
+
sei_nalu_size
+
nalu_count
*
((
int
)
sizeof
(
start_code
)
-
(
int
)
length_code_size
);
nalu_count
*
((
int
)
sizeof
(
start_code
)
-
(
int
)
length_code_size
);
status
=
ff_alloc_packet2
(
avctx
,
pkt
,
out_buf_size
,
out_buf_size
);
status
=
ff_alloc_packet2
(
avctx
,
pkt
,
out_buf_size
,
out_buf_size
);
...
@@ -1317,7 +1341,7 @@ static int vtenc_cm_to_avpacket(
...
@@ -1317,7 +1341,7 @@ static int vtenc_cm_to_avpacket(
length_code_size
,
length_code_size
,
sample_buffer
,
sample_buffer
,
pkt
->
data
+
header_size
,
pkt
->
data
+
header_size
,
pkt
->
size
-
header_size
pkt
->
size
-
header_size
-
sei_nalu_size
);
);
if
(
status
)
{
if
(
status
)
{
...
@@ -1325,6 +1349,19 @@ static int vtenc_cm_to_avpacket(
...
@@ -1325,6 +1349,19 @@ static int vtenc_cm_to_avpacket(
return
status
;
return
status
;
}
}
if
(
sei_nalu_size
>
0
)
{
uint8_t
*
sei_nalu
=
pkt
->
data
+
pkt
->
size
-
sei_nalu_size
;
memcpy
(
sei_nalu
,
start_code
,
sizeof
(
start_code
));
sei_nalu
+=
sizeof
(
start_code
);
sei_nalu
[
0
]
=
H264_NAL_SEI
;
sei_nalu
[
1
]
=
SEI_TYPE_USER_DATA_REGISTERED
;
sei_nalu
[
2
]
=
sei
->
size
;
sei_nalu
+=
3
;
memcpy
(
sei_nalu
,
sei
->
data
,
sei
->
size
);
sei_nalu
+=
sei
->
size
;
sei_nalu
[
0
]
=
1
;
// RBSP
}
if
(
is_key_frame
)
{
if
(
is_key_frame
)
{
pkt
->
flags
|=
AV_PKT_FLAG_KEY
;
pkt
->
flags
|=
AV_PKT_FLAG_KEY
;
}
}
...
@@ -1707,6 +1744,7 @@ static int vtenc_send_frame(AVCodecContext *avctx,
...
@@ -1707,6 +1744,7 @@ static int vtenc_send_frame(AVCodecContext *avctx,
CMTime
time
;
CMTime
time
;
CFDictionaryRef
frame_dict
;
CFDictionaryRef
frame_dict
;
CVPixelBufferRef
cv_img
=
NULL
;
CVPixelBufferRef
cv_img
=
NULL
;
ExtraSEI
*
sei
=
NULL
;
int
status
=
create_cv_pixel_buffer
(
avctx
,
frame
,
&
cv_img
);
int
status
=
create_cv_pixel_buffer
(
avctx
,
frame
,
&
cv_img
);
if
(
status
)
return
status
;
if
(
status
)
return
status
;
...
@@ -1717,6 +1755,20 @@ static int vtenc_send_frame(AVCodecContext *avctx,
...
@@ -1717,6 +1755,20 @@ static int vtenc_send_frame(AVCodecContext *avctx,
return
status
;
return
status
;
}
}
if
(
vtctx
->
a53_cc
)
{
sei
=
av_mallocz
(
sizeof
(
*
sei
));
if
(
!
sei
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Not enough memory for closed captions, skipping
\n
"
);
}
else
{
int
ret
=
ff_alloc_a53_sei
(
frame
,
0
,
&
sei
->
data
,
&
sei
->
size
);
if
(
ret
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Not enough memory for closed captions, skipping
\n
"
);
av_free
(
sei
);
sei
=
NULL
;
}
}
}
time
=
CMTimeMake
(
frame
->
pts
*
avctx
->
time_base
.
num
,
avctx
->
time_base
.
den
);
time
=
CMTimeMake
(
frame
->
pts
*
avctx
->
time_base
.
num
,
avctx
->
time_base
.
den
);
status
=
VTCompressionSessionEncodeFrame
(
status
=
VTCompressionSessionEncodeFrame
(
vtctx
->
session
,
vtctx
->
session
,
...
@@ -1724,7 +1776,7 @@ static int vtenc_send_frame(AVCodecContext *avctx,
...
@@ -1724,7 +1776,7 @@ static int vtenc_send_frame(AVCodecContext *avctx,
time
,
time
,
kCMTimeInvalid
,
kCMTimeInvalid
,
frame_dict
,
frame_dict
,
NULL
,
sei
,
NULL
NULL
);
);
...
@@ -1749,6 +1801,7 @@ static av_cold int vtenc_frame(
...
@@ -1749,6 +1801,7 @@ static av_cold int vtenc_frame(
bool
get_frame
;
bool
get_frame
;
int
status
;
int
status
;
CMSampleBufferRef
buf
=
NULL
;
CMSampleBufferRef
buf
=
NULL
;
ExtraSEI
*
sei
=
NULL
;
if
(
frame
)
{
if
(
frame
)
{
status
=
vtenc_send_frame
(
avctx
,
vtctx
,
frame
);
status
=
vtenc_send_frame
(
avctx
,
vtctx
,
frame
);
...
@@ -1785,11 +1838,15 @@ static av_cold int vtenc_frame(
...
@@ -1785,11 +1838,15 @@ static av_cold int vtenc_frame(
goto
end_nopkt
;
goto
end_nopkt
;
}
}
status
=
vtenc_q_pop
(
vtctx
,
!
frame
,
&
buf
);
status
=
vtenc_q_pop
(
vtctx
,
!
frame
,
&
buf
,
&
sei
);
if
(
status
)
goto
end_nopkt
;
if
(
status
)
goto
end_nopkt
;
if
(
!
buf
)
goto
end_nopkt
;
if
(
!
buf
)
goto
end_nopkt
;
status
=
vtenc_cm_to_avpacket
(
avctx
,
buf
,
pkt
);
status
=
vtenc_cm_to_avpacket
(
avctx
,
buf
,
pkt
,
sei
);
if
(
sei
)
{
if
(
sei
->
data
)
av_free
(
sei
->
data
);
av_free
(
sei
);
}
CFRelease
(
buf
);
CFRelease
(
buf
);
if
(
status
)
goto
end_nopkt
;
if
(
status
)
goto
end_nopkt
;
...
@@ -1878,7 +1935,7 @@ static int vtenc_populate_extradata(AVCodecContext *avctx,
...
@@ -1878,7 +1935,7 @@ static int vtenc_populate_extradata(AVCodecContext *avctx,
if
(
status
)
if
(
status
)
goto
pe_cleanup
;
goto
pe_cleanup
;
status
=
vtenc_q_pop
(
vtctx
,
0
,
&
buf
);
status
=
vtenc_q_pop
(
vtctx
,
0
,
&
buf
,
NULL
);
if
(
status
)
{
if
(
status
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"popping: %d
\n
"
,
status
);
av_log
(
avctx
,
AV_LOG_ERROR
,
"popping: %d
\n
"
,
status
);
goto
pe_cleanup
;
goto
pe_cleanup
;
...
@@ -1976,6 +2033,8 @@ static const AVOption options[] = {
...
@@ -1976,6 +2033,8 @@ static const AVOption options[] = {
{
"frames_after"
,
"Other frames will come after the frames in this session. This helps smooth concatenation issues."
,
{
"frames_after"
,
"Other frames will come after the frames in this session. This helps smooth concatenation issues."
,
OFFSET
(
frames_after
),
AV_OPT_TYPE_BOOL
,
{
.
i64
=
0
},
0
,
1
,
VE
},
OFFSET
(
frames_after
),
AV_OPT_TYPE_BOOL
,
{
.
i64
=
0
},
0
,
1
,
VE
},
{
"a53cc"
,
"Use A53 Closed Captions (if available)"
,
OFFSET
(
a53_cc
),
AV_OPT_TYPE_BOOL
,
{.
i64
=
0
},
0
,
1
,
VE
},
{
NULL
},
{
NULL
},
};
};
...
...
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