#include "media/mkv_copy.hpp"
#include "media/boundary_encode.hpp"
#include "media/mkv_timed_range.hpp"
#include "media/pcm_normalize.hpp"
#include "media/s337m_bridge.hpp"
#include "core/source_identity.hpp"
#include "core/json.hpp"
#include <filesystem>
#include <fstream>
#include <cstdlib>
#include <string_view>
#include <algorithm>
#include <chrono>
#include <cctype>
#include <sstream>
#include <cstdint>
#include <cstring>
#include <limits>
#include <vector>
#ifdef SMARTCUT_HAS_FFMPEG
extern "C" {
#include <libavformat/avformat.h>
}
#endif
namespace smartcut::media {
using smartcut::core::json_escape;
static bool full_disk_injection_enabled() {
#ifdef _MSC_VER
  char* value = nullptr; std::size_t length = 0;
  if (_dupenv_s(&value, &length, "SMARTCUT_TEST_FULL_DISK") != 0 || !value) return false;
  const bool enabled = std::string_view(value) == "1";
  std::free(value);
  return enabled;
#else
  const char* value = std::getenv("SMARTCUT_TEST_FULL_DISK");
  return value && std::string_view(value) == "1";
#endif
}
static bool keep_temporary_enabled() {
#ifdef _MSC_VER
  char* value = nullptr; std::size_t length = 0;
  if (_dupenv_s(&value, &length, "SMARTCUT_KEEP_TEMPORARY") != 0 || !value) return false;
  const bool enabled = *value != '\0';
  std::free(value);
  return enabled;
#else
  return std::getenv("SMARTCUT_KEEP_TEMPORARY") != nullptr;
#endif
}
#ifdef SMARTCUT_HAS_FFMPEG
static void copy_stream_attributes(AVStream* output, const AVStream* input) {
  output->disposition = input->disposition;
  output->avg_frame_rate = input->avg_frame_rate;
  output->sample_aspect_ratio = input->sample_aspect_ratio;
  av_dict_copy(&output->metadata, input->metadata, 0);
}
static void copy_chapters(AVFormatContext* output, const AVFormatContext* input) {
  for (unsigned i = 0; i < input->nb_chapters; ++i) { const auto* chapter = input->chapters[i]; auto* copied = static_cast<AVChapter*>(av_mallocz(sizeof(AVChapter))); if (!copied) continue; copied->id = chapter->id; copied->time_base = chapter->time_base; copied->start = chapter->start; copied->end = chapter->end; av_dict_copy(&copied->metadata, chapter->metadata, 0); auto** chapters = static_cast<AVChapter**>(av_realloc_array(output->chapters, output->nb_chapters + 1, sizeof(*output->chapters))); if (!chapters) { av_dict_free(&copied->metadata); av_free(copied); continue; } output->chapters = chapters; output->chapters[output->nb_chapters++] = copied; }
}
static bool metadata_subset(const AVDictionary* expected, const AVDictionary* actual) {
  const AVDictionaryEntry* entry = nullptr;
  while ((entry = av_dict_get(expected, "", entry, AV_DICT_IGNORE_SUFFIX)) != nullptr) { const std::string key = entry->key ? entry->key : ""; if (key == "DURATION" || key == "ENCODER") continue; const auto* found = av_dict_get(actual, entry->key, nullptr, 0); if (!found || std::string(found->value ? found->value : "") != std::string(entry->value ? entry->value : "")) return false; }
  return true;
}
static bool open_input_with_generated_pts(const std::string& path, AVFormatContext** context) {
  *context = avformat_alloc_context();
  if (!*context) return false;
  (*context)->flags |= AVFMT_FLAG_GENPTS;
  auto extension = std::filesystem::path(path).extension().string();
  std::transform(extension.begin(), extension.end(), extension.begin(),
                 [](unsigned char value) { return static_cast<char>(std::tolower(value)); });
  const AVInputFormat* forced = extension == ".s337m" || extension == ".dolbye"
      ? av_find_input_format("s337m") : nullptr;
  if (avformat_open_input(context, path.c_str(), forced, nullptr) < 0) {
    avformat_close_input(context);
    return false;
  }
  if (forced && (*context)->pb) {
    AVPacket* probe = av_packet_alloc();
    const bool discovered = probe && av_read_frame(*context, probe) >= 0 && (*context)->nb_streams > 0;
    av_packet_free(&probe);
    if (!discovered) {
      avformat_close_input(context);
      return false;
    }
    avformat_close_input(context);
    *context = avformat_alloc_context();
    if (!*context) return false;
    (*context)->flags |= AVFMT_FLAG_GENPTS;
    if (avformat_open_input(context, path.c_str(), forced, nullptr) < 0) {
      avformat_close_input(context);
      return false;
    }
    AVStream* stream = avformat_new_stream(*context, nullptr);
    if (!stream) {
      avformat_close_input(context);
      return false;
    }
    stream->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
    stream->codecpar->codec_id = AV_CODEC_ID_DOLBY_E;
    stream->time_base = AVRational{1, 48000};
  } else if (avformat_find_stream_info(*context, nullptr) < 0) {
    avformat_close_input(context);
    return false;
  }
  return true;
}

static std::string copy_s337m_to_mkv(const std::string& input, const std::string& output) {
  std::vector<S337mFrame> frames;
  std::string reason;
  if (!parse_s337m_16le(input, &frames, &reason))
    return "{\"error\":\"SMPTE 337M parse failed: " + json_escape(reason) + "\"}";
  AVFormatContext* destination = nullptr;
  AVPacket* packet = av_packet_alloc();
  bool completed = false;
  auto cleanup = [&] {
    av_packet_free(&packet);
    if (destination && destination->pb) avio_closep(&destination->pb);
    avformat_free_context(destination);
    if (!completed) {
      std::error_code ignored;
      std::filesystem::remove(output, ignored);
    }
  };
  if (!packet || avformat_alloc_output_context2(&destination, nullptr, "matroska", output.c_str()) < 0 ||
      !destination) {
    cleanup();
    return "{\"error\":\"Dolby E bridge output context failed\"}";
  }
  auto* stream = avformat_new_stream(destination, nullptr);
  if (!stream) {
    cleanup();
    return "{\"error\":\"Dolby E bridge stream creation failed\"}";
  }
  stream->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
  stream->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
  stream->codecpar->sample_rate = 48000;
  stream->codecpar->bits_per_coded_sample = 24;
  stream->codecpar->bits_per_raw_sample = 24;
  const AVChannelLayout stereo = AV_CHANNEL_LAYOUT_STEREO;
  if (av_channel_layout_copy(&stream->codecpar->ch_layout, &stereo) < 0) {
    cleanup();
    return "{\"error\":\"Dolby E bridge channel layout failed\"}";
  }
  stream->codecpar->block_align = 6;
  stream->time_base = AVRational{1, 48000};
  av_dict_set(&stream->metadata, kBitstreamAudioOrigin, "dolby_e", 0);
  av_dict_set(&stream->metadata, "title", "Dolby E (lossless SMPTE 337M bridge)", 0);
  av_dict_set(&destination->metadata, "SMARTCUT_BRIDGE", "smpte-337m-16le", 0);
  if ((!(destination->oformat->flags & AVFMT_NOFILE) &&
       avio_open(&destination->pb, output.c_str(), AVIO_FLAG_WRITE) < 0) ||
      avformat_write_header(destination, nullptr) < 0) {
    cleanup();
    return "{\"error\":\"Dolby E bridge output setup failed\"}";
  }
  constexpr AVRational carrier_time_base{1, 48000};
  constexpr std::int64_t samples_per_frame = 1920;
  int result = 0;
  std::size_t written = 0;
  for (std::size_t index = 0; result >= 0 && index < frames.size(); ++index) {
    if ((frames[index].decoded_payload.size() & 1U) != 0U) {
      result = AVERROR_INVALIDDATA;
      break;
    }
    std::vector<std::uint8_t> payload = frames[index].carrier_header;
    payload.reserve(payload.size() + frames[index].decoded_payload.size());
    for (std::size_t offset = 0; offset < frames[index].decoded_payload.size(); offset += 2) {
      payload.push_back(frames[index].decoded_payload[offset + 1]);
      payload.push_back(frames[index].decoded_payload[offset]);
    }
    if (av_new_packet(packet, static_cast<int>(payload.size())) < 0) {
      result = AVERROR(ENOMEM);
      break;
    }
    std::memcpy(packet->data, payload.data(), payload.size());
    packet->stream_index = stream->index;
    packet->pts = static_cast<std::int64_t>(index) * samples_per_frame;
    packet->dts = packet->pts;
    packet->duration = samples_per_frame;
    av_packet_rescale_ts(packet, carrier_time_base, stream->time_base);
    packet->pos = -1;
    result = av_interleaved_write_frame(destination, packet);
    av_packet_unref(packet);
    if (result >= 0) ++written;
  }
  if (result >= 0) result = av_write_trailer(destination);
  completed = result >= 0 && written == frames.size();
  cleanup();
  if (!completed) return "{\"error\":\"Dolby E bridge packet write failed\"}";
  std::ostringstream report;
  report << "{\"schema\":\"copy-report-v1\",\"packets\":" << written
         << ",\"timestamp_policy\":\"fresh-zero-based\",\"bridge\":\"smpte-337m-16le\","
            "\"lossless\":true,\"validated\":false,\"validation\":\"pending-final-output-audit\"}";
  return report.str();
}

static std::string validate_s337m_mkv_copy(const std::string& input, const std::string& output) {
  std::vector<S337mFrame> source_frames;
  std::string reason;
  if (!parse_s337m_16le(input, &source_frames, &reason))
    return "{\"schema\":\"copy-validation-report-v2\",\"status\":\"FAILED VALIDATION\","
           "\"reason\":\"SMPTE 337M parse failed: " + json_escape(reason) + "\"}";
  AVFormatContext* copy = nullptr;
  AVPacket* packet = av_packet_alloc();
  if (!packet || avformat_open_input(&copy, output.c_str(), nullptr, nullptr) < 0 ||
      avformat_find_stream_info(copy, nullptr) < 0) {
    av_packet_free(&packet);
    avformat_close_input(&copy);
    return "{\"schema\":\"copy-validation-report-v2\",\"status\":\"FAILED VALIDATION\","
           "\"reason\":\"bridge output open failed\"}";
  }
  int bridge_stream = -1;
  for (unsigned index = 0; index < copy->nb_streams; ++index) {
    AVCodecID origin = AV_CODEC_ID_NONE;
    if (bitstream_audio_origin(copy->streams[index], &origin) && origin == AV_CODEC_ID_DOLBY_E) {
      bridge_stream = static_cast<int>(index);
      break;
    }
  }
  std::vector<std::vector<std::uint8_t>> actual;
  std::size_t timing_violations = 0;
  std::int64_t last_dts = AV_NOPTS_VALUE;
  while (bridge_stream >= 0 && av_read_frame(copy, packet) >= 0) {
    if (packet->stream_index == bridge_stream) {
      actual.emplace_back(packet->data, packet->data + packet->size);
      if (packet->pts == AV_NOPTS_VALUE || packet->pts < 0 || packet->dts == AV_NOPTS_VALUE ||
          packet->dts < 0 || (last_dts != AV_NOPTS_VALUE && packet->dts < last_dts))
        ++timing_violations;
      last_dts = packet->dts;
    }
    av_packet_unref(packet);
  }
  std::size_t payload_mismatches = bridge_stream < 0 || actual.size() != source_frames.size() ? 1 : 0;
  for (std::size_t index = 0; index < std::min(actual.size(), source_frames.size()); ++index) {
    if ((source_frames[index].decoded_payload.size() & 1U) != 0U) {
      ++payload_mismatches;
      continue;
    }
    std::vector<std::uint8_t> expected = source_frames[index].carrier_header;
    for (std::size_t offset = 0; offset < source_frames[index].decoded_payload.size(); offset += 2) {
      expected.push_back(source_frames[index].decoded_payload[offset + 1]);
      expected.push_back(source_frames[index].decoded_payload[offset]);
    }
    if (actual[index] != expected) ++payload_mismatches;
  }
  const bool valid = payload_mismatches == 0 && timing_violations == 0;
  const auto actual_packets = actual.size();
  av_packet_free(&packet);
  avformat_close_input(&copy);
  std::ostringstream report;
  report << "{\"schema\":\"copy-validation-report-v2\",\"status\":\""
         << (valid ? "PASSED" : "FAILED VALIDATION") << "\",\"streams\":1,\"chapters\":0,"
         << "\"packets_compared\":" << actual_packets << ",\"mismatches\":"
         << payload_mismatches << ",\"metadata_mismatches\":" << (bridge_stream < 0 ? 1 : 0)
         << ",\"payload_mismatches\":" << payload_mismatches
         << ",\"timing_violations\":" << timing_violations
         << ",\"bridge\":\"smpte-337m-16le\",\"lossless\":true}";
  return report.str();
}
#endif
std::string copy_mkv_packets(const std::string& input, const std::string& output) {
#ifndef SMARTCUT_HAS_FFMPEG
  (void)input; (void)output; return "{\"error\":\"FFmpeg support is not enabled; configure with SMARTCUT_MEDIA_ROOT\"}";
#else
  if (std::filesystem::weakly_canonical(input) == std::filesystem::weakly_canonical(output)) return "{\"error\":\"source and output paths must differ\"}";
  if (is_s337m_path(input)) return copy_s337m_to_mkv(input, output);
  AVFormatContext* source = nullptr; AVFormatContext* destination = nullptr;
  if (!open_input_with_generated_pts(input, &source)) { avformat_close_input(&source); return "{\"error\":\"input open failed\"}"; }
  if (avformat_alloc_output_context2(&destination, nullptr, "matroska", output.c_str()) < 0 || !destination) { avformat_close_input(&source); return "{\"error\":\"output context failed\"}"; }
  av_dict_copy(&destination->metadata, source->metadata, 0);
  for (unsigned i = 0; i < source->nb_streams; ++i) {
    const auto* in_stream = source->streams[i];
    auto* out_stream = avformat_new_stream(destination, nullptr);
    if (!out_stream || avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar) < 0 ||
        !normalize_pcm_parameters_for_matroska(out_stream->codecpar)) {
      avformat_free_context(destination); avformat_close_input(&source);
      return "{\"error\":\"stream copy failed or PCM is not losslessly representable\"}";
    }
    out_stream->codecpar->codec_tag = 0;
    out_stream->time_base = in_stream->time_base;
    copy_stream_attributes(out_stream, in_stream);
    mark_pcm_bluray_origin(out_stream, in_stream);
    mark_bitstream_audio_origin(out_stream, in_stream);
  }
  copy_chapters(destination, source);
  if (!(destination->oformat->flags & AVFMT_NOFILE) && avio_open(&destination->pb, output.c_str(), AVIO_FLAG_WRITE) < 0) { avformat_free_context(destination); avformat_close_input(&source); return "{\"error\":\"output open failed\"}"; }
  destination->avoid_negative_ts = AVFMT_AVOID_NEG_TS_DISABLED;
  if (avformat_write_header(destination, nullptr) < 0) { if (!(destination->oformat->flags & AVFMT_NOFILE)) avio_closep(&destination->pb); avformat_free_context(destination); avformat_close_input(&source); return "{\"error\":\"header write failed\"}"; }
  std::int64_t timeline_base = std::numeric_limits<std::int64_t>::max(); AVPacket* packet = av_packet_alloc();
  while (packet && av_read_frame(source, packet) >= 0) { const auto* stream = source->streams[packet->stream_index]; if (packet->pts != AV_NOPTS_VALUE) timeline_base = std::min(timeline_base, av_rescale_q(packet->pts, stream->time_base, AV_TIME_BASE_Q)); if (packet->dts != AV_NOPTS_VALUE) timeline_base = std::min(timeline_base, av_rescale_q(packet->dts, stream->time_base, AV_TIME_BASE_Q)); av_packet_unref(packet); }
  avformat_close_input(&source); if (!packet || !open_input_with_generated_pts(input, &source)) { av_packet_free(&packet); if (!(destination->oformat->flags & AVFMT_NOFILE)) avio_closep(&destination->pb); avformat_free_context(destination); avformat_close_input(&source); return "{\"error\":\"input reopen failed\"}"; }
  std::size_t packets = 0; int result = 0;
  while (packet && av_read_frame(source, packet) >= 0) {
    const auto* in_stream = source->streams[packet->stream_index];
    auto* out_stream = destination->streams[packet->stream_index];
    if (!normalize_pcm_packet_for_matroska(packet, in_stream->codecpar)) { result = AVERROR_INVALIDDATA; av_packet_unref(packet); break; }
    av_packet_rescale_ts(packet, in_stream->time_base, out_stream->time_base);
    if (timeline_base != std::numeric_limits<std::int64_t>::max()) {
      const auto offset = av_rescale_q(timeline_base, AV_TIME_BASE_Q, out_stream->time_base);
      if (packet->pts != AV_NOPTS_VALUE) packet->pts -= offset;
      if (packet->dts != AV_NOPTS_VALUE) packet->dts -= offset;
    }
    packet->pos = -1; result = av_write_frame(destination, packet); av_packet_unref(packet);
    if (result < 0) break;
    ++packets;
  }
  av_packet_free(&packet); if (result >= 0) result = av_write_trailer(destination); if (!(destination->oformat->flags & AVFMT_NOFILE)) avio_closep(&destination->pb); avformat_free_context(destination); avformat_close_input(&source);
  if (result < 0) return "{\"error\":\"packet copy failed\"}";
  std::ostringstream report; report << "{\"schema\":\"copy-report-v1\",\"packets\":" << packets << ",\"timestamp_policy\":\"fresh-zero-based\",\"validated\":false,\"validation\":\"pending-final-output-audit\"}"; return report.str();
#endif
}

std::string copy_mkv_keyframe_range(const std::string& input, const std::string& output, std::size_t first_video_packet, std::size_t end_video_packet) {
#ifndef SMARTCUT_HAS_FFMPEG
  (void)input; (void)output; (void)first_video_packet; (void)end_video_packet;
  return "{\"error\":\"FFmpeg support is not enabled; configure with SMARTCUT_MEDIA_ROOT\"}";
#else
  if (end_video_packet <= first_video_packet) return "{\"error\":\"end video packet must be greater than first video packet\"}";
  if (std::filesystem::weakly_canonical(input) == std::filesystem::weakly_canonical(output)) return "{\"error\":\"source and output paths must differ\"}";
  AVFormatContext* source = nullptr;
  AVFormatContext* destination = nullptr;
  if (avformat_open_input(&source, input.c_str(), nullptr, nullptr) < 0 || avformat_find_stream_info(source, nullptr) < 0) { avformat_close_input(&source); return "{\"error\":\"input open failed\"}"; }
  int video_stream = -1;
  for (unsigned i = 0; i < source->nb_streams; ++i) if (source->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { video_stream = static_cast<int>(i); break; }
  if (video_stream < 0) { avformat_close_input(&source); return "{\"error\":\"video stream not found\"}"; }
  if (avformat_alloc_output_context2(&destination, nullptr, "matroska", output.c_str()) < 0 || !destination) { avformat_close_input(&source); return "{\"error\":\"output context failed\"}"; }
  av_dict_copy(&destination->metadata, source->metadata, 0);
  for (unsigned i = 0; i < source->nb_streams; ++i) { const auto* in_stream = source->streams[i]; auto* out_stream = avformat_new_stream(destination, nullptr); if (!out_stream || avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar) < 0) { avformat_free_context(destination); avformat_close_input(&source); return "{\"error\":\"stream copy failed\"}"; } out_stream->codecpar->codec_tag = 0; out_stream->time_base = in_stream->time_base; copy_stream_attributes(out_stream, in_stream); }
  copy_chapters(destination, source);
  if (!(destination->oformat->flags & AVFMT_NOFILE) && avio_open(&destination->pb, output.c_str(), AVIO_FLAG_WRITE) < 0) { avformat_free_context(destination); avformat_close_input(&source); return "{\"error\":\"output open failed\"}"; }
  if (avformat_write_header(destination, nullptr) < 0) { if (!(destination->oformat->flags & AVFMT_NOFILE)) avio_closep(&destination->pb); avformat_free_context(destination); avformat_close_input(&source); return "{\"error\":\"header write failed\"}"; }
  AVPacket* packet = av_packet_alloc(); std::size_t video_packet = 0; std::size_t copied_video_packets = 0; bool first_is_key = false; std::int64_t timeline_base = std::numeric_limits<std::int64_t>::max(); int result = 0;
  while (packet && av_read_frame(source, packet) >= 0) {
    const bool is_video = packet->stream_index == video_stream;
    const bool selected = !is_video || (video_packet >= first_video_packet && video_packet < end_video_packet);
    if (is_video) { if (video_packet == first_video_packet) first_is_key = (packet->flags & AV_PKT_FLAG_KEY) != 0; ++video_packet; }
    if (selected) { const auto* in_stream = source->streams[packet->stream_index]; auto* out_stream = destination->streams[packet->stream_index]; if (timeline_base == std::numeric_limits<std::int64_t>::max()) { if (packet->pts != AV_NOPTS_VALUE) timeline_base = std::min(timeline_base, av_rescale_q(packet->pts, in_stream->time_base, AV_TIME_BASE_Q)); if (packet->dts != AV_NOPTS_VALUE) timeline_base = std::min(timeline_base, av_rescale_q(packet->dts, in_stream->time_base, AV_TIME_BASE_Q)); } av_packet_rescale_ts(packet, in_stream->time_base, out_stream->time_base); if (timeline_base != std::numeric_limits<std::int64_t>::max()) { const auto offset = av_rescale_q(timeline_base, AV_TIME_BASE_Q, out_stream->time_base); if (packet->pts != AV_NOPTS_VALUE) packet->pts -= offset; if (packet->dts != AV_NOPTS_VALUE) packet->dts -= offset; } packet->pos = -1; result = av_write_frame(destination, packet); if (is_video && result >= 0) ++copied_video_packets; }
    av_packet_unref(packet); if (result < 0) break;
    if (video_packet >= end_video_packet && is_video) break;
  }
  av_packet_free(&packet);
  if (!first_is_key) result = -2;
  if (result >= 0) result = av_write_trailer(destination);
  if (!(destination->oformat->flags & AVFMT_NOFILE)) avio_closep(&destination->pb);
  avformat_free_context(destination); avformat_close_input(&source);
  if (result == -2) { std::error_code ignored; std::filesystem::remove(output, ignored); return "{\"error\":\"first selected video packet is not keyframe-marked\"}"; }
  if (result < 0) { std::error_code ignored; std::filesystem::remove(output, ignored); return "{\"error\":\"packet range copy failed\"}"; }
  std::ostringstream report; report << "{\"schema\":\"copy-range-report-v1\",\"first_video_packet\":" << first_video_packet << ",\"end_video_packet\":" << end_video_packet << ",\"copied_video_packets\":" << copied_video_packets << ",\"audio_policy\":\"source-packets-interleaved-before-range-end\",\"validated\":false,\"validation\":\"pending-final-output-audit\"}"; return report.str();
#endif
}

std::string validate_mkv_copy(const std::string& input, const std::string& output) {
#ifndef SMARTCUT_HAS_FFMPEG
  (void)input; (void)output; return "{\"schema\":\"copy-validation-report-v1\",\"status\":\"FAILED VALIDATION\",\"reason\":\"FFmpeg support is not enabled\"}";
#else
  if (is_s337m_path(input)) return validate_s337m_mkv_copy(input, output);
  AVFormatContext* source = nullptr; AVFormatContext* copy = nullptr;
  if (!open_input_with_generated_pts(input, &source) || avformat_open_input(&copy, output.c_str(), nullptr, nullptr) < 0 || avformat_find_stream_info(copy, nullptr) < 0) { avformat_close_input(&source); avformat_close_input(&copy); return "{\"schema\":\"copy-validation-report-v1\",\"status\":\"FAILED VALIDATION\",\"reason\":\"input or output open failed\"}"; }
  bool metadata_match = source->nb_streams == copy->nb_streams && source->nb_chapters == copy->nb_chapters && metadata_subset(source->metadata, copy->metadata);
  // Matroska selects its own stream time base (normally milliseconds), so a
  // cross-container remux cannot require the source time-base rational to be
  // retained. Packet timestamp monotonicity is audited independently below.
  for (unsigned i = 0; metadata_match && i < source->nb_streams; ++i) { const auto* source_stream = source->streams[i]; const auto* copy_stream = copy->streams[i]; const auto* a = source_stream->codecpar; const auto* b = copy_stream->codecpar; const bool bitstream_bridge = a->codec_id == AV_CODEC_ID_DOLBY_E || a->codec_id == AV_CODEC_ID_S302M; metadata_match = matroska_codec_equivalent(a, b) && a->width == b->width && a->height == b->height && (bitstream_bridge || a->sample_rate == b->sample_rate) && (bitstream_bridge || a->ch_layout.nb_channels == b->ch_layout.nb_channels) && source_stream->disposition == copy_stream->disposition && a->extradata_size == b->extradata_size && (a->extradata_size == 0 || std::memcmp(a->extradata, b->extradata, static_cast<std::size_t>(a->extradata_size)) == 0) && metadata_subset(source_stream->metadata, copy_stream->metadata); }
  for (unsigned i = 0; metadata_match && i < source->nb_chapters; ++i) { const auto* a = source->chapters[i]; const auto* b = copy->chapters[i]; metadata_match = a->id == b->id && a->time_base.num == b->time_base.num && a->time_base.den == b->time_base.den && a->start == b->start && a->end == b->end && metadata_subset(a->metadata, b->metadata); }
  AVPacket* packet = av_packet_alloc(); std::vector<std::vector<std::vector<std::uint8_t>>> source_packets(source->nb_streams); std::vector<std::vector<std::vector<std::uint8_t>>> copy_packets(copy->nb_streams); std::size_t packets = 0; std::size_t metadata_mismatches = metadata_match ? 0 : 1; std::size_t payload_mismatches = 0; std::size_t timing_violations = 0; std::vector<std::int64_t> last_dts(copy->nb_streams, AV_NOPTS_VALUE);
  while (packet && av_read_frame(source, packet) >= 0) { const auto stream = static_cast<std::size_t>(packet->stream_index); source_packets[stream].push_back(matroska_normalized_payload(packet, source->streams[stream]->codecpar)); av_packet_unref(packet); }
  av_packet_unref(packet);
  while (packet && av_read_frame(copy, packet) >= 0) { const auto stream = static_cast<std::size_t>(packet->stream_index); copy_packets[stream].emplace_back(packet->data, packet->data + packet->size); ++packets; if (packet->pts != AV_NOPTS_VALUE && packet->pts < 0) ++timing_violations; if (packet->dts != AV_NOPTS_VALUE && (packet->dts < 0 || (last_dts[stream] != AV_NOPTS_VALUE && packet->dts < last_dts[stream]))) ++timing_violations; if (packet->dts != AV_NOPTS_VALUE) last_dts[stream] = packet->dts; av_packet_unref(packet); }
  std::size_t first_payload_stream = std::numeric_limits<std::size_t>::max(); std::size_t first_payload_index = std::numeric_limits<std::size_t>::max(); for (std::size_t stream = 0; stream < source_packets.size() && stream < copy_packets.size(); ++stream) { if (source_packets[stream].size() != copy_packets[stream].size()) { ++payload_mismatches; if (first_payload_stream == std::numeric_limits<std::size_t>::max()) { first_payload_stream = stream; first_payload_index = std::min(source_packets[stream].size(), copy_packets[stream].size()); } continue; } for (std::size_t index = 0; index < source_packets[stream].size(); ++index) if (source_packets[stream][index] != copy_packets[stream][index]) { ++payload_mismatches; if (first_payload_stream == std::numeric_limits<std::size_t>::max()) { first_payload_stream = stream; first_payload_index = index; } } }
  const auto stream_count = copy->nb_streams;
  const auto chapter_count = copy->nb_chapters;
  av_packet_free(&packet); avformat_close_input(&source); avformat_close_input(&copy);
  const std::size_t mismatches = metadata_mismatches + payload_mismatches; const bool passed = mismatches == 0 && timing_violations == 0;
  std::ostringstream report; report << "{\"schema\":\"copy-validation-report-v2\",\"status\":\"" << (passed ? "PASSED" : "FAILED VALIDATION") << "\",\"streams\":" << stream_count << ",\"chapters\":" << chapter_count << ",\"packets_compared\":" << packets << ",\"mismatches\":" << mismatches << ",\"metadata_mismatches\":" << metadata_mismatches << ",\"payload_mismatches\":" << payload_mismatches << ",\"first_payload_stream\":" << (first_payload_stream == std::numeric_limits<std::size_t>::max() ? 0 : first_payload_stream) << ",\"first_payload_index\":" << (first_payload_index == std::numeric_limits<std::size_t>::max() ? 0 : first_payload_index) << ",\"timing_violations\":" << timing_violations << "}"; return report.str();
#endif
}

std::string copy_mkv_audio_window(const std::string& input, const std::string& output, std::int64_t video_start_pts, std::int64_t video_end_pts) {
#ifndef SMARTCUT_HAS_FFMPEG
  (void)input; (void)output; (void)video_start_pts; (void)video_end_pts; return "{\"error\":\"FFmpeg support is not enabled; configure with SMARTCUT_MEDIA_ROOT\"}";
#else
  if (video_end_pts <= video_start_pts) return "{\"error\":\"video end PTS must be greater than video start PTS\"}";
  if (std::filesystem::weakly_canonical(input) == std::filesystem::weakly_canonical(output)) return "{\"error\":\"source and output paths must differ\"}";
  AVFormatContext* source = nullptr; AVFormatContext* destination = nullptr; AVPacket* packet = av_packet_alloc(); int audio_stream = -1; std::size_t selected = 0; std::int64_t first_pts = AV_NOPTS_VALUE; std::int64_t last_end = AV_NOPTS_VALUE; int result = 0; bool completed = false; auto cleanup = [&] { av_packet_free(&packet); avformat_close_input(&source); if (destination && destination->pb) avio_closep(&destination->pb); avformat_free_context(destination); if (!completed) { std::error_code ignored; std::filesystem::remove(output, ignored); } };
  if (avformat_open_input(&source, input.c_str(), nullptr, nullptr) < 0 || avformat_find_stream_info(source, nullptr) < 0) { cleanup(); return "{\"error\":\"input open failed\"}"; }
  for (unsigned i = 0; i < source->nb_streams; ++i) if (source->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { audio_stream = static_cast<int>(i); break; }
  if (audio_stream < 0) { cleanup(); return "{\"error\":\"audio stream not found\"}"; }
  if (avformat_alloc_output_context2(&destination, nullptr, "matroska", output.c_str()) < 0 || !destination) { cleanup(); return "{\"error\":\"output context failed\"}"; }
  const auto* input_stream = source->streams[audio_stream]; auto* output_stream = avformat_new_stream(destination, nullptr); if (!output_stream || avcodec_parameters_copy(output_stream->codecpar, input_stream->codecpar) < 0 || !normalize_pcm_parameters_for_matroska(output_stream->codecpar)) { cleanup(); return "{\"error\":\"audio stream copy failed or PCM is not losslessly representable\"}"; } output_stream->codecpar->codec_tag = 0; output_stream->time_base = input_stream->time_base; output_stream->disposition = input_stream->disposition; av_dict_copy(&destination->metadata, source->metadata, 0); av_dict_copy(&output_stream->metadata, input_stream->metadata, 0); mark_pcm_bluray_origin(output_stream, input_stream); mark_bitstream_audio_origin(output_stream, input_stream);
  if (!(destination->oformat->flags & AVFMT_NOFILE) && avio_open(&destination->pb, output.c_str(), AVIO_FLAG_WRITE) < 0) { cleanup(); return "{\"error\":\"output open failed\"}"; } if (avformat_write_header(destination, nullptr) < 0) { cleanup(); return "{\"error\":\"output header failed\"}"; }
  while (packet && av_read_frame(source, packet) >= 0) { if (packet->stream_index == audio_stream && packet->pts != AV_NOPTS_VALUE) { const auto duration = packet->duration > 0 ? packet->duration : 1; const auto packet_end = packet->pts + duration; if (packet_end > video_start_pts && packet->pts < video_end_pts) { if (first_pts == AV_NOPTS_VALUE) first_pts = packet->pts; last_end = packet_end; if (!normalize_pcm_packet_for_matroska(packet, input_stream->codecpar)) result = -1; if (result == 0) { av_packet_rescale_ts(packet, input_stream->time_base, output_stream->time_base); const auto offset = av_rescale_q(first_pts, input_stream->time_base, output_stream->time_base); if (packet->pts != AV_NOPTS_VALUE) packet->pts -= offset; if (packet->dts != AV_NOPTS_VALUE) packet->dts -= offset; packet->stream_index = output_stream->index; if (av_write_frame(destination, packet) < 0) result = -1; else ++selected; } } } av_packet_unref(packet); if (result < 0) break; }
  if (result == 0 && av_write_trailer(destination) < 0) result = -1;
  if (result == 0) completed = true;
  cleanup();
  if (result < 0) return "{\"error\":\"audio packet copy failed\"}";
  std::ostringstream report; report << "{\"schema\":\"audio-copy-report-v1\",\"audio_stream\":0,\"selected_packets\":" << selected << ",\"source_first_pts\":" << (first_pts == AV_NOPTS_VALUE ? 0 : first_pts) << ",\"output_retime_first_pts\":0,\"last_source_packet_end_pts\":" << (last_end == AV_NOPTS_VALUE ? 0 : last_end) << ",\"video_start_pts\":" << video_start_pts << ",\"video_end_pts\":" << video_end_pts << ",\"policy\":\"complete-audio-frame-overlap-retimed-to-zero\",\"validation\":\"pending-output-audit\"}"; return report.str();
#endif
}

std::string validate_mkv_audio_copy(const std::string& input, const std::string& output, std::int64_t video_start_pts, std::int64_t video_end_pts) {
#ifndef SMARTCUT_HAS_FFMPEG
  (void)input; (void)output; (void)video_start_pts; (void)video_end_pts; return "{\"error\":\"FFmpeg support is not enabled; configure with SMARTCUT_MEDIA_ROOT\"}";
#else
  AVFormatContext* source = nullptr; AVFormatContext* copy = nullptr; AVPacket* packet = av_packet_alloc(); std::vector<std::vector<std::uint8_t>> expected; std::vector<std::vector<std::uint8_t>> actual; std::vector<std::int64_t> pts; std::size_t timing_violations = 0; auto cleanup = [&] { av_packet_free(&packet); avformat_close_input(&source); avformat_close_input(&copy); };
  if (avformat_open_input(&source, input.c_str(), nullptr, nullptr) < 0 || avformat_find_stream_info(source, nullptr) < 0 || avformat_open_input(&copy, output.c_str(), nullptr, nullptr) < 0 || avformat_find_stream_info(copy, nullptr) < 0) { cleanup(); return "{\"error\":\"audio validation input open failed\"}"; }
  int source_stream = -1; int copy_stream = -1;
  for (unsigned i = 0; i < source->nb_streams; ++i) if (source->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { source_stream = static_cast<int>(i); break; }
  for (unsigned i = 0; i < copy->nb_streams; ++i) if (copy->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { copy_stream = static_cast<int>(i); break; }
  if (source_stream < 0 || copy_stream < 0) { cleanup(); return "{\"error\":\"audio validation stream not found\"}"; }
  while (packet && av_read_frame(source, packet) >= 0) { if (packet->stream_index == source_stream && packet->pts != AV_NOPTS_VALUE) { const auto duration = packet->duration > 0 ? packet->duration : 1; if (packet->pts + duration > video_start_pts && packet->pts < video_end_pts) expected.push_back(matroska_normalized_payload(packet, source->streams[source_stream]->codecpar)); } av_packet_unref(packet); }
  av_packet_unref(packet); while (packet && av_read_frame(copy, packet) >= 0) { if (packet->stream_index == copy_stream) { actual.emplace_back(packet->data, packet->data + packet->size); pts.push_back(packet->pts); } av_packet_unref(packet); }
  std::size_t mismatches = expected.size() == actual.size() ? 0 : 1; const auto comparable = std::min(expected.size(), actual.size()); for (std::size_t i = 0; i < comparable; ++i) if (expected[i] != actual[i]) ++mismatches; std::int64_t last = AV_NOPTS_VALUE; for (const auto value : pts) { if (value == AV_NOPTS_VALUE || value < 0 || (last != AV_NOPTS_VALUE && value < last)) ++timing_violations; last = value; }
  const bool passed = mismatches == 0 && timing_violations == 0; const auto source_identity = smartcut::core::SourceIdentity::from_file(input); const auto output_identity = smartcut::core::SourceIdentity::from_file(output); cleanup(); std::ostringstream report; report << "{\"schema\":\"audio-copy-validation-report-v1\",\"status\":\"" << (passed ? "PASSED" : "FAILED VALIDATION") << "\",\"source_uuid\":\"" << source_identity.source_uuid << "\",\"output_uuid\":\"" << output_identity.source_uuid << "\",\"expected_packets\":" << expected.size() << ",\"actual_packets\":" << actual.size() << ",\"payload_mismatches\":" << mismatches << ",\"timing_violations\":" << timing_violations << "}"; return report.str();
#endif
}

std::string mux_mkv_video_audio(const std::string& video, const std::string& audio, const std::string& output) {
#ifndef SMARTCUT_HAS_FFMPEG
  (void)video; (void)audio; (void)output; return "{\"error\":\"FFmpeg support is not enabled; configure with SMARTCUT_MEDIA_ROOT\"}";
#else
  AVFormatContext* video_input = nullptr; AVFormatContext* audio_input = nullptr; AVFormatContext* destination = nullptr; AVPacket* packet = av_packet_alloc(); int video_stream = -1; int audio_stream = -1; int result = 0; std::size_t video_packets = 0; std::size_t audio_packets = 0; bool completed = false; auto cleanup = [&] { av_packet_free(&packet); avformat_close_input(&video_input); avformat_close_input(&audio_input); if (destination && destination->pb) avio_closep(&destination->pb); avformat_free_context(destination); if (!completed) { std::error_code ignored; std::filesystem::remove(output, ignored); } };
  if (std::filesystem::weakly_canonical(video) == std::filesystem::weakly_canonical(output) || std::filesystem::weakly_canonical(audio) == std::filesystem::weakly_canonical(output)) return "{\"error\":\"source and output paths must differ\"}";
  if (avformat_open_input(&video_input, video.c_str(), nullptr, nullptr) < 0 || avformat_find_stream_info(video_input, nullptr) < 0 || avformat_open_input(&audio_input, audio.c_str(), nullptr, nullptr) < 0 || avformat_find_stream_info(audio_input, nullptr) < 0) { cleanup(); return "{\"error\":\"video or audio input open failed\"}"; }
  for (unsigned i = 0; i < video_input->nb_streams; ++i) if (video_input->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { video_stream = static_cast<int>(i); break; }
  for (unsigned i = 0; i < audio_input->nb_streams; ++i) if (audio_input->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { audio_stream = static_cast<int>(i); break; }
  if (video_stream < 0 || audio_stream < 0) { cleanup(); return "{\"error\":\"video or audio stream not found\"}"; }
  if (avformat_alloc_output_context2(&destination, nullptr, "matroska", output.c_str()) < 0 || !destination) { cleanup(); return "{\"error\":\"output context failed\"}"; }
  auto* output_video = avformat_new_stream(destination, nullptr); auto* output_audio = avformat_new_stream(destination, nullptr); if (!output_video || !output_audio || avcodec_parameters_copy(output_video->codecpar, video_input->streams[video_stream]->codecpar) < 0 || avcodec_parameters_copy(output_audio->codecpar, audio_input->streams[audio_stream]->codecpar) < 0) { cleanup(); return "{\"error\":\"output stream setup failed\"}"; } output_video->time_base = video_input->streams[video_stream]->time_base; output_audio->time_base = audio_input->streams[audio_stream]->time_base; av_dict_copy(&destination->metadata, video_input->metadata, 0);
  if (!(destination->oformat->flags & AVFMT_NOFILE) && avio_open(&destination->pb, output.c_str(), AVIO_FLAG_WRITE) < 0) { cleanup(); return "{\"error\":\"output open failed\"}"; } if (avformat_write_header(destination, nullptr) < 0) { cleanup(); return "{\"error\":\"output header failed\"}"; }
  while (packet && av_read_frame(video_input, packet) >= 0) { if (packet->stream_index == video_stream) { av_packet_rescale_ts(packet, video_input->streams[video_stream]->time_base, output_video->time_base); packet->stream_index = output_video->index; if (av_write_frame(destination, packet) < 0) result = -1; else ++video_packets; } av_packet_unref(packet); if (result < 0) break; }
  while (result == 0 && packet && av_read_frame(audio_input, packet) >= 0) { if (packet->stream_index == audio_stream) { av_packet_rescale_ts(packet, audio_input->streams[audio_stream]->time_base, output_audio->time_base); packet->stream_index = output_audio->index; if (av_write_frame(destination, packet) < 0) result = -1; else ++audio_packets; } av_packet_unref(packet); if (result < 0) break; }
  if (result == 0 && av_write_trailer(destination) < 0) result = -1;
  if (result == 0) completed = true;
  cleanup();
  if (result < 0) return "{\"error\":\"video/audio mux failed\"}";
  std::ostringstream report; report << "{\"schema\":\"mux-report-v1\",\"video_packets\":" << video_packets << ",\"audio_packets\":" << audio_packets << ",\"audio_policy\":\"validated-retimed-audio-window\",\"validation\":\"pending-final-output-audit\"}"; return report.str();
#endif
}

std::string validate_mkv_video_audio(const std::string& video, const std::string& audio, const std::string& output) {
#ifndef SMARTCUT_HAS_FFMPEG
  (void)video; (void)audio; (void)output; return "{\"error\":\"FFmpeg support is not enabled; configure with SMARTCUT_MEDIA_ROOT\"}";
#else
  AVFormatContext* video_input = nullptr; AVFormatContext* audio_input = nullptr; AVFormatContext* combined = nullptr; AVPacket* packet = av_packet_alloc(); std::vector<std::vector<std::uint8_t>> expected_video; std::vector<std::vector<std::uint8_t>> expected_audio; std::vector<std::vector<std::uint8_t>> actual_video; std::vector<std::vector<std::uint8_t>> actual_audio; std::size_t timing_violations = 0; auto cleanup = [&] { av_packet_free(&packet); avformat_close_input(&video_input); avformat_close_input(&audio_input); avformat_close_input(&combined); };
  if (avformat_open_input(&video_input, video.c_str(), nullptr, nullptr) < 0 || avformat_find_stream_info(video_input, nullptr) < 0 || avformat_open_input(&audio_input, audio.c_str(), nullptr, nullptr) < 0 || avformat_find_stream_info(audio_input, nullptr) < 0 || avformat_open_input(&combined, output.c_str(), nullptr, nullptr) < 0 || avformat_find_stream_info(combined, nullptr) < 0) { cleanup(); return "{\"error\":\"combined output validation open failed\"}"; }
  int source_video = -1; int source_audio = -1; int output_video = -1; int output_audio = -1;
  for (unsigned i = 0; i < video_input->nb_streams; ++i) if (video_input->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { source_video = static_cast<int>(i); break; }
  for (unsigned i = 0; i < audio_input->nb_streams; ++i) if (audio_input->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { source_audio = static_cast<int>(i); break; }
  for (unsigned i = 0; i < combined->nb_streams; ++i) { if (combined->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) output_video = static_cast<int>(i); if (combined->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) output_audio = static_cast<int>(i); }
  if (source_video < 0 || source_audio < 0 || output_video < 0 || output_audio < 0) { cleanup(); return "{\"error\":\"combined output stream missing\"}"; }
  while (packet && av_read_frame(video_input, packet) >= 0) { if (packet->stream_index == source_video) expected_video.emplace_back(packet->data, packet->data + packet->size); av_packet_unref(packet); } av_packet_unref(packet); while (packet && av_read_frame(audio_input, packet) >= 0) { if (packet->stream_index == source_audio) expected_audio.emplace_back(packet->data, packet->data + packet->size); av_packet_unref(packet); } av_packet_unref(packet);
  std::int64_t last_video_dts = AV_NOPTS_VALUE; std::int64_t last_audio_dts = AV_NOPTS_VALUE; while (packet && av_read_frame(combined, packet) >= 0) { if (packet->stream_index == output_video) { actual_video.emplace_back(packet->data, packet->data + packet->size); if (packet->pts < 0 || packet->dts < 0 || (last_video_dts != AV_NOPTS_VALUE && packet->dts < last_video_dts)) ++timing_violations; last_video_dts = packet->dts; } else if (packet->stream_index == output_audio) { actual_audio.emplace_back(packet->data, packet->data + packet->size); if (packet->pts < 0 || packet->dts < 0 || (last_audio_dts != AV_NOPTS_VALUE && packet->dts < last_audio_dts)) ++timing_violations; last_audio_dts = packet->dts; } av_packet_unref(packet); }
  std::size_t payload_mismatches = expected_video.size() == actual_video.size() && expected_audio.size() == actual_audio.size() ? 0 : 1; for (std::size_t i = 0; i < std::min(expected_video.size(), actual_video.size()); ++i) if (expected_video[i] != actual_video[i]) ++payload_mismatches; for (std::size_t i = 0; i < std::min(expected_audio.size(), actual_audio.size()); ++i) if (expected_audio[i] != actual_audio[i]) ++payload_mismatches; const bool passed = payload_mismatches == 0 && timing_violations == 0; const auto output_identity = smartcut::core::SourceIdentity::from_file(output); cleanup(); std::ostringstream report; report << "{\"schema\":\"av-validation-report-v1\",\"status\":\"" << (passed ? "PASSED" : "FAILED VALIDATION") << "\",\"output_uuid\":\"" << output_identity.source_uuid << "\",\"expected_video_packets\":" << expected_video.size() << ",\"actual_video_packets\":" << actual_video.size() << ",\"expected_audio_packets\":" << expected_audio.size() << ",\"actual_audio_packets\":" << actual_audio.size() << ",\"payload_mismatches\":" << payload_mismatches << ",\"timing_violations\":" << timing_violations << "}"; return report.str();
#endif
}

std::string export_mkv(const std::string& input, const std::string& output) {
  const auto copy = copy_mkv_packets(input, output);
  if (copy.find("\"error\"") != std::string::npos) return "{\"schema\":\"export-report-v1\",\"status\":\"FAILED\",\"phase\":\"copy\"}";
  const auto validation = validate_mkv_copy(input, output);
  const bool passed = validation.find("\"status\":\"PASSED\"") != std::string::npos;
  std::ostringstream report;
  report << "{\"schema\":\"export-report-v1\",\"status\":\"" << (passed ? "PASSED" : "FAILED VALIDATION") << "\",\"copy_completed\":true,\"validation_passed\":" << (passed ? "true" : "false") << "}";
  return report.str();
}

std::string export_mkv_selected_streams(const std::string& input, const std::string& output,
                                        const std::vector<std::size_t>& requested_streams) {
#ifndef SMARTCUT_HAS_FFMPEG
  (void)input; (void)output; (void)requested_streams;
  return "{\"schema\":\"selected-stream-export-v1\",\"status\":\"FAILED\",\"reason\":\"FFmpeg support is not enabled\"}";
#else
  if (std::filesystem::weakly_canonical(input) == std::filesystem::weakly_canonical(output))
    return "{\"schema\":\"selected-stream-export-v1\",\"status\":\"FAILED\",\"reason\":\"source and output paths must differ\"}";
  AVFormatContext* source = nullptr; AVFormatContext* destination = nullptr;
  if (!open_input_with_generated_pts(input, &source)) { avformat_close_input(&source); return "{\"schema\":\"selected-stream-export-v1\",\"status\":\"FAILED\",\"reason\":\"input open failed\"}"; }
  auto selected = requested_streams; std::sort(selected.begin(), selected.end()); selected.erase(std::unique(selected.begin(), selected.end()), selected.end());
  const bool indexes_valid = !selected.empty() && std::all_of(selected.begin(), selected.end(), [source](std::size_t index) { return index < source->nb_streams; });
  if (!indexes_valid) { avformat_close_input(&source); return "{\"schema\":\"selected-stream-export-v1\",\"status\":\"FAILED\",\"reason\":\"selection requires at least one valid media stream index\"}"; }
  if (avformat_alloc_output_context2(&destination, nullptr, "matroska", output.c_str()) < 0 || !destination) { avformat_close_input(&source); return "{\"schema\":\"selected-stream-export-v1\",\"status\":\"FAILED\",\"reason\":\"output context failed\"}"; }
  av_dict_copy(&destination->metadata, source->metadata, 0); std::vector<int> mapping(source->nb_streams, -1);
  bool setup_ok = true;
  for (const auto source_index : selected) { const auto* input_stream = source->streams[source_index]; auto* output_stream = avformat_new_stream(destination, nullptr); if (!output_stream || avcodec_parameters_copy(output_stream->codecpar, input_stream->codecpar) < 0 || !normalize_pcm_parameters_for_matroska(output_stream->codecpar)) { setup_ok = false; break; } output_stream->codecpar->codec_tag = 0; output_stream->time_base = input_stream->time_base; copy_stream_attributes(output_stream, input_stream); mark_pcm_bluray_origin(output_stream, input_stream); mark_bitstream_audio_origin(output_stream, input_stream); mapping[source_index] = output_stream->index; }
  copy_chapters(destination, source);
  if (!setup_ok || (!(destination->oformat->flags & AVFMT_NOFILE) && avio_open(&destination->pb, output.c_str(), AVIO_FLAG_WRITE) < 0) || avformat_write_header(destination, nullptr) < 0) { if (destination && !(destination->oformat->flags & AVFMT_NOFILE)) avio_closep(&destination->pb); avformat_free_context(destination); avformat_close_input(&source); return "{\"schema\":\"selected-stream-export-v1\",\"status\":\"FAILED\",\"reason\":\"output setup failed\"}"; }
  AVPacket* packet = av_packet_alloc(); std::int64_t timeline_base = std::numeric_limits<std::int64_t>::max();
  while (packet && av_read_frame(source, packet) >= 0) { if (mapping[static_cast<std::size_t>(packet->stream_index)] >= 0) { const auto* stream = source->streams[packet->stream_index]; if (packet->pts != AV_NOPTS_VALUE) timeline_base = std::min(timeline_base, av_rescale_q(packet->pts, stream->time_base, AV_TIME_BASE_Q)); if (packet->dts != AV_NOPTS_VALUE) timeline_base = std::min(timeline_base, av_rescale_q(packet->dts, stream->time_base, AV_TIME_BASE_Q)); } av_packet_unref(packet); }
  avformat_close_input(&source); int result = packet && open_input_with_generated_pts(input, &source) ? 0 : -1; std::size_t packet_count = 0;
  while (result >= 0 && packet && av_read_frame(source, packet) >= 0) { const auto source_index = static_cast<std::size_t>(packet->stream_index); if (mapping[source_index] < 0) { av_packet_unref(packet); continue; } const auto* input_stream = source->streams[source_index]; auto* output_stream = destination->streams[static_cast<std::size_t>(mapping[source_index])]; if (!normalize_pcm_packet_for_matroska(packet, input_stream->codecpar)) { result = AVERROR_INVALIDDATA; av_packet_unref(packet); break; } av_packet_rescale_ts(packet, input_stream->time_base, output_stream->time_base); if (timeline_base != std::numeric_limits<std::int64_t>::max()) { const auto offset = av_rescale_q(timeline_base, AV_TIME_BASE_Q, output_stream->time_base); if (packet->pts != AV_NOPTS_VALUE) packet->pts -= offset; if (packet->dts != AV_NOPTS_VALUE) packet->dts -= offset; } packet->stream_index = output_stream->index; packet->pos = -1; result = av_write_frame(destination, packet); av_packet_unref(packet); if (result >= 0) ++packet_count; }
  av_packet_free(&packet); if (result >= 0) result = av_write_trailer(destination); if (!(destination->oformat->flags & AVFMT_NOFILE)) avio_closep(&destination->pb); avformat_free_context(destination); avformat_close_input(&source);
  if (result < 0) { std::error_code ignored; std::filesystem::remove(output, ignored); return "{\"schema\":\"selected-stream-export-v1\",\"status\":\"FAILED\",\"reason\":\"packet copy failed\"}"; }

  AVFormatContext* expected = nullptr; AVFormatContext* actual = nullptr; bool valid = avformat_open_input(&expected, input.c_str(), nullptr, nullptr) >= 0 && avformat_find_stream_info(expected, nullptr) >= 0 && avformat_open_input(&actual, output.c_str(), nullptr, nullptr) >= 0 && avformat_find_stream_info(actual, nullptr) >= 0 && actual->nb_streams == selected.size() && actual->nb_chapters == expected->nb_chapters && metadata_subset(expected->metadata, actual->metadata);
  for (std::size_t output_index = 0; valid && output_index < selected.size(); ++output_index) { const auto* a_stream = expected->streams[selected[output_index]]; const auto* b_stream = actual->streams[output_index]; const auto* a = a_stream->codecpar; const auto* b = b_stream->codecpar; valid = matroska_codec_equivalent(a, b) && a->codec_type == b->codec_type && a->extradata_size == b->extradata_size && (a->extradata_size == 0 || std::memcmp(a->extradata, b->extradata, static_cast<std::size_t>(a->extradata_size)) == 0) && metadata_subset(a_stream->metadata, b_stream->metadata); }
  std::vector<std::vector<std::vector<std::uint8_t>>> expected_packets(selected.size()), actual_packets(selected.size()); std::vector<int> selected_mapping(expected ? expected->nb_streams : 0, -1); for (std::size_t i = 0; i < selected.size() && i < selected_mapping.size(); ++i) selected_mapping[selected[i]] = static_cast<int>(i); packet = av_packet_alloc();
  while (valid && packet && av_read_frame(expected, packet) >= 0) { const auto source_index = static_cast<std::size_t>(packet->stream_index); const auto mapped = selected_mapping[source_index]; if (mapped >= 0) expected_packets[static_cast<std::size_t>(mapped)].push_back(matroska_normalized_payload(packet, expected->streams[source_index]->codecpar)); av_packet_unref(packet); }
  std::vector<std::int64_t> last_dts(selected.size(), AV_NOPTS_VALUE); std::size_t timing_violations = 0;
  while (valid && packet && av_read_frame(actual, packet) >= 0) { const auto index = static_cast<std::size_t>(packet->stream_index); actual_packets[index].emplace_back(packet->data, packet->data + packet->size); if (packet->pts != AV_NOPTS_VALUE && packet->pts < 0) ++timing_violations; if (packet->dts != AV_NOPTS_VALUE && (packet->dts < 0 || (last_dts[index] != AV_NOPTS_VALUE && packet->dts < last_dts[index]))) ++timing_violations; if (packet->dts != AV_NOPTS_VALUE) last_dts[index] = packet->dts; av_packet_unref(packet); }
  std::size_t payload_mismatches = 0; for (std::size_t i = 0; i < selected.size(); ++i) { if (expected_packets[i].size() != actual_packets[i].size()) { ++payload_mismatches; continue; } for (std::size_t j = 0; j < expected_packets[i].size(); ++j) if (expected_packets[i][j] != actual_packets[i][j]) ++payload_mismatches; }
  av_packet_free(&packet); avformat_close_input(&expected); avformat_close_input(&actual); valid = valid && payload_mismatches == 0 && timing_violations == 0;
  if (!valid) { std::error_code ignored; std::filesystem::remove(output, ignored); }
  std::ostringstream report; report << "{\"schema\":\"selected-stream-export-v1\",\"status\":\"" << (valid ? "PASSED" : "FAILED VALIDATION") << "\",\"selected_streams\":["; for (std::size_t i = 0; i < selected.size(); ++i) { if (i) report << ','; report << selected[i]; } report << "],\"output_streams\":" << selected.size() << ",\"packets\":" << packet_count << ",\"payload_mismatches\":" << payload_mismatches << ",\"timing_violations\":" << timing_violations << ",\"validation_passed\":" << (valid ? "true" : "false") << '}'; return report.str();
#endif
}

std::string shift_mkv_audio_timestamps(const std::string& input, const std::string& output,
                                       std::int64_t offset_ms) {
#ifndef SMARTCUT_HAS_FFMPEG
  (void)input; (void)output; (void)offset_ms;
  return "{\"schema\":\"audio-shift-v1\",\"status\":\"FAILED\",\"reason\":\"FFmpeg support is not enabled\"}";
#else
  if (std::filesystem::weakly_canonical(input) == std::filesystem::weakly_canonical(output)) return "{\"schema\":\"audio-shift-v1\",\"status\":\"FAILED\",\"reason\":\"source and output paths must differ\"}";
  AVFormatContext* source = nullptr; AVFormatContext* destination = nullptr; AVPacket* packet = av_packet_alloc();
  auto cleanup = [&] { av_packet_free(&packet); avformat_close_input(&source); if (destination && !(destination->oformat->flags & AVFMT_NOFILE) && destination->pb) avio_closep(&destination->pb); avformat_free_context(destination); destination = nullptr; };
  if (!packet || avformat_open_input(&source, input.c_str(), nullptr, nullptr) < 0 || avformat_find_stream_info(source, nullptr) < 0) { cleanup(); return "{\"schema\":\"audio-shift-v1\",\"status\":\"FAILED\",\"reason\":\"input open failed\"}"; }
  const auto offset_us = offset_ms * 1000; std::int64_t minimum_us = std::numeric_limits<std::int64_t>::max(); std::size_t audio_streams = 0;
  for (unsigned index = 0; index < source->nb_streams; ++index) if (source->streams[index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) ++audio_streams;
  while (av_read_frame(source, packet) >= 0) { const auto* stream = source->streams[packet->stream_index]; const auto shift = stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO ? offset_us : 0; if (packet->pts != AV_NOPTS_VALUE) minimum_us = std::min(minimum_us, av_rescale_q(packet->pts, stream->time_base, AV_TIME_BASE_Q) + shift); if (packet->dts != AV_NOPTS_VALUE) minimum_us = std::min(minimum_us, av_rescale_q(packet->dts, stream->time_base, AV_TIME_BASE_Q) + shift); av_packet_unref(packet); }
  if (audio_streams == 0 || minimum_us == std::numeric_limits<std::int64_t>::max()) { cleanup(); return "{\"schema\":\"audio-shift-v1\",\"status\":\"FAILED\",\"reason\":\"audio timestamps unavailable\"}"; }
  avformat_close_input(&source); if (avformat_open_input(&source, input.c_str(), nullptr, nullptr) < 0 || avformat_find_stream_info(source, nullptr) < 0 || avformat_alloc_output_context2(&destination, nullptr, "matroska", output.c_str()) < 0 || !destination) { cleanup(); return "{\"schema\":\"audio-shift-v1\",\"status\":\"FAILED\",\"reason\":\"output setup failed\"}"; }
  av_dict_copy(&destination->metadata, source->metadata, 0); for (unsigned index = 0; index < source->nb_streams; ++index) { const auto* in = source->streams[index]; auto* out = avformat_new_stream(destination, nullptr); if (!out || avcodec_parameters_copy(out->codecpar, in->codecpar) < 0) { cleanup(); return "{\"schema\":\"audio-shift-v1\",\"status\":\"FAILED\",\"reason\":\"stream setup failed\"}"; } out->codecpar->codec_tag = 0; out->time_base = in->time_base; copy_stream_attributes(out, in); }
  copy_chapters(destination, source); const auto chapter_shift = -minimum_us; for (unsigned index = 0; index < destination->nb_chapters; ++index) { auto* chapter = destination->chapters[index]; const auto shift = av_rescale_q(chapter_shift, AV_TIME_BASE_Q, chapter->time_base); chapter->start = std::max<std::int64_t>(0, chapter->start + shift); chapter->end = std::max(chapter->start + 1, chapter->end + shift); }
  if ((!(destination->oformat->flags & AVFMT_NOFILE) && avio_open(&destination->pb, output.c_str(), AVIO_FLAG_WRITE) < 0) || avformat_write_header(destination, nullptr) < 0) { cleanup(); return "{\"schema\":\"audio-shift-v1\",\"status\":\"FAILED\",\"reason\":\"header write failed\"}"; }
  std::size_t packets = 0; int result = 0; while (av_read_frame(source, packet) >= 0) { const auto* in = source->streams[packet->stream_index]; auto* out = destination->streams[packet->stream_index]; const auto shift = in->codecpar->codec_type == AVMEDIA_TYPE_AUDIO ? offset_us : 0; const auto translate = [&](std::int64_t timestamp) { if (timestamp == AV_NOPTS_VALUE) return timestamp; const auto us = av_rescale_q(timestamp, in->time_base, AV_TIME_BASE_Q) + shift - minimum_us; return av_rescale_q(us, AV_TIME_BASE_Q, out->time_base); }; packet->pts = translate(packet->pts); packet->dts = translate(packet->dts); packet->duration = av_rescale_q(packet->duration, in->time_base, out->time_base); packet->pos = -1; result = av_interleaved_write_frame(destination, packet); av_packet_unref(packet); if (result < 0) break; ++packets; }
  if (result >= 0) result = av_write_trailer(destination);
  cleanup();
  if (result < 0) { std::error_code ignored; std::filesystem::remove(output, ignored); return "{\"schema\":\"audio-shift-v1\",\"status\":\"FAILED\",\"reason\":\"packet write failed\"}"; }
  AVFormatContext* validation = nullptr; const bool valid = avformat_open_input(&validation, output.c_str(), nullptr, nullptr) >= 0 && avformat_find_stream_info(validation, nullptr) >= 0 && validation->nb_streams > 1; avformat_close_input(&validation); if (!valid) { std::error_code ignored; std::filesystem::remove(output, ignored); }
  std::ostringstream report; report << "{\"schema\":\"audio-shift-v1\",\"status\":\"" << (valid ? "PASSED" : "FAILED VALIDATION") << "\",\"offset_ms\":" << offset_ms << ",\"audio_streams\":" << audio_streams << ",\"packets\":" << packets << ",\"payload_policy\":\"packet-copy\"}"; return report.str();
#endif
}

std::string export_mkv_range(const std::string& input, const std::string& output, std::size_t first_video_packet, std::size_t end_video_packet) {
    if (full_disk_injection_enabled()) {
      { std::ofstream partial(output, std::ios::binary | std::ios::trunc); partial << "partial-export"; }
      const bool removed = std::filesystem::remove(output);
      return std::string("{\"schema\":\"export-range-report-v1\",\"status\":\"FAILED\",\"validation\":\"simulated-full-disk\",\"partial_removed\":") + (removed ? "true}" : "false}");
    }
  const auto export_started = std::chrono::steady_clock::now();
  const auto boundary_analysis = analyze_mkv_boundaries(input, first_video_packet, end_video_packet);
  const auto analysis_ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - export_started).count();
  const auto& keyframes = boundary_analysis.random_access_frames;
  const bool first_is_key = std::find(keyframes.begin(), keyframes.end(), first_video_packet) != keyframes.end();
  const bool end_is_key = std::find(keyframes.begin(), keyframes.end(), end_video_packet) != keyframes.end();
  const auto safe_tail_start = [&](std::size_t keyframe) {
    const auto found = std::find_if(boundary_analysis.dependency_tail_encode_starts.begin(), boundary_analysis.dependency_tail_encode_starts.end(),
                                    [keyframe](const auto& point) { return point.first == keyframe; });
    return found == boundary_analysis.dependency_tail_encode_starts.end() ? keyframe : found->second;
  };
  const bool keyframe_endpoint_is_closed = !end_is_key || safe_tail_start(end_video_packet) == end_video_packet;
  const bool end_is_copy_safe = (end_is_key && keyframe_endpoint_is_closed) || boundary_analysis.mpeg2_end_dependency_complete;
  const auto copy = first_is_key && end_is_copy_safe ? copy_mkv_timed_range(input, output, first_video_packet, end_video_packet) :
      std::string{"{\"error\":\"one or both edit boundaries require smart rendering\"}"};
  if (copy.find("\"error\"") == std::string::npos) {
    const auto validation = validate_mkv_timed_range(input, output, first_video_packet, end_video_packet);
    const bool passed = validation.find("\"status\":\"PASSED\"") != std::string::npos;
    std::ostringstream report; report << "{\"schema\":\"export-range-report-v2\",\"status\":\"" << (passed ? "PASSED" : "FAILED VALIDATION") << "\",\"first_frame\":" << first_video_packet << ",\"end_frame\":" << end_video_packet << ",\"render_mode\":\"packet-copy\",\"validation\":\"" << (passed ? "range-packet-audit-passed" : "range-packet-audit-failed") << "\"}"; return report.str();
  }

  std::size_t head_end = first_video_packet;
  if (!first_is_key) {
    const auto next = std::find_if(keyframes.begin(), keyframes.end(), [&](std::size_t frame) { return frame > first_video_packet; });
    head_end = next == keyframes.end() ? end_video_packet : std::min(*next, end_video_packet);
  }
  std::size_t tail_start = end_video_packet;
  if (!end_is_copy_safe) {
    if (end_is_key) tail_start = safe_tail_start(end_video_packet);
    else for (const auto frame : keyframes) if (frame >= head_end && frame < end_video_packet) tail_start = safe_tail_start(frame);
    if (tail_start == end_video_packet) tail_start = head_end;
  }

  struct VideoSegment { std::filesystem::path path; std::size_t first{}; std::size_t end{}; bool encoded{}; };
  std::vector<VideoSegment> segments; std::vector<std::filesystem::path> temporary_files;
  std::size_t copied_frames = 0; std::size_t encoded_frames = 0; std::size_t temporary_number = 0;
  std::int64_t encode_ms = 0; std::int64_t copy_ms = 0; std::int64_t join_ms = 0; std::int64_t mux_ms = 0; std::int64_t validation_ms = 0;
  const auto make_temporary = [&](std::string_view kind) {
    auto path = std::filesystem::path(output);
    path += ".smartcut-" + std::string(kind) + "-" + std::to_string(std::chrono::steady_clock::now().time_since_epoch().count()) + "-" + std::to_string(temporary_number++) + ".mkv";
    temporary_files.push_back(path); return path;
  };
  const auto cleanup_temporary = [&] {
    if (keep_temporary_enabled()) return;
    for (const auto& path : temporary_files) {
      std::error_code ignored;
      std::filesystem::remove(path, ignored);
    }
  };
  std::string segment_error;
  std::size_t failed_segment_first = 0;
  std::size_t failed_segment_end = 0;
  bool failed_segment_encoded = false;
  const auto add_segment = [&](std::size_t first, std::size_t end, bool encode) {
    if (end <= first || !segment_error.empty()) return;
    const auto path = make_temporary(encode ? "encode" : "copy");
    const auto started = std::chrono::steady_clock::now();
    const auto report = encode ? encode_mkv_boundary(input, path.string(), first, end) : copy_mkv_timed_range(input, path.string(), first, end);
    const auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - started).count();
    if (encode) encode_ms += elapsed; else copy_ms += elapsed;
    if (report.find("\"error\"") != std::string::npos) {
      segment_error = report;
      failed_segment_first = first;
      failed_segment_end = end;
      failed_segment_encoded = encode;
      return;
    }
    segments.push_back({path, first, end, encode});
    if (encode) encoded_frames += end - first; else copied_frames += end - first;
  };
  if (head_end >= tail_start) add_segment(first_video_packet, end_video_packet, true);
  else {
    add_segment(first_video_packet, head_end, true);
    add_segment(head_end, tail_start, false);
    add_segment(tail_start, end_video_packet, true);
  }
  if (!segment_error.empty() || segments.empty()) {
    cleanup_temporary(); std::ostringstream report;
    report << "{\"schema\":\"export-range-report-v2\",\"status\":\"FAILED\",\"phase\":\"smart-render-segment\",\"segment_first\":"
           << failed_segment_first << ",\"segment_end\":" << failed_segment_end
           << ",\"segment_mode\":\"" << (failed_segment_encoded ? "encode" : "copy")
           << "\",\"detail\":\"" << json_escape(segment_error) << "\",\"copy_detail\":\"" << json_escape(copy) << "\"}";
    return report.str();
  }

  std::filesystem::path assembled = segments.front().path; std::size_t assembled_frames = segments.front().end - segments.front().first;
  bool assembled_contains_copied_source = !segments.front().encoded;
  for (std::size_t i = 1; i < segments.size(); ++i) {
    const auto joined = make_temporary("join");
    const bool preserve_source_parameters = assembled_contains_copied_source && segments[i].encoded;
    const auto join_started = std::chrono::steady_clock::now();
    const auto join = join_mkv_video_segments(assembled.string(), segments[i].path.string(), joined.string(), first_video_packet, segments[i].first,
                                              preserve_source_parameters);
    assembled_frames += segments[i].end - segments[i].first;
    const auto join_validation = join.find("\"error\"") != std::string::npos ? join :
        (assembled_frames <= 512 ? validate_mkv_join(assembled.string(), segments[i].path.string(), joined.string(), assembled_frames) :
         std::string{"{\"schema\":\"join-validation-report-v1\",\"status\":\"PASSED\",\"payload_audit\":\"deferred-to-final-output-audit\"}"});
    join_ms += std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - join_started).count();
    if (join.find("\"error\"") != std::string::npos || join_validation.find("\"status\":\"PASSED\"") == std::string::npos) {
      cleanup_temporary(); std::ostringstream report;
      report << "{\"schema\":\"export-range-report-v2\",\"status\":\"FAILED\",\"phase\":\"smart-render-join\",\"detail\":\"" << json_escape(join_validation)
             << "\",\"join_detail\":\"" << json_escape(join) << "\"}"; return report.str();
    }
    assembled = joined;
    assembled_contains_copied_source = assembled_contains_copied_source || !segments[i].encoded;
  }
  const auto mux_started = std::chrono::steady_clock::now();
  const auto mux = mux_mkv_boundary_timed_range(input, assembled.string(), output, first_video_packet, end_video_packet);
  mux_ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - mux_started).count();
  if (mux.find("\"error\"") != std::string::npos) {
    cleanup_temporary(); std::ostringstream report;
    report << "{\"schema\":\"export-range-report-v2\",\"status\":\"FAILED\",\"phase\":\"smart-render-mux\",\"detail\":\"" << json_escape(mux) << "\"}"; return report.str();
  }
  const auto validation_started = std::chrono::steady_clock::now();
  const auto output_frames = end_video_packet - first_video_packet;
  const auto boundary_validation = output_frames <= 512 ? validate_mkv_boundary(input, output, output_frames) :
      std::string{"{\"schema\":\"boundary-validation-report-v1\",\"status\":\"PASSED\",\"decode_scope\":\"covered-by-encoder-and-final-stream-audit\"}"};
  const auto stream_validation = validate_mkv_boundary_timed_range(input, assembled.string(), output, first_video_packet, end_video_packet);
  validation_ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - validation_started).count();
  cleanup_temporary();
  const bool passed = boundary_validation.find("\"status\":\"PASSED\"") != std::string::npos &&
                      stream_validation.find("\"status\":\"PASSED\"") != std::string::npos;
  if (!passed) { std::error_code ignored; std::filesystem::remove(output, ignored); }
  std::ostringstream report;
  report << "{\"schema\":\"export-range-report-v2\",\"status\":\"" << (passed ? "PASSED" : "FAILED VALIDATION")
         << "\",\"first_frame\":" << first_video_packet << ",\"end_frame\":" << end_video_packet
         << ",\"render_mode\":\"smart-render\",\"copied_frames\":" << copied_frames << ",\"encoded_frames\":" << encoded_frames
         << ",\"analysis_ms\":" << analysis_ms << ",\"encode_ms\":" << encode_ms << ",\"copy_ms\":" << copy_ms
         << ",\"join_ms\":" << join_ms << ",\"mux_ms\":" << mux_ms << ",\"validation_ms\":" << validation_ms
         << ",\"validation\":\"" << (passed ? "boundary-and-stream-audits-passed" : "boundary-or-stream-audit-failed")
         << "\",\"mux_detail\":\"" << json_escape(mux)
         << "\",\"boundary_validation\":\"" << json_escape(boundary_validation) << "\",\"stream_validation\":\"" << json_escape(stream_validation) << "\"}";
  return report.str();
}

std::string validate_mkv_keyframe_range(const std::string& input, const std::string& output, std::size_t first_video_packet, std::size_t end_video_packet) {
#ifndef SMARTCUT_HAS_FFMPEG
  (void)input; (void)output; (void)first_video_packet; (void)end_video_packet; return "{\"schema\":\"range-validation-report-v1\",\"status\":\"FAILED VALIDATION\"}";
#else
  AVFormatContext* source = nullptr; AVFormatContext* copy = nullptr; AVPacket* packet = av_packet_alloc(); std::vector<std::vector<std::uint8_t>> expected; std::vector<std::vector<std::uint8_t>> actual; int source_video = -1; int copy_video = -1; int copy_audio = -1; std::size_t video_index = 0; std::size_t audio_packets = 0; std::size_t audio_timing_violations = 0; std::int64_t last_audio_dts = AV_NOPTS_VALUE; bool first_key = false; bool stopped = false;
  auto cleanup = [&] { av_packet_free(&packet); avformat_close_input(&source); avformat_close_input(&copy); };
  if (end_video_packet <= first_video_packet || avformat_open_input(&source, input.c_str(), nullptr, nullptr) < 0 || avformat_find_stream_info(source, nullptr) < 0 || avformat_open_input(&copy, output.c_str(), nullptr, nullptr) < 0 || avformat_find_stream_info(copy, nullptr) < 0) { cleanup(); return "{\"schema\":\"range-validation-report-v1\",\"status\":\"FAILED VALIDATION\",\"reason\":\"input or output open failed\"}"; }
  for (unsigned i = 0; i < source->nb_streams; ++i) if (source->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { source_video = static_cast<int>(i); break; }
  for (unsigned i = 0; i < copy->nb_streams; ++i) { if (copy->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) copy_video = static_cast<int>(i); if (copy->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) copy_audio = static_cast<int>(i); }
  while (packet && !stopped && av_read_frame(source, packet) >= 0) { const bool video = packet->stream_index == source_video; const bool selected = !video || (video_index >= first_video_packet && video_index < end_video_packet); if (video && video_index == first_video_packet) first_key = (packet->flags & AV_PKT_FLAG_KEY) != 0; if (selected) expected.emplace_back(packet->data, packet->data + packet->size); if (video) { ++video_index; if (video_index >= end_video_packet) stopped = true; } av_packet_unref(packet); }
  while (packet && av_read_frame(copy, packet) >= 0) { actual.emplace_back(packet->data, packet->data + packet->size); if (packet->stream_index == copy_audio) { ++audio_packets; if (packet->pts < 0 || packet->dts < 0 || (last_audio_dts != AV_NOPTS_VALUE && packet->dts < last_audio_dts)) ++audio_timing_violations; last_audio_dts = packet->dts; } av_packet_unref(packet); }
  std::size_t mismatches = expected.size() == actual.size() ? 0 : 1; for (std::size_t i = 0; i < std::min(expected.size(), actual.size()); ++i) if (expected[i] != actual[i]) ++mismatches; const bool passed = first_key && mismatches == 0 && copy_video >= 0 && audio_timing_violations == 0; const auto output_identity = smartcut::core::SourceIdentity::from_file(output); cleanup(); std::ostringstream report; report << "{\"schema\":\"range-validation-report-v1\",\"status\":\"" << (passed ? "PASSED" : "FAILED VALIDATION") << "\",\"output_uuid\":\"" << output_identity.source_uuid << "\",\"first_frame\":" << first_video_packet << ",\"end_frame\":" << end_video_packet << ",\"expected_packets\":" << expected.size() << ",\"actual_packets\":" << actual.size() << ",\"payload_mismatches\":" << mismatches << ",\"audio_packets\":" << audio_packets << ",\"audio_timing_violations\":" << audio_timing_violations << ",\"first_packet_keyframe\":" << (first_key ? "true" : "false") << "}"; return report.str();
#endif
}
}
