Close try/catch gap around appsink pull_sample()
Standalone gst-launch testing confirmed appsink-as-playbin-video-sink works fine outside the extension (reaches PLAYING, negotiates caps, runs to completion), narrowing the "no frames received" symptom down to something inside our own new-sample handling in the shell process. _onNewSample()'s try/catch didn't cover the sink.pull_sample() call itself — if that specific call throws when invoked as a GJS signal callback, the exception bypassed our logging entirely, falling back to GJS's generic uncaught-exception path (which, like the openPreferences case, may not mention "benthicbloom" and gets missed by a filtered grep). Now the whole handler is covered, logs when the signal fires for the first time, logs a null pull_sample() or failed buffer.map() explicitly, and the watchdog reports the new-sample fire count so we can tell "signal never fired" from "signal fired but processing failed" on the next test. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019RDqbdjsiisSU7CbQke4g8
This commit is contained in:
+20
-8
@@ -50,6 +50,7 @@ export class LiveWallpaperManager {
|
|||||||
this._upowerSignalId = 0;
|
this._upowerSignalId = 0;
|
||||||
|
|
||||||
this._frameCount = 0;
|
this._frameCount = 0;
|
||||||
|
this._newSampleCallCount = 0;
|
||||||
this._noFrameWatchdogId = 0;
|
this._noFrameWatchdogId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,13 +163,16 @@ export class LiveWallpaperManager {
|
|||||||
this._logger.debug(`playbin.set_state(PLAYING) returned ${stateChangeResult}`);
|
this._logger.debug(`playbin.set_state(PLAYING) returned ${stateChangeResult}`);
|
||||||
|
|
||||||
this._frameCount = 0;
|
this._frameCount = 0;
|
||||||
|
this._newSampleCallCount = 0;
|
||||||
this._noFrameWatchdogId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 4, () => {
|
this._noFrameWatchdogId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 4, () => {
|
||||||
this._noFrameWatchdogId = 0;
|
this._noFrameWatchdogId = 0;
|
||||||
if (this._active && this._frameCount === 0) {
|
if (this._active && this._frameCount === 0) {
|
||||||
this._logger.warn(
|
this._logger.warn(
|
||||||
'Live wallpaper: no frames received 4s after starting playback. ' +
|
`Live wallpaper: no frames received 4s after starting playback ` +
|
||||||
'The pipeline likely stalled during caps negotiation or preroll without ' +
|
`(new-sample signal fired ${this._newSampleCallCount} times). ` +
|
||||||
'raising an error — check for GStreamer WARNING messages logged above.');
|
'If that count is 0, the signal itself never fired (check for a stalled ' +
|
||||||
|
'pipeline above); if it is nonzero, pull_sample()/buffer processing is failing ' +
|
||||||
|
'— check for a "Failed to process live wallpaper frame" error above.');
|
||||||
}
|
}
|
||||||
return GLib.SOURCE_REMOVE;
|
return GLib.SOURCE_REMOVE;
|
||||||
});
|
});
|
||||||
@@ -185,19 +189,27 @@ export class LiveWallpaperManager {
|
|||||||
|
|
||||||
_onNewSample(sink) {
|
_onNewSample(sink) {
|
||||||
const Gst = this._Gst;
|
const Gst = this._Gst;
|
||||||
const sample = sink.pull_sample();
|
this._newSampleCallCount = (this._newSampleCallCount ?? 0) + 1;
|
||||||
if (!sample)
|
if (this._newSampleCallCount === 1)
|
||||||
return Gst.FlowReturn.OK;
|
this._logger.debug('Live wallpaper: new-sample signal fired for the first time');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const sample = sink.pull_sample();
|
||||||
|
if (!sample) {
|
||||||
|
this._logger.debug('Live wallpaper: pull_sample() returned no sample');
|
||||||
|
return Gst.FlowReturn.OK;
|
||||||
|
}
|
||||||
|
|
||||||
const buffer = sample.get_buffer();
|
const buffer = sample.get_buffer();
|
||||||
const structure = sample.get_caps().get_structure(0);
|
const structure = sample.get_caps().get_structure(0);
|
||||||
const [, width] = structure.get_int('width');
|
const [, width] = structure.get_int('width');
|
||||||
const [, height] = structure.get_int('height');
|
const [, height] = structure.get_int('height');
|
||||||
|
|
||||||
const [ok, mapInfo] = buffer.map(Gst.MapFlags.READ);
|
const [ok, mapInfo] = buffer.map(Gst.MapFlags.READ);
|
||||||
if (!ok)
|
if (!ok) {
|
||||||
|
this._logger.debug('Live wallpaper: buffer.map() failed');
|
||||||
return Gst.FlowReturn.OK;
|
return Gst.FlowReturn.OK;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this._updateFrame(mapInfo.data, width, height);
|
this._updateFrame(mapInfo.data, width, height);
|
||||||
@@ -210,7 +222,7 @@ export class LiveWallpaperManager {
|
|||||||
buffer.unmap(mapInfo);
|
buffer.unmap(mapInfo);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this._logger.error(e, 'Failed to process live wallpaper frame');
|
this._logger.error(e, 'Failed to process live wallpaper frame (new-sample handler)');
|
||||||
}
|
}
|
||||||
|
|
||||||
return Gst.FlowReturn.OK;
|
return Gst.FlowReturn.OK;
|
||||||
|
|||||||
Reference in New Issue
Block a user