mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
ext/resindvd/gstmpegdemux.c: Remove whitespace line.
Original commit message from CVS: * ext/resindvd/gstmpegdemux.c: Remove whitespace line. * ext/resindvd/resindvdbin.c: * ext/resindvd/resindvdbin.h: Make it so that audio/video pads aren't added to the bin until after data flow starts. * ext/resindvd/resin-play: Move video buffer queue outside resindvdbin * ext/resindvd/resindvdsrc.c: Check that the nav_clock_id didn't already get unscheduled. * gst/dvdspu/gstdvdspu.c: Remove assert that sometimes triggers erroneously.
This commit is contained in:
parent
72dedf7904
commit
95fa5e8b95
7 changed files with 130 additions and 38 deletions
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
||||||
|
2008-07-14 Jan Schmidt <thaytan@noraisin.net>
|
||||||
|
|
||||||
|
* ext/resindvd/gstmpegdemux.c:
|
||||||
|
Remove whitespace line.
|
||||||
|
|
||||||
|
* ext/resindvd/resindvdbin.c:
|
||||||
|
* ext/resindvd/resindvdbin.h:
|
||||||
|
Make it so that audio/video pads aren't added to the bin
|
||||||
|
until after data flow starts.
|
||||||
|
|
||||||
|
* ext/resindvd/resin-play:
|
||||||
|
Move video buffer queue outside resindvdbin
|
||||||
|
|
||||||
|
* ext/resindvd/resindvdsrc.c:
|
||||||
|
Check that the nav_clock_id didn't already get unscheduled.
|
||||||
|
|
||||||
|
* gst/dvdspu/gstdvdspu.c:
|
||||||
|
Remove assert that sometimes triggers erroneously.
|
||||||
|
|
||||||
2008-07-13 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
2008-07-13 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||||
|
|
||||||
* gst/deinterlace2/tvtime/greedyh.asm:
|
* gst/deinterlace2/tvtime/greedyh.asm:
|
||||||
|
|
|
@ -346,7 +346,6 @@ gst_flups_demux_create_stream (GstFluPSDemux * demux, gint id, gint stream_type)
|
||||||
GST_DEBUG_OBJECT (demux, "create pad %s, caps %" GST_PTR_FORMAT, name, caps);
|
GST_DEBUG_OBJECT (demux, "create pad %s, caps %" GST_PTR_FORMAT, name, caps);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
|
|
||||||
|
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
gst-launch rsndvdbin name=dvd "$DEVICE_OPT" \
|
gst-launch rsndvdbin name=dvd "$DEVICE_OPT" \
|
||||||
dvd. ! dvdspu name=spu ! ffmpegcolorspace ! videoscale ! ximagesink force-aspect-ratio=true \
|
dvdspu name=spu ! ffmpegcolorspace ! videoscale ! ximagesink force-aspect-ratio=true \
|
||||||
dvd. ! spu. \
|
dvd. ! queue max-size-buffers=3 max-size-bytes=0 ! spu.video \
|
||||||
|
dvd. ! spu.subpicture \
|
||||||
dvd. ! audioconvert ! autoaudiosink $@
|
dvd. ! audioconvert ! autoaudiosink $@
|
||||||
|
|
|
@ -37,6 +37,7 @@ GST_DEBUG_CATEGORY_EXTERN (resindvd_debug);
|
||||||
#define GST_CAT_DEFAULT resindvd_debug
|
#define GST_CAT_DEFAULT resindvd_debug
|
||||||
|
|
||||||
#define DECODEBIN_AUDIO 0
|
#define DECODEBIN_AUDIO 0
|
||||||
|
#define USE_VIDEOQ 0
|
||||||
|
|
||||||
#define DVDBIN_LOCK(d) g_mutex_lock((d)->dvd_lock)
|
#define DVDBIN_LOCK(d) g_mutex_lock((d)->dvd_lock)
|
||||||
#define DVDBIN_UNLOCK(d) g_mutex_unlock((d)->dvd_lock)
|
#define DVDBIN_UNLOCK(d) g_mutex_unlock((d)->dvd_lock)
|
||||||
|
@ -98,6 +99,8 @@ static void rsn_dvdbin_get_property (GObject * object, guint prop_id,
|
||||||
GValue * value, GParamSpec * pspec);
|
GValue * value, GParamSpec * pspec);
|
||||||
static GstStateChangeReturn rsn_dvdbin_change_state (GstElement * element,
|
static GstStateChangeReturn rsn_dvdbin_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
|
static void dvdbin_pad_blocked_cb (GstPad * pad, gboolean blocked,
|
||||||
|
RsnDvdBin * dvdbin);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rsn_dvdbin_base_init (gpointer gclass)
|
rsn_dvdbin_base_init (gpointer gclass)
|
||||||
|
@ -337,7 +340,6 @@ create_elements (RsnDvdBin * dvdbin)
|
||||||
{
|
{
|
||||||
GstPad *src = NULL;
|
GstPad *src = NULL;
|
||||||
GstPad *sink = NULL;
|
GstPad *sink = NULL;
|
||||||
GstPad *ghost = NULL;
|
|
||||||
|
|
||||||
if (!try_create_piece (dvdbin, DVD_ELEM_SOURCE, NULL,
|
if (!try_create_piece (dvdbin, DVD_ELEM_SOURCE, NULL,
|
||||||
RESIN_TYPE_DVDSRC, "dvdsrc", "DVD source")) {
|
RESIN_TYPE_DVDSRC, "dvdsrc", "DVD source")) {
|
||||||
|
@ -378,19 +380,18 @@ create_elements (RsnDvdBin * dvdbin)
|
||||||
g_signal_connect (G_OBJECT (dvdbin->pieces[DVD_ELEM_VIDDEC]),
|
g_signal_connect (G_OBJECT (dvdbin->pieces[DVD_ELEM_VIDDEC]),
|
||||||
"new-decoded-pad", G_CALLBACK (viddec_pad_added), dvdbin);
|
"new-decoded-pad", G_CALLBACK (viddec_pad_added), dvdbin);
|
||||||
|
|
||||||
#if 1
|
|
||||||
if (!try_create_piece (dvdbin, DVD_ELEM_PARSET, NULL, RSN_TYPE_RSNPARSETTER,
|
if (!try_create_piece (dvdbin, DVD_ELEM_PARSET, NULL, RSN_TYPE_RSNPARSETTER,
|
||||||
"rsnparsetter", "Aspect ratio adjustment"))
|
"rsnparsetter", "Aspect ratio adjustment"))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
#else
|
|
||||||
if (!try_create_piece (dvdbin, DVD_ELEM_PARSET, "identity", 0,
|
|
||||||
"rsnparsetter", "Aspect ratio adjustment"))
|
|
||||||
return FALSE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#if USE_VIDEOQ
|
||||||
|
/* Add a small amount of queueing after the video decoder. */
|
||||||
if (!try_create_piece (dvdbin, DVD_ELEM_VIDQ, "queue", 0, "vid_q",
|
if (!try_create_piece (dvdbin, DVD_ELEM_VIDQ, "queue", 0, "vid_q",
|
||||||
"video decoder buffer"))
|
"video decoder buffer"))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
g_object_set (dvdbin->pieces[DVD_ELEM_VIDQ],
|
||||||
|
"max-size-time", G_GUINT64_CONSTANT (0), "max-size-bytes", 0,
|
||||||
|
"max-size-buffers", 3, NULL);
|
||||||
|
|
||||||
src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_PARSET], "src");
|
src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_PARSET], "src");
|
||||||
sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_VIDQ], "sink");
|
sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_VIDQ], "sink");
|
||||||
|
@ -398,21 +399,21 @@ create_elements (RsnDvdBin * dvdbin)
|
||||||
goto failed_vidq_connect;
|
goto failed_vidq_connect;
|
||||||
if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink)))
|
if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink)))
|
||||||
goto failed_vidq_connect;
|
goto failed_vidq_connect;
|
||||||
|
gst_object_unref (src);
|
||||||
g_object_set (dvdbin->pieces[DVD_ELEM_VIDQ],
|
gst_object_unref (sink);
|
||||||
"max-size-time", G_GUINT64_CONSTANT (0), "max-size-bytes", 0,
|
src = sink = NULL;
|
||||||
"max-size-buffers", 3, NULL);
|
|
||||||
|
|
||||||
src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_VIDQ], "src");
|
src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_VIDQ], "src");
|
||||||
|
#else
|
||||||
|
src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_PARSET], "src");
|
||||||
|
#endif
|
||||||
if (src == NULL)
|
if (src == NULL)
|
||||||
goto failed_vidq_ghost;
|
goto failed_video_ghost;
|
||||||
ghost = gst_ghost_pad_new ("video", src);
|
dvdbin->video_pad = gst_ghost_pad_new ("video", src);
|
||||||
if (ghost == NULL)
|
if (dvdbin->video_pad == NULL)
|
||||||
goto failed_vidq_ghost;
|
goto failed_video_ghost;
|
||||||
if (!gst_element_add_pad (GST_ELEMENT (dvdbin), ghost))
|
|
||||||
goto failed_vidq_ghost;
|
|
||||||
gst_object_unref (src);
|
gst_object_unref (src);
|
||||||
ghost = src = sink = NULL;
|
src = NULL;
|
||||||
|
|
||||||
if (!try_create_piece (dvdbin, DVD_ELEM_SPU_SELECT, NULL,
|
if (!try_create_piece (dvdbin, DVD_ELEM_SPU_SELECT, NULL,
|
||||||
RSN_TYPE_STREAM_SELECTOR, "subpselect", "Subpicture stream selector"))
|
RSN_TYPE_STREAM_SELECTOR, "subpselect", "Subpicture stream selector"))
|
||||||
|
@ -421,13 +422,14 @@ create_elements (RsnDvdBin * dvdbin)
|
||||||
src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_SPU_SELECT], "src");
|
src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_SPU_SELECT], "src");
|
||||||
if (src == NULL)
|
if (src == NULL)
|
||||||
goto failed_spu_ghost;
|
goto failed_spu_ghost;
|
||||||
ghost = gst_ghost_pad_new ("subpicture", src);
|
dvdbin->subpicture_pad = gst_ghost_pad_new ("subpicture", src);
|
||||||
if (ghost == NULL)
|
if (dvdbin->subpicture_pad == NULL)
|
||||||
goto failed_spu_ghost;
|
|
||||||
if (!gst_element_add_pad (GST_ELEMENT (dvdbin), ghost))
|
|
||||||
goto failed_spu_ghost;
|
goto failed_spu_ghost;
|
||||||
|
gst_pad_set_active (dvdbin->subpicture_pad, TRUE);
|
||||||
|
gst_pad_set_blocked_async (dvdbin->subpicture_pad, TRUE,
|
||||||
|
(GstPadBlockCallback) dvdbin_pad_blocked_cb, dvdbin);
|
||||||
gst_object_unref (src);
|
gst_object_unref (src);
|
||||||
ghost = src = sink = NULL;
|
src = NULL;
|
||||||
|
|
||||||
if (!try_create_piece (dvdbin, DVD_ELEM_AUD_SELECT, NULL,
|
if (!try_create_piece (dvdbin, DVD_ELEM_AUD_SELECT, NULL,
|
||||||
RSN_TYPE_STREAM_SELECTOR, "audioselect", "Audio stream selector"))
|
RSN_TYPE_STREAM_SELECTOR, "audioselect", "Audio stream selector"))
|
||||||
|
@ -478,13 +480,14 @@ create_elements (RsnDvdBin * dvdbin)
|
||||||
src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "src");
|
src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "src");
|
||||||
if (src == NULL)
|
if (src == NULL)
|
||||||
goto failed_aud_ghost;
|
goto failed_aud_ghost;
|
||||||
ghost = gst_ghost_pad_new ("audio", src);
|
dvdbin->audio_pad = gst_ghost_pad_new ("audio", src);
|
||||||
if (ghost == NULL)
|
if (dvdbin->audio_pad == NULL)
|
||||||
goto failed_aud_ghost;
|
|
||||||
if (!gst_element_add_pad (GST_ELEMENT (dvdbin), ghost))
|
|
||||||
goto failed_aud_ghost;
|
goto failed_aud_ghost;
|
||||||
|
gst_pad_set_active (dvdbin->audio_pad, TRUE);
|
||||||
|
gst_pad_set_blocked_async (dvdbin->audio_pad, TRUE,
|
||||||
|
(GstPadBlockCallback) dvdbin_pad_blocked_cb, dvdbin);
|
||||||
gst_object_unref (src);
|
gst_object_unref (src);
|
||||||
ghost = src = sink = NULL;
|
src = NULL;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -492,11 +495,13 @@ failed_connect:
|
||||||
GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
|
GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
|
||||||
("Could not connect DVD source and demuxer elements"));
|
("Could not connect DVD source and demuxer elements"));
|
||||||
goto error_out;
|
goto error_out;
|
||||||
|
#if USE_VIDEOQ
|
||||||
failed_vidq_connect:
|
failed_vidq_connect:
|
||||||
GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
|
GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
|
||||||
("Could not connect DVD aspect ratio adjuster and video buffer elements"));
|
("Could not connect DVD aspect ratio adjuster and video buffer elements"));
|
||||||
goto error_out;
|
goto error_out;
|
||||||
failed_vidq_ghost:
|
#endif
|
||||||
|
failed_video_ghost:
|
||||||
GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
|
GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
|
||||||
("Could not ghost SPU output pad"));
|
("Could not ghost SPU output pad"));
|
||||||
goto error_out;
|
goto error_out;
|
||||||
|
@ -513,8 +518,6 @@ failed_aud_ghost:
|
||||||
("Could not ghost audio output pad"));
|
("Could not ghost audio output pad"));
|
||||||
goto error_out;
|
goto error_out;
|
||||||
error_out:
|
error_out:
|
||||||
if (ghost != NULL)
|
|
||||||
gst_object_unref (ghost);
|
|
||||||
if (src != NULL)
|
if (src != NULL)
|
||||||
gst_object_unref (src);
|
gst_object_unref (src);
|
||||||
if (sink != NULL)
|
if (sink != NULL)
|
||||||
|
@ -550,6 +553,27 @@ remove_elements (RsnDvdBin * dvdbin)
|
||||||
} else
|
} else
|
||||||
DVDBIN_UNLOCK (dvdbin);
|
DVDBIN_UNLOCK (dvdbin);
|
||||||
}
|
}
|
||||||
|
if (dvdbin->video_pad) {
|
||||||
|
if (dvdbin->video_added)
|
||||||
|
gst_element_remove_pad (GST_ELEMENT (dvdbin), dvdbin->video_pad);
|
||||||
|
else
|
||||||
|
gst_object_unref (dvdbin->video_pad);
|
||||||
|
}
|
||||||
|
if (dvdbin->audio_pad) {
|
||||||
|
if (dvdbin->audio_added)
|
||||||
|
gst_element_remove_pad (GST_ELEMENT (dvdbin), dvdbin->audio_pad);
|
||||||
|
else
|
||||||
|
gst_object_unref (dvdbin->audio_pad);
|
||||||
|
}
|
||||||
|
if (dvdbin->subpicture_pad) {
|
||||||
|
if (dvdbin->subpicture_added)
|
||||||
|
gst_element_remove_pad (GST_ELEMENT (dvdbin), dvdbin->subpicture_pad);
|
||||||
|
else
|
||||||
|
gst_object_unref (dvdbin->subpicture_pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
dvdbin->video_added = dvdbin->audio_added = dvdbin->subpicture_added = FALSE;
|
||||||
|
dvdbin->video_pad = dvdbin->audio_pad = dvdbin->subpicture_pad = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstPad *
|
static GstPad *
|
||||||
|
@ -656,6 +680,39 @@ failed:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dvdbin_pad_blocked_cb (GstPad * pad, gboolean blocked, RsnDvdBin * dvdbin)
|
||||||
|
{
|
||||||
|
gboolean changed = FALSE;
|
||||||
|
if (!blocked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pad == dvdbin->subpicture_pad) {
|
||||||
|
if (!dvdbin->subpicture_added) {
|
||||||
|
gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->subpicture_pad);
|
||||||
|
dvdbin->subpicture_added = TRUE;
|
||||||
|
changed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_pad_set_blocked_async (pad, FALSE,
|
||||||
|
(GstPadBlockCallback) dvdbin_pad_blocked_cb, dvdbin);
|
||||||
|
} else if (pad == dvdbin->audio_pad) {
|
||||||
|
if (!dvdbin->audio_added) {
|
||||||
|
gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->audio_pad);
|
||||||
|
dvdbin->audio_added = TRUE;
|
||||||
|
changed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_pad_set_blocked_async (pad, FALSE,
|
||||||
|
(GstPadBlockCallback) dvdbin_pad_blocked_cb, dvdbin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed &&
|
||||||
|
dvdbin->video_added && dvdbin->audio_added && dvdbin->subpicture_added) {
|
||||||
|
gst_element_no_more_pads (GST_ELEMENT (dvdbin));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
viddec_pad_added (GstElement * element, GstPad * pad, gboolean last,
|
viddec_pad_added (GstElement * element, GstPad * pad, gboolean last,
|
||||||
RsnDvdBin * dvdbin)
|
RsnDvdBin * dvdbin)
|
||||||
|
@ -668,6 +725,16 @@ viddec_pad_added (GstElement * element, GstPad * pad, gboolean last,
|
||||||
gst_pad_link (pad, q_pad);
|
gst_pad_link (pad, q_pad);
|
||||||
|
|
||||||
gst_object_unref (q_pad);
|
gst_object_unref (q_pad);
|
||||||
|
|
||||||
|
if (!dvdbin->video_added) {
|
||||||
|
gst_pad_set_active (dvdbin->video_pad, TRUE);
|
||||||
|
gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->video_pad);
|
||||||
|
dvdbin->video_added = TRUE;
|
||||||
|
|
||||||
|
if (dvdbin->video_added && dvdbin->audio_added && dvdbin->subpicture_added) {
|
||||||
|
gst_element_no_more_pads (GST_ELEMENT (dvdbin));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DECODEBIN_AUDIO
|
#if DECODEBIN_AUDIO
|
||||||
|
@ -750,7 +817,6 @@ rsn_dvdbin_change_state (GstElement * element, GstStateChange transition)
|
||||||
remove_elements (dvdbin);
|
remove_elements (dvdbin);
|
||||||
return GST_STATE_CHANGE_FAILURE;
|
return GST_STATE_CHANGE_FAILURE;
|
||||||
}
|
}
|
||||||
gst_element_no_more_pads (GST_ELEMENT (dvdbin));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -65,6 +65,11 @@ struct _RsnDvdBin
|
||||||
|
|
||||||
GstPad *video_pad;
|
GstPad *video_pad;
|
||||||
GstPad *audio_pad;
|
GstPad *audio_pad;
|
||||||
|
GstPad *subpicture_pad;
|
||||||
|
|
||||||
|
gboolean video_added;
|
||||||
|
gboolean audio_added;
|
||||||
|
gboolean subpicture_added;
|
||||||
|
|
||||||
GList *mq_req_pads;
|
GList *mq_req_pads;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1556,8 +1556,10 @@ rsn_dvdsrc_nav_clock_cb (GstClock * clock, GstClockTime time, GstClockID id,
|
||||||
g_mutex_lock (src->dvd_lock);
|
g_mutex_lock (src->dvd_lock);
|
||||||
|
|
||||||
/* Destroy the clock id that caused this callback */
|
/* Destroy the clock id that caused this callback */
|
||||||
gst_clock_id_unref (src->nav_clock_id);
|
if (src->nav_clock_id) {
|
||||||
src->nav_clock_id = NULL;
|
gst_clock_id_unref (src->nav_clock_id);
|
||||||
|
src->nav_clock_id = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
while (src->pending_nav_blocks) {
|
while (src->pending_nav_blocks) {
|
||||||
RsnDvdPendingNav *cur = (RsnDvdPendingNav *) src->pending_nav_blocks->data;
|
RsnDvdPendingNav *cur = (RsnDvdPendingNav *) src->pending_nav_blocks->data;
|
||||||
|
|
|
@ -1094,7 +1094,7 @@ gst_dvd_spu_advance_spu (GstDVDSpu * dvdspu, GstClockTime new_ts)
|
||||||
|
|
||||||
/* If we get here, we have an SPU buffer, and it's time to process the
|
/* If we get here, we have an SPU buffer, and it's time to process the
|
||||||
* next cmd */
|
* next cmd */
|
||||||
g_assert (state->buf != NULL && state->next_ts <= new_ts);
|
g_assert (state->buf != NULL);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dvdspu, "Executing cmd blk with TS %" GST_TIME_FORMAT
|
GST_DEBUG_OBJECT (dvdspu, "Executing cmd blk with TS %" GST_TIME_FORMAT
|
||||||
" @ offset %u", GST_TIME_ARGS (state->next_ts), state->cur_cmd_blk);
|
" @ offset %u", GST_TIME_ARGS (state->next_ts), state->cur_cmd_blk);
|
||||||
|
|
Loading…
Reference in a new issue