Answers.Body: <p>First, a nitpick: you don't want to compute hashes on the <em>encoded</em> frame data before or while writing. You're testing the fidelity of the  lossless encoding so you need to compare the <em>decoded</em> frame of the x264 encode with the corresponding PNG.</p>
  
  <p>So, first here's how to do what you specifically asked for.</p>
  
  <p>Use the tee pseudo-muxer</p>
  
  <pre><code>ffmpeg -framerate 30 -start_number 0 -i "%IMAGES_DIRECTORY%\%%03d.png" ^
  -filter_complex "[0]{some filter here}[otherOut]" ^
  -map 0 -c:v libx264rgb -qp 0 -pix_fmt rgb24 -f tee "%IMAGES_DIRECTORY%\lossless.avi|[f=avi]pipe:" ^
  -map 0 -f framehash -hash SHA512 "%IMAGES_DIRECTORY%\original.hashes" ^
  -map [otherOut] {some other encoding} someOtherFile.idc | ffmpeg -f avi -i - -f framehash -hash SHA512 %IMAGES_DIRECTORY%\decoded.hashes" 
  </code></pre>
  
  <hr>
  
  <p>If your end goal is to check the fidelity of the lossless encoding, use</p>
  
  <pre><code>ffmpeg -framerate 30 -start_number 0 -i "%IMAGES_DIRECTORY%\%%03d.png" ^
  -filter_complex "[0]{some filter here}[otherOut]" ^
  -map 0 -c:v libx264rgb -qp 0 -pix_fmt rgb24 "%IMAGES_DIRECTORY%\lossless.avi" ^
  -map [otherOut] {some other encoding} someOtherFile.idc
  </code></pre>
  
  <p>and then</p>
  
  <pre><code>ffmpeg -framerate 30 -start_number 0 -i "%IMAGES_DIRECTORY%\%%03d.png" -i lossless.avi ^
  -filter_complex "ssim" -f null -
  </code></pre>
  
  <p>If the result is lossless, the readout will say</p>
  
  <pre><code>SSIM R:1.000000 (inf) G:1.000000 (inf) B:1.000000 (inf) All:1.000000 (inf)
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-09-09T19:37:00.460Z
Answers.Text: This answer made so many different things click for me (`hash` doesn't use raw input, `-map 0` instead of `split`, and that's what a tee is for).  Thanks!  But it doesn't avoid the problem of reading lossless.avi off of the disk to decode/compare it.  In fact, you are also reading the original images off of the disk twice to compare them to the decoded image.
Answers.UserDisplayName: Mutant Platypus
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-09-09T20:01:32.187Z
Answers.Text: Is there no way to take encoded packets and fork them to a muxer and a decoder in the same FFMPEG instance?
Answers.UserDisplayName: Mutant Platypus
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-09-09T20:16:34.583Z
Answers.Text: No. Encoding occurs after decoding (and filtering), so that provision isn't there. Looks like you are concerned about disk I/O. What you could do is pipe lossless avi to another ffmpeg instance which computes hashes.
Answers.UserDisplayName: Gyan
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-09-10T06:42:43.393Z
Answers.Text: I've edited my first command, so that the AVI output is simultaneously piped to another ffmpeg instance which then computes hashes on the *decoded* frames.
Answers.UserDisplayName: Gyan
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-09-12T14:40:43.713Z
Answers.Text: And here I was looking up how to split outputs on the Windows command line.  (To send the `lossless.avi` to a file and a pipe.  Ugh.)  This much better, thanks!  The only issue was the output filename in the `tee` needed to be surrounded in single quotes.  Also, I'm not sure that I like SSIM, as it is much more computationally complex than a hash and the output is subject to rounding errors.  I'll do a quick performance comparison, but the ideal solution is to just do a bit-for-bit comparison as both streams are flowing through memory... but a hash is close enough.
Answers.UserDisplayName: Mutant Platypus
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-09-09T17:52:37.677Z
Answers.LastActivityDate: 2016-09-10T06:41:33.990Z
Answers.LastEditDate: 2016-09-10T06:41:33.990Z
Answers.UserDisplayName: Gyan
Body: <p>I am experimenting with losslessly compressing some raw video.  How can I perform a frame hash on the encoded output <em>before or while</em> writing it to the file system?  I want to make an <code>original.hashes</code> and a <code>compressed.hashes</code>.  (I will compare them with another tool later.)</p>
  
  <pre><code>ffmpeg -r 30 -start_number 0 -i "%IMAGES_DIRECTORY%\%%03d.png" ^
  -filter_complex "split=3 [copyHash] [copyLossless] [otherIn]; [otherIn] {some filter here} [otherOut]" ^
  -map [copyLossless] -c:v libx264rgb -qp 0 -pix_fmt rgb24 "%IMAGES_DIRECTORY%\lossless.avi" ^
  -map [copyHash] -f framehash -hash SHA512 "%IMAGES_DIRECTORY%\original.hashes" ^
  -map [otherOut] {some other encoding} someOtherFile.idc
  
  ffmpeg -start_number 0 -i "%IMAGES_DIRECTORY%\lossless.avi" -pix_fmt rgb24 -f framehash -hash SHA512  "%IMAGES_DIRECTORY%\decoded.hashes"
  
  comp original.hashes decoded.hashes
  </code></pre>
  
  <p>So above, I would like to avoid the second call to ffmpeg.  Like if I could split the <code>lossless.avi</code> output of the first call to two new streams:  One to the file system and one to a demuxer feeding the hash muxer.</p>
  
Tags: <ffmpeg>
Title: FFMPEG Calculate Hash After Encoding Before Writing
UserDisplayName: Mutant Platypus
ThreadText: # FFMPEG Calculate Hash After Encoding Before Writing
  
  (Asked by: username_0 on 2016-09-09)
  
  I am experimenting with losslessly compressing some raw video. How can I perform a frame hash on the encoded output *before or while* writing it to the file system? I want to make an `original.hashes` and a `compressed.hashes`. (I will compare them with another tool later.)
  
  ```
  ffmpeg -r 30 -start_number 0 -i "%IMAGES_DIRECTORY%\%%03d.png" ^
  -filter_complex "split=3 [copyHash] [copyLossless] [otherIn]; [otherIn] {some filter here} [otherOut]" ^
  -map [copyLossless] -c:v libx264rgb -qp 0 -pix_fmt rgb24 "%IMAGES_DIRECTORY%\lossless.avi" ^
  -map [copyHash] -f framehash -hash SHA512 "%IMAGES_DIRECTORY%\original.hashes" ^
  -map [otherOut] {some other encoding} someOtherFile.idc
  
  ffmpeg -start_number 0 -i "%IMAGES_DIRECTORY%\lossless.avi" -pix_fmt rgb24 -f framehash -hash SHA512  "%IMAGES_DIRECTORY%\decoded.hashes"
  
  comp original.hashes decoded.hashes
  
  ```
  
  So above, I would like to avoid the second call to ffmpeg. Like if I could split the `lossless.avi` output of the first call to two new streams: One to the file system and one to a demuxer feeding the hash muxer.
  
  **Tags:** ffmpeg
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2016-09-09. Score: 0 | Accepted answer
  
  First, a nitpick: you don't want to compute hashes on the *encoded* frame data before or while writing. You're testing the fidelity of the lossless encoding so you need to compare the *decoded* frame of the x264 encode with the corresponding PNG.
  
  So, first here's how to do what you specifically asked for.
  
  Use the tee pseudo-muxer
  
  ```
  ffmpeg -framerate 30 -start_number 0 -i "%IMAGES_DIRECTORY%\%%03d.png" ^
  -filter_complex "[0]{some filter here}[otherOut]" ^
  -map 0 -c:v libx264rgb -qp 0 -pix_fmt rgb24 -f tee "%IMAGES_DIRECTORY%\lossless.avi|[f=avi]pipe:" ^
  -map 0 -f framehash -hash SHA512 "%IMAGES_DIRECTORY%\original.hashes" ^
  -map [otherOut] {some other encoding} someOtherFile.idc | ffmpeg -f avi -i - -f framehash -hash SHA512 %IMAGES_DIRECTORY%\decoded.hashes" 
  
  ```
  
  ---
  
  If your end goal is to check the fidelity of the lossless encoding, use
  
  ```
  ffmpeg -framerate 30 -start_number 0 -i "%IMAGES_DIRECTORY%\%%03d.png" ^
  -filter_complex "[0]{some filter here}[otherOut]" ^
  -map 0 -c:v libx264rgb -qp 0 -pix_fmt rgb24 "%IMAGES_DIRECTORY%\lossless.avi" ^
  -map [otherOut] {some other encoding} someOtherFile.idc
  
  ```
  
  and then
  
  ```
  ffmpeg -framerate 30 -start_number 0 -i "%IMAGES_DIRECTORY%\%%03d.png" -i lossless.avi ^
  -filter_complex "ssim" -f null -
  
  ```
  
  If the result is lossless, the readout will say
  
  ```
  SSIM R:1.000000 (inf) G:1.000000 (inf) B:1.000000 (inf) All:1.000000 (inf)
  
  ```
  
  > **Comments:**
  > **username_0**: This answer made so many different things click for me (`hash` doesn't use raw input, `-map 0` instead of `split`, and that's what a tee is for).  Thanks!  But it doesn't avoid the problem of reading lossless.avi off of the disk to decode/compare it.  In fact, you are also reading the original images off of the disk twice to compare them to the decoded image.  
  > **username_0**: Is there no way to take encoded packets and fork them to a muxer and a decoder in the same FFMPEG instance?  
  > **username_1**: No. Encoding occurs after decoding (and filtering), so that provision isn't there. Looks like you are concerned about disk I/O. What you could do is pipe lossless avi to another ffmpeg instance which computes hashes.  
  > **username_1**: I've edited my first command, so that the AVI output is simultaneously piped to another ffmpeg instance which then computes hashes on the *decoded* frames.  
  > **username_0**: And here I was looking up how to split outputs on the Windows command line.  (To send the `lossless.avi` to a file and a pipe.  Ugh.)  This much better, thanks!  The only issue was the output filename in the `tee` needed to be surrounded in single quotes.  Also, I'm not sure that I like SSIM, as it is much more computationally complex than a hash and the output is subject to rounding errors.  I'll do a quick performance comparison, but the ideal solution is to just do a bit-for-bit comparison as both streams are flowing through memory... but a hash is close enough.  
  
  ---
  
  