{"version":3,"sources":["../src/probe/avi.ts"],"names":["loadLibav","prepareLibavInput"],"mappings":"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","file":"avi-32UABODO.cjs","sourcesContent":["import type {\n  AudioCodec,\n  AudioTrackInfo,\n  ContainerKind,\n  MediaContext,\n  VideoCodec,\n  VideoTrackInfo,\n} from \"../types.js\";\nimport type { NormalizedSource } from \"../util/source.js\";\nimport { prepareLibavInput, type LibavInputHandle } from \"../util/libav-http-reader.js\";\nimport { loadLibav } from \"../strategies/fallback/libav-loader.js\";\n\n/**\n * Probe AVI/ASF/FLV (and any other format mediabunny doesn't speak) via\n * libav.js. This module is `import()`-ed only when sniffing identifies one of\n * those containers.\n *\n * Critical: codec identification goes through `libav.avcodec_get_name(id)`\n * which returns the FFmpeg codec name as a string (e.g. \"h264\", \"mpeg4\",\n * \"wmv3\"). The numeric AV_CODEC_ID_* enum is *not* exposed on the libav\n * instance (only AVMEDIA_TYPE_*, AV_PIX_FMT_*, AV_SAMPLE_FMT_* and a handful\n * of others are), so comparing codec_ids against constants does not work.\n */\nexport async function probeWithLibav(\n  source: NormalizedSource,\n  sniffed: ContainerKind,\n): Promise<MediaContext> {\n  // AVI/ASF/FLV demuxers are not in any libav.js npm variant — they live in\n  // the custom \"avbridge\" build produced by `scripts/build-libav.sh`. The loader\n  // emits an actionable error if the build hasn't been run yet. Threading\n  // is OFF by default in `loadLibav` (see the comment there for why).\n  const libav = (await loadLibav(\"avbridge\")) as unknown as LibavInstance;\n\n  const filename = source.name ?? `input.${sniffed === \"unknown\" ? \"bin\" : sniffed}`;\n  // For Blob/File sources we use libav's in-memory readahead file. For URL\n  // sources we attach an HTTP block reader so libav demuxes via Range\n  // requests instead of buffering the whole file.\n  const handle: LibavInputHandle = await prepareLibavInput(libav as unknown as Parameters<typeof prepareLibavInput>[0], filename, source);\n\n  let fmt_ctx: number | undefined;\n  let streams: LibavStream[] = [];\n  try {\n    const result = await libav.ff_init_demuxer_file(filename);\n    fmt_ctx = result[0];\n    streams = result[1];\n  } catch (err) {\n    await handle.detach().catch(() => {});\n    // Errors thrown across the libav.js worker/pthread boundary aren't\n    // always Error instances — they can be plain objects, numbers (errno\n    // codes), or strings. Stringify defensively so the user-facing message\n    // never has `(undefined)` in it.\n    const inner =\n      err instanceof Error\n        ? err.message\n        : typeof err === \"object\" && err !== null\n          ? JSON.stringify(err)\n          : String(err);\n    // eslint-disable-next-line no-console\n    console.error(\"[avbridge] ff_init_demuxer_file raw error:\", err);\n    throw new Error(\n      `libav.js could not demux ${filename}. The current libav variant likely lacks the required demuxer (e.g. AVI). See vendor/libav/README.md for build instructions. (${inner || \"no message — see console for raw error\"})`,\n    );\n  }\n\n  const videoTracks: VideoTrackInfo[] = [];\n  const audioTracks: AudioTrackInfo[] = [];\n\n  for (const stream of streams) {\n    const codecName = (await safe(() => libav.avcodec_get_name(stream.codec_id))) ?? `unknown(${stream.codec_id})`;\n    // codecpar holds width/height/channels/sample_rate/profile/level/extradata\n    // for the actual stream. We have to copy it out of WASM memory.\n    const codecpar = await safe(() => libav.ff_copyout_codecpar(stream.codecpar));\n\n    if (stream.codec_type === libav.AVMEDIA_TYPE_VIDEO) {\n      videoTracks.push({\n        id: stream.index,\n        codec: ffmpegToAvbridgeVideo(codecName),\n        width: codecpar?.width ?? 0,\n        height: codecpar?.height ?? 0,\n        fps: await framerate(libav, stream),\n      });\n    } else if (stream.codec_type === libav.AVMEDIA_TYPE_AUDIO) {\n      audioTracks.push({\n        id: stream.index,\n        codec: ffmpegToAvbridgeAudio(codecName),\n        channels: codecpar?.channels ?? codecpar?.ch_layout_nb_channels ?? 0,\n        sampleRate: codecpar?.sample_rate ?? 0,\n      });\n    }\n  }\n\n  // We need this duration but cannot reliably get it from the streams alone\n  // for AVI; libav.js exposes it via the AVFormatContext duration helper.\n  const duration = await safeDuration(libav, fmt_ctx!);\n\n  // Close the demuxer; the strategy will reopen it later if it ends up being\n  // chosen. Probing should not pin native resources.\n  await libav.avformat_close_input_js(fmt_ctx!).catch(() => {});\n  await handle.detach().catch(() => {});\n\n  return {\n    source: source.original,\n    name: source.name,\n    byteLength: source.byteLength,\n    container: sniffed === \"unknown\" ? \"unknown\" : sniffed,\n    videoTracks,\n    audioTracks,\n    subtitleTracks: [],\n    probedBy: \"libav\",\n    duration,\n  };\n}\n\n/**\n * Read frame rate from the stream's `AVCodecParameters.framerate`.\n *\n * `avg_frame_rate` / `r_frame_rate` live on the AVStream in C but libav.js\n * doesn't expose them as JS properties on the stream record — only via\n * dedicated accessor functions we don't ship. `codecpar.framerate` IS\n * accessible via `AVCodecParameters_framerate_num/_den` and is populated\n * for most containers (for AVI it's parsed from `dwRate`/`dwScale` in the\n * stream header).\n *\n * Returns undefined if unavailable so the caller can fall back to a\n * container-appropriate default (currently 30 fps, which is wrong for\n * 25 fps PAL and 23.976 fps film content — hence the importance of\n * reading this correctly).\n */\nasync function framerate(\n  libav: LibavInstance,\n  stream: LibavStream,\n): Promise<number | undefined> {\n  // The stream record may still carry these (new libav.js versions) —\n  // prefer them when present.\n  if (typeof stream.avg_frame_rate_num === \"number\" && stream.avg_frame_rate_den) {\n    return stream.avg_frame_rate_num / stream.avg_frame_rate_den;\n  }\n  if (stream.avg_frame_rate && typeof stream.avg_frame_rate === \"object\") {\n    if (stream.avg_frame_rate.den === 0) return undefined;\n    return stream.avg_frame_rate.num / stream.avg_frame_rate.den;\n  }\n  try {\n    const num = await libav.AVCodecParameters_framerate_num?.(stream.codecpar);\n    const den = await libav.AVCodecParameters_framerate_den?.(stream.codecpar);\n    if (typeof num === \"number\" && typeof den === \"number\" && den > 0 && num > 0) {\n      return num / den;\n    }\n  } catch {\n    // Fall through.\n  }\n  return undefined;\n}\n\nasync function safeDuration(libav: LibavInstance, fmt_ctx: number): Promise<number | undefined> {\n  try {\n    // `AVFormatContext.duration` is an int64 in microseconds (AV_TIME_BASE).\n    // libav.js exposes it as a split lo/hi pair the same way it does for\n    // packet pts — `AVFormatContext_duration(ctx)` returns the low 32 bits,\n    // `AVFormatContext_durationhi(ctx)` returns the high 32 bits. Reading\n    // only the low half (the previous bug) gave garbage for any file whose\n    // duration > ~35 minutes, and zero for shorter files where the value\n    // happened to live in the high half.\n    const lo = await libav.AVFormatContext_duration?.(fmt_ctx);\n    const hi = await libav.AVFormatContext_durationhi?.(fmt_ctx);\n    if (typeof lo !== \"number\" || typeof hi !== \"number\") return undefined;\n\n    // AV_NOPTS_VALUE = -2^63 → ptshi = -2147483648, pts = 0. Means \"unknown\".\n    if (hi === -2147483648 && lo === 0) return undefined;\n\n    // Reconstruct the 64-bit value. Prefer libav's helper when available\n    // because it correctly handles signed 32-bit two's complement.\n    const us =\n      typeof libav.i64tof64 === \"function\"\n        ? libav.i64tof64(lo, hi)\n        : hi * 0x100000000 + lo + (lo < 0 ? 0x100000000 : 0);\n\n    if (!Number.isFinite(us) || us <= 0) return undefined;\n    return us / 1_000_000;\n  } catch {\n    return undefined;\n  }\n}\n\nasync function safe<T>(fn: () => Promise<T> | T): Promise<T | undefined> {\n  try { return await fn(); } catch { return undefined; }\n}\n\n/** Map FFmpeg codec names to avbridge video codec identifiers. */\nfunction ffmpegToAvbridgeVideo(name: string): VideoCodec {\n  switch (name) {\n    case \"h264\":   return \"h264\";\n    case \"hevc\":   return \"h265\";\n    case \"vp8\":    return \"vp8\";\n    case \"vp9\":    return \"vp9\";\n    case \"av1\":    return \"av1\";\n    case \"mpeg4\":  return \"mpeg4\";   // MPEG-4 Part 2 / DivX / Xvid\n    case \"msmpeg4v1\":\n    case \"msmpeg4v2\":\n    case \"msmpeg4v3\":                 // a.k.a. DIV3\n      return \"mpeg4\";\n    case \"wmv1\":\n    case \"wmv2\":\n    case \"wmv3\":\n      return \"wmv3\";\n    case \"vc1\":    return \"vc1\";\n    case \"mpeg2video\": return \"mpeg2\";\n    case \"mpeg1video\": return \"mpeg1\";\n    case \"theora\": return \"theora\";\n    case \"rv10\":   return \"rv10\";\n    case \"rv20\":   return \"rv20\";\n    case \"rv30\":   return \"rv30\";\n    case \"rv40\":   return \"rv40\";\n    case \"dvvideo\": return \"dv\";       // DV / DVCPRO (camcorder, MiniDV)\n    case \"hq_hqa\": return \"hq_hqa\";    // Canopus HQ / HQA (Grass Valley)\n    default:       return name as VideoCodec;\n  }\n}\n\nfunction ffmpegToAvbridgeAudio(name: string): AudioCodec {\n  switch (name) {\n    case \"aac\":    return \"aac\";\n    case \"mp3\":\n    case \"mp3float\":\n      return \"mp3\";\n    case \"opus\":   return \"opus\";\n    case \"vorbis\": return \"vorbis\";\n    case \"flac\":   return \"flac\";\n    case \"ac3\":    return \"ac3\";\n    case \"eac3\":   return \"eac3\";\n    case \"wmav1\":\n    case \"wmav2\":  return \"wmav2\";\n    case \"wmapro\": return \"wmapro\";\n    case \"alac\":   return \"alac\";\n    case \"cook\":   return \"cook\";\n    case \"ra_144\": return \"ra_144\";\n    case \"ra_288\": return \"ra_288\";\n    case \"sipr\":   return \"sipr\";\n    case \"atrac3\": return \"atrac3\";\n    case \"dca\":\n    case \"dts\":    return \"dts\";\n    case \"truehd\":\n    case \"mlp\":    return \"truehd\";\n    default:       return name as AudioCodec;\n  }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Minimal structural types for the slice of libav.js we touch.\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface LibavStream {\n  index: number;\n  codec_type: number;\n  codec_id: number;\n  codecpar: number;\n  avg_frame_rate?: { num: number; den: number };\n  avg_frame_rate_num?: number;\n  avg_frame_rate_den?: number;\n}\n\ninterface LibavCodecpar {\n  width?: number;\n  height?: number;\n  channels?: number;\n  ch_layout_nb_channels?: number;\n  sample_rate?: number;\n  profile?: number;\n  level?: number;\n}\n\ninterface LibavInstance {\n  mkreadaheadfile(name: string, blob: Blob): Promise<void>;\n  unlinkreadaheadfile(name: string): Promise<void>;\n  ff_init_demuxer_file(name: string): Promise<[number, LibavStream[]]>;\n  ff_copyout_codecpar(codecpar: number): Promise<LibavCodecpar>;\n  avcodec_get_name(codec_id: number): Promise<string>;\n  avformat_close_input_js(ctx: number): Promise<void>;\n  AVFormatContext_duration?(ctx: number): Promise<number>;\n  AVFormatContext_durationhi?(ctx: number): Promise<number>;\n  i64tof64?(lo: number, hi: number): number;\n\n  AVCodecParameters_framerate_num?(codecpar: number): Promise<number>;\n  AVCodecParameters_framerate_den?(codecpar: number): Promise<number>;\n\n  AVMEDIA_TYPE_VIDEO: number;\n  AVMEDIA_TYPE_AUDIO: number;\n}\n"]}