#include "recorder_video_widget.h"
#include <QDebug>
#include <QApplication>
#include <QOpenGLContext>
#include <QDateTime>
#include <cstring>

extern "C" {
#include <libavutil/pixfmt.h>
#include <libswscale/swscale.h>
}

// 顶点着色器源码
static const char* vertexShaderSource = R"(
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoord;

out vec2 TexCoord;

uniform bool flipHorizontal;
uniform bool flipVertical;

void main() {
    gl_Position = vec4(aPos, 0.0, 1.0);
    
    vec2 texCoord = aTexCoord;
    if (flipHorizontal) {
        texCoord.x = 1.0 - texCoord.x;
    }
    if (flipVertical) {
        texCoord.y = 1.0 - texCoord.y;
    }
    
    TexCoord = texCoord;
}
)";

// YUV片段着色器源码
static const char* yuvFragmentShaderSource = R"(
#version 330 core
out vec4 FragColor;

in vec2 TexCoord;

uniform sampler2D textureY;
uniform sampler2D textureU;
uniform sampler2D textureV;
uniform bool grayscale;
uniform float brightness;
uniform float contrast;
uniform float saturation;

void main() {
    float y = texture(textureY, TexCoord).r;
    float u = texture(textureU, TexCoord).r - 0.5;
    float v = texture(textureV, TexCoord).r - 0.5;
    
    // YUV to RGB conversion
    float r = y + 1.402 * v;
    float g = y - 0.344 * u - 0.714 * v;
    float b = y + 1.772 * u;
    
    vec3 rgb = vec3(r, g, b);
    
    // Apply brightness
    rgb += brightness;
    
    // Apply contrast
    rgb = (rgb - 0.5) * contrast + 0.5;
    
    // Apply saturation
    if (!grayscale) {
        float gray = dot(rgb, vec3(0.299, 0.587, 0.114));
        rgb = mix(vec3(gray), rgb, saturation);
    } else {
        float gray = dot(rgb, vec3(0.299, 0.587, 0.114));
        rgb = vec3(gray);
    }
    
    FragColor = vec4(clamp(rgb, 0.0, 1.0), 1.0);
}
)";

// RGB片段着色器源码
static const char* rgbFragmentShaderSource = R"(
#version 330 core
out vec4 FragColor;

in vec2 TexCoord;

uniform sampler2D textureRGB;
uniform bool grayscale;
uniform float brightness;
uniform float contrast;
uniform float saturation;

void main() {
    vec3 rgb = texture(textureRGB, TexCoord).rgb;
    
    // Apply brightness
    rgb += brightness;
    
    // Apply contrast
    rgb = (rgb - 0.5) * contrast + 0.5;
    
    // Apply saturation
    if (!grayscale) {
        float gray = dot(rgb, vec3(0.299, 0.587, 0.114));
        rgb = mix(vec3(gray), rgb, saturation);
    } else {
        float gray = dot(rgb, vec3(0.299, 0.587, 0.114));
        rgb = vec3(gray);
    }
    
    FragColor = vec4(clamp(rgb, 0.0, 1.0), 1.0);
}
)";

RecorderVideoWidget::RecorderVideoWidget(QWidget* parent)
    : QOpenGLWidget(parent)
    , m_textureY(0)
    , m_textureU(0)
    , m_textureV(0)
    , m_textureRGB(0)
    , m_VAO(0)
    , m_VBO(0)
    , m_frameWidth(0)
    , m_frameHeight(0)
    , m_frameFormat(AV_PIX_FMT_NONE)
    , m_frameReady(false)
    , m_keepAspectRatio(true)
    , m_showFPS(true)
    , m_noVideoText("No Video")
    , m_backgroundColor(Qt::black)
    , m_grayscale(false)
    , m_flipHorizontal(false)
    , m_flipVertical(false)
    , m_brightness(0.0f)
    , m_contrast(1.0f)
    , m_saturation(1.0f)
    , m_frameCount(0)
    , m_currentFPS(0.0)
    , m_lastFPSUpdate(0)
    , m_initialized(false) {
    
    // 初始化帧数据
    for (int i = 0; i < 4; ++i) {
        m_frameData[i] = nullptr;
        m_frameLinesize[i] = 0;
    }
    
    // 创建FPS定时器
    m_fpsTimer = new QTimer(this);
    connect(m_fpsTimer, &QTimer::timeout, this, &RecorderVideoWidget::updateFPS);
    m_fpsTimer->start(1000); // 每秒更新一次FPS
    
    // 设置OpenGL格式
    QSurfaceFormat format;
    format.setVersion(3, 3);
    format.setProfile(QSurfaceFormat::CoreProfile);
    setFormat(format);
}

RecorderVideoWidget::~RecorderVideoWidget() {
    cleanup();
}

bool RecorderVideoWidget::initialize(int width, int height, int format) {
    QMutexLocker locker(&m_mutex);
    
    if (width <= 0 || height <= 0) {
        qWarning() << "Invalid video dimensions:" << width << "x" << height;
        return false;
    }
    
    // 分配帧缓冲区
    if (!allocateFrameBuffer(width, height, format)) {
        qWarning() << "Failed to allocate frame buffer";
        return false;
    }
    
    m_initialized = true;
    
    // 触发重绘
    QMetaObject::invokeMethod(this, "update", Qt::QueuedConnection);
    
    return true;
}

void RecorderVideoWidget::cleanup() {
    QMutexLocker locker(&m_mutex);
    
    makeCurrent();
    
    // 释放OpenGL资源
    if (m_textureY) {
        glDeleteTextures(1, &m_textureY);
        m_textureY = 0;
    }
    if (m_textureU) {
        glDeleteTextures(1, &m_textureU);
        m_textureU = 0;
    }
    if (m_textureV) {
        glDeleteTextures(1, &m_textureV);
        m_textureV = 0;
    }
    if (m_textureRGB) {
        glDeleteTextures(1, &m_textureRGB);
        m_textureRGB = 0;
    }
    if (m_VAO) {
        glDeleteVertexArrays(1, &m_VAO);
        m_VAO = 0;
    }
    if (m_VBO) {
        glDeleteBuffers(1, &m_VBO);
        m_VBO = 0;
    }
    
    m_shaderProgram.reset();
    
    doneCurrent();
    
    // 释放帧缓冲区
    freeFrameBuffer();
    
    m_frameReady = false;
    m_initialized = false;
}

bool RecorderVideoWidget::updateFrame(AVFrame* frame) {
    if (!frame || !m_initialized) {
        qDebug() << "RecorderVideoWidget::updateFrame failed: frame=" << frame << ", initialized=" << m_initialized;
        return false;
    }
    
    // 验证帧数据的有效性
    if (frame->width <= 0 || frame->height <= 0 || !frame->data[0]) {
        qWarning() << "Invalid frame data received, skipping: width=" << frame->width 
                   << ", height=" << frame->height << ", data[0]=" << frame->data[0];
        return false;
    }
    
    qDebug() << "RecorderVideoWidget::updateFrame: width=" << frame->width 
             << ", height=" << frame->height << ", format=" << frame->format;
    
    QMutexLocker locker(&m_mutex);
    
    try {
        // 检查帧格式是否匹配
        if (frame->width != m_frameWidth || 
            frame->height != m_frameHeight || 
            frame->format != m_frameFormat) {
            
            // 重新分配缓冲区
            if (!allocateFrameBuffer(frame->width, frame->height, frame->format)) {
                qWarning() << "Failed to allocate frame buffer";
                return false;
            }
            qDebug() << "Frame buffer reallocated:" << frame->width << "x" << frame->height;
        }
        
        // 复制帧数据
        if (!copyFromAVFrame(frame)) {
            qWarning() << "Failed to copy frame data";
            return false;
        }
        
        m_frameReady = true;
        m_frameCount++;
        
        // 限制触发重绘的频率，避免过度绘制
        if (m_frameCount % 2 == 0) {  // 每2帧触发一次重绘
            QMetaObject::invokeMethod(this, "update", Qt::QueuedConnection);
        }
        
        return true;
    } catch (const std::exception& e) {
        qWarning() << "Exception in updateFrame:" << e.what();
        return false;
    } catch (...) {
        qWarning() << "Unknown exception in updateFrame";
        return false;
    }
}

bool RecorderVideoWidget::updateFrame(const VideoFrame& frame) {
    if (!m_initialized) {
        return false;
    }
    
    QMutexLocker locker(&m_mutex);
    
    // 检查帧格式是否匹配
    if (frame.width != m_frameWidth || 
        frame.height != m_frameHeight || 
        frame.format != m_frameFormat) {
        
        // 重新分配缓冲区
        if (!allocateFrameBuffer(frame.width, frame.height, frame.format)) {
            return false;
        }
    }
    
    // 复制帧数据
    if (!copyFromVideoFrame(frame)) {
        return false;
    }
    
    m_frameReady = true;
    m_frameCount++;
    
    // 触发重绘
    QMetaObject::invokeMethod(this, "update", Qt::QueuedConnection);
    
    return true;
}

void RecorderVideoWidget::clearFrame() {
    QMutexLocker locker(&m_mutex);
    
    m_frameReady = false;
    
    // 触发重绘
    QMetaObject::invokeMethod(this, "update", Qt::QueuedConnection);
}

void RecorderVideoWidget::setGrayscale(bool enable) {
    m_grayscale = enable;
    update();
}

void RecorderVideoWidget::setFlipHorizontal(bool enable) {
    m_flipHorizontal = enable;
    update();
}

void RecorderVideoWidget::setFlipVertical(bool enable) {
    m_flipVertical = enable;
    update();
}

void RecorderVideoWidget::setBrightness(float brightness) {
    m_brightness = qBound(-1.0f, brightness, 1.0f);
    update();
}

void RecorderVideoWidget::setContrast(float contrast) {
    m_contrast = qBound(0.0f, contrast, 2.0f);
    update();
}

void RecorderVideoWidget::setSaturation(float saturation) {
    m_saturation = qBound(0.0f, saturation, 2.0f);
    update();
}

void RecorderVideoWidget::initializeGL() {
    initializeOpenGLFunctions();
    QOpenGLExtraFunctions::initializeOpenGLFunctions();
    
    // 设置背景色
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    
    // 初始化着色器
    if (!initShaders()) {
        qWarning() << "Failed to initialize shaders";
        return;
    }
    
    // 创建纹理
    createTextures();
    
    // 创建顶点数组对象
    glGenVertexArrays(1, &m_VAO);
    glGenBuffers(1, &m_VBO);
    
    glBindVertexArray(m_VAO);
    
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES), VERTICES, GL_STATIC_DRAW);
    
    // 位置属性
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    
    // 纹理坐标属性
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
    glEnableVertexAttribArray(1);
    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

void RecorderVideoWidget::paintGL() {
    glClear(GL_COLOR_BUFFER_BIT);
    
    QMutexLocker locker(&m_mutex);
    
    if (!m_frameReady || !m_shaderProgram) {
        // 绘制无视频提示
        locker.unlock();
        drawNoVideoHint();
        return;
    }
    
    // 使用着色器程序
    m_shaderProgram->bind();
    
    // 设置uniform变量
    m_shaderProgram->setUniformValue("grayscale", m_grayscale);
    m_shaderProgram->setUniformValue("flipHorizontal", m_flipHorizontal);
    m_shaderProgram->setUniformValue("flipVertical", m_flipVertical);
    m_shaderProgram->setUniformValue("brightness", m_brightness);
    m_shaderProgram->setUniformValue("contrast", m_contrast);
    m_shaderProgram->setUniformValue("saturation", m_saturation);
    
    // 更新纹理数据
    updateTextures();
    
    // 绑定纹理
    if (m_frameFormat == AV_PIX_FMT_YUV420P) {
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, m_textureY);
        m_shaderProgram->setUniformValue("textureY", 0);
        
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, m_textureU);
        m_shaderProgram->setUniformValue("textureU", 1);
        
        glActiveTexture(GL_TEXTURE2);
        glBindTexture(GL_TEXTURE_2D, m_textureV);
        m_shaderProgram->setUniformValue("textureV", 2);
    } else {
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, m_textureRGB);
        m_shaderProgram->setUniformValue("textureRGB", 0);
    }
    
    // 绘制四边形
    glBindVertexArray(m_VAO);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    glBindVertexArray(0);
    
    m_shaderProgram->release();
    
    locker.unlock();
    
    // 绘制FPS信息
    if (m_showFPS) {
        drawFPSInfo();
    }
}

void RecorderVideoWidget::resizeGL(int width, int height) {
    glViewport(0, 0, width, height);
}

void RecorderVideoWidget::mousePressEvent(QMouseEvent* event) {
    if (event->button() == Qt::LeftButton) {
        emit clicked(event->pos());
    }
    QOpenGLWidget::mousePressEvent(event);
}

void RecorderVideoWidget::mouseDoubleClickEvent(QMouseEvent* event) {
    if (event->button() == Qt::LeftButton) {
        emit doubleClicked(event->pos());
    }
    QOpenGLWidget::mouseDoubleClickEvent(event);
}

void RecorderVideoWidget::updateFPS() {
    qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
    
    if (m_lastFPSUpdate > 0) {
        qint64 elapsed = currentTime - m_lastFPSUpdate;
        if (elapsed > 0) {
            m_currentFPS = (m_frameCount * 1000.0) / elapsed;
        }
    }
    
    m_frameCount = 0;
    m_lastFPSUpdate = currentTime;
    
    if (m_showFPS) {
        update();
    }
}

bool RecorderVideoWidget::initShaders() {
    m_shaderProgram = std::make_unique<QOpenGLShaderProgram>();
    
    // 添加顶点着色器
    if (!m_shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource)) {
        qWarning() << "Failed to compile vertex shader:" << m_shaderProgram->log();
        return false;
    }
    
    // 根据格式选择片段着色器
    const char* fragmentSource = (m_frameFormat == AV_PIX_FMT_YUV420P) ? 
                                  yuvFragmentShaderSource : rgbFragmentShaderSource;
    
    if (!m_shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentSource)) {
        qWarning() << "Failed to compile fragment shader:" << m_shaderProgram->log();
        return false;
    }
    
    // 链接着色器程序
    if (!m_shaderProgram->link()) {
        qWarning() << "Failed to link shader program:" << m_shaderProgram->log();
        return false;
    }
    
    return true;
}

void RecorderVideoWidget::createTextures() {
    // 创建Y纹理
    glGenTextures(1, &m_textureY);
    glBindTexture(GL_TEXTURE_2D, m_textureY);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    
    // 创建U纹理
    glGenTextures(1, &m_textureU);
    glBindTexture(GL_TEXTURE_2D, m_textureU);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    
    // 创建V纹理
    glGenTextures(1, &m_textureV);
    glBindTexture(GL_TEXTURE_2D, m_textureV);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    
    // 创建RGB纹理
    glGenTextures(1, &m_textureRGB);
    glBindTexture(GL_TEXTURE_2D, m_textureRGB);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

void RecorderVideoWidget::updateTextures() {
    if (!m_frameReady) {
        return;
    }
    
    if (m_frameFormat == AV_PIX_FMT_YUV420P) {
        // 更新Y纹理
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, m_textureY);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, m_frameWidth, m_frameHeight, 
                     0, GL_RED, GL_UNSIGNED_BYTE, m_frameData[0]);
        
        // 更新U纹理
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, m_textureU);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, m_frameWidth/2, m_frameHeight/2, 
                     0, GL_RED, GL_UNSIGNED_BYTE, m_frameData[1]);
        
        // 更新V纹理
        glActiveTexture(GL_TEXTURE2);
        glBindTexture(GL_TEXTURE_2D, m_textureV);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, m_frameWidth/2, m_frameHeight/2, 
                     0, GL_RED, GL_UNSIGNED_BYTE, m_frameData[2]);
    } else {
        // 更新RGB纹理
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, m_textureRGB);
        
        GLenum format = GL_RGB;
        if (m_frameFormat == AV_PIX_FMT_RGBA || m_frameFormat == AV_PIX_FMT_BGRA) {
            format = GL_RGBA;
        }
        
        glTexImage2D(GL_TEXTURE_2D, 0, format, m_frameWidth, m_frameHeight, 
                     0, format, GL_UNSIGNED_BYTE, m_frameData[0]);
    }
}

QRectF RecorderVideoWidget::calculateDisplayRect() const {
    if (!m_keepAspectRatio || m_frameWidth <= 0 || m_frameHeight <= 0) {
        return QRectF(0, 0, width(), height());
    }
    
    double widgetAspect = static_cast<double>(width()) / height();
    double frameAspect = static_cast<double>(m_frameWidth) / m_frameHeight;
    
    QRectF displayRect;
    
    if (widgetAspect > frameAspect) {
        // 控件更宽，以高度为准
        int displayWidth = static_cast<int>(height() * frameAspect);
        displayRect = QRectF((width() - displayWidth) / 2, 0, displayWidth, height());
    } else {
        // 控件更高，以宽度为准
        int displayHeight = static_cast<int>(width() / frameAspect);
        displayRect = QRectF(0, (height() - displayHeight) / 2, width(), displayHeight);
    }
    
    return displayRect;
}

void RecorderVideoWidget::drawNoVideoHint() {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    
    // 设置背景色
    painter.fillRect(rect(), m_backgroundColor);
    
    // 绘制提示文本
    painter.setPen(Qt::white);
    painter.setFont(QFont("Arial", 16));
    painter.drawText(rect(), Qt::AlignCenter, m_noVideoText);
}

void RecorderVideoWidget::drawFPSInfo() {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    
    // 设置字体和颜色
    painter.setPen(Qt::yellow);
    painter.setFont(QFont("Arial", 12, QFont::Bold));
    
    // 绘制FPS信息
    QString fpsText = QString("FPS: %1").arg(m_currentFPS, 0, 'f', 1);
    QRect textRect = painter.fontMetrics().boundingRect(fpsText);
    
    // 绘制背景
    QRect bgRect = textRect.adjusted(-5, -2, 5, 2);
    bgRect.moveTopLeft(QPoint(10, 10));
    painter.fillRect(bgRect, QColor(0, 0, 0, 128));
    
    // 绘制文本
    painter.drawText(bgRect, Qt::AlignCenter, fpsText);
}

bool RecorderVideoWidget::copyFromAVFrame(AVFrame* frame) {
    if (!frame || !frame->data[0]) {
        return false;
    }
    
    // 复制Y平面
    if (m_frameData[0] && frame->data[0]) {
        for (int y = 0; y < m_frameHeight; ++y) {
            memcpy(m_frameData[0] + y * m_frameLinesize[0],
                   frame->data[0] + y * frame->linesize[0],
                   m_frameWidth);
        }
    }
    
    // 复制U平面
    if (m_frameFormat == AV_PIX_FMT_YUV420P && m_frameData[1] && frame->data[1]) {
        for (int y = 0; y < m_frameHeight / 2; ++y) {
            memcpy(m_frameData[1] + y * m_frameLinesize[1],
                   frame->data[1] + y * frame->linesize[1],
                   m_frameWidth / 2);
        }
    }
    
    // 复制V平面
    if (m_frameFormat == AV_PIX_FMT_YUV420P && m_frameData[2] && frame->data[2]) {
        for (int y = 0; y < m_frameHeight / 2; ++y) {
            memcpy(m_frameData[2] + y * m_frameLinesize[2],
                   frame->data[2] + y * frame->linesize[2],
                   m_frameWidth / 2);
        }
    }
    
    return true;
}

bool RecorderVideoWidget::copyFromVideoFrame(const VideoFrame& frame) {
    if (!frame.data[0]) {
        return false;
    }
    
    // 复制Y平面或RGB数据
    if (m_frameData[0] && frame.data[0]) {
        for (int y = 0; y < m_frameHeight; ++y) {
            int copySize = (m_frameFormat == AV_PIX_FMT_YUV420P) ? m_frameWidth : 
                          (m_frameWidth * ((m_frameFormat == AV_PIX_FMT_RGB24) ? 3 : 4));
            memcpy(m_frameData[0] + y * m_frameLinesize[0],
                   frame.data[0] + y * frame.linesize[0],
                   copySize);
        }
    }
    
    // 复制U平面
    if (m_frameFormat == AV_PIX_FMT_YUV420P && m_frameData[1] && frame.data[1]) {
        for (int y = 0; y < m_frameHeight / 2; ++y) {
            memcpy(m_frameData[1] + y * m_frameLinesize[1],
                   frame.data[1] + y * frame.linesize[1],
                   m_frameWidth / 2);
        }
    }
    
    // 复制V平面
    if (m_frameFormat == AV_PIX_FMT_YUV420P && m_frameData[2] && frame.data[2]) {
        for (int y = 0; y < m_frameHeight / 2; ++y) {
            memcpy(m_frameData[2] + y * m_frameLinesize[2],
                   frame.data[2] + y * frame.linesize[2],
                   m_frameWidth / 2);
        }
    }
    
    return true;
}

bool RecorderVideoWidget::allocateFrameBuffer(int width, int height, int format) {
    // 验证参数
    if (width <= 0 || height <= 0 || width > 8192 || height > 8192) {
        qWarning() << "Invalid frame dimensions:" << width << "x" << height;
        return false;
    }
    
    // 释放旧缓冲区
    freeFrameBuffer();
    
    m_frameWidth = width;
    m_frameHeight = height;
    m_frameFormat = format;
    
    try {
        if (format == AV_PIX_FMT_YUV420P) {
            // 分配Y平面
            m_frameLinesize[0] = width;
            size_t ySize = static_cast<size_t>(width) * height;
            m_frameData[0] = static_cast<uint8_t*>(av_malloc(ySize));
            
            // 分配U平面
            m_frameLinesize[1] = width / 2;
            size_t uvSize = static_cast<size_t>(width) * height / 4;
            m_frameData[1] = static_cast<uint8_t*>(av_malloc(uvSize));
            
            // 分配V平面
            m_frameLinesize[2] = width / 2;
            m_frameData[2] = static_cast<uint8_t*>(av_malloc(uvSize));
            
            bool success = m_frameData[0] && m_frameData[1] && m_frameData[2];
            if (!success) {
                qWarning() << "Failed to allocate YUV420P frame buffer";
                freeFrameBuffer(); // 清理部分分配的内存
                return false;
            }
            
            qDebug() << "Allocated YUV420P buffer:" << width << "x" << height 
                     << "Y:" << ySize << "U/V:" << uvSize;
            return true;
        } else {
            // RGB格式
            int bytesPerPixel = (format == AV_PIX_FMT_RGB24) ? 3 : 4;
            m_frameLinesize[0] = width * bytesPerPixel;
            size_t totalSize = static_cast<size_t>(width) * height * bytesPerPixel;
            m_frameData[0] = static_cast<uint8_t*>(av_malloc(totalSize));
            
            bool success = (m_frameData[0] != nullptr);
            if (!success) {
                qWarning() << "Failed to allocate RGB frame buffer";
                freeFrameBuffer();
                return false;
            }
            
            qDebug() << "Allocated RGB buffer:" << width << "x" << height 
                     << "size:" << totalSize;
            return true;
        }
    } catch (const std::exception& e) {
        qWarning() << "Exception in allocateFrameBuffer:" << e.what();
        freeFrameBuffer();
        return false;
    } catch (...) {
        qWarning() << "Unknown exception in allocateFrameBuffer";
        freeFrameBuffer();
        return false;
    }
}

void RecorderVideoWidget::freeFrameBuffer() {
    for (int i = 0; i < 4; ++i) {
        if (m_frameData[i]) {
            av_free(m_frameData[i]);
            m_frameData[i] = nullptr;
        }
        m_frameLinesize[i] = 0;
    }
    
    m_frameWidth = 0;
    m_frameHeight = 0;
    m_frameFormat = AV_PIX_FMT_NONE;
}

// 静态成员定义
constexpr float RecorderVideoWidget::VERTICES[];
constexpr unsigned int RecorderVideoWidget::INDICES[];