Simple media ingest script
Your code is pretty clear and readable. Congratulations!

Here are some suggestions:


Stop using sleep! Unless this is for a Hollywood hacker movie, it just slows things down. Nobody thinks delays are cool after the first three times you run something.
Take command-line arguments instead of prompting for everything. It's a lot easier to just put stuff into a command line than it is to respond to it at the keyboard. Something like:

ingest -t $HOME/media -b SONY -p "My Project" 


There are plenty of SO answers on how to do this.
Add some more functions! Anything you find yourself doing twice should be a function. Also, anything that you have to "break the flow" in order to do should be a function. Here are some examples:

while [[ -z "$target_directory" ]]
    do
        echo -e "Path of target directory?"
        read target_directory
    done

while [[ -z "$brand" ]]
    do
        echo -e "\nBrand Prefix?"
        read brand
    done


That's twice! Write a function to do this:

target_dir=$(prompt_for_variable target_dir 'Path of target directory?')"
brand="$(prompt_for_variable brand 'Brand Prefix?')"


Now consider this:

while true;
do
    read -p "Additional rsync options? [y/n] " rsync_add
    case $rsync_add in
        [Yy]* )


Right in the middle of "construct_rsync" you stop and loop forever prompting the user for a y/n answer. Write a function for that!

if get_yn 'Additional rsync options?'
then
     read -p "Enter the additional options: " rsync_options
fi

Don't lie to anybody, especially yourself. You have a function called construct_rsync but what does it do? It runs the command. Either change the name, or change the function.
Beware of $?. In your log function you refer to it several times. But $? is updated each time a command is run. So if you're going to make decisions based on the value, you should either capture the value into a separate variable (status=$? ... if $status) or make a single decision right up front (if $? ... else ... fi)