diff --git a/vrecord b/vrecord
index fa261f70..5ac5d248 100755
--- a/vrecord
+++ b/vrecord
@@ -2003,10 +2003,12 @@ _lookup_choice(){
# audio codec
"24-bit PCM")
+ _add_mediaconch_rule_set "${AUDIO_CODEC_PCM_TEST}"
MIDDLEOPTIONS_PRES+=(-c:a pcm_s24le)
MIDDLEOPTIONS_PRES+=(-rf64 auto)
AUDIO_EXT='wav' ;;
"24-bit FLAC")
+ _add_mediaconch_rule_set "${AUDIO_CODEC_FLAC_TEST}"
MIDDLEOPTIONS_PRES+=(-c:a flac)
MIDDLEOPTIONS_PRES+=(-sample_fmt s32)
MIDDLEOPTIONS_PRES+=(-bits_per_raw_sample:a 24)
@@ -2808,7 +2810,6 @@ CONTAINER_MATROSKA_TEST='
'
CODEC_GENERAL_TEST='
- YUV
CFR
YUV
@@ -2895,6 +2896,52 @@ AUDIO_CODEC_FLAC_TEST='
24
'
+
+CONTAINER_MP4_TEST='
+ mp4
+ MPEG-4
+ Base Media
+'
+
+CODEC_H264_TEST='
+ AVC
+ 4:2:0
+ Progressive
+ CFR
+'
+
+STANDARD_NTSC_ACCESS_DEINTERLACED_TEST='
+
+ 480
+ 720
+ 29.970
+ Progressive
+ BT.601 NTSC
+ BT.601
+
+'
+
+STANDARD_PAL_ACCESS_DEINTERLACED_TEST='
+
+ 576
+ 720
+ 25.000
+ Progressive
+ BT.601 PAL
+ BT.601
+
+'
+
+AUDIO_CODEC_AAC_TEST='
+ AAC
+
+ 1
+ 2
+
+ 48000
+'
+
+
# define mediaconch test fragment -end
_start_mediaconch_policy(){
@@ -2903,6 +2950,7 @@ cat < "${MEDIACONCH_POLICY_TMP}"
This policy tests FFV1 Matroska and Quicktime files made using vrecord and checks their validity
+ This policy tests video files made using vrecord and checks their validity against vrecord's specifications
MC_START
}
@@ -2920,6 +2968,65 @@ _add_mediaconch_rule_set(){
fi
}
+_check_access_mp4_mediaconch() {
+ if [[ "${MP4_CHOICE}" = "true" ]] && [[ -f "${MP4NAME}" ]] && "${MEDIACONCH_INSTALLED}" ; then
+ _report -d "Checking access MP4 conformance against a mediaconch policy..."
+ MP4_POLICY_TMP="$(_maketemp .mediaconch_mp4.xml)"
+ cat < "${MP4_POLICY_TMP}"
+
+
+ This policy tests the access MP4 file made using vrecord and checks its validity against vrecord's access specifications
+MC_MP4_START
+ echo "${CONTAINER_GENERAL_TEST}" >> "${MP4_POLICY_TMP}"
+ echo "${CONTAINER_MP4_TEST}" >> "${MP4_POLICY_TMP}"
+ echo "${CODEC_H264_TEST}" >> "${MP4_POLICY_TMP}"
+ if [[ "${STANDARD}" = "ntsc" ]] ; then
+ echo "${STANDARD_NTSC_ACCESS_DEINTERLACED_TEST}" >> "${MP4_POLICY_TMP}"
+ elif [[ "${STANDARD}" = "pal" ]] ; then
+ echo "${STANDARD_PAL_ACCESS_DEINTERLACED_TEST}" >> "${MP4_POLICY_TMP}"
+ fi
+ echo "${AUDIO_CODEC_AAC_TEST}" >> "${MP4_POLICY_TMP}"
+ cat <> "${MP4_POLICY_TMP}"
+
+
+MC_MP4_END
+ MP4_REPORT_TMP="$(_maketemp _mediaconch_mp4report.xml)"
+ MP4_REPORT="${DIR}/${FULL_OUTPUT_ID}_mp4_mediaconch_report.xml"
+ MP4_POLICY="${DIR}/${FULL_OUTPUT_ID}_mp4_mediaconch_policy.xml"
+ mediaconch -fx -p "${MP4_POLICY_TMP}" "${MP4NAME}" | xmlstarlet fo > "${MP4_REPORT_TMP}"
+ MP4_STATUS="$(xmlstarlet sel -N mc="https://mediaarea.net/mediaconch" -t -v mc:MediaConch/mc:media/mc:policy/@outcome -n "${MP4_REPORT_TMP}")"
+ if [[ "${MP4_STATUS}" = "pass" ]] ; then
+ _report -dt "Access MP4 passed policy check."
+ _writeingestlog "mediaconch_mp4_outcome" "passed"
+ elif [[ "${MP4_STATUS}" = "fail" ]] ; then
+ _report -wt "The access MP4 file did not pass vrecord policy check."
+ _mv_tmp_file "${MP4_REPORT_TMP}" "${MP4_REPORT}"
+ _mv_tmp_file "${MP4_POLICY_TMP}" "${MP4_POLICY}"
+ _writeingestlog "mediaconch_mp4_outcome" "failed ${MP4_POLICY}"
+ _report -wt "See ${MP4_REPORT} for a full MediaConch policy report."
+ _report -wt "Or review this attempt to summarize the issue:"
+ xmlstarlet edit -N "mc=https://mediaarea.net/mediaconch" -d "//*[@outcome='pass']" "${MP4_REPORT}" | xmlstarlet fo
+ else
+ _report -wt "Mediaconch ended in an unexpected way for the access MP4 (status: ${MP4_STATUS})."
+ _report -wt "${MP4_REPORT_TMP}:"
+ cat "${MP4_REPORT_TMP}"
+ _writeingestlog "mediaconch_mp4_outcome" "error ${MP4_STATUS}"
+ fi
+ fi
+}
+
+_check_file_truncation() {
+ TEST_FILE="${1}"
+ TEST_LABEL="${2}"
+ if [[ -f "${TEST_FILE}" ]] ; then
+ IS_TRUNCATED=$(mediainfo --Output=XML "${TEST_FILE}" | xmlstarlet sel -t -v "//*[local-name()='IsTruncated']" -n 2>/dev/null || echo "")
+ if [[ "${IS_TRUNCATED}" = "Yes" ]] ; then
+ cowsay "$(_report -w "WARNING: MediaInfo reports that the ${TEST_LABEL} file (${TEST_FILE}) may be truncated or incomplete.")"
+ fi
+ _writeingestlog "${TEST_LABEL}_truncated" "${IS_TRUNCATED}"
+ fi
+}
+
_add_fadgi_header2vtt(){
VTT_FILE="${1}"
VTT_TYPE="${2}"
@@ -3144,11 +3251,6 @@ if [[ ! "${VIDEO_CODEC_CHOICE}" = "h264" ]] ; then
_add_mediaconch_rule_set "${CODEC_GENERAL_TEST}"
fi
_add_mediaconch_rule_set "${AUDIO_CODEC_GENERAL_TEST}"
-if [[ "${AUDIO_CODEC_CHOICE}" = "24-bit PCM" ]] ; then
- _add_mediaconch_rule_set "${AUDIO_CODEC_PCM_TEST}"
-elif [[ "${AUDIO_CODEC_CHOICE}" = "24-bit FLAC" ]] ; then
- _add_mediaconch_rule_set "${AUDIO_CODEC_FLAC_TEST}"
-fi
# CLI passthrough and audiopassthrough modes
if [[ "${RUNTYPE}" = "passthrough" ]] ; then
@@ -3247,7 +3349,7 @@ if [[ "${DEVICE_INPUT_CHOICE}" = "0" ]] ; then
AUDIOMAP=$(sed "s/0:a:0/1:a:0/g" <<< "$AUDIOMAP")
fi
if [[ "${MP4_CHOICE}" = "true" ]] ; then
- RECORDINGFILTER_MP4+=",bwdif,format=yuv420p"
+ RECORDINGFILTER_MP4+=",bwdif=send_frame,format=yuv420p"
RECORD_COMMAND_MP4+=(-filter_complex "[0:v:0]${RECORDINGFILTER_MP4#,*}[mp4_v_out];${AUDIOMAP_MP4}")
MP4NAME="${DIR}/${FULL_OUTPUT_ID}.mp4"
EXTRAOUTPUTS+=("${MIDDLEOPTIONS_ALL[@]}" -movflags write_colr+faststart "${RECORD_COMMAND_MP4[@]}" -c:v h264 -g 12 -profile:v main -level "${ACCESS_MP4_LEVEL}" -b:v "${ACCESS_MP4_BITRATE}" -c:a aac -map "[mp4_v_out]" "${AUDIO_CHANNEL_MAP[@]:2}" "${MP4NAME}")
@@ -3564,26 +3666,40 @@ if [[ "${DEVICE_INPUT_CHOICE}" = 0 ]] ; then
_writeingestlog "Decklink input buffer overrun" "Yes"
fi
- # policy checks with mediaconch
- if "$MEDIACONCH_INSTALLED" ; then
+ # mediaconch policy check on the preservation output
+ if "${MEDIACONCH_INSTALLED}" ; then
_report -d "Checking file conformance against a mediaconch policy..."
- STATUS=$(mediaconch -fx -p "${MEDIACONCH_POLICY_TMP}" "${VRECORD_OUTPUT}" | xmlstarlet sel -N mc="https://mediaarea.net/mediaconch" -t -v mc:MediaConch/mc:media/mc:policy/@outcome -n)
+ MEDIACONCH_REPORT="${DIR}/${FULL_OUTPUT_ID}_mediaconch_report.xml"
+ MEDIACONCH_REPORT_TMP="$(_maketemp _mediaconch_report.xml)"
+ MEDIACONCH_POLICY="${DIR}/${FULL_OUTPUT_ID}_mediaconch_policy.xml"
+ mediaconch -fx -p "${MEDIACONCH_POLICY_TMP}" "${VRECORD_OUTPUT}" | xmlstarlet fo > "${MEDIACONCH_REPORT_TMP}"
+ STATUS="$(xmlstarlet sel -N mc="https://mediaarea.net/mediaconch" -t -v mc:MediaConch/mc:media/mc:policy/@outcome -n "${MEDIACONCH_REPORT_TMP}")"
if [[ "${STATUS}" = "pass" ]] ; then
_report -dt "File passed policy check for the video."
_writeingestlog "mediaconch_outcome" "passed"
elif [[ "${STATUS}" = "fail" ]] ; then
_report -wt "File did not pass vrecord policy check and may not conform to digital preservation standards."
- mediaconch -fx -p "${MEDIACONCH_POLICY_TMP}" "${VRECORD_OUTPUT}" | xmlstarlet fo > "${DIR}/${FULL_OUTPUT_ID}_mediaconchreport.xml"
- _mv_tmp_file "${MEDIACONCH_POLICY_TMP}" "${DIR}/${FULL_OUTPUT_ID}_mediaconch_policy.xml"
- _writeingestlog "mediaconch_outcome" "failed ${DIR}/${FULL_OUTPUT_ID}_mediaconch_policy.xml"
- _report -wt "See ${DIR}/${FULL_OUTPUT_ID}_mediaconchreport.xml for a full MediaConch policy report."
+ _mv_tmp_file "${MEDIACONCH_REPORT_TMP}" "${MEDIACONCH_REPORT}"
+ _mv_tmp_file "${MEDIACONCH_POLICY_TMP}" "${MEDIACONCH_POLICY}"
+ _writeingestlog "mediaconch_outcome" "failed ${MEDIACONCH_POLICY}"
+ _report -wt "See ${MEDIACONCH_REPORT} for a full MediaConch policy report."
_report -wt "Or review this attempt to summarize the issue:"
- xmlstarlet edit -N "mc=https://mediaarea.net/mediaconch" -d "//*[@outcome='pass']" "${DIR}/${FULL_OUTPUT_ID}_mediaconchreport.xml"
+ xmlstarlet edit -N "mc=https://mediaarea.net/mediaconch" -d "//*[@outcome='pass']" "${MEDIACONCH_REPORT}" | xmlstarlet fo
else
- _report -wt "Mediaconch ended in an unexpected way (${STATUS}). Here is its output."
- mediaconch -p "${MEDIACONCH_POLICY_TMP}" "${VRECORD_OUTPUT}"
+ _report -wt "Mediaconch ended in an unexpected way (status: ${STATUS}). Here is its output."
+ _report -wt "${MEDIACONCH_REPORT}:"
+ cat "${MEDIACONCH_REPORT}"
+ _writeingestlog "mediaconch_outcome" "error ${STATUS}"
fi
fi
+ # mediaconch policy check on the access MP4
+ _check_access_mp4_mediaconch
+
+ # check file truncation
+ _check_file_truncation "${VRECORD_OUTPUT}" "preservation"
+ if [[ "${MP4_CHOICE}" = "true" ]] && [[ -f "${MP4NAME}" ]] ; then
+ _check_file_truncation "${MP4NAME}" "access_mp4"
+ fi
# embed logs in Matroska files
if "$MKVPROPEDIT_INSTALLED" ; then