#!/bin/bash

function print_usage {
  echo "============================================================================================="
  echo "        convert_videos.sh [file|directory] [output directory] {bb|bb_storm|ps3} {file prefix}" 
  echo "============================================================================================="
}

function verify_file {
  echo j
}

function process_file {
  ORIG_FILE="$1"
  DEST_DIR="$2"

  if [[ -z ${BLACKBERRY} ]]; then
    DEST_FILE=${DEST_DIR}/${FILE_PREFIX}$( basename "${ORIG_FILE}" | perl -ne 's/\.(?:[a-z,A-Z,0-9]{3,4})$/\.mp4/; print $_' )
  else
    DEST_FILE=${DEST_DIR}/${FILE_PREFIX}$( basename "${ORIG_FILE}" | perl -ne 's/\.(?:[a-z,A-Z,0-9]{3,4})$/_bb\.mp4/; print $_' )
  fi

  if [[ -f "${DEST_FILE}" ]]; then
    echo "    We already processed \"${ORIG_FILE}\" ... skipping"
  else
    VID_INFO_FPS=$( mplayer -identify -nosound -vo null -nocache -really-quiet -frames 1 "${ORIG_FILE}" 2>/dev/null | grep FPS ) 
    VID_INFO_FPS=${VID_INFO_FPS#*=}
    VID_INFO_WIDTH=$( mplayer -identify -nosound -vo null -nocache -really-quiet -frames 1 "${ORIG_FILE}" 2>/dev/null | grep WIDTH ) 
    VID_INFO_WIDTH=${VID_INFO_WIDTH##*=}
    VID_INFO_HEIGHT=$( mplayer -identify -nosound -vo null -nocache -really-quiet -frames 1 "${ORIG_FILE}" 2>/dev/null | grep HEIGHT ) 
    VID_INFO_HEIGHT=${VID_INFO_HEIGHT##*=}
    VID_INFO_ASPECT=$( mplayer -identify -nosound -vo null -nocache -really-quiet -frames 1 "${ORIG_FILE}" 2>/dev/null | grep ASPECT ) 
    VID_INFO_ASPECT=${VID_INFO_ASPECT##*=}

    AUD_INFO_FORMAT=$( mplayer -identify -ao null -vo null -nocache -really-quiet -frames 1 "${ORIG_FILE}" 2>/dev/null | grep AUDIO_FORMAT ) 
    AUD_INFO_FORMAT=${AUD_INFO_FORMAT##*=}
    AUD_INFO_CHANNELS=$( mplayer -identify -ao null -vo null -nocache -really-quiet -frames 1 "${ORIG_FILE}" 2>/dev/null | grep AUDIO_NCH ) 
    AUD_INFO_CHANNELS=${AUD_INFO_CHANNELS##*=}
    AUD_INFO_BITRATE=$( mplayer -identify -ao null -vo null -nocache -really-quiet -frames 1 "${ORIG_FILE}" 2>/dev/null | grep ID_AUDIO_BITRATE ) 
    AUD_INFO_BITRATE=${AUD_INFO_BITRATE##*=}

    if (( ${AUD_INFO_BITRATE} < 163840 )); then
      AUD_INFO_BITRATE=160
    else
      AUD_INFO_BITRATE=$( expr ${AUD_INFO_BITRATE} / 1024 )
    fi

    ###############
    #  We need to make the frame rate an acceptible amoun
    ###############
    case ${VID_INFO_FPS} in
      60.000)
        # HD
        VID_INFO_FPS=59.94
        ;;
      30.000)
        # NTSC
        VID_INFO_FPS=29.97
        ;;
      24.000)
        # PAL
        VID_INFO_FPS=23.97
        ;;
    esac 

    ###############
    #  We need to make the video resolution a multiple of 16 for it to be properly compressed
    ###############
    if (( ${VID_INFO_HEIGHT} % 16 )); then
      VID_BORDER_VERTICAL=$( expr 16 - ${VID_INFO_HEIGHT} % 16 )
      VID_BORDER_VERTICAL=$( expr ${VID_BORDER_VERTICAL} / 2 )

      if (( ${VID_BORDER_VERTICAL} % 2 )); then
        let VID_BORDER_VERTICAL_TOP+=$( expr ${VID_BORDER_VERTICAL} - 1 )
        let VID_BORDER_VERTICAL_BOTTOM+=$( expr ${VID_BORDER_VERTICAL} + 1 )
      else
        VID_BORDER_VERTICAL_TOP=${VID_BORDER_VERTICAL}
        VID_BORDER_VERTICAL_BOTTOM=${VID_BORDER_VERTICAL}
      fi
    else
      VID_BORDER_VERTICAL_TOP=0
      VID_BORDER_VERTICAL_BOTTOM=0
    fi
 
    if (( ${VID_INFO_WIDTH} % 16 )); then
      VID_BORDER_HORIZONTAL=$( 16 - ${VID_INFO_WIDTH} % 16 )
      VID_BORDER_HORIZONTAL=$( ${VID_INFO_WIDTH} / 2 )

      if (( ${VID_BORDER_HORIZONTAL} % 2 )); then
        let VID_BORDER_HORIZONTAL_RIGHT+=$( expr ${VID_BORDER_HORIZONTAL} + 1 )
        let VID_BORDER_HORIZONTAL_LEFT+=$( expr ${VID_BORDER_HORIZONTAL} - 1 )
      else
        VID_BORDER_HORIZONTAL_RIGHT=${VID_BORDER_HORIZONTAL}
        VID_BORDER_HORIZONTAL_LEFT=${VID_BORDER_HORIZONTAL}
      fi
    else
      VID_BORDER_HORIZONTAL_LEFT=0
      VID_BORDER_HORIZONTAL_RIGHT=0
    fi

    if [[ -z ${VID_INFO_ASPECT} ]] || [[ ${VID_INFO_ASPECT} == "0.0000" ]]; then
      VID_INFO_ASPECT="16:9"
    fi

    if [[ -z ${AUD_INFO_CHANNELS} ]]; then
      AUD_INFO_CHANNELS=2
    fi


    ##############
    # If we're not converting for the blackberry, perform a normal conversion 
    ##############
    if [[ -z ${BLACKBERRY} ]]; then
      VID_INFO_RESOLUTION="${VID_INFO_WIDTH}x${VID_INFO_HEIGHT}"

      convert_file_first_pass 

      if [[ ! -z ${FIRST_PASS_BITRATE} ]]; then
        BITRATE=${FIRST_PASS_BITRATE}
      fi
    else
      ############
      # if we have a blackberry, set the resolution appropriately
      ############
      case ${BB_TYPE} in
        STORM)
          VID_INFO_RESOLUTION="480x360"
          ;;
        *)
          VID_INFO_RESOLUTION="240x180"
          ;;
      esac
    fi

    convert_file_second_pass 
  fi
}

function process_directory {
 ORIG_VIDEO_DIR="$1"
 DEST_VIDEO_DIR="$2"

  if [[ -d "${ORIG_VIDEO_DIR}" ]] && [[ -d "${DEST_VIDEO_DIR}" ]]; then
    IFS=$'\n'

    for ORIG_VIDEO_FILE in $( find "${ORIG_VIDEO_DIR}" -depth -maxdepth 1 -type f -readable -iregex '.*\.\(3gp\|3g2\|avi\|divx\|flv\|m4v\|mj2\|mov\|mp1\|mp2\|mp4\|mpe\|mpeg\|mpeg4\|mpg\|mkv\|mv\|ogm\|rm\|rmvb\|rv\|qt\|wmv\)' ); do
      process_file "${ORIG_VIDEO_FILE}" "${DEST_VIDEO_DIR}"
    done
  fi 
}

function convert_file_first_pass {
  echo "----------------------------------------------------"
  echo "   First pass: ${ORIG_FILE}"
  echo "ffmpeg -i \"${ORIG_FILE}\" -an -pass 1 \
    -vcodec libx264 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 \
    -me_method epzs -subq 1 -trellis 0 -refs 1 -bf 3 -b_strategy 1 -level 31 -coder 1 -me_range 16 -g 250 -keyint_min 25 \
    -sc_threshold 40 -i_qfactor 0.71 -bt 200kb -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 1 -qmax 51 -qdiff 4 \
    -padtop ${VID_BORDER_VERTICAL_TOP} -padbottom ${VID_BORDER_VERTICAL_BOTTOM} \
    -padleft ${VID_BORDER_HORIZONTAL_LEFT} -padright ${VID_BORDER_HORIZONTAL_RIGHT} \
    -threads 2 \
    -s ${VID_INFO_RESOLUTION} -aspect ${VID_INFO_ASPECT} -f rawvideo -y /dev/null" 

  ffmpeg -i "${ORIG_FILE}" -an -pass 1 \
    -vcodec libx264 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 \
    -me_method epzs -subq 1 -trellis 0 -refs 1 -bf 3 -b_strategy 1 -level 31 -coder 1 -me_range 16 -g 250 -keyint_min 250 \
    -sc_threshold 40 -i_qfactor 0.71 -bt 200kb -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 1 -qmax 51 -qdiff 4 \
    -padtop ${VID_BORDER_VERTICAL_TOP} -padbottom ${VID_BORDER_VERTICAL_BOTTOM} \
    -padleft ${VID_BORDER_HORIZONTAL_LEFT} -padright ${VID_BORDER_HORIZONTAL_RIGHT} \
    -threads 2 \
    -s ${VID_INFO_RESOLUTION} -aspect ${VID_INFO_ASPECT} -f rawvideo -y /dev/null 2>&1 | tee pass2.out

  BITRATE=$( grep -e "\[libx264.*kb\/s" pass2.out )
  BITRATE=${BITRATE##*:}
  BITRATE=${BITRATE/.*}

  echo "average first pass bitrate: ${BITRATE}"

  if [[ -n ${BITRATE} ]]; then
    if (( ${BITRATE} % 16 )); then
      let BITRATE+=$( expr ${BITRATE} % 16 )
    fi
  else
    if (( ${VID_INFO_WIDTH} > 1024 )); then
       BITRATE=15360
    elif (( ${VID_INFO_WIDTH} > 900 )); then
       BITRATE=10240 
    elif (( ${VID_INFO_WIDTH} > 719 )); then
       BITRATE=8192
    elif (( ${VID_INFO_WIDTH} > 620 )); then
       BITRATE=2560
    else
       BITRATE=512
    fi
  fi

  MAX_BITRATE=$( expr ${BITRATE} + 512 )
}

function convert_file_second_pass {
  echo "----------------------------------------------------"
  echo "   Second pass: ${ORIG_FILE}"

  if [[ -n ${BLACKBERRY} ]]; then
    echo "ffmpeg -i \"${ORIG_FILE}\" -vcodec mpeg4 -vtag XVID -s ${VID_INFO_RESOLUTION} \
      -qscale 10 -ab 48k -ar 22050 -ac 2 -acodec libmp3lame -deinterlace \
      -b 512kb -qmin 1 -qmax 51 \
      -padtop ${VID_BORDER_VERTICAL_TOP} -padbottom ${VID_BORDER_VERTICAL_BOTTOM} \
      -padleft ${VID_BORDER_HORIZONTAL_LEFT} -padright ${VID_BORDER_HORIZONTAL_RIGHT} \
      -aspect ${VID_INFO_ASPECT} \"${DEST_FILE}\""

    ffmpeg -i "${ORIG_FILE}" -vcodec mpeg4 -vtag XVID -s ${VID_INFO_RESOLUTION} \
      -ab 48k -ar 22050 -ac 2 -acodec libmp3lame -deinterlace \
      -b 512kb -qmin 1 -qmax 51 \
      -padtop ${VID_BORDER_VERTICAL_TOP} -padbottom ${VID_BORDER_VERTICAL_BOTTOM} \
      -padleft ${VID_BORDER_HORIZONTAL_LEFT} -padright ${VID_BORDER_HORIZONTAL_RIGHT} \
      -aspect ${VID_INFO_ASPECT} "${DEST_FILE}"
  else
    echo "ffmpeg -i \"${ORIG_FILE}\" -acodec libfaac -ar 44100 -ac ${AUD_INFO_CHANNELS} \
      -async 1 -f mp4 -pass 2 -vcodec libx264 -vtag XVID -flags +loop+ilme -cmp +chroma \
      -partitions +parti4x4+partp8x8+partb8x8 -flags2 +mixed_refs -me_method umh -subq 5 \
      -trellis 1 -refs 5 -bf 3 -b_strategy 1 -level 31 -coder 1 -me_range 16 \
      -g 250 -keyint_min 250 -sc_threshold 40 -i_qfactor 0.71 -bt 200kb \
      -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 3 -qmax 15 -qdiff 4 \
      -s ${VID_INFO_RESOLUTION} -aspect ${VID_INFO_ASPECT} \
      -padtop ${VID_BORDER_VERTICAL_TOP} -padbottom ${VID_BORDER_VERTICAL_BOTTOM} \
      -padleft ${VID_BORDER_HORIZONTAL_LEFT} -padright ${VID_BORDER_HORIZONTAL_RIGHT} \
      -b ${BITRATE}kb -maxrate ${MAX_BITRATE}kb \
      -bufsize ${MAX_BITRATE}kb -ab ${AUD_INFO_BITRATE}kb \
      -threads 2 \
      -r ${VID_INFO_FPS} \"${DEST_FILE}\""

    ffmpeg -i "${ORIG_FILE}" -acodec libfaac -ar 44100 -ac ${AUD_INFO_CHANNELS} \
      -async 1 -f mp4 -pass 2 -vcodec libx264 -vtag XVID -flags +loop+ilme -cmp +chroma \
      -partitions +parti4x4+partp8x8+partb8x8 -flags2 +mixed_refs -me_method umh -subq 5 \
      -trellis 1 -refs 5 -bf 3 -b_strategy 1 -level 31 -coder 1 -me_range 16 \
      -g 250 -keyint_min 250 -sc_threshold 40 -i_qfactor 0.71 -bt 200kb \
      -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 1 -qmax 51 -qdiff 4 \
      -s ${VID_INFO_RESOLUTION} -aspect ${VID_INFO_ASPECT} \
      -padtop ${VID_BORDER_VERTICAL_TOP} -padbottom ${VID_BORDER_VERTICAL_BOTTOM} \
      -padleft ${VID_BORDER_HORIZONTAL_LEFT} -padright ${VID_BORDER_HORIZONTAL_RIGHT} \
      -b ${BITRATE}kb -maxrate ${MAX_BITRATE}kb \
      -bufsize ${MAX_BITRATE}kb -ab ${AUD_INFO_BITRATE}kb \
      -threads 2 \
      -r ${VID_INFO_FPS} "${DEST_FILE}"
  fi
}

if [[ -n "$1" ]] && [[ -n "$2" ]]; then
  if [[ -n "$3" ]]; then
    case "$3" in
      bb)
        BLACKBERRY=1
        BB_TYPE="norm"
        ;;
      bb_storm)
        BLACKBERRY=1
        BB_TYPE="STORM"
        ;;
      ps3)
        ;;
      *)
        ;;
    esac
  fi

  if [[ -n "$4" ]]; then
    FILE_PREFIX="${4}_"
  else
    FILE_PREFIX=""
  fi

  if [[ -f "$1" ]]; then
    process_file "$1" "$2"
  elif [[ -d "$1" ]]; then
    process_directory "$1" "$2"
  fi
else
  print_usage
  exit
fi

