Skip to content
Mattias Wadman edited this page Oct 20, 2023 · 5 revisions
# Usage:
# Put this code in avi.jq
# -L . tells fq to look for include file in the correct diretory
# 'include "avi"; ..." include avi.jq
#
# $ fq -o decode_samples=false -o decode_extended_chunks=false -L . 'include "avi"; [avi_non_keyframes] | length' file.avi
# 123
# $ fq -o decode_samples=false -o decode_extended_chunks=false -L . 'include "avi"; avi_non_keyframes.frame_nr' file.avi
# 1
# 123

# find streams using predicate f on the stream header chunks (strh)
# outputs {stream_nr: <stream index number>, strh: <strh chunk>}
def avi_streams_by(f):
  ( [ .chunks[0]
    | grep_by(.id == "strh")
    ]
  | to_entries[] as {$key, $value}
  | $value
  | select(f)
  | { stream_nr: $key
    , strh: $value
    }
  );
# outputs all streams
def avi_streams: avi_streams_by(true);

# outputs each sample index for avi_streams_by(f)
# also takes care of choosing ix (> 2gb etc) index or idx1
# filter using predicate ix_f for ix index
# filter using predicate idx1_f for idx1 index
# outputs {frame_nr: <frame number>, sample_index: <sample index entry>}
def avi_streams_indexes_by(f; ix_f; idx1_f):
  ( avi_streams_by(f) as {$stream_nr, $strh}
  | if (.streams[$stream_nr] | has("indexes")) then
      ( [.streams[$stream_nr].indexes[].index[]]
      | to_entries[] as {$key, $value}
      | $value
      | select(ix_f)
      | {frame_nr: $key, sample_index: $value}
      )
    else
      ( first(.chunks[] | select(.id == "idx1"))
      | .indexes
      | map(select(.stream_nr == $stream_nr))
      | to_entries[] as {$key, $value}
      | $value
      | select(idx1_f)
      | {frame_nr: $key, sample_index: $value}
      )
    end
  );

# output non-keyframe for video stream
def avi_non_keyframes:
  avi_streams_indexes_by(
    .type == "vids"; # stream predicate
    .key_frame == false; # ix predicate
    .flags.key_frame == false # idx1 predicate
  );
Clone this wiki locally