Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
5941dc1b
Commit
5941dc1b
authored
Jul 13, 2015
by
Felix Paul Kühne
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
videotoolbox: various small improvements, bug fixes and cleanup
parent
dd873cc2
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
113 additions
and
139 deletions
+113
-139
modules/codec/videotoolbox.m
modules/codec/videotoolbox.m
+113
-139
No files found.
modules/codec/videotoolbox.m
View file @
5941dc1b
...
...
@@ -69,7 +69,6 @@ vlc_module_end()
#pragma mark - local prototypes
static
CFDataRef
avvCCreate
(
decoder_t
*
,
uint8_t
*
,
uint32_t
);
static
CFDataRef
ESDSCreate
(
decoder_t
*
,
uint8_t
*
,
uint32_t
);
static
picture_t
*
DecodeBlock
(
decoder_t
*
,
block_t
**
);
static
void
DecoderCallback
(
void
*
,
void
*
,
OSStatus
,
VTDecodeInfoFlags
,
...
...
@@ -188,8 +187,8 @@ static CMVideoCodecType CodecPrecheck(decoder_t *p_dec)
if
(
codec
!=
0
)
break
;
#endif
/* mpgv / mp2v needs fixing, so disable
d in non-debug builds
*/
#if
ndef NDEBUG
/* mpgv / mp2v needs fixing, so disable
it for now
*/
#if
0
case VLC_CODEC_MPGV:
codec = kCMVideoCodecType_MPEG1Video;
break;
...
...
@@ -242,6 +241,7 @@ static int StartVideoToolbox(decoder_t *p_dec, block_t *p_block)
if
(
p_sys
->
codec
==
kCMVideoCodecType_H264
)
{
if
((
p_dec
->
fmt_in
.
video
.
i_width
==
0
||
p_dec
->
fmt_in
.
video
.
i_height
==
0
)
&&
p_block
==
NULL
)
{
msg_Dbg
(
p_dec
,
"waiting for H264 SPS/PPS, extra data %i"
,
p_dec
->
fmt_in
.
i_extra
);
return
VLC_SUCCESS
;
// return VLC_GENERIC to leave the waiting to someone else
}
...
...
@@ -250,18 +250,10 @@ static int StartVideoToolbox(decoder_t *p_dec, block_t *p_block)
int
i_ret
=
0
;
if
(
p_block
==
NULL
)
{
/* we are not mid-stream but at the beginning of playback
* therefore, the demuxer gives us an avvC atom, which can
* be passed to the decoder with slight or no modifications
* at all */
extradata
=
avvCCreate
(
p_dec
,
(
uint8_t
*
)
p_dec
->
fmt_in
.
p_extra
,
p_dec
->
fmt_in
.
i_extra
);
int
buf_size
=
p_dec
->
fmt_in
.
i_extra
+
20
;
size
=
p_dec
->
fmt_in
.
i_extra
;
p_buf
=
malloc
(
buf_size
);
p_buf
=
malloc
(
buf_size
);
if
(
!
p_buf
)
{
msg_Warn
(
p_dec
,
"extra buffer allocation failed"
);
...
...
@@ -269,7 +261,7 @@ static int StartVideoToolbox(decoder_t *p_dec, block_t *p_block)
}
/* we need to convert the SPS and PPS units we received from the
* dem
xu
er's avvC atom so we can process them further */
* dem
ux
er's avvC atom so we can process them further */
i_ret
=
convert_sps_pps
(
p_dec
,
p_dec
->
fmt_in
.
p_extra
,
p_dec
->
fmt_in
.
i_extra
,
...
...
@@ -285,92 +277,97 @@ static int StartVideoToolbox(decoder_t *p_dec, block_t *p_block)
i_ret
=
VLC_SUCCESS
;
}
if
(
i_ret
==
VLC_SUCCESS
)
{
uint8_t
*
p_sps_buf
=
NULL
,
*
p_pps_buf
=
NULL
;
size_t
i_sps_size
=
0
,
i_pps_size
=
0
;
/* get the SPS and PPS units from the NAL unit which is either
* part of the demuxer's avvC atom or the mid stream data block */
i_ret
=
h264_get_spspps
(
p_buf
,
size
,
&
p_sps_buf
,
&
i_sps_size
,
&
p_pps_buf
,
&
i_pps_size
);
if
(
i_ret
==
VLC_SUCCESS
)
{
struct
nal_sps
sps_data
;
i_ret
=
h264_parse_sps
(
p_sps_buf
,
i_sps_size
,
&
sps_data
);
if
(
i_ret
==
VLC_SUCCESS
)
{
/* this data is more trust-worthy than what we receive
* from the demuxer, so we will use it to over-write
* the current values */
i_video_width
=
sps_data
.
i_width
;
i_video_height
=
sps_data
.
i_height
;
i_sar_den
=
sps_data
.
vui
.
i_sar_den
;
i_sar_num
=
sps_data
.
vui
.
i_sar_num
;
/* no evaluation here as this is done in the precheck */
p_sys
->
codec_profile
=
sps_data
.
i_profile
;
p_sys
->
codec_level
=
sps_data
.
i_level
;
if
(
p_block
!=
NULL
)
{
/* on mid stream changes, we have a block and need to
* glue our own avvC atom together to give it to the
* decoder */
bo_t
bo
;
bool
status
=
bo_init
(
&
bo
,
1024
);
if
(
status
!=
true
)
return
VLC_ENOMEM
;
bo_add_8
(
&
bo
,
1
);
/* configuration version */
bo_add_8
(
&
bo
,
sps_data
.
i_profile
);
bo_add_8
(
&
bo
,
sps_data
.
i_profile_compatibility
);
bo_add_8
(
&
bo
,
sps_data
.
i_level
);
bo_add_8
(
&
bo
,
0xff
);
/* 0b11111100 | lengthsize = 0x11 */
bo_add_8
(
&
bo
,
0xe0
|
(
i_sps_size
>
0
?
1
:
0
));
/* 0b11100000 | sps_count */
if
(
i_sps_size
>
4
)
{
/* the SPS data we have got includes 4 leading
* bytes which we need to remove */
uint8_t
*
fixed_sps
=
malloc
(
i_sps_size
-
4
);
for
(
int
i
=
0
;
i
<
i_sps_size
-
4
;
i
++
)
{
fixed_sps
[
i
]
=
p_sps_buf
[
i
+
4
];
}
bo_add_16be
(
&
bo
,
i_sps_size
-
4
);
bo_add_mem
(
&
bo
,
i_sps_size
-
4
,
fixed_sps
);
free
(
fixed_sps
);
}
bo_add_8
(
&
bo
,
(
i_pps_size
>
0
?
1
:
0
));
/* pps_count */
if
(
i_pps_size
>
4
)
{
/* the PPS data we have got includes 4 leading
* bytes which we need to remove */
uint8_t
*
fixed_pps
=
malloc
(
i_pps_size
-
4
);
for
(
int
i
=
0
;
i
<
i_pps_size
-
4
;
i
++
)
{
fixed_pps
[
i
]
=
p_pps_buf
[
i
+
4
];
}
bo_add_16be
(
&
bo
,
i_pps_size
-
4
);
bo_add_mem
(
&
bo
,
i_pps_size
-
4
,
fixed_pps
);
free
(
fixed_pps
);
}
extradata
=
CFDataCreate
(
kCFAllocatorDefault
,
bo
.
b
->
p_buffer
,
bo
.
b
->
i_buffer
);
}
}
if
(
i_ret
!=
VLC_SUCCESS
)
{
return
VLC_EGENERIC
;
}
uint8_t
*
p_sps_buf
=
NULL
,
*
p_pps_buf
=
NULL
;
size_t
i_sps_size
=
0
,
i_pps_size
=
0
;
if
(
!
p_buf
)
{
return
VLC_EGENERIC
;
}
/* get the SPS and PPS units from the NAL unit which is either
* part of the demuxer's avvC atom or the mid stream data block */
i_ret
=
h264_get_spspps
(
p_buf
,
size
,
&
p_sps_buf
,
&
i_sps_size
,
&
p_pps_buf
,
&
i_pps_size
);
if
(
i_ret
!=
VLC_SUCCESS
)
{
msg_Warn
(
p_dec
,
"sps pps parsing failed"
);
return
VLC_EGENERIC
;
}
struct
nal_sps
sps_data
;
i_ret
=
h264_parse_sps
(
p_sps_buf
,
i_sps_size
,
&
sps_data
);
if
(
i_ret
!=
VLC_SUCCESS
)
{
return
VLC_EGENERIC
;
}
/* this data is more trust-worthy than what we receive
* from the demuxer, so we will use it to over-write
* the current values */
i_video_width
=
sps_data
.
i_width
;
i_video_height
=
sps_data
.
i_height
;
i_sar_den
=
sps_data
.
vui
.
i_sar_den
;
i_sar_num
=
sps_data
.
vui
.
i_sar_num
;
/* no evaluation here as this is done in the precheck */
p_sys
->
codec_profile
=
sps_data
.
i_profile
;
p_sys
->
codec_level
=
sps_data
.
i_level
;
/* create avvC atom to forward to the HW decoder */
bo_t
bo
;
bool
status
=
bo_init
(
&
bo
,
1024
);
if
(
status
!=
true
)
return
VLC_ENOMEM
;
bo_add_8
(
&
bo
,
1
);
/* configuration version */
bo_add_8
(
&
bo
,
sps_data
.
i_profile
);
bo_add_8
(
&
bo
,
sps_data
.
i_profile_compatibility
);
bo_add_8
(
&
bo
,
sps_data
.
i_level
);
bo_add_8
(
&
bo
,
0xff
);
/* 0b11111100 | lengthsize = 0x11 */
bo_add_8
(
&
bo
,
0xe0
|
(
i_sps_size
>
0
?
1
:
0
));
/* 0b11100000 | sps_count */
if
(
i_sps_size
>
4
)
{
/* the SPS data we have got includes 4 leading
* bytes which we need to remove */
uint8_t
*
fixed_sps
=
malloc
(
i_sps_size
-
4
);
for
(
int
i
=
0
;
i
<
i_sps_size
-
4
;
i
++
)
{
fixed_sps
[
i
]
=
p_sps_buf
[
i
+
4
];
}
bo_add_16be
(
&
bo
,
i_sps_size
-
4
);
bo_add_mem
(
&
bo
,
i_sps_size
-
4
,
fixed_sps
);
free
(
fixed_sps
);
}
bo_add_8
(
&
bo
,
(
i_pps_size
>
0
?
1
:
0
));
/* pps_count */
if
(
i_pps_size
>
4
)
{
/* the PPS data we have got includes 4 leading
* bytes which we need to remove */
uint8_t
*
fixed_pps
=
malloc
(
i_pps_size
-
4
);
for
(
int
i
=
0
;
i
<
i_pps_size
-
4
;
i
++
)
{
fixed_pps
[
i
]
=
p_pps_buf
[
i
+
4
];
}
bo_add_16be
(
&
bo
,
i_pps_size
-
4
);
bo_add_mem
(
&
bo
,
i_pps_size
-
4
,
fixed_pps
);
free
(
fixed_pps
);
}
extradata
=
CFDataCreate
(
kCFAllocatorDefault
,
bo
.
b
->
p_buffer
,
bo
.
b
->
i_buffer
);
if
(
extradata
)
CFDictionarySetValue
(
extradata_info
,
CFSTR
(
"avcC"
),
extradata
);
...
...
@@ -562,7 +559,6 @@ static int StartVideoToolbox(decoder_t *p_dec, block_t *p_block)
if
(
p_block
)
{
/* this is a mid stream change so we need to tell the core about it */
decoder_UpdateVideoFormat
(
p_dec
);
block_Release
(
p_block
);
}
p_sys
->
b_started
=
YES
;
...
...
@@ -576,15 +572,17 @@ static void StopVideoToolbox(decoder_t *p_dec)
if
(
p_sys
->
b_started
)
{
p_sys
->
b_started
=
false
;
if
(
p_sys
->
session
!=
NULL
)
{
if
(
p_sys
->
session
!=
nil
)
{
VTDecompressionSessionInvalidate
(
p_sys
->
session
);
CFRelease
(
p_sys
->
session
);
p_sys
->
session
=
NULL
;
p_sys
->
session
=
nil
;
}
}
if
(
p_sys
->
videoFormatDescription
!=
NULL
)
if
(
p_sys
->
videoFormatDescription
!=
nil
)
{
CFRelease
(
p_sys
->
videoFormatDescription
);
p_sys
->
videoFormatDescription
=
nil
;
}
}
#pragma mark - module open and close
...
...
@@ -673,34 +671,6 @@ static inline void bo_add_mp4_tag_descr(bo_t *p_bo, uint8_t tag, uint32_t size)
bo_add_8
(
p_bo
,
size
&
0x7F
);
}
static
CFDataRef
avvCCreate
(
decoder_t
*
p_dec
,
uint8_t
*
p_buf
,
uint32_t
i_buf_size
)
{
VLC_UNUSED
(
p_dec
);
CFDataRef
data
;
/* each NAL sent to the decoder is preceded by a 4 byte header
* we need to change the avcC header to signal headers of 4 bytes, if needed */
if
(
i_buf_size
>=
4
&&
(
p_buf
[
4
]
&
0x03
)
!=
0x03
)
{
uint8_t
*
p_fixed_buf
;
p_fixed_buf
=
malloc
(
i_buf_size
);
if
(
!
p_fixed_buf
)
return
NULL
;
memcpy
(
p_fixed_buf
,
p_buf
,
i_buf_size
);
p_fixed_buf
[
4
]
|=
0x03
;
data
=
CFDataCreate
(
kCFAllocatorDefault
,
p_fixed_buf
,
i_buf_size
);
}
else
{
data
=
CFDataCreate
(
kCFAllocatorDefault
,
p_buf
,
i_buf_size
);
}
return
data
;
}
static
CFDataRef
ESDSCreate
(
decoder_t
*
p_dec
,
uint8_t
*
p_buf
,
uint32_t
i_buf_size
)
{
int
full_size
=
3
+
5
+
13
+
5
+
i_buf_size
+
3
;
...
...
@@ -746,16 +716,12 @@ static CFDataRef ESDSCreate(decoder_t *p_dec, uint8_t *p_buf, uint32_t i_buf_siz
static
bool
H264ProcessBlock
(
decoder_t
*
p_dec
,
block_t
*
p_block
)
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
int
buf_size
=
p_dec
->
fmt_in
.
i_extra
+
20
;
uint32_t
size
=
p_dec
->
fmt_in
.
i_extra
;
void
*
p_buf
=
malloc
(
buf_size
);
if
(
!
p_buf
)
{
msg_Warn
(
p_dec
,
"extra buffer allocation failed"
);
if
(
!
p_block
->
p_buffer
)
return
false
;
}
int
buf_size
=
p_dec
->
fmt_in
.
i_extra
+
20
;
uint32_t
size
=
p_dec
->
fmt_in
.
i_extra
;
uint8_t
*
p_sps_buf
=
NULL
,
*
p_pps_buf
=
NULL
;
size_t
i_sps_size
=
0
,
i_pps_size
=
0
;
int
i_ret
=
0
;
...
...
@@ -811,7 +777,7 @@ static bool H264ProcessBlock(decoder_t *p_dec, block_t *p_block)
static
CMSampleBufferRef
VTSampleBufferCreate
(
decoder_t
*
p_dec
,
CMFormatDescriptionRef
fmt_desc
,
void
*
buffer
,
in
t
size
,
size_
t
size
,
mtime_t
i_pts
,
mtime_t
i_dts
,
mtime_t
i_length
)
...
...
@@ -923,12 +889,16 @@ static picture_t *DecodeBlock(decoder_t *p_dec, block_t **pp_block)
p_sys
->
codec
=
kCMVideoCodecType_H264
;
i_ret
=
StartVideoToolbox
(
p_dec
,
p_block
);
}
if
(
i_ret
!=
VLC_SUCCESS
||
!
p_sys
->
b_started
)
if
(
i_ret
!=
VLC_SUCCESS
||
!
p_sys
->
b_started
)
{
*
pp_block
=
NULL
;
return
NULL
;
}
if
(
p_sys
->
codec
==
kCMVideoCodecType_H264
)
{
if
(
!
H264ProcessBlock
(
p_dec
,
p_block
))
if
(
!
H264ProcessBlock
(
p_dec
,
p_block
))
{
*
pp_block
=
NULL
;
return
NULL
;
}
}
CMSampleBufferRef
sampleBuffer
;
...
...
@@ -957,7 +927,11 @@ static picture_t *DecodeBlock(decoder_t *p_dec, block_t **pp_block)
p_dec
->
b_error
=
true
;
}
else
if
(
status
==
-
8969
||
status
==
-
12909
)
{
msg_Err
(
p_dec
,
"decoder failure: bad data"
);
p_dec
->
b_error
=
true
;
StopVideoToolbox
(
p_dec
);
CFRelease
(
sampleBuffer
);
block_Release
(
p_block
);
*
pp_block
=
NULL
;
return
NULL
;
}
else
if
(
status
==
-
12911
||
status
==
-
8960
)
{
msg_Err
(
p_dec
,
"decoder failure: internal malfunction"
);
p_dec
->
b_error
=
true
;
...
...
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