mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 00:36:51 +00:00
dvbsubenc: Write Display Definition Segment if a non-default width/height is used
Otherwise it can't be rendered by dvbsuboverlay or ffmpeg at least. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3446>
This commit is contained in:
parent
c6af0a39e7
commit
76eb870251
3 changed files with 58 additions and 15 deletions
|
@ -721,9 +721,35 @@ dvbenc_write_region_segment (GstByteWriter * b, int object_version, int page_id,
|
|||
gst_byte_writer_set_pos (b, pos);
|
||||
}
|
||||
|
||||
static void
|
||||
dvbenc_write_display_definition_segment (GstByteWriter * b, int object_version,
|
||||
int page_id, guint16 width, guint16 height)
|
||||
{
|
||||
guint seg_size_pos, pos;
|
||||
|
||||
gst_byte_writer_put_uint8 (b, DVB_SEGMENT_SYNC_BYTE);
|
||||
gst_byte_writer_put_uint8 (b, DVB_SEGMENT_TYPE_DISPLAY_DEFINITION);
|
||||
gst_byte_writer_put_uint16_be (b, page_id);
|
||||
|
||||
/* Size placeholder */
|
||||
seg_size_pos = gst_byte_writer_get_pos (b);
|
||||
gst_byte_writer_put_uint16_be (b, 0);
|
||||
|
||||
/* version number, display window flag, reserved bits */
|
||||
gst_byte_writer_put_uint8 (b, (object_version << 4) | (0 << 3) | 0x07);
|
||||
gst_byte_writer_put_uint16_be (b, width);
|
||||
gst_byte_writer_put_uint16_be (b, height);
|
||||
|
||||
/* Re-write the size field */
|
||||
pos = gst_byte_writer_get_pos (b);
|
||||
gst_byte_writer_set_pos (b, seg_size_pos);
|
||||
gst_byte_writer_put_uint16_be (b, pos - (seg_size_pos + 2));
|
||||
gst_byte_writer_set_pos (b, pos);
|
||||
}
|
||||
|
||||
GstBuffer *
|
||||
gst_dvbenc_encode (int object_version, int page_id, SubpictureRect * s,
|
||||
guint num_subpictures)
|
||||
gst_dvbenc_encode (int object_version, int page_id, int display_version,
|
||||
guint16 width, guint16 height, SubpictureRect * s, guint num_subpictures)
|
||||
{
|
||||
GstByteWriter b;
|
||||
guint seg_size_pos, pos;
|
||||
|
@ -744,6 +770,11 @@ gst_dvbenc_encode (int object_version, int page_id, SubpictureRect * s,
|
|||
* 0x20 0x00 prefixed */
|
||||
gst_byte_writer_put_uint16_be (&b, 0x2000);
|
||||
|
||||
/* If non-default width/height are used, write a display definiton segment */
|
||||
if (width != 720 || height != 576)
|
||||
dvbenc_write_display_definition_segment (&b, display_version, page_id,
|
||||
width, height);
|
||||
|
||||
/* Page Composition Segment */
|
||||
gst_byte_writer_put_uint8 (&b, DVB_SEGMENT_SYNC_BYTE);
|
||||
gst_byte_writer_put_uint8 (&b, DVB_SEGMENT_TYPE_PAGE_COMPOSITION);
|
||||
|
|
|
@ -393,7 +393,9 @@ process_largest_subregion (GstDvbSubEnc * enc, GstVideoFrame * vframe)
|
|||
s.x = left;
|
||||
s.y = top;
|
||||
|
||||
packet = gst_dvbenc_encode (enc->object_version & 0xF, 1, &s, 1);
|
||||
packet =
|
||||
gst_dvbenc_encode (enc->object_version & 0xF, 1, enc->display_version,
|
||||
enc->in_info.width, enc->in_info.height, &s, 1);
|
||||
if (packet == NULL) {
|
||||
gst_video_frame_unmap (&ayuv8p_frame);
|
||||
goto fail;
|
||||
|
@ -440,7 +442,9 @@ gst_dvb_sub_enc_generate_end_packet (GstDvbSubEnc * enc, GstClockTime pts)
|
|||
GST_DEBUG_OBJECT (enc, "Outputting end of page at TS %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (enc->current_end_time));
|
||||
|
||||
packet = gst_dvbenc_encode (enc->object_version & 0xF, 1, NULL, 0);
|
||||
packet =
|
||||
gst_dvbenc_encode (enc->object_version & 0xF, 1, enc->display_version,
|
||||
enc->in_info.width, enc->in_info.height, NULL, 0);
|
||||
if (packet == NULL) {
|
||||
GST_ELEMENT_ERROR (enc, STREAM, FAILED,
|
||||
("Internal data stream error."),
|
||||
|
@ -501,27 +505,34 @@ gst_dvb_sub_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
|
|||
{
|
||||
GstDvbSubEnc *enc = GST_DVB_SUB_ENC (gst_pad_get_parent (pad));
|
||||
gboolean ret = FALSE;
|
||||
GstVideoInfo in_info;
|
||||
GstCaps *out_caps = NULL;
|
||||
|
||||
GST_DEBUG_OBJECT (enc, "setcaps called with %" GST_PTR_FORMAT, caps);
|
||||
if (!gst_video_info_from_caps (&enc->in_info, caps)) {
|
||||
if (!gst_video_info_from_caps (&in_info, caps)) {
|
||||
GST_ERROR_OBJECT (enc, "Failed to parse input caps");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
out_caps = gst_caps_new_simple ("subpicture/x-dvb",
|
||||
"width", G_TYPE_INT, enc->in_info.width,
|
||||
"height", G_TYPE_INT, enc->in_info.height,
|
||||
"framerate", GST_TYPE_FRACTION, enc->in_info.fps_n, enc->in_info.fps_d,
|
||||
NULL);
|
||||
if (!enc->in_info.finfo || !gst_video_info_is_equal (&in_info, &enc->in_info)) {
|
||||
enc->in_info = in_info;
|
||||
enc->display_version++;
|
||||
|
||||
out_caps = gst_caps_new_simple ("subpicture/x-dvb",
|
||||
"width", G_TYPE_INT, enc->in_info.width,
|
||||
"height", G_TYPE_INT, enc->in_info.height,
|
||||
"framerate", GST_TYPE_FRACTION, enc->in_info.fps_n, enc->in_info.fps_d,
|
||||
NULL);
|
||||
|
||||
if (!gst_pad_set_caps (enc->srcpad, out_caps)) {
|
||||
GST_WARNING_OBJECT (enc, "failed setting downstream caps");
|
||||
gst_caps_unref (out_caps);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
if (!gst_pad_set_caps (enc->srcpad, out_caps)) {
|
||||
GST_WARNING_OBJECT (enc, "failed setting downstream caps");
|
||||
gst_caps_unref (out_caps);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
gst_caps_unref (out_caps);
|
||||
ret = TRUE;
|
||||
|
||||
beach:
|
||||
|
|
|
@ -47,6 +47,7 @@ struct _GstDvbSubEnc
|
|||
GstElement element;
|
||||
|
||||
GstVideoInfo in_info;
|
||||
int display_version;
|
||||
GstPad *sinkpad;
|
||||
GstPad *srcpad;
|
||||
|
||||
|
@ -68,4 +69,4 @@ GST_ELEMENT_REGISTER_DECLARE (dvbsubenc);
|
|||
|
||||
gboolean gst_dvbsubenc_ayuv_to_ayuv8p (GstVideoFrame * src, GstVideoFrame * dest, int max_colours, guint32 *out_num_colours);
|
||||
|
||||
GstBuffer *gst_dvbenc_encode (int object_version, int page_id, SubpictureRect *s, guint num_subpictures);
|
||||
GstBuffer *gst_dvbenc_encode (int object_version, int page_id, int display_version, guint16 width, guint16 height, SubpictureRect *s, guint num_subpictures);
|
||||
|
|
Loading…
Reference in a new issue