gst-discoverer reports 1x1 dimensions for valid MP4 files

Hello all! I have MP4 files where gst-discoverer-1.0 reports video dimensions as 1x1 pixels, but the actual video content is 3840x1080.

The affected videos:

  • Play normally in media players (macos: quick time player)

  • Process successfully with vtdechw hardware decoder

  • Have valid video data (just corrupt metadata)

  • Show correct dimensions when trimmed from middle sections (I mean I trimmed a part of that video and used gst-discover, then it correctly shows)

    The 1x1 dimensions cause pipeline linking failures because elements expecting proper dimensions can’t link properly.

    My workaround:

    1. Check if reported dimensions are ≤2 pixels
    2. Use safe fallback dimensions (1920x1080 for initial setup, minimal viable 32x18)
    3. Let actual frame processing handle real dimensions from decoded video data

    Questions:

    1. What could cause discoverer to report 1x1 for valid video files?
    2. Is there a way to force discoverer to re-analyze or get dimensions from decoder output?
    3. Is this workaround approach reasonable, or should I handle this differently?

    The issue seems related to specific encoding/metadata corruption rather than video content.

âžś  desktop gst-discoverer-1.0 /Users/enes/Desktop/ex2.mp4
Analyzing file:///Users/enes/Desktop/ex2.mp4
Done discovering file:///Users/enes/Desktop/ex2.mp4

Properties:
Duration: 0:01:01.414000000
Seekable: yes
Live: no
container #0: Quicktime
video #1: H.264 (High Profile)
Stream ID: b5474b41613e038cb75ae4cb596e88c9e11822aea1ab216972138842d5ce5e60/001
Width: 1
Height: 1
Depth: 24
Frame rate: 50/1
Pixel aspect ratio: 1/1
Interlaced: false
Bitrate: 0
Max bitrate: 1006489
audio #2: MPEG-4 AAC
Stream ID: b5474b41613e038cb75ae4cb596e88c9e11822aea1ab216972138842d5ce5e60/002
Language: 
Channels: 2 (front-left, front-right)
Sample rate: 44100
Depth: 32
Bitrate: 194911
Max bitrate: 194911

Note: rough idea about how I get dimensions:

  
  // From pad-added callback when decodebin creates new pads
  let caps = src_pad.current_caps().unwrap();
  let struct_ = caps.structure(0).unwrap();
  let width = struct_.get::<i32>("width").unwrap_or(1920) as u32;
  let height = struct_.get::<i32>("height").unwrap_or(1080) as u32;

Can you create an issue with such a file in gitlab?

thank you! seems you need to see the video to understand this issue, I see. Unfortunately, the video is from a sensitive psychotherapy session, so I cannot share it on the web. The video was recorded with two special cameras for a scientific project. However, the final video was created using the script I wrote below. I will try to reproduce this issue with a “dummy” video and share it on GitLab, but the script I wrote works fine for my own regular videos.

If I can do that, I’ll create a new thread on GitLab and add the link here. Thank you all! :slight_smile:



# Enes Altun, August 14, 2022, MIT LICENCE
# A script to merge two videos side-by-side


OUTPUT_HEIGHT=1080
OUTPUT_FILE_PREFIX="merged_sbs"

function show_usage() {
  echo "Usage: ./merge_videos.sh <video1> <video2> [--mute1 | --mute2 | --mix]"
  echo ""
  echo "Options:"
  echo "  --mute1    Mute the first video and use audio from the second."
  echo "  --mute2    Mute the second video and use audio from the first."
  echo "  --mix      Mix the audio from both videos together."
  echo ""
  echo "Example:"
  echo "  ./merge_videos.sh left_cam.mp4 right_cam.mov --mute2"
}

function has_audio() {
  ffprobe -v error -select_streams a:0 -show_entries stream=codec_type \
  -of default=noprint_wrappers=1:nokey=1 "$1" 2>/dev/null | grep -q audio
}

if ! command -v ffmpeg &> /dev/null; then
  echo "Error: ffmpeg is not installed or not in your system's PATH."
  exit 1
fi

if [ "$#" -ne 3 ]; then
  show_usage
  exit 1
fi

VIDEO1="$1"
VIDEO2="$2"
AUDIO_OPTION="$3"

if [ ! -f "$VIDEO1" ]; then
  echo "Error: Input file not found: '$VIDEO1'"
  exit 1
fi

if [ ! -f "$VIDEO2" ]; then
  echo "Error: Input file not found: '$VIDEO2'"
  exit 1
fi

HAS_AUDIO1=false
HAS_AUDIO2=false
has_audio "$VIDEO1" && HAS_AUDIO1=true
has_audio "$VIDEO2" && HAS_AUDIO2=true

echo "Video1 has audio: $HAS_AUDIO1"
echo "Video2 has audio: $HAS_AUDIO2"

echo "Inputs validated. Preparing to merge videos..."

VIDEO_FILTER="[0:v]scale=-2:${OUTPUT_HEIGHT}[v0];[1:v]scale=-2:${OUTPUT_HEIGHT}[v1];[v0][v1]hstack=inputs=2:shortest=0[v]"

case "$AUDIO_OPTION" in
  --mute1)
    echo "Using audio from the second video ('$VIDEO2')."
    if $HAS_AUDIO2; then
      FILTER_COMPLEX="${VIDEO_FILTER}; anullsrc=channel_layout=stereo:sample_rate=44100[sil1]; [sil1][1:a:0]amix=inputs=2[aout]"
    else
      FILTER_COMPLEX="${VIDEO_FILTER}; anullsrc=channel_layout=stereo:sample_rate=44100[aout]"
    fi
    ;;
  --mute2)
    echo "Using audio from the first video ('$VIDEO1')."
    if $HAS_AUDIO1; then
      FILTER_COMPLEX="${VIDEO_FILTER}; anullsrc=channel_layout=stereo:sample_rate=44100[sil2]; [0:a:0][sil2]amix=inputs=2[aout]"
    else
      FILTER_COMPLEX="${VIDEO_FILTER}; anullsrc=channel_layout=stereo:sample_rate=44100[aout]"
    fi
    ;;
  --mix)
    echo "Mixing audio from both videos."
    if $HAS_AUDIO1 && $HAS_AUDIO2; then
      FILTER_COMPLEX="${VIDEO_FILTER}; [0:a:0][1:a:0]amix=inputs=2[aout]"
    elif $HAS_AUDIO1; then
      FILTER_COMPLEX="${VIDEO_FILTER}; anullsrc=channel_layout=stereo:sample_rate=44100[sil2]; [0:a:0][sil2]amix=inputs=2[aout]"
    elif $HAS_AUDIO2; then
      FILTER_COMPLEX="${VIDEO_FILTER}; anullsrc=channel_layout=stereo:sample_rate=44100[sil1]; [sil1][1:a:0]amix=inputs=2[aout]"
    else
      FILTER_COMPLEX="${VIDEO_FILTER}; anullsrc=channel_layout=stereo:sample_rate=44100[aout]"
    fi
    ;;
  *)
    echo "Error: Invalid audio option '$AUDIO_OPTION'."
    show_usage
    exit 1
    ;;
esac

TIMESTAMP=$(date +%Y%m%d_%H%M%S)
OUTPUT_FILE="${OUTPUT_FILE_PREFIX}_${TIMESTAMP}.mp4"
echo "Output will be saved to: $OUTPUT_FILE"
echo "Processing... This may take a while depending on video length and your computer's speed."

ffmpeg \
  -i "$VIDEO1" \
  -i "$VIDEO2" \
  -filter_complex "$FILTER_COMPLEX" \
  -map "[v]" \
  -map "[aout]" \
  -c:v libx264 \
  -preset veryfast \
  -crf 23 \
  -c:a aac \
  -b:a 192k \
  -pix_fmt yuv420p \
  -shortest \
  -y \
  "$OUTPUT_FILE"

if [ $? -eq 0 ]; then
  echo ""
  echo "Success! Video merged successfully."
  echo "Output file: $OUTPUT_FILE"
else
  echo ""
  echo "Error: FFmpeg failed to process the videos."
  exit 1
fi

Yeah there seems to be something specifically wrong with that video.

You could share the “headers” only, specifically the moov box which you can find either at the beginning (goes until the string mdat then), or at the very end of the file. That wouldn’t contain any sensitive media data.

1 Like

GitLab issue:

1 Like

The problem has been fixed by @slomo baseparse: Try harder to fixate caps based on upstream in default negotiation (!9593) · Merge requests · GStreamer / gstreamer · GitLab

Thank you all!

1 Like