Skip to content

Commit 0c00753

Browse files
author
Alexander Matveev
committed
8313105: Improved media framing
Backport-of: 0a52a4c
1 parent 10f8b43 commit 0c00753

File tree

7 files changed

+362
-190
lines changed

7 files changed

+362
-190
lines changed
Lines changed: 103 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,50 +23,51 @@
2323
* questions.
2424
*/
2525

26+
// For UINT_MAX, we cannot use GLib here, since it is shared code between
27+
// GStreamer and AVFoundation.
28+
#include <limits.h>
29+
2630
#include "VideoFrame.h"
2731
#include <Common/VSMemory.h>
2832

2933
//*************************************************************************************************
3034
//********** class CVideoFrame
3135
//*************************************************************************************************
3236
CVideoFrame::CVideoFrame()
33-
: m_iWidth(0),
34-
m_iHeight(0),
35-
m_iEncodedWidth(0),
36-
m_iEncodedHeight(0),
37+
: m_uiWidth(0),
38+
m_uiHeight(0),
39+
m_uiEncodedWidth(0),
40+
m_uiEncodedHeight(0),
3741
m_typeFrame(UNKNOWN),
3842
m_bHasAlpha(false),
3943
m_dTime(0.0),
40-
m_FrameDirty(false),
41-
m_iPlaneCount(1)
44+
m_FrameDirty(false)
4245
{
43-
m_piPlaneStrides[0] = m_piPlaneStrides[1] = m_piPlaneStrides[2] = m_piPlaneStrides[3] = 0;
44-
m_pulPlaneSize[0] = m_pulPlaneSize[1] = m_pulPlaneSize[2] = m_pulPlaneSize[3] = 0;
45-
m_pvPlaneData[0] = m_pvPlaneData[1] = m_pvPlaneData[2] = m_pvPlaneData[3] = NULL;
46+
Reset();
4647
}
4748

4849
CVideoFrame::~CVideoFrame()
4950
{
5051
}
5152

52-
int CVideoFrame::GetWidth()
53+
unsigned int CVideoFrame::GetWidth()
5354
{
54-
return m_iWidth;
55+
return m_uiWidth;
5556
}
5657

57-
int CVideoFrame::GetHeight()
58+
unsigned int CVideoFrame::GetHeight()
5859
{
59-
return m_iHeight;
60+
return m_uiHeight;
6061
}
6162

62-
int CVideoFrame::GetEncodedWidth()
63+
unsigned int CVideoFrame::GetEncodedWidth()
6364
{
64-
return m_iEncodedWidth;
65+
return m_uiEncodedWidth;
6566
}
6667

67-
int CVideoFrame::GetEncodedHeight()
68+
unsigned int CVideoFrame::GetEncodedHeight()
6869
{
69-
return m_iEncodedHeight;
70+
return m_uiEncodedHeight;
7071
}
7172

7273
CVideoFrame::FrameType CVideoFrame::GetType()
@@ -84,31 +85,41 @@ double CVideoFrame::GetTime()
8485
return m_dTime;
8586
}
8687

87-
int CVideoFrame::GetPlaneCount()
88+
unsigned int CVideoFrame::GetPlaneCount()
8889
{
89-
return m_iPlaneCount;
90+
return m_uiPlaneCount;
91+
}
92+
93+
void CVideoFrame::SetPlaneCount(unsigned int count)
94+
{
95+
if (count <= MAX_PLANE_COUNT) {
96+
m_uiPlaneCount = count;
97+
} else {
98+
// Should never happen
99+
m_uiPlaneCount = MAX_PLANE_COUNT;
100+
}
90101
}
91102

92-
void* CVideoFrame::GetDataForPlane(int planeIndex)
103+
void* CVideoFrame::GetDataForPlane(unsigned int planeIndex)
93104
{
94-
if (planeIndex < 4 && planeIndex >= 0) {
105+
if (planeIndex < MAX_PLANE_COUNT) {
95106
return m_pvPlaneData[planeIndex];
96107
}
97108
return NULL;
98109
}
99110

100-
unsigned long CVideoFrame::GetSizeForPlane(int planeIndex)
111+
unsigned long CVideoFrame::GetSizeForPlane(unsigned int planeIndex)
101112
{
102-
if (planeIndex < 4 && planeIndex >= 0) {
113+
if (planeIndex < MAX_PLANE_COUNT) {
103114
return m_pulPlaneSize[planeIndex];
104115
}
105116
return 0;
106117
}
107118

108-
int CVideoFrame::GetStrideForPlane(int planeIndex)
119+
unsigned int CVideoFrame::GetStrideForPlane(unsigned int planeIndex)
109120
{
110-
if (planeIndex < 4 && planeIndex >= 0) {
111-
return m_piPlaneStrides[planeIndex];
121+
if (planeIndex < MAX_PLANE_COUNT) {
122+
return m_puiPlaneStrides[planeIndex];
112123
}
113124
return 0;
114125
}
@@ -118,12 +129,22 @@ CVideoFrame *CVideoFrame::ConvertToFormat(FrameType type)
118129
return NULL;
119130
}
120131

121-
void CVideoFrame::SwapPlanes(int aa, int bb)
132+
void CVideoFrame::Reset()
133+
{
134+
m_uiPlaneCount = 0;
135+
for (int i = 0; i < MAX_PLANE_COUNT; i++) {
136+
m_puiPlaneStrides[i] = 0;
137+
m_pulPlaneSize[i] = 0;
138+
m_pvPlaneData[i] = NULL;
139+
}
140+
}
141+
142+
void CVideoFrame::SwapPlanes(unsigned int aa, unsigned int bb)
122143
{
123-
if (aa != bb && aa >= 0 && aa < m_iPlaneCount && bb >= 0 && bb < m_iPlaneCount) {
124-
int stride = m_piPlaneStrides[aa];
125-
m_piPlaneStrides[aa] = m_piPlaneStrides[bb];
126-
m_piPlaneStrides[bb] = stride;
144+
if (aa != bb && aa < m_uiPlaneCount && bb < m_uiPlaneCount) {
145+
unsigned int stride = m_puiPlaneStrides[aa];
146+
m_puiPlaneStrides[aa] = m_puiPlaneStrides[bb];
147+
m_puiPlaneStrides[bb] = stride;
127148

128149
unsigned long size = m_pulPlaneSize[aa];
129150
m_pulPlaneSize[aa] = m_pulPlaneSize[bb];
@@ -134,3 +155,53 @@ void CVideoFrame::SwapPlanes(int aa, int bb)
134155
m_pvPlaneData[bb] = vptr;
135156
}
136157
}
158+
159+
unsigned long CVideoFrame::CalcSize(unsigned int a, unsigned int b, bool *pbValid)
160+
{
161+
if (pbValid == NULL || *(pbValid) == false) {
162+
return 0;
163+
}
164+
165+
if (b > 0 && a <= (UINT_MAX / b)) {
166+
return (a * b);
167+
}
168+
169+
*(pbValid) = false;
170+
return 0;
171+
}
172+
173+
unsigned long CVideoFrame::AddSize(unsigned long a, unsigned long b, bool *pbValid)
174+
{
175+
if (pbValid == NULL || *(pbValid) == false) {
176+
return 0;
177+
}
178+
179+
// unsigned long can be 32-bit or 64-bit, make sure it is no more then UINT_MAX
180+
if (a <= UINT_MAX && b <= UINT_MAX && a <= (UINT_MAX - b)) {
181+
return (a + b);
182+
}
183+
184+
*(pbValid) = false;
185+
return 0;
186+
}
187+
188+
void* CVideoFrame::CalcPlanePointer(intptr_t baseAddress, unsigned int offset,
189+
unsigned long planeSize, unsigned long baseSize,
190+
bool *pbValid)
191+
{
192+
if (pbValid == NULL || *(pbValid) == false) {
193+
return NULL;
194+
}
195+
196+
// We will read planeSize bytes from baseAddress starting with offset, so
197+
// make sure we do not read pass baseSize.
198+
unsigned long endOfPlane = AddSize(offset, planeSize, pbValid);
199+
if (*(pbValid)) { // Make sure AddSize() did not failed.
200+
if (endOfPlane <= baseSize) {
201+
return (void*)(baseAddress + offset);
202+
}
203+
}
204+
205+
*(pbValid) = false;
206+
return NULL;
207+
}

modules/javafx.media/src/main/native/jfxmedia/PipelineManagement/VideoFrame.h

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,9 @@
2727
#define _VIDEO_FRAME_H_
2828

2929
#include <stdlib.h>
30+
#include <stdint.h>
31+
32+
#define MAX_PLANE_COUNT 4
3033

3134
/**
3235
* class CVideoFrame
@@ -56,41 +59,61 @@ class CVideoFrame
5659

5760
double GetTime();
5861

59-
int GetWidth();
60-
int GetHeight();
61-
int GetEncodedWidth();
62-
int GetEncodedHeight();
62+
unsigned int GetWidth();
63+
unsigned int GetHeight();
64+
unsigned int GetEncodedWidth();
65+
unsigned int GetEncodedHeight();
6366

6467
FrameType GetType();
6568
bool HasAlpha();
6669

67-
int GetPlaneCount();
68-
void* GetDataForPlane(int planeIndex);
69-
unsigned long GetSizeForPlane(int planeIndex);
70-
int GetStrideForPlane(int planeIndex);
70+
unsigned int GetPlaneCount();
71+
void SetPlaneCount(unsigned int count);
72+
void* GetDataForPlane(unsigned int planeIndex);
73+
unsigned long GetSizeForPlane(unsigned int planeIndex);
74+
unsigned int GetStrideForPlane(unsigned int planeIndex);
7175

7276
virtual CVideoFrame *ConvertToFormat(FrameType type);
7377

7478
bool GetFrameDirty() { return m_FrameDirty; }
7579
void SetFrameDirty(bool dirty) { m_FrameDirty = dirty; }
7680

7781
protected:
78-
int m_iWidth;
79-
int m_iHeight;
80-
int m_iEncodedWidth;
81-
int m_iEncodedHeight;
82+
unsigned int m_uiWidth;
83+
unsigned int m_uiHeight;
84+
unsigned int m_uiEncodedWidth;
85+
unsigned int m_uiEncodedHeight;
8286
FrameType m_typeFrame;
8387
bool m_bHasAlpha;
8488
double m_dTime;
8589
bool m_FrameDirty;
8690

8791
// frame data buffers
88-
int m_iPlaneCount;
89-
void* m_pvPlaneData[4];
90-
unsigned long m_pulPlaneSize[4];
91-
int m_piPlaneStrides[4];
92+
void* m_pvPlaneData[MAX_PLANE_COUNT];
93+
unsigned long m_pulPlaneSize[MAX_PLANE_COUNT];
94+
unsigned int m_puiPlaneStrides[MAX_PLANE_COUNT];
95+
96+
void Reset();
97+
void SwapPlanes(unsigned int aa, unsigned int bb);
98+
99+
// CalcSize(), AddSize(), CalcPlanePointer() requires bValid to be set to
100+
// true initially, if bValid is false these functions do nothing. It is
101+
// implemented this way, so all these functions can be chain called without
102+
// checking bValid after each call. bValid will be set to false only if
103+
// calculation failed and will never be set to true.
104+
// Multiplies a and b, bValid set to false if integer overflow detected.
105+
unsigned long CalcSize(unsigned int a, unsigned int b, bool *pbValid);
106+
// Adds a and b, bValid set to false if integer overflow detected.
107+
unsigned long AddSize(unsigned long a, unsigned long b, bool *pbValid);
108+
// Calculates plane pointer (baseAddress + offset) and checks that calculated
109+
// pointer within buffer. Returns NULL and sets bValid to false if calculated
110+
// pointer is invalid.
111+
void* CalcPlanePointer(intptr_t baseAddress, unsigned int offset,
112+
unsigned long planeSize, unsigned long baseSize,
113+
bool *pbValid);
92114

93-
void SwapPlanes(int aa, int bb);
115+
private:
116+
unsigned int m_uiPlaneCount;
94117
};
95118

96119
#endif //_VIDEO_FRAME_H_

modules/javafx.media/src/main/native/jfxmedia/jni/NativeVideoBuffer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ JNIEXPORT jobject JNICALL Java_com_sun_media_jfxmediaimpl_NativeVideoBuffer_nati
7171
{
7272
CVideoFrame *frame = (CVideoFrame*)jlong_to_ptr(nativeHandle);
7373
if (frame) {
74-
void *dataPtr = frame->GetDataForPlane((int)plane);
75-
jlong capacity = (jlong)frame->GetSizeForPlane((int)plane);
74+
void *dataPtr = frame->GetDataForPlane((unsigned int)plane);
75+
jlong capacity = (jlong)frame->GetSizeForPlane((unsigned int)plane);
7676
jobject buffer = env->NewDirectByteBuffer(dataPtr, capacity);
7777
if (env->ExceptionCheck()) {
7878
env->ExceptionClear();
@@ -215,7 +215,7 @@ JNIEXPORT jintArray JNICALL Java_com_sun_media_jfxmediaimpl_NativeVideoBuffer_na
215215
return NULL;
216216
}
217217

218-
for (int ii=0; ii < count; ii++) {
218+
for (unsigned int ii=0; ii < count; ii++) {
219219
strideArray[ii] = frame->GetStrideForPlane(ii);
220220
}
221221

0 commit comments

Comments
 (0)