Precognitive waiting - waiting for something to finish, before it starts
You have an interesting problem to solve. Your solution would be helped a lot with a small extension to the SourceAndFileName class. Consider the following version of it:

private static class SourceAndFileName
{
    private final DetectorMessageSource m_source;
    private final String m_fileName;

    private final ReentrantLock lock = new ReentrantLock();
    private final Condition arrived = lock.condition();
    private URL aviURL = null;

    public SourceAndFileName( DetectorMessageSource source, String fileName )
    {
        m_source = source;
        m_fileName = fileName;
    }

    public void setURL(URL url) {
        lock.lock();
        try {
            if (aviURL == null) {
                aviURL = url;
            }
            arrived.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public URL getURL(long timeout) {
        long now = System.currentTimeMillis();
        final long delayto = now + timeout;
        lock.lock();
        try {
            while (aviURL == null &amp;&amp; now &lt; delayto) {
                arrived.await(delayto - now, TimeUnit.MILLISECONDS);
                now = System.currentTimeMillis();
            }
            return aviURL
        } finally {
            lock.unlock();
        }

    }

    .... the rest is the same.....
}


OK, so, with the above class, you can get (with a timed delay, if you want) the URL, and you can set it too. This encapsulates the logic for the process well... but, the problem is that you need to have one, and only one instance of this for each source/fileName. This is solved with a single ConcurrentMap... (using the same key/value instances).

private ConcurrentMap&lt;SourceAndFileName, SourceAndFileName&gt; m_map = Maps.newConcurrentMap();

private SourceAndFileName getKey(DetectorMessageSource messageSource, String fileName)
{
    // be optimistic, and assume we are the first in....
    SourceAndFileName key = new SourceAndFileName(messageSource, fileName);
    SourceAndFileName current = m_map.putIfAbsent(key,key);
    if (current != null) {
        // we were wrong, and not the first in, so use the key from the previous one.
        return current;
    }
    return key;
}

@Override
public void messageReceived( MessageSource messageSource, UrlAviMessage message )
{
    // be optimistic, and assume we are first in....
    SourceAndFileName key = getKey((DetectorMessageSource)messageSource, message.getFileName());

    // set the location, which will trigger the get to return, if necessary...
    key.setURL(message.getLocation());

}

@Override
public InputStream waitForAvi( DetectorMessageSource messageSource, String aviFileName ) throws InterruptedException
{
    // be optimistic, and assume we are first in....
    SourceAndFileName key = getKey((DetectorMessageSource)messageSource, message.getFileName());

    URL url = key.get( 5000 ); // 5 second delay....

    // TODO download the avi to a temp local folder so we can add connect and read timeouts on the connection

    return url.openStream();
}


A more general code review is also in order...


The m_... type prefixing of variables is not useful in modern IDE's where it is normally color-coded where variables are from....
Java style guidelines put the { opening brace on the same line as the block condition (while/if/etc.).
your hashCode/equals methods on the key class would benefit from early-return statements instead of carrying the result variable.