A partial solution I’ve found so far is to escape the brackets in the initial call, then replace the escaped characters in the do_foo_shortcode
function.
function do_foo_shortcode($atts, $content = null) {
extract(shortcode_atts(array(
'bar' => '',
), $atts, 'foo'));
$bar = str_replace("[", "[", $bar);
$bar = str_replace("]", "]", $bar);
$bar = do_shortcode($bar);
$content = do_shortcode($content);
return "$bar - $content";
}
And calling it as
[foo bar="[video src=video-source.mp4]"]Hello world![/foo]
Of course, this is an incomplete solution since it doesn’t allow more than 1-level nesting, and quote marks cannot be used in the inner shortcode. Not to mention how complicate is to write it.