Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Johan Sternerup
gst-plugins-bad
Commits
bf0d9523
Commit
bf0d9523
authored
May 25, 2016
by
Mats Lindestam
Committed by
Tim-Philipp Müller
Jun 13, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
h264parse: refactored handling of SPS/PPS when pushing frames
https://bugzilla.gnome.org/show_bug.cgi?id=766803
parent
0c04e004
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
88 additions
and
81 deletions
+88
-81
gst/videoparsers/gsth264parse.c
gst/videoparsers/gsth264parse.c
+88
-81
No files found.
gst/videoparsers/gsth264parse.c
View file @
bf0d9523
...
...
@@ -2199,6 +2199,92 @@ gst_h264_parse_prepare_key_unit (GstH264Parse * parse, GstEvent * event)
parse
->
push_codec
=
TRUE
;
}
static
gboolean
gst_h264_parse_handle_sps_pps_nals
(
GstH264Parse
*
h264parse
,
GstBuffer
*
buffer
,
GstBaseParseFrame
*
frame
)
{
GstBuffer
*
codec_nal
;
gint
i
;
gboolean
send_done
=
FALSE
;
GstClockTime
timestamp
=
GST_BUFFER_TIMESTAMP
(
buffer
);
if
(
h264parse
->
align
==
GST_H264_PARSE_ALIGN_NAL
)
{
/* send separate config NAL buffers */
GST_DEBUG_OBJECT
(
h264parse
,
"- sending SPS/PPS"
);
for
(
i
=
0
;
i
<
GST_H264_MAX_SPS_COUNT
;
i
++
)
{
if
((
codec_nal
=
h264parse
->
sps_nals
[
i
]))
{
GST_DEBUG_OBJECT
(
h264parse
,
"sending SPS nal"
);
gst_h264_parse_push_codec_buffer
(
h264parse
,
codec_nal
,
timestamp
);
send_done
=
TRUE
;
}
}
for
(
i
=
0
;
i
<
GST_H264_MAX_PPS_COUNT
;
i
++
)
{
if
((
codec_nal
=
h264parse
->
pps_nals
[
i
]))
{
GST_DEBUG_OBJECT
(
h264parse
,
"sending PPS nal"
);
gst_h264_parse_push_codec_buffer
(
h264parse
,
codec_nal
,
timestamp
);
send_done
=
TRUE
;
}
}
}
else
{
/* insert config NALs into AU */
GstByteWriter
bw
;
GstBuffer
*
new_buf
;
const
gboolean
bs
=
h264parse
->
format
==
GST_H264_PARSE_FORMAT_BYTE
;
const
gint
nls
=
4
-
h264parse
->
nal_length_size
;
gboolean
ok
;
gst_byte_writer_init_with_size
(
&
bw
,
gst_buffer_get_size
(
buffer
),
FALSE
);
ok
=
gst_byte_writer_put_buffer
(
&
bw
,
buffer
,
0
,
h264parse
->
idr_pos
);
GST_DEBUG_OBJECT
(
h264parse
,
"- inserting SPS/PPS"
);
for
(
i
=
0
;
i
<
GST_H264_MAX_SPS_COUNT
;
i
++
)
{
if
((
codec_nal
=
h264parse
->
sps_nals
[
i
]))
{
gsize
nal_size
=
gst_buffer_get_size
(
codec_nal
);
GST_DEBUG_OBJECT
(
h264parse
,
"inserting SPS nal"
);
if
(
bs
)
{
ok
&=
gst_byte_writer_put_uint32_be
(
&
bw
,
1
);
}
else
{
ok
&=
gst_byte_writer_put_uint32_be
(
&
bw
,
(
nal_size
<<
(
nls
*
8
)));
ok
&=
gst_byte_writer_set_pos
(
&
bw
,
gst_byte_writer_get_pos
(
&
bw
)
-
nls
);
}
ok
&=
gst_byte_writer_put_buffer
(
&
bw
,
codec_nal
,
0
,
nal_size
);
send_done
=
TRUE
;
}
}
for
(
i
=
0
;
i
<
GST_H264_MAX_PPS_COUNT
;
i
++
)
{
if
((
codec_nal
=
h264parse
->
pps_nals
[
i
]))
{
gsize
nal_size
=
gst_buffer_get_size
(
codec_nal
);
GST_DEBUG_OBJECT
(
h264parse
,
"inserting PPS nal"
);
if
(
bs
)
{
ok
&=
gst_byte_writer_put_uint32_be
(
&
bw
,
1
);
}
else
{
ok
&=
gst_byte_writer_put_uint32_be
(
&
bw
,
(
nal_size
<<
(
nls
*
8
)));
ok
&=
gst_byte_writer_set_pos
(
&
bw
,
gst_byte_writer_get_pos
(
&
bw
)
-
nls
);
}
ok
&=
gst_byte_writer_put_buffer
(
&
bw
,
codec_nal
,
0
,
nal_size
);
send_done
=
TRUE
;
}
}
ok
&=
gst_byte_writer_put_buffer
(
&
bw
,
buffer
,
h264parse
->
idr_pos
,
-
1
);
/* collect result and push */
new_buf
=
gst_byte_writer_reset_and_get_buffer
(
&
bw
);
gst_buffer_copy_into
(
new_buf
,
buffer
,
GST_BUFFER_COPY_METADATA
,
0
,
-
1
);
/* should already be keyframe/IDR, but it may not have been,
* so mark it as such to avoid being discarded by picky decoder */
GST_BUFFER_FLAG_UNSET
(
new_buf
,
GST_BUFFER_FLAG_DELTA_UNIT
);
gst_buffer_replace
(
&
frame
->
out_buffer
,
new_buf
);
gst_buffer_unref
(
new_buf
);
/* some result checking seems to make some compilers happy */
if
(
G_UNLIKELY
(
!
ok
))
{
GST_ERROR_OBJECT
(
h264parse
,
"failed to insert SPS/PPS"
);
}
}
return
send_done
;
}
static
GstFlowReturn
gst_h264_parse_pre_push_frame
(
GstBaseParse
*
parse
,
GstBaseParseFrame
*
frame
)
{
...
...
@@ -2274,93 +2360,14 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
if
(
GST_TIME_AS_SECONDS
(
diff
)
>=
h264parse
->
interval
||
initial_frame
||
h264parse
->
push_codec
)
{
GstBuffer
*
codec_nal
;
gint
i
;
GstClockTime
new_ts
;
/* avoid overwriting a perfectly fine timestamp */
new_ts
=
GST_CLOCK_TIME_IS_VALID
(
timestamp
)
?
timestamp
:
h264parse
->
last_report
;
if
(
h264parse
->
align
==
GST_H264_PARSE_ALIGN_NAL
)
{
/* send separate config NAL buffers */
GST_DEBUG_OBJECT
(
h264parse
,
"- sending SPS/PPS"
);
for
(
i
=
0
;
i
<
GST_H264_MAX_SPS_COUNT
;
i
++
)
{
if
((
codec_nal
=
h264parse
->
sps_nals
[
i
]))
{
GST_DEBUG_OBJECT
(
h264parse
,
"sending SPS nal"
);
gst_h264_parse_push_codec_buffer
(
h264parse
,
codec_nal
,
timestamp
);
h264parse
->
last_report
=
new_ts
;
}
}
for
(
i
=
0
;
i
<
GST_H264_MAX_PPS_COUNT
;
i
++
)
{
if
((
codec_nal
=
h264parse
->
pps_nals
[
i
]))
{
GST_DEBUG_OBJECT
(
h264parse
,
"sending PPS nal"
);
gst_h264_parse_push_codec_buffer
(
h264parse
,
codec_nal
,
timestamp
);
h264parse
->
last_report
=
new_ts
;
}
}
}
else
{
/* insert config NALs into AU */
GstByteWriter
bw
;
GstBuffer
*
new_buf
;
const
gboolean
bs
=
h264parse
->
format
==
GST_H264_PARSE_FORMAT_BYTE
;
const
gint
nls
=
4
-
h264parse
->
nal_length_size
;
gboolean
ok
;
gst_byte_writer_init_with_size
(
&
bw
,
gst_buffer_get_size
(
buffer
),
FALSE
);
ok
=
gst_byte_writer_put_buffer
(
&
bw
,
buffer
,
0
,
h264parse
->
idr_pos
);
GST_DEBUG_OBJECT
(
h264parse
,
"- inserting SPS/PPS"
);
for
(
i
=
0
;
i
<
GST_H264_MAX_SPS_COUNT
;
i
++
)
{
if
((
codec_nal
=
h264parse
->
sps_nals
[
i
]))
{
gsize
nal_size
=
gst_buffer_get_size
(
codec_nal
);
GST_DEBUG_OBJECT
(
h264parse
,
"inserting SPS nal"
);
if
(
bs
)
{
ok
&=
gst_byte_writer_put_uint32_be
(
&
bw
,
1
);
}
else
{
ok
&=
gst_byte_writer_put_uint32_be
(
&
bw
,
(
nal_size
<<
(
nls
*
8
)));
ok
&=
gst_byte_writer_set_pos
(
&
bw
,
gst_byte_writer_get_pos
(
&
bw
)
-
nls
);
}
ok
&=
gst_byte_writer_put_buffer
(
&
bw
,
codec_nal
,
0
,
nal_size
);
h264parse
->
last_report
=
new_ts
;
}
}
for
(
i
=
0
;
i
<
GST_H264_MAX_PPS_COUNT
;
i
++
)
{
if
((
codec_nal
=
h264parse
->
pps_nals
[
i
]))
{
gsize
nal_size
=
gst_buffer_get_size
(
codec_nal
);
GST_DEBUG_OBJECT
(
h264parse
,
"inserting PPS nal"
);
if
(
bs
)
{
ok
&=
gst_byte_writer_put_uint32_be
(
&
bw
,
1
);
}
else
{
ok
&=
gst_byte_writer_put_uint32_be
(
&
bw
,
(
nal_size
<<
(
nls
*
8
)));
ok
&=
gst_byte_writer_set_pos
(
&
bw
,
gst_byte_writer_get_pos
(
&
bw
)
-
nls
);
}
ok
&=
gst_byte_writer_put_buffer
(
&
bw
,
codec_nal
,
0
,
nal_size
);
h264parse
->
last_report
=
new_ts
;
}
}
ok
&=
gst_byte_writer_put_buffer
(
&
bw
,
buffer
,
h264parse
->
idr_pos
,
-
1
);
/* collect result and push */
new_buf
=
gst_byte_writer_reset_and_get_buffer
(
&
bw
);
gst_buffer_copy_into
(
new_buf
,
buffer
,
GST_BUFFER_COPY_METADATA
,
0
,
-
1
);
/* should already be keyframe/IDR, but it may not have been,
* so mark it as such to avoid being discarded by picky decoder */
GST_BUFFER_FLAG_UNSET
(
new_buf
,
GST_BUFFER_FLAG_DELTA_UNIT
);
gst_buffer_replace
(
&
frame
->
out_buffer
,
new_buf
);
gst_buffer_unref
(
new_buf
);
/* some result checking seems to make some compilers happy */
if
(
G_UNLIKELY
(
!
ok
))
{
GST_ERROR_OBJECT
(
h264parse
,
"failed to insert SPS/PPS"
);
}
if
(
gst_h264_parse_handle_sps_pps_nals
(
h264parse
,
buffer
,
frame
))
{
h264parse
->
last_report
=
new_ts
;
}
}
/* we pushed whatever we had */
...
...
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