diff --git a/subprojects/gst-plugins-bad/gst/dvbsubenc/gstdvbsubenc-util.c b/subprojects/gst-plugins-bad/gst/dvbsubenc/gstdvbsubenc-util.c index c9a152b19c..e1e8d046ee 100644 --- a/subprojects/gst-plugins-bad/gst/dvbsubenc/gstdvbsubenc-util.c +++ b/subprojects/gst-plugins-bad/gst/dvbsubenc/gstdvbsubenc-util.c @@ -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); diff --git a/subprojects/gst-plugins-bad/gst/dvbsubenc/gstdvbsubenc.c b/subprojects/gst-plugins-bad/gst/dvbsubenc/gstdvbsubenc.c index ab25ae24f7..ad316f78bc 100644 --- a/subprojects/gst-plugins-bad/gst/dvbsubenc/gstdvbsubenc.c +++ b/subprojects/gst-plugins-bad/gst/dvbsubenc/gstdvbsubenc.c @@ -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: diff --git a/subprojects/gst-plugins-bad/gst/dvbsubenc/gstdvbsubenc.h b/subprojects/gst-plugins-bad/gst/dvbsubenc/gstdvbsubenc.h index 507e9f54d7..c43c6b1a97 100644 --- a/subprojects/gst-plugins-bad/gst/dvbsubenc/gstdvbsubenc.h +++ b/subprojects/gst-plugins-bad/gst/dvbsubenc/gstdvbsubenc.h @@ -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);