mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 15:51:11 +00:00
mpegvideoparse: use gstvideoparseutils to handle user data
This commit is contained in:
parent
22ec7fbbc2
commit
d5946fc804
2 changed files with 24 additions and 101 deletions
|
@ -461,93 +461,20 @@ parse_packet_extension (GstMpegvParse * mpvparse, GstMapInfo * info, guint off)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A53-4 Table 6.7 */
|
|
||||||
#define A53_USER_DATA_ID_GA94 0x47413934
|
|
||||||
#define A53_USER_DATA_ID_DTG1 0x44544731
|
|
||||||
|
|
||||||
/* A53-4 Table 6.9 */
|
|
||||||
#define A53_USER_DATA_TYPE_CODE_MPEG_CC_DATA 0x03
|
|
||||||
#define A53_USER_DATA_TYPE_CODE_BAR_DATA 0x06
|
|
||||||
|
|
||||||
/* CEA-708 Table 2 */
|
|
||||||
#define CEA_708_PROCESS_CC_DATA_FLAG 0x40
|
|
||||||
#define CEA_708_PROCESS_EM_DATA_FLAG 0x80
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_user_data_packet (GstMpegvParse * mpvparse, const guint8 * data,
|
parse_user_data_packet (GstMpegvParse * mpvparse, const guint8 * data,
|
||||||
guint size)
|
guint size)
|
||||||
{
|
{
|
||||||
gboolean a53_user_data_ga94 = FALSE;
|
GstByteReader br;
|
||||||
gboolean a53_user_data_dtg1 = FALSE;
|
GstVideoParseUtilsField field = GST_VIDEO_PARSE_UTILS_FIELD_1;
|
||||||
gboolean a53_user_data_mpeg_cc = FALSE;
|
gst_byte_reader_init (&br, data, size);
|
||||||
gboolean a53_process_708_cc_data = FALSE;
|
|
||||||
gboolean process_708_em_data = FALSE;
|
|
||||||
|
|
||||||
if (size < 2) {
|
if (mpvparse->picext.picture_structure ==
|
||||||
GST_DEBUG_OBJECT (mpvparse, "user data packet too short, ignoring");
|
(guint8) GST_MPEG_VIDEO_PICTURE_STRUCTURE_BOTTOM_FIELD)
|
||||||
return;
|
field = GST_VIDEO_PARSE_UTILS_FIELD_2;
|
||||||
}
|
gst_video_parse_user_data ((GstElement *) mpvparse, &mpvparse->user_data, &br,
|
||||||
|
field, ITU_T_T35_MANUFACTURER_US_ATSC);
|
||||||
|
|
||||||
/* A53 part 4 closed captions */
|
|
||||||
if (size > 6) {
|
|
||||||
guint32 user_data_id = GST_READ_UINT32_BE (data);
|
|
||||||
a53_user_data_ga94 = user_data_id == A53_USER_DATA_ID_GA94;
|
|
||||||
a53_user_data_dtg1 = user_data_id == A53_USER_DATA_ID_DTG1;
|
|
||||||
a53_user_data_mpeg_cc = data[4] == A53_USER_DATA_TYPE_CODE_MPEG_CC_DATA;
|
|
||||||
a53_process_708_cc_data = (data[5] & CEA_708_PROCESS_CC_DATA_FLAG) != 0;
|
|
||||||
process_708_em_data = (data[5] & CEA_708_PROCESS_EM_DATA_FLAG) != 0;
|
|
||||||
|
|
||||||
if (a53_user_data_dtg1) {
|
|
||||||
GST_DEBUG_OBJECT (mpvparse,
|
|
||||||
"ignoring closed captions as DTG1 is not supported");
|
|
||||||
} else if (a53_user_data_ga94) {
|
|
||||||
GST_DEBUG_OBJECT (mpvparse, "GA94 closed captions");
|
|
||||||
if (!a53_user_data_mpeg_cc) {
|
|
||||||
GST_DEBUG_OBJECT (mpvparse,
|
|
||||||
"ignoring closed captions as A53_USER_DATA_TYPE_CODE_MPEG_CC_DATA is not set");
|
|
||||||
}
|
|
||||||
if (!a53_process_708_cc_data) {
|
|
||||||
GST_DEBUG_OBJECT (mpvparse,
|
|
||||||
"ignoring closed captions as CEA_708_PROCESS_CC_DATA_FLAG is not set");
|
|
||||||
}
|
|
||||||
if (!process_708_em_data) {
|
|
||||||
GST_DEBUG_OBJECT (mpvparse,
|
|
||||||
"CEA_708_PROCESS_EM_DATA_FLAG flag is not set");
|
|
||||||
}
|
|
||||||
/* ignore em data flag for now as it breaks one of the tests */
|
|
||||||
process_708_em_data = /*process_708_em_data && */ (data[6] == 0xff);
|
|
||||||
if (!process_708_em_data) {
|
|
||||||
GST_DEBUG_OBJECT (mpvparse,
|
|
||||||
"ignoring closed captions as em data does not equal 0xFF");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (size > 6 && a53_user_data_ga94 && a53_user_data_mpeg_cc
|
|
||||||
&& a53_process_708_cc_data && process_708_em_data) {
|
|
||||||
guint8 cc_count = data[5] & 0x1f;
|
|
||||||
guint cc_size = cc_count * 3;
|
|
||||||
|
|
||||||
data += 7;
|
|
||||||
size -= 7;
|
|
||||||
|
|
||||||
if (cc_size == 0 || cc_size > size) {
|
|
||||||
GST_DEBUG_OBJECT (mpvparse, "ignoring closed captions, not enough data");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Shouldn't really happen so let's not go out of our way to handle it */
|
|
||||||
if (mpvparse->closedcaptions_size > 0)
|
|
||||||
GST_WARNING_OBJECT (mpvparse, "unused pending closed captions!");
|
|
||||||
|
|
||||||
g_assert (cc_size <= sizeof (mpvparse->closedcaptions));
|
|
||||||
memcpy (mpvparse->closedcaptions, data, cc_size);
|
|
||||||
mpvparse->closedcaptions_size = cc_size;
|
|
||||||
mpvparse->closedcaptions_type = GST_VIDEO_CAPTION_TYPE_CEA708_RAW;
|
|
||||||
GST_DEBUG_OBJECT (mpvparse, "CEA-708 closed captions, %u bytes", cc_size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_MEMDUMP_OBJECT (mpvparse, "unhandled user data packet", data, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* caller guarantees at least start code in @buf at @off ( - 4)*/
|
/* caller guarantees at least start code in @buf at @off ( - 4)*/
|
||||||
|
@ -1040,6 +967,7 @@ gst_mpegv_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
GstMpegVideoPictureHdr *pic_hdr = NULL;
|
GstMpegVideoPictureHdr *pic_hdr = NULL;
|
||||||
GstMpegVideoPictureExt *pic_ext = NULL;
|
GstMpegVideoPictureExt *pic_ext = NULL;
|
||||||
GstMpegVideoQuantMatrixExt *quant_ext = NULL;
|
GstMpegVideoQuantMatrixExt *quant_ext = NULL;
|
||||||
|
GstBuffer *parse_buffer = NULL;
|
||||||
|
|
||||||
/* tag sending done late enough in hook to ensure pending events
|
/* tag sending done late enough in hook to ensure pending events
|
||||||
* have already been sent */
|
* have already been sent */
|
||||||
|
@ -1105,23 +1033,21 @@ gst_mpegv_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
meta->slice_offset = mpvparse->slice_offset;
|
meta->slice_offset = mpvparse->slice_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mpvparse->closedcaptions_size > 0) {
|
if (frame->out_buffer) {
|
||||||
GstBuffer *buf;
|
parse_buffer = frame->out_buffer =
|
||||||
|
gst_buffer_make_writable (frame->out_buffer);
|
||||||
if (frame->out_buffer) {
|
} else {
|
||||||
buf = frame->out_buffer = gst_buffer_make_writable (frame->out_buffer);
|
parse_buffer = frame->buffer = gst_buffer_make_writable (frame->buffer);
|
||||||
} else {
|
|
||||||
buf = frame->buffer = gst_buffer_make_writable (frame->buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_buffer_add_video_caption_meta (buf,
|
|
||||||
mpvparse->closedcaptions_type, mpvparse->closedcaptions,
|
|
||||||
mpvparse->closedcaptions_size);
|
|
||||||
|
|
||||||
mpvparse->closedcaptions_type = GST_VIDEO_CAPTION_TYPE_UNKNOWN;
|
|
||||||
mpvparse->closedcaptions_size = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pic_ext && !pic_ext->progressive_frame) {
|
||||||
|
GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_INTERLACED);
|
||||||
|
if (pic_ext->top_field_first)
|
||||||
|
GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_TFF);
|
||||||
|
}
|
||||||
|
gst_video_push_user_data ((GstElement *) mpvparse, &mpvparse->user_data,
|
||||||
|
parse_buffer);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/base/gstbaseparse.h>
|
#include <gst/base/gstbaseparse.h>
|
||||||
|
#include "gstvideoparseutils.h"
|
||||||
#include <gst/codecparsers/gstmpegvideoparser.h>
|
#include <gst/codecparsers/gstmpegvideoparser.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
@ -87,10 +87,7 @@ struct _GstMpegvParse {
|
||||||
gboolean picext_updated;
|
gboolean picext_updated;
|
||||||
gboolean quantmatrext_updated;
|
gboolean quantmatrext_updated;
|
||||||
|
|
||||||
/* pending closed captions */
|
GstVideoParseUserData user_data;
|
||||||
guint8 closedcaptions[96];
|
|
||||||
guint closedcaptions_size;
|
|
||||||
GstVideoCaptionType closedcaptions_type;
|
|
||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
gboolean drop;
|
gboolean drop;
|
||||||
|
|
Loading…
Reference in a new issue