Index: wp-includes/class-oembed.php
===================================================================
--- wp-includes/class-oembed.php	(revision 12151)
+++ wp-includes/class-oembed.php	(working copy)
@@ -47,8 +47,11 @@
 			'http://revision3.com/*'                => array( 'http://revision3.com/api/oembed/',         false ),
 			'http://i*.photobucket.com/albums/*'    => array( 'http://photobucket.com/oembed',            false ),
 			'http://gi*.photobucket.com/groups/*'   => array( 'http://photobucket.com/oembed',            false ),
-			'#http://(www\.)?scribd.com/.*#i'       => array( 'http://www.scribd.com/services/oembed',    true)
+			'#http://(www\.)?scribd.com/.*#i'       => array( 'http://www.scribd.com/services/oembed',    true ),
 		) );
+
+		// Fix Scribd embeds. They contain new lines in the middle of the HTML which breaks wpautop().
+		add_filter( 'oembed_dataparse', array(&$this, 'strip_scribd_newlines'), 10, 3 );
 	}
 
 	/**
@@ -87,7 +90,7 @@
 		if ( !$provider || false === $data = $this->fetch( $provider, $url, $args ) )
 			return false;
 
-		return apply_filters( 'oembed_output', $this->data2html( $data, $url ), $url, $args );
+		return apply_filters( 'oembed_result', $this->data2html( $data, $url ), $url, $args );
 	}
 
 	/**
@@ -206,18 +209,40 @@
 					return false;
 
 				$title = ( !empty($data->title) ) ? $data->title : '';
-				return '<img src="' . esc_attr( clean_url( $data->url ) ) . '" alt="' . esc_attr($title) . '" width="' . esc_attr($data->width) . '" height="' . esc_attr($data->height) . '" />';
+				$return = '<img src="' . esc_attr( clean_url( $data->url ) ) . '" alt="' . esc_attr($title) . '" width="' . esc_attr($data->width) . '" height="' . esc_attr($data->height) . '" />';
+				break;
 
 			case 'video':
 			case 'rich':
-				return ( !empty($data->html) ) ? $data->html : false;
+				$return = ( !empty($data->html) ) ? $data->html : false;
+				break;
 
 			case 'link':
-				return ( !empty($data->title) ) ? '<a href="' . clean_url($url) . '">' . esc_html($data->title) . '</a>' : false;
+				$return = ( !empty($data->title) ) ? '<a href="' . clean_url($url) . '">' . esc_html($data->title) . '</a>' : false;
+				break;
+
+			default;
+				$return = false;
 		}
 
-		return false;
+		// You can use this filter to add support for custom data types or to filter the result
+		return apply_filters( 'oembed_dataparse', $return, $data, $url );
 	}
+
+	/**
+	 * Strip new lines from the HTML if it's a Scribd embed.
+	 *
+	 * @param string $html Existing HTML.
+	 * @param object $data Data object from WP_oEmbed::data2html()
+	 * @param string $url The original URL passed to oEmbed.
+	 * @return string Possibly modified $html
+	 */
+	function strip_scribd_newlines( $html, $data, $url ) {
+		if ( preg_match( '#http://(www\.)?scribd.com/.*#i', $url ) )
+			$html = str_replace( array( "\r\n", "\n" ), '', $html );
+
+		return $html;
+	}
 }
 
 /**
Index: wp-includes/media.php
===================================================================
--- wp-includes/media.php	(revision 12151)
+++ wp-includes/media.php	(working copy)
@@ -927,6 +927,9 @@
 		if ( get_option('embed_autourls') )
 			add_filter( 'the_content', array(&$this, 'autoembed'), 8 );
 
+		// After a post is saved, invalidate the oEmbed cache
+		add_action( 'save_post', array(&$this, 'delete_oembed_caches') );
+
 		// After a post is saved, cache oEmbed items via AJAX
 		add_action( 'edit_form_advanced', array(&$this, 'maybe_run_ajax_cache') );
 	}
@@ -1048,7 +1051,7 @@
 			foreach ( $handlers as $id => $handler ) {
 				if ( preg_match( $handler['regex'], $url, $matches ) && is_callable( $handler['callback'] ) ) {
 					if ( false !== $return = call_user_func( $handler['callback'], $matches, $attr, $url, $rawattr ) )
-						return $return;
+						return apply_filters( 'embed_handler_html', $return, $url, $attr );
 				}
 			}
 		}
@@ -1070,7 +1073,7 @@
 					return $this->maybe_make_link( $url );
 
 				if ( !empty($cache) )
-					return $cache;
+					return apply_filters( 'embed_oembed_html', $cache, $url, $attr );
 			}
 
 			// Use oEmbed to get the HTML
@@ -1086,7 +1089,7 @@
 
 			// If there was a result, return it
 			if ( $html )
-				return $html;
+				return apply_filters( 'embed_oembed_html', $html, $url, $attr );
 		}
 
 		// Still unknown
@@ -1094,6 +1097,19 @@
 	}
 
 	/**
+	 * Delete all oEmbed caches.
+	 *
+	 * @param int $post_ID Post ID to delete the caches for.
+	 */
+	function delete_oembed_caches( $post_ID ) {
+		$post_metas = get_post_custom_keys( $post_ID );
+		foreach( $post_metas as $post_meta_key ) {
+			if ( '_oembed_' == substr( $post_meta_key, 0, 8 ) )
+				delete_post_meta( $post_ID, $post_meta_key );
+		}
+	}
+
+	/**
 	 * Triggers a caching of all oEmbed results.
 	 *
 	 * @param int $post_ID Post ID to do the caching for.
@@ -1101,17 +1117,9 @@
 	function cache_oembed( $post_ID ) {
 		$post = get_post( $post_ID );
 
-		// post_type check is incase of "save_post" usage
 		if ( empty($post->ID) || !in_array( $post->post_type, apply_filters( 'embed_cache_oembed_types', array( 'post', 'page' ) ) ) )
 			return;
 
-		// Dump existing caches
-		$post_metas = get_post_custom_keys( $post->ID );
-		foreach( $post_metas as $post_meta_key ) {
-			if ( '_oembed_' == substr( $post_meta_key, 0, 8 ) )
-				delete_post_meta( $post->ID, $post_meta_key );
-		}
-
 		// Trigger a caching
 		if ( !empty($post->post_content) ) {
 			$this->post_ID = $post->ID;
@@ -1161,7 +1169,8 @@
 	 * @return string Linked URL or the original URL.
 	 */
 	function maybe_make_link( $url ) {
-		return ( $this->linkifunknown ) ? '<a href="' . esc_attr($url) . '">' . esc_html($url) . '</a>' : $url;
+		$output = ( $this->linkifunknown ) ? '<a href="' . esc_attr($url) . '">' . esc_html($url) . '</a>' : $url;
+		return apply_filters( 'embed_maybe_make_link', $output, $url );
 	}
 }
 $wp_embed = new WP_Embed();

