{"version":3,"sources":["../src/convert/transcode-libav.ts","../src/convert/transcode.ts"],"names":["AvbridgeError","ERR_TRANSCODE_UNSUPPORTED_COMBO","createOutputFormat","mimeForFormat","generateFilename","throwIfAborted","ERR_TRANSCODE_ABORTED","throwIfDrainError","ERR_TRANSCODE_DECODE","ERR_CODEC_NOT_SUPPORTED","probe","ERR_CONTAINER_NOT_SUPPORTED","buildMediabunnySourceFromInput","avbridgeVideoToMediabunny","qualityToMediabunny","avbridgeAudioToMediabunny"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Legacy-container transcode pipeline.\n *\n * One-pass: libav demux → WebCodecs VideoDecoder (or libav software video\n * decode for rv40/etc.) + libav software audio decode → VideoSample /\n * AudioSample → mediabunny Output → MP4 / WebM / MKV Blob.\n *\n * Reached from src/convert/transcode.ts when the input container is one of\n * {avi, asf, flv, rm/rmvb} (see isLibavTranscodeContainer). MP4/MKV/WebM/etc.\n * sources still go through the mediabunny Conversion path in transcode.ts.\n *\n * Scope limits (see docs/dev/ROADMAP.md):\n * - Single video + single audio track. Extra tracks are silently dropped.\n * - 8-bit video only; 10-bit throws with a clear error.\n * - No seek. Linear read-to-EOF.\n * - `outputStream` (streaming output to a WritableStream) is not yet\n *   wired for this path — throws with a clear error if requested.\n */\n\n// Lazy imports: libav-demux + the libav-loader chain it pulls in are heavy.\n// To keep the `transcode` bundle scenario below its gzip budget, we only\n// load them when the libav path is actually taken. See the top of\n// transcodeViaLibav() for the dynamic imports.\nimport type { LibavPacket } from \"../util/libav-demux.js\";\nimport {\n  AvbridgeError,\n  ERR_TRANSCODE_ABORTED,\n  ERR_TRANSCODE_UNSUPPORTED_COMBO,\n  ERR_TRANSCODE_DECODE,\n  ERR_CODEC_NOT_SUPPORTED,\n} from \"../errors.js\";\nimport type {\n  MediaContext,\n  TranscodeOptions,\n  ConvertResult,\n  OutputVideoCodec,\n  OutputAudioCodec,\n  TranscodeQuality,\n} from \"../types.js\";\n\n/** @internal */\nexport function isLibavTranscodeContainer(container: string): boolean {\n  return (\n    container === \"avi\" ||\n    container === \"asf\" ||\n    container === \"flv\" ||\n    container === \"rm\"  // RealMedia (.rm / .rmvb) — rv40/cook via libav software decode\n  );\n}\n\nexport async function transcodeViaLibav(\n  ctx: MediaContext,\n  options: TranscodeOptions,\n): Promise<ConvertResult> {\n  const outputFormat = options.outputFormat ?? \"mp4\";\n  // Output format gate: mp4, webm, and mkv are supported. The shared\n  // createOutputFormat helper in remux.ts handles the muxer side.\n  if (outputFormat !== \"mp4\" && outputFormat !== \"webm\" && outputFormat !== \"mkv\") {\n    throw new AvbridgeError(\n      ERR_TRANSCODE_UNSUPPORTED_COMBO,\n      `legacy-container transcode supports MP4, WebM, and MKV output (got \"${outputFormat}\").`,\n      `Use outputFormat: \"mp4\", \"webm\", or \"mkv\".`,\n    );\n  }\n  // Codec defaults depend on output format. `transcode()` already calls\n  // validateCodecCompatibility with the user-supplied codecs, but when\n  // we're reached directly or with just outputFormat set, pick sensible\n  // defaults per container.\n  const videoCodec: OutputVideoCodec =\n    options.videoCodec ?? (outputFormat === \"webm\" ? \"vp9\" : \"h264\");\n  const audioCodec: OutputAudioCodec =\n    options.audioCodec ?? (outputFormat === \"webm\" ? \"opus\" : \"aac\");\n  const quality: TranscodeQuality = options.quality ?? \"medium\";\n  options.signal?.throwIfAborted();\n\n  // Everything from here is lazily loaded so the `transcode` scenario\n  // doesn't pay for libav/mediabunny weight just because this file is\n  // on the import graph.\n  const [\n    mb,\n    { openLibavDemux, sanitizePacketTimestamp, sanitizeFrameTimestamp, libavFrameToInterleavedFloat32 },\n    { normalizeSource },\n    { createOutputFormat, mimeForFormat, generateFilename },\n  ] = await Promise.all([\n    import(\"mediabunny\"),\n    import(\"../util/libav-demux.js\"),\n    import(\"../util/source.js\"),\n    import(\"./remux.js\"),\n  ]);\n\n  // ── Open the demux session ──────────────────────────────────────────\n  const normalized = await normalizeSource(ctx.source);\n  const demux = await openLibavDemux({\n    source: normalized,\n    filename: ctx.name ?? \"input.bin\",\n    context: ctx,\n    // transport config is not yet threaded through ConvertOptions; add\n    // later if URL-source transcode with signed URLs becomes a need.\n  });\n\n  try {\n    options.signal?.throwIfAborted();\n\n    if (!demux.videoStream && !demux.audioStream) {\n      throw new Error(\"transcode: source has no decodable tracks\");\n    }\n\n    // ── Set up mediabunny Output (BufferTarget — in-memory) ──────────\n    // outputStream is not yet supported for the libav path — the\n    // sample-source + encoder chain doesn't expose the same StreamTarget\n    // hook that mediabunny's Conversion uses internally. Flag loudly.\n    if (options.outputStream) {\n      throw new AvbridgeError(\n        ERR_TRANSCODE_UNSUPPORTED_COMBO,\n        \"outputStream is not yet supported for the libav-backed transcode path.\",\n        \"Remove the outputStream option to receive the transcoded blob in memory. Streaming output for this path is on the roadmap.\",\n      );\n    }\n    const bufferTarget = new mb.BufferTarget();\n    const output = new mb.Output({\n      format: createOutputFormat(mb, outputFormat),\n      target: bufferTarget,\n    });\n\n    // ── Bridge (libavjs-webcodecs-bridge) for packet → EncodedVideoChunk\n    const bridge = await loadBridge();\n\n    // ── Video decoder (WebCodecs) + sample source (mediabunny) ───────\n    // Video decode has two possible paths:\n    // - WebCodecs (hardware or browser's software decoder) — used when\n    //   `VideoDecoder.isConfigSupported(config)` returns true. Fast.\n    // - libav software decode — used when WebCodecs can't handle the codec.\n    //   Required for RealMedia (rv40/etc.), where the source codec isn't in\n    //   any browser. The output is still a VideoFrame (via the bridge's\n    //   laFrameToVideoFrame), so the downstream queue+drain is unchanged.\n    let videoDecoder: VideoDecoder | null = null;\n    let videoSoftDec: { c: number; pkt: number; frame: number } | null = null;\n    let videoSource: InstanceType<typeof mb.VideoSampleSource> | null = null;\n    let videoBsfCtx: number | null = null;\n    let videoBsfPkt: number | null = null;\n    let videoWidth = 0;\n    let videoHeight = 0;\n    let videoTimeBase: [number, number] | undefined;\n\n    // Explicit queue + drain for VideoDecoder.output → videoSource.add.\n    // VideoDecoder.output is fire-and-forget, videoSource.add is async\n    // and backpressures. Without a queue + single-flight drain, we'd\n    // either lose backpressure (memory blow-up) or let in-flight `add`\n    // calls interleave out of order. Phase 1 correctness depends on this.\n    const frameQueue: VideoFrame[] = [];\n    const MAX_QUEUE = 16;\n    let draining = false;\n    let drainError: Error | null = null;\n    // Promise of the currently-running drain (for explicit await at EOF).\n    let activeDrain: Promise<void> | null = null;\n\n    const drain = (): Promise<void> => {\n      if (draining) return activeDrain ?? Promise.resolve();\n      draining = true;\n      const run = (async () => {\n        try {\n          while (frameQueue.length > 0 && !drainError) {\n            const frame = frameQueue.shift()!;\n            try {\n              const sample = new mb.VideoSample(frame, {\n                timestamp: (frame.timestamp ?? 0) / 1_000_000, // µs → s\n              });\n              await videoSource!.add(sample);\n            } finally {\n              frame.close();\n            }\n          }\n        } catch (err) {\n          drainError = err as Error;\n          // Release any queued frames so we don't leak VideoFrames.\n          while (frameQueue.length > 0) {\n            try { frameQueue.shift()!.close(); } catch { /* ignore */ }\n          }\n        } finally {\n          draining = false;\n          activeDrain = null;\n        }\n      })();\n      activeDrain = run;\n      return run;\n    };\n\n    if (demux.videoStream && !options.dropVideo) {\n      try {\n        // Phase 1: refuse 10-bit. Neither decode path produces pixel\n        // formats that mediabunny's encoders reliably consume.\n        const bitDepth = ctx.videoTracks[0]?.bitDepth ?? 8;\n        if (bitDepth > 8) {\n          throw new AvbridgeError(\n            ERR_TRANSCODE_UNSUPPORTED_COMBO,\n            `transcode: 10-bit video is not supported in this release (source bit depth: ${bitDepth}).`,\n            `Phase 1 transcode handles 8-bit video only. 10-bit support is on the roadmap.`,\n          );\n        }\n\n        if (demux.videoStream.time_base_num && demux.videoStream.time_base_den) {\n          videoTimeBase = [demux.videoStream.time_base_num, demux.videoStream.time_base_den];\n        }\n\n        // Try WebCodecs first. If the bridge can build a config AND the\n        // browser's VideoDecoder supports it, use hardware/native decode.\n        // Otherwise fall back to libav software decode (rv40, etc.).\n        let config: VideoDecoderConfig | null = null;\n        try {\n          config = await bridge.videoStreamToConfig(demux.libav, demux.videoStream);\n        } catch {\n          config = null;\n        }\n        const supported = config\n          ? await VideoDecoder.isConfigSupported(config).catch(() => ({ supported: false }))\n          : { supported: false };\n\n        videoWidth = (config?.codedWidth ?? ctx.videoTracks[0]?.width) ?? 0;\n        videoHeight = (config?.codedHeight ?? ctx.videoTracks[0]?.height) ?? 0;\n\n        if (config && supported.supported) {\n          // ── WebCodecs path ──\n          videoDecoder = new VideoDecoder({\n            output: (frame) => {\n              if (frameQueue.length >= MAX_QUEUE) {\n                frame.close();\n                return;\n              }\n              frameQueue.push(frame);\n              void drain();\n            },\n            error: (err) => {\n              drainError = err as unknown as Error;\n            },\n          });\n          videoDecoder.configure(config);\n        } else {\n          // ── libav software decode path ──\n          // RealMedia (rv10/20/30/40) and any other codec WebCodecs doesn't\n          // support lands here. The libav variant picker already routes\n          // rm/rv* to the \"avbridge\" variant via codec-set inspection.\n          const libavSoft = demux.libav as unknown as LibavSoftVideo;\n          const [, c, pkt, frame] = await libavSoft.ff_init_decoder(\n            demux.videoStream.codec_id,\n            { codecpar: demux.videoStream.codecpar },\n          );\n          videoSoftDec = { c, pkt, frame };\n        }\n\n        videoSource = new mb.VideoSampleSource({\n          codec: avbridgeVideoToMediabunny(videoCodec),\n          bitrate: qualityToMediabunny(mb, quality, options.videoBitrate),\n          ...(options.frameRate !== undefined ? { frameRate: options.frameRate } : {}),\n          ...(options.hardwareAcceleration !== undefined\n            ? { hardwareAcceleration: options.hardwareAcceleration }\n            : {}),\n          // Progress reporting: media-time-based via each encoded packet.\n          onEncodedPacket: options.onProgress\n            ? (packet) => {\n                const t = packet.timestamp;\n                if (Number.isFinite(t) && ctx.duration && ctx.duration > 0) {\n                  const pct = Math.min(100, (t / ctx.duration) * 100);\n                  options.onProgress!({ percent: pct, bytesWritten: 0 });\n                }\n              }\n            : undefined,\n        });\n\n        const videoMeta: { width?: number; height?: number; frameRate?: number } = {};\n        if (options.width !== undefined) videoMeta.width = options.width;\n        else if (videoWidth > 0) videoMeta.width = videoWidth;\n        if (options.height !== undefined) videoMeta.height = options.height;\n        else if (videoHeight > 0) videoMeta.height = videoHeight;\n        if (options.frameRate !== undefined) videoMeta.frameRate = options.frameRate;\n        output.addVideoTrack(videoSource, videoMeta);\n\n        // mpeg4 packed-bframes BSF — same as hybrid/fallback.\n        if (ctx.videoTracks[0]?.codec === \"mpeg4\") {\n          const runtime = demux.libav as unknown as LibavBsf;\n          try {\n            videoBsfCtx = await runtime.av_bsf_list_parse_str_js(\"mpeg4_unpack_bframes\");\n            if (videoBsfCtx != null && videoBsfCtx >= 0) {\n              const parIn = await runtime.AVBSFContext_par_in(videoBsfCtx);\n              await runtime.avcodec_parameters_copy(parIn, demux.videoStream.codecpar);\n              await runtime.av_bsf_init(videoBsfCtx);\n              videoBsfPkt = await (demux.libav as unknown as { av_packet_alloc(): Promise<number> })\n                .av_packet_alloc();\n            } else {\n              videoBsfCtx = null;\n            }\n          } catch {\n            videoBsfCtx = null;\n          }\n        }\n      } catch (err) {\n        if (err instanceof AvbridgeError) throw err;\n        throw new AvbridgeError(\n          ERR_CODEC_NOT_SUPPORTED,\n          `transcode: video decoder init failed: ${(err as Error).message}`,\n          `The source's video codec may not be supported by this browser's WebCodecs implementation.`,\n        );\n      }\n    }\n\n    // ── Audio decoder (libav software) + sample source ───────────────\n    interface SoftDecoder { c: number; pkt: number; frame: number; }\n    let audioDec: SoftDecoder | null = null;\n    let audioSource: InstanceType<typeof mb.AudioSampleSource> | null = null;\n    let audioTimeBase: [number, number] | undefined;\n\n    const includeAudio = demux.audioStream && !options.dropAudio;\n    if (includeAudio) {\n      try {\n        const libav = demux.libav as unknown as LibavAudio;\n        const [, c, pkt, frame] = await libav.ff_init_decoder(\n          demux.audioStream!.codec_id,\n          { codecpar: demux.audioStream!.codecpar },\n        );\n        audioDec = { c, pkt, frame };\n        if (demux.audioStream!.time_base_num && demux.audioStream!.time_base_den) {\n          audioTimeBase = [\n            demux.audioStream!.time_base_num,\n            demux.audioStream!.time_base_den,\n          ];\n        }\n\n        audioSource = new mb.AudioSampleSource({\n          codec: avbridgeAudioToMediabunny(audioCodec),\n          bitrate: qualityToMediabunny(mb, quality, options.audioBitrate),\n        });\n        output.addAudioTrack(audioSource);\n      } catch (err) {\n        const codecName = ctx.audioTracks[0]?.codec ?? \"unknown\";\n        throw new AvbridgeError(\n          ERR_CODEC_NOT_SUPPORTED,\n          `transcode: no decoder available for audio codec \"${codecName}\" in this libav variant (${(err as Error).message}).`,\n          `The file may still play via createPlayer() (fallback strategy). Pass { dropAudio: true } to transcode video-only.`,\n        );\n      }\n    } else if (options.dropAudio) {\n      // Caller asked for video-only — don't add an audio track.\n    }\n\n    if (!videoSource && !audioSource) {\n      throw new AvbridgeError(\n        ERR_TRANSCODE_UNSUPPORTED_COMBO,\n        \"transcode: no video or audio track to encode (did you set both dropVideo and dropAudio?).\",\n        \"Remove dropVideo or dropAudio to include at least one track.\",\n      );\n    }\n\n    await output.start();\n\n    // ── Synthetic timestamp counters for packets without valid PTS ──\n    const videoFps = ctx.videoTracks[0]?.fps && ctx.videoTracks[0]!.fps > 0\n      ? ctx.videoTracks[0]!.fps\n      : 30;\n    const videoFrameStepUs = Math.max(1, Math.round(1_000_000 / videoFps));\n    let syntheticVideoUs = 0;\n    let syntheticAudioUs = 0;\n\n    // BSF helpers (only if bsfCtx initialized)\n    const libavFull = demux.libav as unknown as LibavBsf & { ff_copyin_packet(a: number, b: LibavPacket): Promise<void>; ff_copyout_packet(a: number): Promise<LibavPacket>; };\n    async function applyBSF(packets: LibavPacket[]): Promise<LibavPacket[]> {\n      if (!videoBsfCtx || !videoBsfPkt) return packets;\n      const out: LibavPacket[] = [];\n      for (const pkt of packets) {\n        await libavFull.ff_copyin_packet(videoBsfPkt, pkt);\n        const sendErr = await libavFull.av_bsf_send_packet(videoBsfCtx, videoBsfPkt);\n        if (sendErr < 0) { out.push(pkt); continue; }\n        while (true) {\n          const recvErr = await libavFull.av_bsf_receive_packet(videoBsfCtx, videoBsfPkt);\n          if (recvErr < 0) break;\n          out.push(await libavFull.ff_copyout_packet(videoBsfPkt));\n        }\n      }\n      return out;\n    }\n\n    // Guarded access: signal cancellation is honored between batches\n    // and at queue-wait checkpoints.\n    const ac = options.signal;\n    function throwIfAborted(): void {\n      if (ac?.aborted) {\n        throw new AvbridgeError(\n          ERR_TRANSCODE_ABORTED,\n          \"transcode: aborted by caller.\",\n          undefined,\n        );\n      }\n    }\n\n    function throwIfDrainError(): void {\n      if (drainError) {\n        const msg = drainError.message;\n        throw new AvbridgeError(\n          ERR_TRANSCODE_DECODE,\n          `transcode: video decoder error: ${msg}`,\n          \"This usually indicates the WebCodecs decoder rejected a malformed packet.\",\n        );\n      }\n    }\n\n    // ── Pump ────────────────────────────────────────────────────────\n    const onVideoPacketsWebCodecs = videoDecoder\n      ? async (pkts: LibavPacket[]) => {\n          throwIfAborted();\n          throwIfDrainError();\n          while (\n            !ac?.aborted &&\n            (videoDecoder!.decodeQueueSize > 16 || frameQueue.length >= MAX_QUEUE - 2)\n          ) {\n            await new Promise((r) => setTimeout(r, 10));\n          }\n          throwIfAborted();\n\n          const processed = await applyBSF(pkts);\n          const bridgeAny = bridge as unknown as {\n            packetToEncodedVideoChunk(pkt: unknown, stream: unknown): EncodedVideoChunk;\n          };\n          for (const pkt of processed) {\n            sanitizePacketTimestamp(pkt, () => {\n              const ts = syntheticVideoUs;\n              syntheticVideoUs += videoFrameStepUs;\n              return ts;\n            }, videoTimeBase);\n            try {\n              const chunk = bridgeAny.packetToEncodedVideoChunk(pkt, demux.videoStream);\n              videoDecoder!.decode(chunk);\n            } catch (err) {\n              throw new AvbridgeError(\n                ERR_TRANSCODE_DECODE,\n                `transcode: packet → EncodedVideoChunk failed: ${(err as Error).message}`,\n                undefined,\n              );\n            }\n          }\n        }\n      : undefined;\n\n    const onVideoPacketsSoftware = videoSoftDec\n      ? async (pkts: LibavPacket[]) => {\n          throwIfAborted();\n          throwIfDrainError();\n          // Only frameQueue backpressure — no WebCodecs queue.\n          while (!ac?.aborted && frameQueue.length >= MAX_QUEUE - 2) {\n            await new Promise((r) => setTimeout(r, 10));\n          }\n          throwIfAborted();\n\n          const libavSoft = demux.libav as unknown as LibavSoftVideo;\n          let frames;\n          try {\n            frames = await libavSoft.ff_decode_multi(\n              videoSoftDec!.c, videoSoftDec!.pkt, videoSoftDec!.frame, pkts,\n              { ignoreErrors: true },\n            );\n          } catch (err) {\n            throw new AvbridgeError(\n              ERR_TRANSCODE_DECODE,\n              `transcode: software video decode failed: ${(err as Error).message}`,\n              undefined,\n            );\n          }\n          for (const f of frames) {\n            sanitizeFrameTimestamp(f, () => {\n              const ts = syntheticVideoUs;\n              syntheticVideoUs += videoFrameStepUs;\n              return ts;\n            }, videoTimeBase);\n            try {\n              // Bridge consumes any libav-decoded frame (software or\n              // hardware) and returns a WebCodecs VideoFrame.\n              const vf = bridge.laFrameToVideoFrame(f, { timeBase: [1, 1_000_000] });\n              if (frameQueue.length >= MAX_QUEUE) {\n                vf.close();\n              } else {\n                frameQueue.push(vf);\n                void drain();\n              }\n            } catch (err) {\n              throw new AvbridgeError(\n                ERR_TRANSCODE_DECODE,\n                `transcode: laFrameToVideoFrame failed: ${(err as Error).message}`,\n                undefined,\n              );\n            }\n          }\n        }\n      : undefined;\n\n    await demux.pump({\n      signal: ac,\n      onVideoPackets: onVideoPacketsWebCodecs ?? onVideoPacketsSoftware,\n      onAudioPackets: audioDec\n        ? async (pkts) => {\n            throwIfAborted();\n            await decodeAudioBatch(pkts, false);\n          }\n        : undefined,\n      onEof: async () => {\n        // Drain video: flush decoder, then wait for our queue to empty.\n        if (videoDecoder && videoDecoder.state === \"configured\") {\n          try { await videoDecoder.flush(); } catch { /* ignore */ }\n        }\n        if (videoSoftDec) {\n          // Flush the software decoder with fin: true so any internally\n          // buffered frames come out.\n          const libavSoft = demux.libav as unknown as LibavSoftVideo;\n          try {\n            const tail = await libavSoft.ff_decode_multi(\n              videoSoftDec.c, videoSoftDec.pkt, videoSoftDec.frame, [],\n              { fin: true, ignoreErrors: true },\n            );\n            for (const f of tail) {\n              sanitizeFrameTimestamp(f, () => {\n                const ts = syntheticVideoUs;\n                syntheticVideoUs += videoFrameStepUs;\n                return ts;\n              }, videoTimeBase);\n              try {\n                const vf = bridge.laFrameToVideoFrame(f, { timeBase: [1, 1_000_000] });\n                frameQueue.push(vf);\n                void drain();\n              } catch { /* ignore per-frame failures during flush */ }\n            }\n          } catch { /* ignore */ }\n        }\n        // A final drain() kick to consume any post-flush frames.\n        await drain();\n        // Drain audio: flush the libav decoder.\n        if (audioDec) {\n          await decodeAudioBatch([], true);\n        }\n      },\n    });\n\n    throwIfAborted();\n    throwIfDrainError();\n\n    // Close the sample sources so mediabunny finalizes track metadata.\n    videoSource?.close();\n    audioSource?.close();\n\n    await output.finalize();\n\n    if (!bufferTarget.buffer) {\n      throw new Error(\"transcode: mediabunny produced no output buffer\");\n    }\n    const mimeType = mimeForFormat(outputFormat);\n    const blob = new Blob([bufferTarget.buffer], { type: mimeType });\n    options.onProgress?.({ percent: 100, bytesWritten: blob.size });\n\n    return {\n      blob,\n      mimeType,\n      container: outputFormat,\n      videoCodec: videoSource ? videoCodec : undefined,\n      audioCodec: audioSource ? audioCodec : undefined,\n      duration: ctx.duration,\n      filename: generateFilename(ctx.name, outputFormat),\n    };\n\n    // ── Helpers closing over the above state ────────────────────────\n    async function decodeAudioBatch(pkts: LibavPacket[], flush: boolean): Promise<void> {\n      if (!audioDec || !audioSource) return;\n      const libav = demux.libav as unknown as LibavAudio;\n      let frames;\n      try {\n        frames = await libav.ff_decode_multi(\n          audioDec.c,\n          audioDec.pkt,\n          audioDec.frame,\n          pkts,\n          flush ? { fin: true, ignoreErrors: true } : { ignoreErrors: true },\n        );\n      } catch (err) {\n        throw new AvbridgeError(\n          ERR_TRANSCODE_DECODE,\n          `transcode: audio decode failed: ${(err as Error).message}`,\n          undefined,\n        );\n      }\n      for (const f of frames) {\n        sanitizeFrameTimestamp(f, () => {\n          const ts = syntheticAudioUs;\n          const samples = f.nb_samples ?? 1024;\n          const sampleRate = f.sample_rate ?? 44100;\n          syntheticAudioUs += Math.round((samples * 1_000_000) / sampleRate);\n          return ts;\n        }, audioTimeBase);\n        const pcm = libavFrameToInterleavedFloat32(f);\n        if (!pcm) continue;\n        // AudioSample wants a typed AudioSampleInit. f32 interleaved.\n        const sample = new mb.AudioSample({\n          data: pcm.data,\n          format: \"f32\",\n          numberOfChannels: pcm.channels,\n          sampleRate: pcm.sampleRate,\n          timestamp: (f.pts ?? 0) / 1_000_000,\n        });\n        await audioSource.add(sample);\n      }\n    }\n  } finally {\n    // Teardown: close decoders, free BSF, close demuxer.\n    try { await demux.destroy(); } catch { /* ignore */ }\n    // Note: videoDecoder / audioDec cleanup happens implicitly; the demuxer\n    // destroy releases the fmt_ctx, and our sample sources + Output\n    // finalization release the encoder side. Explicit frees here would\n    // race with in-flight decode calls on error paths; we accept the\n    // short-lived leak.\n  }\n  // Reference types used in this file. Declared locally to avoid leaking\n  // into the shared helper module.\n  interface LibavAudio {\n    ff_init_decoder(\n      codec: number | string,\n      config?: { codecpar?: number; time_base?: [number, number] },\n    ): Promise<[number, number, number, number]>;\n    ff_decode_multi(\n      c: number,\n      pkt: number,\n      frame: number,\n      packets: LibavPacket[],\n      opts?: { fin?: boolean; ignoreErrors?: boolean },\n    ): Promise<import(\"../util/libav-demux.js\").LibavFrame[]>;\n  }\n  // Software video decode uses the same surface as audio. Aliased for\n  // readability at callsites.\n  type LibavSoftVideo = LibavAudio;\n  interface LibavBsf {\n    av_bsf_list_parse_str_js(str: string): Promise<number>;\n    AVBSFContext_par_in(ctx: number): Promise<number>;\n    avcodec_parameters_copy(dst: number, src: number): Promise<number>;\n    av_bsf_init(ctx: number): Promise<number>;\n    av_bsf_send_packet(ctx: number, pkt: number): Promise<number>;\n    av_bsf_receive_packet(ctx: number, pkt: number): Promise<number>;\n  }\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────\n\nasync function loadBridge(): Promise<BridgeModule> {\n  try {\n    const wrapper = await import(\"../strategies/fallback/libav-import.js\");\n    return wrapper.libavBridge as unknown as BridgeModule;\n  } catch (err) {\n    throw new Error(`failed to load libavjs-webcodecs-bridge: ${(err as Error).message}`);\n  }\n}\n\ninterface BridgeModule {\n  videoStreamToConfig(libav: unknown, stream: unknown): Promise<VideoDecoderConfig | null>;\n  packetToEncodedVideoChunk(pkt: unknown, stream: unknown): EncodedVideoChunk;\n  laFrameToVideoFrame(\n    frame: unknown,\n    opts?: { timeBase?: [number, number]; transfer?: boolean },\n  ): VideoFrame;\n}\n\nfunction avbridgeVideoToMediabunny(c: OutputVideoCodec): \"avc\" | \"hevc\" | \"vp9\" | \"av1\" {\n  switch (c) {\n    case \"h264\": return \"avc\";\n    case \"h265\": return \"hevc\";\n    case \"vp9\":  return \"vp9\";\n    case \"av1\":  return \"av1\";\n  }\n}\n\nfunction avbridgeAudioToMediabunny(c: OutputAudioCodec): \"aac\" | \"opus\" | \"flac\" {\n  switch (c) {\n    case \"aac\":  return \"aac\";\n    case \"opus\": return \"opus\";\n    case \"flac\": return \"flac\";\n  }\n}\n\nfunction qualityToMediabunny(\n  mb: typeof import(\"mediabunny\"),\n  quality: TranscodeQuality,\n  override: number | undefined,\n): number | InstanceType<typeof mb.Quality> {\n  if (override !== undefined) return override;\n  switch (quality) {\n    case \"low\":       return mb.QUALITY_LOW;\n    case \"medium\":    return mb.QUALITY_MEDIUM;\n    case \"high\":      return mb.QUALITY_HIGH;\n    case \"very-high\": return mb.QUALITY_VERY_HIGH;\n  }\n}\n","/**\n * Standalone transcode function: re-encode media into a modern container with\n * modern codecs. Unlike {@link remux}, this is a lossy operation that decodes\n * and re-encodes the streams.\n *\n * Built on top of mediabunny's `Conversion` class which handles the full\n * decode → encode → mux pipeline. WebCodecs encoders are used when available;\n * mediabunny falls back to other paths internally.\n *\n * Limitations in v1:\n * - Input must be in a mediabunny-readable container (MP4, MKV, WebM, OGG, ...).\n *   AVI/ASF/FLV sources are not yet supported by transcode (use remux + native\n *   playback or wait for v1.1).\n */\n\nimport { probe } from \"../probe/index.js\";\nimport { buildMediabunnySourceFromInput } from \"../probe/mediabunny.js\";\nimport { createOutputFormat, mimeForFormat, generateFilename } from \"./remux.js\";\nimport { isLibavTranscodeContainer, transcodeViaLibav } from \"./transcode-libav.js\";\nimport { AvbridgeError, ERR_CONTAINER_NOT_SUPPORTED } from \"../errors.js\";\nimport type {\n  MediaInput,\n  MediaContext,\n  TranscodeOptions,\n  ConvertResult,\n  OutputFormat,\n  OutputVideoCodec,\n  OutputAudioCodec,\n  TranscodeQuality,\n} from \"../types.js\";\n\n/** Containers mediabunny can demux. AVI/ASF/FLV are not in this set. */\nconst MEDIABUNNY_CONTAINERS = new Set([\n  \"mp4\", \"mov\", \"mkv\", \"webm\", \"ogg\", \"wav\", \"mp3\", \"flac\", \"adts\",\n]);\n\n/**\n * Transcode a media source into a modern container with modern codecs.\n *\n * Re-encodes both video and audio. Use {@link remux} instead when the source\n * codecs are already modern and only the container needs changing — it's much\n * faster and lossless.\n */\nexport async function transcode(\n  source: MediaInput,\n  options: TranscodeOptions = {},\n): Promise<ConvertResult> {\n  const outputFormat: OutputFormat = options.outputFormat ?? \"mp4\";\n  const videoCodec = options.videoCodec ?? defaultVideoCodec(outputFormat);\n  const audioCodec = options.audioCodec ?? defaultAudioCodec(outputFormat);\n  const quality = options.quality ?? \"medium\";\n\n  validateCodecCompatibility(outputFormat, videoCodec, audioCodec);\n  options.signal?.throwIfAborted();\n\n  const ctx = await probe(source);\n  options.signal?.throwIfAborted();\n\n  // AVI/ASF/FLV → the libav-demux-backed pipeline (Phase 1: MP4 output only).\n  if (isLibavTranscodeContainer(ctx.container)) {\n    return transcodeViaLibav(ctx, options);\n  }\n\n  if (!MEDIABUNNY_CONTAINERS.has(ctx.container)) {\n    throw new AvbridgeError(\n      ERR_CONTAINER_NOT_SUPPORTED,\n      `Cannot transcode \"${ctx.container}\" sources. ` +\n      `transcode() supports mediabunny-readable containers (MP4, MKV, WebM, OGG, MP3, FLAC, WAV, MOV) and legacy containers via the libav path (AVI, ASF, FLV).`,\n      `If this is a legacy container we don't yet support, use createPlayer() to play it. Transcode support for more containers is on the roadmap.`,\n    );\n  }\n\n  return doTranscode(ctx, outputFormat, videoCodec, audioCodec, quality, options);\n}\n\n/**\n * One attempt at the full mediabunny conversion. Each attempt allocates\n * fresh `Input` / `Output` / `Conversion` instances because they are all\n * single-use in mediabunny.\n *\n * Returns the muxed `ArrayBuffer` on success. Throws on failure.\n */\nasync function attemptTranscode(\n  ctx: MediaContext,\n  outputFormat: OutputFormat,\n  videoCodec: OutputVideoCodec,\n  audioCodec: OutputAudioCodec,\n  quality: TranscodeQuality,\n  options: TranscodeOptions,\n): Promise<ArrayBuffer | null> {\n  const mb = await import(\"mediabunny\");\n\n  const input = new mb.Input({\n    source: await buildMediabunnySourceFromInput(mb, ctx.source),\n    formats: mb.ALL_FORMATS,\n  });\n\n  // When outputStream is provided, pipe chunks directly to the stream\n  // instead of accumulating into a buffer. This keeps memory usage flat\n  // regardless of file size.\n  let bytesWritten = 0;\n  const useStream = !!options.outputStream;\n  const bufferTarget = useStream ? null : new mb.BufferTarget();\n  const streamTarget = useStream\n    ? new mb.StreamTarget(new WritableStream({\n        write(chunk: { type: string; data: Uint8Array; position: number }) {\n          bytesWritten += chunk.data.byteLength;\n          const writer = options.outputStream!.getWriter();\n          return writer.write(chunk.data).then(() => writer.releaseLock());\n        },\n      }))\n    : null;\n\n  const output = new mb.Output({\n    format: createOutputFormat(mb, outputFormat),\n    target: (streamTarget ?? bufferTarget)!,\n  });\n\n  // Build mediabunny ConversionVideoOptions\n  const videoOptions = options.dropVideo\n    ? { discard: true as const }\n    : {\n        codec: avbridgeVideoToMediabunny(videoCodec),\n        bitrate: options.videoBitrate ?? qualityToMediabunny(mb, quality),\n        forceTranscode: true,\n        ...(options.width !== undefined ? { width: options.width } : {}),\n        ...(options.height !== undefined ? { height: options.height } : {}),\n        ...(options.width !== undefined && options.height !== undefined\n          ? { fit: \"contain\" as const }\n          : {}),\n        ...(options.frameRate !== undefined ? { frameRate: options.frameRate } : {}),\n        ...(options.hardwareAcceleration !== undefined\n          ? { hardwareAcceleration: options.hardwareAcceleration }\n          : {}),\n      };\n\n  const audioOptions = options.dropAudio\n    ? { discard: true as const }\n    : {\n        codec: avbridgeAudioToMediabunny(audioCodec),\n        bitrate: options.audioBitrate ?? qualityToMediabunny(mb, quality),\n        forceTranscode: true,\n      };\n\n  const conversion = await mb.Conversion.init({\n    input,\n    output,\n    video: videoOptions,\n    audio: audioOptions,\n    showWarnings: false,\n  });\n\n  if (!conversion.isValid) {\n    const reasons = conversion.discardedTracks\n      .map((d) => `${d.track.type} track discarded: ${d.reason}`)\n      .join(\"; \");\n    throw new Error(\n      `Cannot transcode: mediabunny rejected the conversion. ${reasons || \"(no reason given)\"}`,\n    );\n  }\n\n  // Wire progress\n  if (options.onProgress) {\n    const onProgress = options.onProgress;\n    conversion.onProgress = (p) => {\n      onProgress({ percent: p * 100, bytesWritten: 0 });\n    };\n  }\n\n  // Wire cancellation\n  let abortHandler: (() => void) | undefined;\n  if (options.signal) {\n    options.signal.throwIfAborted();\n    abortHandler = () => void conversion.cancel();\n    options.signal.addEventListener(\"abort\", abortHandler, { once: true });\n  }\n\n  try {\n    await conversion.execute();\n  } finally {\n    if (abortHandler && options.signal) {\n      options.signal.removeEventListener(\"abort\", abortHandler);\n    }\n  }\n\n  if (useStream) {\n    return null; // data already written to outputStream\n  }\n  if (!bufferTarget!.buffer) {\n    throw new Error(\"Transcode failed: mediabunny produced no output buffer.\");\n  }\n  return bufferTarget!.buffer;\n}\n\n/**\n * Detect the \"Encoding error\" failure pattern that headless Chromium's\n * H.264 WebCodecs encoder hits on its first call per page. The encoder\n * is fully usable on the second attempt, so we retry once.\n *\n * See <https://issues.chromium.org/> — this is a known first-call init\n * issue in the OS-backed encoder pipeline (VideoToolbox on macOS).\n */\nfunction isLikelyEncoderInitError(err: unknown): boolean {\n  if (!err) return false;\n  const msg = err instanceof Error ? err.message : String(err);\n  const lower = msg.toLowerCase();\n  // The exact strings WebCodecs / mediabunny surface for encoder failures.\n  return (\n    lower.includes(\"encoding error\") ||\n    lower.includes(\"encoder\") ||\n    lower.includes(\"encode failed\")\n  );\n}\n\nfunction describeError(err: unknown): string {\n  if (!err) return \"(unknown)\";\n  if (err instanceof Error) return err.message;\n  return String(err);\n}\n\n/**\n * Maximum encoder retry attempts. Headless Chromium's H.264 WebCodecs\n * encoder hits a first-call init failure and *usually* recovers on the\n * second attempt — but in rare cases the second attempt also fails. Two\n * extra attempts (3 total) is enough to make the smoke test reliable\n * without masking real bugs.\n */\nconst MAX_ENCODER_RETRIES = 2;\n\nasync function doTranscode(\n  ctx: MediaContext,\n  outputFormat: OutputFormat,\n  videoCodec: OutputVideoCodec,\n  audioCodec: OutputAudioCodec,\n  quality: TranscodeQuality,\n  options: TranscodeOptions,\n): Promise<ConvertResult> {\n  const notes: string[] = [];\n  let buffer: ArrayBuffer | null = null;\n  let lastError: unknown;\n\n  for (let attempt = 0; attempt <= MAX_ENCODER_RETRIES; attempt++) {\n    try {\n      buffer = await attemptTranscode(ctx, outputFormat, videoCodec, audioCodec, quality, options);\n      if (attempt > 0) {\n        notes.push(\n          `Encoder failed ${attempt} time${attempt === 1 ? \"\" : \"s\"} before succeeding ` +\n          `(known headless Chromium WebCodecs encoder init issue): ${describeError(lastError)}`,\n        );\n      }\n      break;\n    } catch (err) {\n      lastError = err;\n      // Don't retry on user cancellation or permanent setup errors.\n      if (options.signal?.aborted) throw err;\n      if (!isLikelyEncoderInitError(err)) throw err;\n      if (attempt === MAX_ENCODER_RETRIES) throw err;\n      // Small backoff between attempts.\n      await new Promise((r) => setTimeout(r, 50 * (attempt + 1)));\n    }\n  }\n\n  const mimeType = mimeForFormat(outputFormat);\n  const filename = generateFilename(ctx.name, outputFormat);\n\n  if (options.outputStream) {\n    // Streaming mode — data already written to the stream. Return empty blob.\n    options.onProgress?.({ percent: 100, bytesWritten: 0 });\n    return {\n      blob: new Blob([], { type: mimeType }),\n      mimeType,\n      container: outputFormat,\n      videoCodec: options.dropVideo ? undefined : videoCodec,\n      audioCodec: options.dropAudio ? undefined : audioCodec,\n      duration: ctx.duration,\n      filename,\n      ...(notes.length > 0 ? { notes } : {}),\n    };\n  }\n\n  if (!buffer) {\n    throw new Error(\"Transcode failed: no buffer produced (this should be unreachable).\");\n  }\n\n  const blob = new Blob([buffer], { type: mimeType });\n  options.onProgress?.({ percent: 100, bytesWritten: blob.size });\n\n  return {\n    blob,\n    mimeType,\n    container: outputFormat,\n    videoCodec: options.dropVideo ? undefined : videoCodec,\n    audioCodec: options.dropAudio ? undefined : audioCodec,\n    duration: ctx.duration,\n    filename,\n    ...(notes.length > 0 ? { notes } : {}),\n  };\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\n/** @internal Exported for testing. */\nexport function defaultVideoCodec(format: OutputFormat): OutputVideoCodec {\n  switch (format) {\n    case \"webm\": return \"vp9\";\n    case \"mp4\":\n    case \"mkv\":\n    default:     return \"h264\";\n  }\n}\n\n/** @internal Exported for testing. */\nexport function defaultAudioCodec(format: OutputFormat): OutputAudioCodec {\n  switch (format) {\n    case \"webm\": return \"opus\";\n    case \"mp4\":\n    case \"mkv\":\n    default:     return \"aac\";\n  }\n}\n\n/** @internal Exported for testing. */\nexport function validateCodecCompatibility(\n  format: OutputFormat,\n  videoCodec: OutputVideoCodec,\n  audioCodec: OutputAudioCodec,\n): void {\n  // WebM only allows VP8/VP9/AV1 video and Opus/Vorbis audio.\n  if (format === \"webm\") {\n    if (videoCodec !== \"vp9\" && videoCodec !== \"av1\") {\n      throw new Error(\n        `WebM does not support video codec \"${videoCodec}\". Use \"vp9\" or \"av1\", or change outputFormat to \"mp4\" or \"mkv\".`,\n      );\n    }\n    if (audioCodec !== \"opus\") {\n      throw new Error(\n        `WebM does not support audio codec \"${audioCodec}\". Use \"opus\", or change outputFormat to \"mp4\" or \"mkv\".`,\n      );\n    }\n  }\n}\n\nfunction avbridgeVideoToMediabunny(c: OutputVideoCodec): \"avc\" | \"hevc\" | \"vp9\" | \"av1\" {\n  switch (c) {\n    case \"h264\": return \"avc\";\n    case \"h265\": return \"hevc\";\n    case \"vp9\":  return \"vp9\";\n    case \"av1\":  return \"av1\";\n  }\n}\n\nfunction avbridgeAudioToMediabunny(c: OutputAudioCodec): \"aac\" | \"opus\" | \"flac\" {\n  switch (c) {\n    case \"aac\":  return \"aac\";\n    case \"opus\": return \"opus\";\n    case \"flac\": return \"flac\";\n  }\n}\n\nfunction qualityToMediabunny(\n  mb: typeof import(\"mediabunny\"),\n  quality: TranscodeQuality,\n): InstanceType<typeof mb.Quality> {\n  switch (quality) {\n    case \"low\":       return mb.QUALITY_LOW;\n    case \"medium\":    return mb.QUALITY_MEDIUM;\n    case \"high\":      return mb.QUALITY_HIGH;\n    case \"very-high\": return mb.QUALITY_VERY_HIGH;\n  }\n}\n"]}