mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
h264parse: use gstvideoparseutils to handle user data
This commit is contained in:
parent
d5946fc804
commit
b7558bd190
2 changed files with 40 additions and 86 deletions
|
@ -532,11 +532,18 @@ gst_h264_parse_process_sei_user_data (GstH264Parse * h264parse,
|
||||||
GstH264RegisteredUserData * rud)
|
GstH264RegisteredUserData * rud)
|
||||||
{
|
{
|
||||||
guint16 provider_code;
|
guint16 provider_code;
|
||||||
guint32 atsc_user_id;
|
|
||||||
GstByteReader br;
|
GstByteReader br;
|
||||||
|
GstVideoParseUtilsField field = GST_VIDEO_PARSE_UTILS_FIELD_1;
|
||||||
|
|
||||||
if (rud->country_code != 0xB5)
|
/* only US country code is currently supported */
|
||||||
return;
|
switch (rud->country_code) {
|
||||||
|
case ITU_T_T35_COUNTRY_CODE_US:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GST_LOG_OBJECT (h264parse, "Unsupported country code %d",
|
||||||
|
rud->country_code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (rud->data == NULL || rud->size < 2)
|
if (rud->data == NULL || rud->size < 2)
|
||||||
return;
|
return;
|
||||||
|
@ -545,75 +552,12 @@ gst_h264_parse_process_sei_user_data (GstH264Parse * h264parse,
|
||||||
|
|
||||||
provider_code = gst_byte_reader_get_uint16_be_unchecked (&br);
|
provider_code = gst_byte_reader_get_uint16_be_unchecked (&br);
|
||||||
|
|
||||||
/* There is also 0x29 / 47 for DirecTV, but we don't handle that for now.
|
if (h264parse->sei_pic_struct ==
|
||||||
* https://en.wikipedia.org/wiki/CEA-708#Picture_User_Data */
|
(guint8) GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD)
|
||||||
if (provider_code != 0x0031)
|
field = GST_VIDEO_PARSE_UTILS_FIELD_2;
|
||||||
return;
|
gst_video_parse_user_data ((GstElement *) h264parse, &h264parse->user_data,
|
||||||
|
&br, field, provider_code);
|
||||||
|
|
||||||
/* ANSI/SCTE 128-2010a section 8.1.2 */
|
|
||||||
if (!gst_byte_reader_get_uint32_be (&br, &atsc_user_id))
|
|
||||||
return;
|
|
||||||
|
|
||||||
atsc_user_id = GUINT32_FROM_BE (atsc_user_id);
|
|
||||||
switch (atsc_user_id) {
|
|
||||||
case GST_MAKE_FOURCC ('G', 'A', '9', '4'):{
|
|
||||||
guint8 user_data_type_code, m;
|
|
||||||
|
|
||||||
/* 8.2.1 ATSC1_data() Semantics, Table 15 */
|
|
||||||
if (!gst_byte_reader_get_uint8 (&br, &user_data_type_code))
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (user_data_type_code) {
|
|
||||||
case 0x03:{
|
|
||||||
guint8 process_cc_data_flag;
|
|
||||||
guint8 cc_count, em_data, b;
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
if (!gst_byte_reader_get_uint8 (&br, &b) || (b & 0x20) != 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!gst_byte_reader_get_uint8 (&br, &em_data) || em_data != 0xff)
|
|
||||||
break;
|
|
||||||
|
|
||||||
process_cc_data_flag = (b & 0x40) != 0;
|
|
||||||
cc_count = b & 0x1f;
|
|
||||||
|
|
||||||
if (cc_count * 3 > gst_byte_reader_get_remaining (&br))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!process_cc_data_flag || cc_count == 0) {
|
|
||||||
gst_byte_reader_skip_unchecked (&br, cc_count * 3);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Shouldn't really happen so let's not go out of our way to handle it */
|
|
||||||
if (h264parse->closedcaptions_size > 0) {
|
|
||||||
GST_WARNING_OBJECT (h264parse, "unused pending closed captions!");
|
|
||||||
GST_MEMDUMP_OBJECT (h264parse, "unused captions being dropped",
|
|
||||||
h264parse->closedcaptions, h264parse->closedcaptions_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < cc_count * 3; i++) {
|
|
||||||
h264parse->closedcaptions[i] =
|
|
||||||
gst_byte_reader_get_uint8_unchecked (&br);
|
|
||||||
}
|
|
||||||
h264parse->closedcaptions_size = cc_count * 3;
|
|
||||||
h264parse->closedcaptions_type = GST_VIDEO_CAPTION_TYPE_CEA708_RAW;
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (h264parse, "Extracted closed captions");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
GST_LOG ("Unhandled atsc1 user data type %d", atsc_user_id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!gst_byte_reader_get_uint8 (&br, &m) || m != 0xff)
|
|
||||||
GST_WARNING_OBJECT (h264parse, "Marker bits mismatch after ATSC1_data");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2593,6 +2537,8 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
GstH264Parse *h264parse;
|
GstH264Parse *h264parse;
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
GstEvent *event;
|
GstEvent *event;
|
||||||
|
GstBuffer *parse_buffer = NULL;
|
||||||
|
gboolean is_interlaced = FALSE;
|
||||||
|
|
||||||
h264parse = GST_H264_PARSE (parse);
|
h264parse = GST_H264_PARSE (parse);
|
||||||
|
|
||||||
|
@ -2651,15 +2597,6 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
buffer = frame->buffer;
|
buffer = frame->buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h264parse->closedcaptions_size > 0) {
|
|
||||||
gst_buffer_add_video_caption_meta (buffer,
|
|
||||||
h264parse->closedcaptions_type, h264parse->closedcaptions,
|
|
||||||
h264parse->closedcaptions_size);
|
|
||||||
|
|
||||||
h264parse->closedcaptions_type = GST_VIDEO_CAPTION_TYPE_UNKNOWN;
|
|
||||||
h264parse->closedcaptions_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((event = check_pending_key_unit_event (h264parse->force_key_unit_event,
|
if ((event = check_pending_key_unit_event (h264parse->force_key_unit_event,
|
||||||
&parse->segment, GST_BUFFER_TIMESTAMP (buffer),
|
&parse->segment, GST_BUFFER_TIMESTAMP (buffer),
|
||||||
GST_BUFFER_FLAGS (buffer), h264parse->pending_key_unit_ts))) {
|
GST_BUFFER_FLAGS (buffer), h264parse->pending_key_unit_ts))) {
|
||||||
|
@ -2750,9 +2687,9 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
|
|
||||||
for (i = 0; i < h264parse->num_clock_timestamp; i++) {
|
for (i = 0; i < h264parse->num_clock_timestamp; i++) {
|
||||||
GstH264ClockTimestamp *tim = &h264parse->clock_timestamp[i];
|
GstH264ClockTimestamp *tim = &h264parse->clock_timestamp[i];
|
||||||
GstVideoTimeCodeFlags flags = 0;
|
|
||||||
gint field_count = -1;
|
gint field_count = -1;
|
||||||
guint n_frames;
|
guint n_frames;
|
||||||
|
GstVideoTimeCodeFlags flags = 0;
|
||||||
|
|
||||||
/* Table D-1 */
|
/* Table D-1 */
|
||||||
switch (h264parse->sei_pic_struct) {
|
switch (h264parse->sei_pic_struct) {
|
||||||
|
@ -2791,8 +2728,10 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
if (tim->counting_type == 4)
|
if (tim->counting_type == 4)
|
||||||
flags |= GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME;
|
flags |= GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME;
|
||||||
|
|
||||||
if (tim->ct_type == GST_H264_CT_TYPE_INTERLACED)
|
if (tim->ct_type == GST_H264_CT_TYPE_INTERLACED) {
|
||||||
flags |= GST_VIDEO_TIME_CODE_FLAGS_INTERLACED;
|
flags |= GST_VIDEO_TIME_CODE_FLAGS_INTERLACED;
|
||||||
|
is_interlaced = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
n_frames =
|
n_frames =
|
||||||
gst_util_uint64_scale_int (tim->n_frames, 1,
|
gst_util_uint64_scale_int (tim->n_frames, 1,
|
||||||
|
@ -2811,6 +2750,22 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
h264parse->num_clock_timestamp = 0;
|
h264parse->num_clock_timestamp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frame->out_buffer) {
|
||||||
|
parse_buffer = frame->out_buffer =
|
||||||
|
gst_buffer_make_writable (frame->out_buffer);
|
||||||
|
} else {
|
||||||
|
parse_buffer = frame->buffer = gst_buffer_make_writable (frame->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_interlaced) {
|
||||||
|
GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_INTERLACED);
|
||||||
|
if (h264parse->sei_pic_struct == GST_H264_SEI_PIC_STRUCT_TOP_FIELD)
|
||||||
|
GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_TFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_video_push_user_data ((GstElement *) h264parse, &h264parse->user_data,
|
||||||
|
parse_buffer);
|
||||||
|
|
||||||
gst_h264_parse_reset_frame (h264parse);
|
gst_h264_parse_reset_frame (h264parse);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <gst/base/gstbaseparse.h>
|
#include <gst/base/gstbaseparse.h>
|
||||||
#include <gst/codecparsers/gsth264parser.h>
|
#include <gst/codecparsers/gsth264parser.h>
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
|
#include "gstvideoparseutils.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -145,10 +146,8 @@ struct _GstH264Parse
|
||||||
gboolean aud_needed;
|
gboolean aud_needed;
|
||||||
gboolean aud_insert;
|
gboolean aud_insert;
|
||||||
|
|
||||||
/* pending closed captions */
|
GstVideoParseUserData user_data;
|
||||||
guint8 closedcaptions[96];
|
|
||||||
guint closedcaptions_size;
|
|
||||||
GstVideoCaptionType closedcaptions_type;
|
|
||||||
|
|
||||||
/* For forward predicted trickmode */
|
/* For forward predicted trickmode */
|
||||||
gboolean discard_bidirectional;
|
gboolean discard_bidirectional;
|
||||||
|
|
Loading…
Reference in a new issue