mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:56:14 +00:00
mpegvideoparse: Only map input buffer once
Instead of constantly map/unmapping it a bit everywhere, we pass along to all functions the GstMapInfo. Makes mpeg video frame parsing 6% faster https://bugzilla.gnome.org/show_bug.cgi?id=702330
This commit is contained in:
parent
dfb101e0ed
commit
1db3d40a4b
1 changed files with 29 additions and 44 deletions
|
@ -263,12 +263,11 @@ gst_mpegv_parse_stop (GstBaseParse * parse)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf,
|
gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstMapInfo * info,
|
||||||
guint size)
|
guint size)
|
||||||
{
|
{
|
||||||
GstMpegVideoPacket packet;
|
GstMpegVideoPacket packet;
|
||||||
guint8 *data_with_prefix;
|
guint8 *data_with_prefix;
|
||||||
GstMapInfo map;
|
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
if (mpvparse->seq_offset < 4) {
|
if (mpvparse->seq_offset < 4) {
|
||||||
|
@ -277,9 +276,7 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_buffer_map (buf, &map, GST_MAP_READ);
|
packet.data = info->data;
|
||||||
g_assert (size <= map.size);
|
|
||||||
packet.data = map.data;
|
|
||||||
packet.type = GST_MPEG_VIDEO_PACKET_SEQUENCE;
|
packet.type = GST_MPEG_VIDEO_PACKET_SEQUENCE;
|
||||||
packet.offset = mpvparse->seq_offset;
|
packet.offset = mpvparse->seq_offset;
|
||||||
packet.size = size - mpvparse->seq_offset;
|
packet.size = size - mpvparse->seq_offset;
|
||||||
|
@ -293,7 +290,6 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf,
|
||||||
if (mpvparse->config &&
|
if (mpvparse->config &&
|
||||||
gst_buffer_memcmp (mpvparse->config, 0, data_with_prefix, MIN (size,
|
gst_buffer_memcmp (mpvparse->config, 0, data_with_prefix, MIN (size,
|
||||||
11)) == 0) {
|
11)) == 0) {
|
||||||
gst_buffer_unmap (buf, &map);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +298,6 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf,
|
||||||
GST_DEBUG_OBJECT (mpvparse,
|
GST_DEBUG_OBJECT (mpvparse,
|
||||||
"failed to parse config data (size %d) at offset %d",
|
"failed to parse config data (size %d) at offset %d",
|
||||||
size, mpvparse->seq_offset);
|
size, mpvparse->seq_offset);
|
||||||
gst_buffer_unmap (buf, &map);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,8 +369,6 @@ gst_mpegv_parse_process_config (GstMpegvParse * mpvparse, GstBuffer * buf,
|
||||||
/* trigger src caps update */
|
/* trigger src caps update */
|
||||||
mpvparse->update_caps = TRUE;
|
mpvparse->update_caps = TRUE;
|
||||||
|
|
||||||
gst_buffer_unmap (buf, &map);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,17 +433,14 @@ picture_type_name (guint8 pct)
|
||||||
#endif /* GST_DISABLE_GST_DEBUG */
|
#endif /* GST_DISABLE_GST_DEBUG */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_packet_extension (GstMpegvParse * mpvparse, GstBuffer * buf, guint off)
|
parse_packet_extension (GstMpegvParse * mpvparse, GstMapInfo * info, guint off)
|
||||||
{
|
{
|
||||||
GstMapInfo map;
|
|
||||||
GstMpegVideoPacket packet;
|
GstMpegVideoPacket packet;
|
||||||
|
|
||||||
gst_buffer_map (buf, &map, GST_MAP_READ);
|
packet.data = info->data;
|
||||||
|
|
||||||
packet.data = map.data;
|
|
||||||
packet.type = GST_MPEG_VIDEO_PACKET_EXTENSION;
|
packet.type = GST_MPEG_VIDEO_PACKET_EXTENSION;
|
||||||
packet.offset = off;
|
packet.offset = off;
|
||||||
packet.size = map.size - off;
|
packet.size = info->size - off;
|
||||||
|
|
||||||
/* FIXME : WE ARE ASSUMING IT IS A *PICTURE* EXTENSION */
|
/* FIXME : WE ARE ASSUMING IT IS A *PICTURE* EXTENSION */
|
||||||
if (gst_mpeg_video_packet_parse_picture_extension (&packet,
|
if (gst_mpeg_video_packet_parse_picture_extension (&packet,
|
||||||
|
@ -469,8 +459,6 @@ parse_packet_extension (GstMpegvParse * mpvparse, GstBuffer * buf, guint off)
|
||||||
}
|
}
|
||||||
mpvparse->picext_updated = TRUE;
|
mpvparse->picext_updated = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_buffer_unmap (buf, &map);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* caller guarantees at least start code in @buf at @off */
|
/* caller guarantees at least start code in @buf at @off */
|
||||||
|
@ -478,16 +466,14 @@ parse_packet_extension (GstMpegvParse * mpvparse, GstBuffer * buf, guint off)
|
||||||
* otherwise returns TRUE if code terminates preceding frame */
|
* otherwise returns TRUE if code terminates preceding frame */
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_mpegv_parse_process_sc (GstMpegvParse * mpvparse,
|
gst_mpegv_parse_process_sc (GstMpegvParse * mpvparse,
|
||||||
GstBuffer * buf, gint off, guint8 code)
|
GstMapInfo * info, gint off, GstMpegVideoPacket * packet)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE, packet = TRUE;
|
gboolean ret = FALSE, checkconfig = TRUE;
|
||||||
|
|
||||||
g_return_val_if_fail (buf && gst_buffer_get_size (buf) >= 4, FALSE);
|
GST_LOG_OBJECT (mpvparse, "process startcode %x (%s) offset:%d", packet->type,
|
||||||
|
picture_start_code_name (packet->type), off);
|
||||||
|
|
||||||
GST_LOG_OBJECT (mpvparse, "process startcode %x (%s) offset:%d", code,
|
switch (packet->type) {
|
||||||
picture_start_code_name (code), off);
|
|
||||||
|
|
||||||
switch (code) {
|
|
||||||
case GST_MPEG_VIDEO_PACKET_PICTURE:
|
case GST_MPEG_VIDEO_PACKET_PICTURE:
|
||||||
GST_LOG_OBJECT (mpvparse, "startcode is PICTURE");
|
GST_LOG_OBJECT (mpvparse, "startcode is PICTURE");
|
||||||
/* picture is aggregated with preceding sequence/gop, if any.
|
/* picture is aggregated with preceding sequence/gop, if any.
|
||||||
|
@ -515,49 +501,45 @@ gst_mpegv_parse_process_sc (GstMpegvParse * mpvparse,
|
||||||
break;
|
break;
|
||||||
case GST_MPEG_VIDEO_PACKET_EXTENSION:
|
case GST_MPEG_VIDEO_PACKET_EXTENSION:
|
||||||
GST_LOG_OBJECT (mpvparse, "startcode is VIDEO PACKET EXTENSION");
|
GST_LOG_OBJECT (mpvparse, "startcode is VIDEO PACKET EXTENSION");
|
||||||
parse_packet_extension (mpvparse, buf, off);
|
parse_packet_extension (mpvparse, info, off);
|
||||||
if (mpvparse->ext_count < G_N_ELEMENTS (mpvparse->ext_offsets))
|
if (mpvparse->ext_count < G_N_ELEMENTS (mpvparse->ext_offsets))
|
||||||
mpvparse->ext_offsets[mpvparse->ext_count++] = off;
|
mpvparse->ext_offsets[mpvparse->ext_count++] = off;
|
||||||
packet = FALSE;
|
checkconfig = FALSE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (GST_MPEG_VIDEO_PACKET_IS_SLICE (code)) {
|
if (GST_MPEG_VIDEO_PACKET_IS_SLICE (packet->type)) {
|
||||||
mpvparse->slice_count++;
|
mpvparse->slice_count++;
|
||||||
if (mpvparse->slice_offset == 0)
|
if (mpvparse->slice_offset == 0)
|
||||||
mpvparse->slice_offset = off - 4;
|
mpvparse->slice_offset = off - 4;
|
||||||
}
|
}
|
||||||
packet = FALSE;
|
checkconfig = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set size to avoid processing config again */
|
/* set size to avoid processing config again */
|
||||||
if (mpvparse->seq_offset >= 0 && off != mpvparse->seq_offset &&
|
if (checkconfig && mpvparse->seq_offset >= 0 && off != mpvparse->seq_offset &&
|
||||||
!mpvparse->seq_size && packet) {
|
!mpvparse->seq_size) {
|
||||||
/* should always be at start */
|
/* should always be at start */
|
||||||
g_assert (mpvparse->seq_offset <= 4);
|
g_assert (mpvparse->seq_offset <= 4);
|
||||||
gst_mpegv_parse_process_config (mpvparse, buf, off - mpvparse->seq_offset);
|
gst_mpegv_parse_process_config (mpvparse, info, off - mpvparse->seq_offset);
|
||||||
mpvparse->seq_size = off - mpvparse->seq_offset;
|
mpvparse->seq_size = off - mpvparse->seq_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* extract some picture info if there is any in the frame being terminated */
|
/* extract some picture info if there is any in the frame being terminated */
|
||||||
if (ret && mpvparse->pic_offset >= 0 && mpvparse->pic_offset < off) {
|
if (ret && mpvparse->pic_offset >= 0 && mpvparse->pic_offset < off) {
|
||||||
GstMapInfo map;
|
GstMpegVideoPacket header;
|
||||||
GstMpegVideoPacket packet;
|
|
||||||
|
|
||||||
gst_buffer_map (buf, &map, GST_MAP_READ);
|
header.data = info->data;
|
||||||
packet.data = map.data;
|
header.type = GST_MPEG_VIDEO_PACKET_PICTURE;
|
||||||
packet.type = GST_MPEG_VIDEO_PACKET_PICTURE;
|
header.offset = mpvparse->pic_offset;
|
||||||
packet.offset = mpvparse->pic_offset;
|
header.size = info->size - mpvparse->pic_offset;
|
||||||
packet.size = map.size - mpvparse->pic_offset;
|
if (gst_mpeg_video_packet_parse_picture_header (&header, &mpvparse->pichdr))
|
||||||
if (gst_mpeg_video_packet_parse_picture_header (&packet, &mpvparse->pichdr))
|
|
||||||
GST_LOG_OBJECT (mpvparse, "picture_coding_type %d (%s), ending"
|
GST_LOG_OBJECT (mpvparse, "picture_coding_type %d (%s), ending"
|
||||||
"frame of size %d", mpvparse->pichdr.pic_type,
|
"frame of size %d", mpvparse->pichdr.pic_type,
|
||||||
picture_type_name (mpvparse->pichdr.pic_type), off - 4);
|
picture_type_name (mpvparse->pichdr.pic_type), off - 4);
|
||||||
else
|
else
|
||||||
GST_LOG_OBJECT (mpvparse, "Couldn't parse picture at offset %d",
|
GST_LOG_OBJECT (mpvparse, "Couldn't parse picture at offset %d",
|
||||||
mpvparse->pic_offset);
|
mpvparse->pic_offset);
|
||||||
|
|
||||||
gst_buffer_unmap (buf, &map);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -631,7 +613,7 @@ retry:
|
||||||
/* note: initial start code is assumed at offset 0 by subsequent code */
|
/* note: initial start code is assumed at offset 0 by subsequent code */
|
||||||
|
|
||||||
/* examine start code, see if it looks like an initial start code */
|
/* examine start code, see if it looks like an initial start code */
|
||||||
if (gst_mpegv_parse_process_sc (mpvparse, buf, 4, packet.type)) {
|
if (gst_mpegv_parse_process_sc (mpvparse, &map, 4, &packet)) {
|
||||||
/* found sc */
|
/* found sc */
|
||||||
GST_LOG_OBJECT (mpvparse, "valid start code found");
|
GST_LOG_OBJECT (mpvparse, "valid start code found");
|
||||||
mpvparse->last_sc = 0;
|
mpvparse->last_sc = 0;
|
||||||
|
@ -676,7 +658,7 @@ next:
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* decide whether this startcode ends a frame */
|
/* decide whether this startcode ends a frame */
|
||||||
ret = gst_mpegv_parse_process_sc (mpvparse, buf, off + 4, packet.type);
|
ret = gst_mpegv_parse_process_sc (mpvparse, &map, off + 4, &packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
@ -984,10 +966,13 @@ gst_mpegv_parse_set_caps (GstBaseParse * parse, GstCaps * caps)
|
||||||
|
|
||||||
if ((value = gst_structure_get_value (s, "codec_data")) != NULL
|
if ((value = gst_structure_get_value (s, "codec_data")) != NULL
|
||||||
&& (buf = gst_value_get_buffer (value))) {
|
&& (buf = gst_value_get_buffer (value))) {
|
||||||
|
GstMapInfo map;
|
||||||
|
gst_buffer_map (buf, &map, GST_MAP_READ);
|
||||||
/* best possible parse attempt,
|
/* best possible parse attempt,
|
||||||
* src caps are based on sink caps so it will end up in there
|
* src caps are based on sink caps so it will end up in there
|
||||||
* whether sucessful or not */
|
* whether sucessful or not */
|
||||||
gst_mpegv_parse_process_config (mpvparse, buf, gst_buffer_get_size (buf));
|
gst_mpegv_parse_process_config (mpvparse, &map, gst_buffer_get_size (buf));
|
||||||
|
gst_buffer_unmap (buf, &map);
|
||||||
gst_mpegv_parse_reset_frame (mpvparse);
|
gst_mpegv_parse_reset_frame (mpvparse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue