mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-23 04:46:26 +02:00
73 lines
2.5 KiB
C++
73 lines
2.5 KiB
C++
// Copyright (c) 2026- PPSSPP Project.
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
// Official git repository and contact information can be found at
|
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
|
|
|
#pragma once
|
|
|
|
#include <vector>
|
|
|
|
#include "Common/CommonTypes.h"
|
|
|
|
struct AVCodecContext;
|
|
struct AVFrame;
|
|
|
|
// A plain "hand it one access unit, get a frame back" H.264 decoder.
|
|
//
|
|
// This exists for sceVideocodec, which is a low level interface to the PSP Media Engine.
|
|
// PPSSPP's MediaEngine can't serve that - it is built around sceMpeg's own model, with the
|
|
// PSMF demuxer, the ringbuffer and its own frame pacing wrapped around the decoder, so this
|
|
// is a second path in addition to that. Implementing the old path around this might happen later.
|
|
//
|
|
// Output is whatever pixel format the decoder produced, normally YUV420P; the caller converts.
|
|
class AvcDecoder {
|
|
public:
|
|
AvcDecoder();
|
|
~AvcDecoder();
|
|
|
|
// Not copyable.
|
|
AvcDecoder(const AvcDecoder &) = delete;
|
|
AvcDecoder &operator=(const AvcDecoder &) = delete;
|
|
|
|
// Decodes one access unit. Returns true when a frame came out - H.264 reorders, so a frame
|
|
// is not produced for every unit fed in, and that is not an error.
|
|
bool Decode(const u8 *data, int size);
|
|
|
|
// Throws away any decoder state, for a seek or a new stream.
|
|
void Flush();
|
|
|
|
bool HasFrame() const { return haveFrame_; }
|
|
int Width() const { return width_; }
|
|
int Height() const { return height_; }
|
|
|
|
// Only meaningful while HasFrame(). Planes are Y, Cb, Cr; strides are in bytes and are not
|
|
// necessarily the width.
|
|
const u8 *Plane(int index) const;
|
|
int Stride(int index) const;
|
|
|
|
// True if we were built without ffmpeg, in which case nothing decodes.
|
|
static bool IsAvailable();
|
|
|
|
private:
|
|
AVCodecContext *codecCtx_ = nullptr;
|
|
AVFrame *frame_ = nullptr;
|
|
// The access unit, copied so we can pad it - ffmpeg reads a little past the end of a packet.
|
|
// Kept between calls so the usual case doesn't allocate.
|
|
std::vector<u8> packetBuf_;
|
|
bool haveFrame_ = false;
|
|
int width_ = 0;
|
|
int height_ = 0;
|
|
};
|