Skip to content

Commit 33bd7d9

Browse files
authored
Merge pull request #548 from valbok/android-crop
Render only cropped part of the frame for MediaCodec
2 parents 0f24242 + 7fb61e2 commit 33bd7d9

File tree

3 files changed

+75
-2
lines changed

3 files changed

+75
-2
lines changed

src/QtAVPlayer/qavhwdevice_mediacodec.cpp

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,59 @@ extern "C" {
1515
#include <libavutil/pixdesc.h>
1616
#include <libavcodec/mediacodec.h>
1717
#include <libavutil/hwcontext_mediacodec.h>
18+
#include <stdatomic.h>
19+
20+
struct FFAMediaCodec;
21+
struct FFAMediaFormat;
22+
// libavcodec/mediacodecdec_common.h
23+
typedef struct MediaCodecDecContext {
24+
25+
AVCodecContext *avctx;
26+
atomic_int refcount;
27+
atomic_int hw_buffer_count;
28+
29+
char *codec_name;
30+
31+
FFAMediaCodec *codec;
32+
FFAMediaFormat *format;
33+
34+
void *surface;
35+
36+
int started;
37+
int draining;
38+
int flushing;
39+
int eos;
40+
41+
int width;
42+
int height;
43+
int stride;
44+
int slice_height;
45+
int color_format;
46+
int crop_top;
47+
int crop_bottom;
48+
int crop_left;
49+
int crop_right;
50+
int display_width;
51+
int display_height;
52+
53+
uint64_t output_buffer_count;
54+
ssize_t current_input_buffer;
55+
56+
bool delay_flush;
57+
atomic_int serial;
58+
59+
bool use_ndk_codec;
60+
} MediaCodecDecContext;
61+
62+
typedef struct MediaCodecBuffer {
63+
64+
MediaCodecDecContext *ctx;
65+
ssize_t index;
66+
int64_t pts;
67+
atomic_int released;
68+
int serial;
69+
70+
} MediaCodecBuffer;
1871
}
1972

2073
QT_BEGIN_NAMESPACE
@@ -96,7 +149,7 @@ class VideoBuffer_MediaCodec : public QAVVideoBuffer_GPU
96149
m_hw->androidSurfaceTexture->attachToGLContext(m_hw->texture);
97150
}
98151

99-
AVMediaCodecBuffer *buffer = reinterpret_cast<AVMediaCodecBuffer *>(frame().frame()->data[3]);
152+
auto buffer = reinterpret_cast<AVMediaCodecBuffer *>(frame().frame()->data[3]);
100153
if (!buffer) {
101154
qWarning() << "Received a frame without AVMediaCodecBuffer.";
102155
} else if (av_mediacodec_release_buffer(buffer, 1) < 0) {
@@ -108,6 +161,17 @@ class VideoBuffer_MediaCodec : public QAVVideoBuffer_GPU
108161
return m_hw->texture;
109162
}
110163

164+
QSize size() const override
165+
{
166+
auto av_frame = frame().frame();
167+
auto buffer = reinterpret_cast<AVMediaCodecBuffer *>(av_frame->data[3]);
168+
if (!buffer) {
169+
return frame().size();
170+
}
171+
auto ctx = reinterpret_cast<MediaCodecDecContext *>(buffer->ctx);
172+
return {ctx->width, ctx->height};
173+
}
174+
111175
QAVHWDevice_MediaCodecPrivate *m_hw = nullptr;
112176
};
113177

src/QtAVPlayer/qavvideobuffer_p.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <QtAVPlayer/qavvideoframe.h>
2323
#include <QVariant>
24+
#include <QSize>
2425

2526
QT_BEGIN_NAMESPACE
2627

@@ -36,6 +37,8 @@ class QAVVideoBuffer
3637
virtual QAVVideoFrame::MapData map() = 0;
3738
virtual QAVVideoFrame::HandleType handleType() const { return QAVVideoFrame::NoHandle; }
3839
virtual QVariant handle(QRhi */*rhi*/ = nullptr) const { return {}; }
40+
// Returns the size of the frame from internal codec
41+
virtual QSize size() const { return m_frame.size(); }
3942
protected:
4043
QAVVideoFrame m_frame;
4144
};

src/QtAVPlayer/qavvideoframe.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,13 +505,19 @@ QAVVideoFrame::operator QVideoFrame() const
505505
return QVideoFrame(new PlanarVideoBuffer(result, type), size(), format);
506506
#else
507507
QVideoFrameFormat videoFormat(size(), format);
508-
508+
509509
QRect viewport(
510510
static_cast<int>(frame()->crop_left),
511511
static_cast<int>(frame()->crop_top),
512512
static_cast<int>(frame()->width - frame()->crop_left - frame()->crop_right),
513513
static_cast<int>(frame()->height - frame()->crop_top - frame()->crop_bottom)
514514
);
515+
// Special case when the codec already cropped the frame and need to render only part of the frame
516+
auto bufSize = reinterpret_cast<QAVVideoFramePrivate *>(result.d_ptr.get())->videoBuffer().size();
517+
if (handleType() == GLTextureHandle && bufSize.height() > size().height() && size().height() == viewport.height()) {
518+
auto diff = bufSize.height() - size().height();
519+
viewport.setHeight(viewport.height() - diff - 1);
520+
}
515521
videoFormat.setViewport(viewport);
516522
#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
517523
videoFormat.setColorSpace(PlanarVideoBuffer::colorSpace(frame()));

0 commit comments

Comments
 (0)