get_actual_width() {
    file=$1
#    resolution=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 "$file")
    width=$(GST_PLUGIN_FEATURE_RANK="avdec_h265:300,avdec_h264:300,avdec_mpeg2video:300" gst-discoverer-1.0 "$file" | grep "Width" | awk '{print $2}')
    echo "$width"
}
get_actual_height() {
    file=$1
#    resolution=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 "$file")
    height=$(GST_PLUGIN_FEATURE_RANK="avdec_h265:300,avdec_h264:300,avdec_mpeg2video:300" gst-discoverer-1.0 "$file" | grep "Height" | awk '{print $2}')

    echo "$height"
}

get_actual_framerate() {
    file=$1
#    framerate=$(ffprobe -v error -select_streams v:0 -show_entries stream=avg_frame_rate -of default=noprint_wrappers=1:nokey=1 "$file")
    framerate=$(GST_PLUGIN_FEATURE_RANK="avdec_h265:300,avdec_h264:300,avdec_mpeg2video:300" gst-discoverer-1.0 "$file" | grep "Frame rate" | awk '{print $3}')
    echo "$framerate"
}

get_actual_duration() {
    file=$1
#    duration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$file")
    duration=$(GST_PLUGIN_FEATURE_RANK="avdec_h265:300,avdec_h264:300,avdec_mpeg2video:300" gst-discoverer-1.0 "$file" | grep "Duration" | awk '{print $2}')
    echo "$duration"
}

get_actual_codec() {
    file=$1
#    codec=$(ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "$file")
    codec=$(GST_PLUGIN_FEATURE_RANK="avdec_h265:300,avdec_h264:300,avdec_mpeg2video:300" gst-discoverer-1.0 "$file" | grep "video #" | awk '{print $3}')
    echo "$codec"
}

get_system_time_ms(){
    milliseconds=$(date +%s%3N)
    echo "$milliseconds"
}

convert_to_seconds() {
    local time=$1

    # convert HH:MM:SS.XXXXXXXX
    total_seconds=$(echo $time | awk -F '[:.]' '{print ($1 * 3600) + ($2 * 60) + $3}')

    echo "$total_seconds"
}

check_transcoding_result(){
    src_file_name=$1
    dest_file_name=$2
    timeCost_ms=$3
    timeCost_s=$((timeCost_ms / 1000))
    expect_width=$4
    expect_height=$5
    expect_fps=$6
    expect_codec=$7

    # check dest binary with dst_golden, the dest file name are the same
    MEDIA_DST_GOLDEN_PATH="$(dirname "$dest_file_name")/../dst_golden"
    MEDIA_DST_FILE="$(basename "$dest_file_name")"
    echo "MEDIA_DST_GOLDEN_PATH: $MEDIA_DST_GOLDEN_PATH"
    echo "MEDIA_DST_FILE: $MEDIA_DST_FILE"
    bin_cmp=$(cmp "$dest_file_name" "$MEDIA_DST_GOLDEN_PATH/$MEDIA_DST_FILE")
    if cmp -s "$dest_file_name" "$MEDIA_DST_GOLDEN_PATH/$MEDIA_DST_FILE"; then
        echo "dest file binary compare ok"
    else
        echo "dest file binary compare fail"
        return 1
    fi

    # check dest width
    dest_width=$(get_actual_width "$dest_file_name")
    echo "dest_width: $dest_width"
    echo "expect_width: $expect_width"

    if [[ $dest_width == *"$expect_width"* ]]; then
        echo "check width ok"
    else
        echo "check width fail"
        return 1
    fi

    # check dest height
    dest_height=$(get_actual_height "$dest_file_name")
    echo "dest_height: $dest_height"
    echo "expect_height: $expect_height"

    if [[ $dest_height == *"$expect_height"* ]]; then
        echo "check height ok"
    else
        echo "check height fail"
        return 1
    fi

    # check dest framerate
    dest_fps=$(get_actual_framerate "$dest_file_name")
    echo "dest_fps: $dest_fps"
    echo "expect_fps: $expect_fps"

    if [[ $dest_fps == *"$expect_fps"* ]]; then
        echo "check fps ok"
    else
        echo "check fps fail"
        return 1
    fi

    # check dest codec
    dest_codec=$(get_actual_codec "$dest_file_name")
    echo "dest_codec: $dest_codec"
    echo "expect_codec: $expect_codec"

    if [[ $dest_codec == *"$expect_codec"* ]]; then
        echo "check codec ok"
    else
        echo "check codec fail"
        return 1
    fi

    # check dest duration
    src_duration_s=$(convert_to_seconds $(get_actual_duration "$src_file_name"))
    dest_duration_s=$(convert_to_seconds $(get_actual_duration "$dest_file_name"))

    echo "src_duration_s: $src_duration_s"
    echo "dest_duration_s: $dest_duration_s"

    if [ -z "$src_duration_s" ] || [ "$src_duration_s" -eq 0 ]; then
        echo "check duration fail, src_duration_s is 0 or empty"
        return 1
    else
        echo "check src_duration_s ok"
    fi

    if [ -z "$dest_duration_s" ] || [ "$dest_duration_s" -eq 0 ]; then
        echo "check duration fail, dest_duration_s is 0 or empty"
        return 1
    else
        echo "check dest_duration_s ok"
    fi

    # compare src file and dest file duration, the difference should be less than 5%
    difference=$(($dest_duration_s - $src_duration_s))
    echo "dest_src_difference: $difference"

    percentage=$((difference * 100 / src_duration_s))
    echo "Percentage: $percentage%"

    if (( percentage <= -5 && percentage >= 5 )); then
        echo "check duration fail, dest file duration and source file duration is not similars"
        return 1
    else
        echo "check duration ok, dest file duration and source file duration is similar"
    fi

    # in order to support realtime trancoding, the transcoding cost time should less than the source file duration
    echo "src_duration_s: $src_duration_s"
    echo "timeCost_s: $timeCost_s"

    if [ "$src_duration_s" -lt "$timeCost_s" ]; then
        echo "check timeCost fail, transcoding time is longer than source file duration time"
        return 1
    else
        echo "check timeCost ok, transcoding time is smaller than source file duration time"
    fi

    # test pass, delete the output files
    #rm -rf $dest_file_name

    return 0
}

export GST_DEFAULT_V4L2_BUF_MODE_BACKUP=
export V4L2_SET_AMLOGIC_DW_MODE_BACKUP=
export V4L2_SET_AMLOGIC_MARGIN_NUM_BACKUP=
# backup the global environment variable
transcoding_begin(){
    GST_DEFAULT_V4L2_BUF_MODE_BACKUP=$GST_DEFAULT_V4L2_BUF_MODE
    export GST_DEFAULT_V4L2_BUF_MODE=DMA_BUF_IMPORT
    V4L2_SET_AMLOGIC_DW_MODE_BACKUP_BACKUP=$V4L2_SET_AMLOGIC_DW_MODE
    export V4L2_SET_AMLOGIC_DW_MODE=16
    V4L2_SET_AMLOGIC_MARGIN_NUM_BACKUP=$V4L2_SET_AMLOGIC_MARGIN_NUM
    export V4L2_SET_AMLOGIC_MARGIN_NUM=1
}

# restore the global environment variable
transcoding_end(){
    export GST_DEFAULT_V4L2_BUF_MODE=$GST_DEFAULT_V4L2_BUF_MODE_BACKUP
    export V4L2_SET_AMLOGIC_DW_MODE=$V4L2_SET_AMLOGIC_DW_MODE_BACKUP
    export V4L2_SET_AMLOGIC_MARGIN_NUM=$V4L2_SET_AMLOGIC_MARGIN_NUM_BACKUP
}