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;
* 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);
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;
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."),
{
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: