зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 970691) for build bustage on a CLOSED TREE
Backed out changeset 83f7aec5a083 (bug 970691) Backed out changeset 94348d189ed5 (bug 970691)
This commit is contained in:
Родитель
2ecbad7b1c
Коммит
50c5a26e84
|
@ -22,8 +22,6 @@
|
|||
#include "nsISupportsUtils.h"
|
||||
#endif
|
||||
|
||||
#include "YuvStamper.h"
|
||||
|
||||
#define VIDEO_RATE USECS_PER_S
|
||||
#define AUDIO_RATE 16000
|
||||
#define AUDIO_FRAME_LENGTH ((AUDIO_RATE * MediaEngine::DEFAULT_AUDIO_TIMER_MS) / 1000)
|
||||
|
@ -241,13 +239,6 @@ MediaEngineDefaultVideoSource::Notify(nsITimer* aTimer)
|
|||
static_cast<layers::PlanarYCbCrImage*>(image.get());
|
||||
layers::PlanarYCbCrData data;
|
||||
AllocateSolidColorFrame(data, mOpts.mWidth, mOpts.mHeight, 0x80, mCb, mCr);
|
||||
|
||||
uint64_t timestamp = PR_Now();
|
||||
YuvStamper::Encode(mOpts.mWidth, mOpts.mHeight, mOpts.mWidth,
|
||||
reinterpret_cast<uint8_t*>(data.mYChannel),
|
||||
reinterpret_cast<uint8_t*>(×tamp), sizeof(timestamp),
|
||||
0, 0);
|
||||
|
||||
ycbcr_image->SetData(data);
|
||||
// SetData copies data, so we can free the frame
|
||||
ReleaseFrame(data);
|
||||
|
|
|
@ -214,5 +214,3 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
|
|||
)
|
||||
GYP_DIRS['signalingtest'].non_unified_sources += signaling_non_unified_sources
|
||||
GYP_DIRS['signalingtest'].non_unified_sources += signaling_non_unified_sources_2
|
||||
|
||||
EXPORTS += ['signaling/src/media-conduit/YuvStamper.h']
|
||||
|
|
|
@ -66,7 +66,6 @@
|
|||
'../../../netwerk/srtp/src/include',
|
||||
'../../../netwerk/srtp/src/crypto/include',
|
||||
'../../../ipc/chromium/src',
|
||||
'../../mtransport/third_party/nrappkit/src/util/libekr',
|
||||
],
|
||||
|
||||
#
|
||||
|
@ -88,9 +87,6 @@
|
|||
'./src/media-conduit/AudioConduit.cpp',
|
||||
'./src/media-conduit/VideoConduit.h',
|
||||
'./src/media-conduit/VideoConduit.cpp',
|
||||
'./src/media-conduit/YuvStamper.h',
|
||||
'./src/media-conduit/YuvStamper.cpp',
|
||||
|
||||
# Common
|
||||
'./src/common/CommonTypes.h',
|
||||
'./src/common/csf_common.h',
|
||||
|
|
|
@ -11,11 +11,8 @@
|
|||
#include "VideoConduit.h"
|
||||
#include "AudioConduit.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "LoadManager.h"
|
||||
#include "YuvStamper.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
|
||||
#include "webrtc/common_video/interface/native_handle.h"
|
||||
#include "webrtc/video_engine/include/vie_errors.h"
|
||||
|
@ -736,24 +733,9 @@ WebrtcVideoConduit::ConfigureRecvMediaCodecs(
|
|||
error = mPtrViEBase->LastError();
|
||||
CSFLogError(logTag, "%s Start Receive Error %d ", __FUNCTION__, error);
|
||||
|
||||
|
||||
return kMediaConduitUnknownError;
|
||||
}
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
if (NS_IsMainThread()) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
|
||||
|
||||
if (branch) {
|
||||
branch->GetBoolPref("media.video.test_latency", &mVideoLatencyTestEnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// by now we should be successfully started the reception
|
||||
mPtrRTP->SetRembStatus(mChannel, false, true);
|
||||
mEngineReceiving = true;
|
||||
|
@ -1068,10 +1050,6 @@ WebrtcVideoConduit::FrameSizeChange(unsigned int width,
|
|||
{
|
||||
CSFLogDebug(logTag, "%s ", __FUNCTION__);
|
||||
|
||||
|
||||
mReceivingWidth = width;
|
||||
mReceivingHeight = height;
|
||||
|
||||
if(mRenderer)
|
||||
{
|
||||
mRenderer->FrameSizeChange(width, height, numStreams);
|
||||
|
@ -1101,18 +1079,6 @@ WebrtcVideoConduit::DeliverFrame(unsigned char* buffer,
|
|||
img = static_cast<layers::Image*>(native_h->GetHandle());
|
||||
}
|
||||
|
||||
if (mVideoLatencyTestEnable && mReceivingWidth && mReceivingHeight) {
|
||||
uint64_t now = PR_Now();
|
||||
uint64_t timestamp = 0;
|
||||
bool ok = YuvStamper::Decode(mReceivingWidth, mReceivingHeight, mReceivingWidth,
|
||||
buffer,
|
||||
reinterpret_cast<uint8_t*>(×tamp),
|
||||
sizeof(timestamp), 0, 0);
|
||||
if (ok) {
|
||||
VideoLatencyUpdate(now - timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
const ImageHandle img_h(img);
|
||||
mRenderer->RenderVideoFrame(buffer, buffer_size, time_stamp, render_time,
|
||||
img_h);
|
||||
|
@ -1241,16 +1207,4 @@ WebrtcVideoConduit::DumpCodecDB() const
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebrtcVideoConduit::VideoLatencyUpdate(uint64_t newSample)
|
||||
{
|
||||
mVideoLatencyAvg = (sRoundingPadding * newSample + sAlphaNum * mVideoLatencyAvg) / sAlphaDen;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
WebrtcVideoConduit::MozVideoLatencyAvg()
|
||||
{
|
||||
return mVideoLatencyAvg / sRoundingPadding;
|
||||
}
|
||||
|
||||
}// end namespace
|
||||
|
|
|
@ -228,11 +228,7 @@ public:
|
|||
mCapId(-1),
|
||||
mCurSendCodecConfig(nullptr),
|
||||
mSendingWidth(0),
|
||||
mSendingHeight(0),
|
||||
mReceivingWidth(640),
|
||||
mReceivingHeight(480),
|
||||
mVideoLatencyTestEnable(false),
|
||||
mVideoLatencyAvg(0)
|
||||
mSendingHeight(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -257,7 +253,6 @@ public:
|
|||
bool GetRTCPSenderReport(DOMHighResTimeStamp* timestamp,
|
||||
unsigned int* packetsSent,
|
||||
uint64_t* bytesSent);
|
||||
uint64_t MozVideoLatencyAvg();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -286,9 +281,6 @@ private:
|
|||
//Utility function to dump recv codec database
|
||||
void DumpCodecDB() const;
|
||||
|
||||
// Video Latency Test averaging filter
|
||||
void VideoLatencyUpdate(uint64_t new_sample);
|
||||
|
||||
// The two sides of a send/receive pair of conduits each keep a pointer to the other.
|
||||
// They also share a single VideoEngine and mChannel. Shutdown must be coordinated
|
||||
// carefully to avoid double-freeing or accessing after one frees.
|
||||
|
@ -322,14 +314,6 @@ private:
|
|||
VideoCodecConfig* mCurSendCodecConfig;
|
||||
unsigned short mSendingWidth;
|
||||
unsigned short mSendingHeight;
|
||||
unsigned short mReceivingWidth;
|
||||
unsigned short mReceivingHeight;
|
||||
bool mVideoLatencyTestEnable;
|
||||
uint64_t mVideoLatencyAvg;
|
||||
|
||||
static const unsigned int sAlphaNum = 7;
|
||||
static const unsigned int sAlphaDen = 8;
|
||||
static const unsigned int sRoundingPadding = 1024;
|
||||
|
||||
mozilla::RefPtr<WebrtcAudioConduit> mSyncedTo;
|
||||
};
|
||||
|
|
|
@ -1,458 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#elif defined XP_WIN
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include "nspr.h"
|
||||
#include "YuvStamper.h"
|
||||
|
||||
typedef uint32_t UINT4; //Needed for r_crc32() call
|
||||
extern "C" {
|
||||
#include "r_crc32.h"
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
#define ON_5 0x20
|
||||
#define ON_4 0x10
|
||||
#define ON_3 0x08
|
||||
#define ON_2 0x04
|
||||
#define ON_1 0x02
|
||||
#define ON_0 0x01
|
||||
|
||||
/*
|
||||
0, 0, 1, 1, 0, 0,
|
||||
0, 1, 0, 0, 1, 0,
|
||||
1, 0, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 0, 1,
|
||||
0, 1, 0, 0, 1, 0,
|
||||
0, 0, 1, 1, 0, 0
|
||||
*/
|
||||
static unsigned char DIGIT_0 [] =
|
||||
{ ON_3 | ON_2,
|
||||
ON_4 | ON_1,
|
||||
ON_5 | ON_0,
|
||||
ON_5 | ON_0,
|
||||
ON_5 | ON_0,
|
||||
ON_4 | ON_1,
|
||||
ON_3 | ON_2
|
||||
};
|
||||
|
||||
/*
|
||||
0, 0, 0, 1, 0, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
*/
|
||||
static unsigned char DIGIT_1 [] =
|
||||
{ ON_2,
|
||||
ON_2,
|
||||
ON_2,
|
||||
ON_2,
|
||||
ON_2,
|
||||
ON_2,
|
||||
ON_2
|
||||
};
|
||||
|
||||
/*
|
||||
1, 1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1,
|
||||
*/
|
||||
static unsigned char DIGIT_2 [] =
|
||||
{ ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
|
||||
ON_0,
|
||||
ON_0,
|
||||
ON_4 | ON_3 | ON_2 | ON_1,
|
||||
ON_5,
|
||||
ON_5,
|
||||
ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
|
||||
};
|
||||
|
||||
/*
|
||||
1, 1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 1, 0,
|
||||
*/
|
||||
static unsigned char DIGIT_3 [] =
|
||||
{ ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
|
||||
ON_0,
|
||||
ON_0,
|
||||
ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
|
||||
ON_0,
|
||||
ON_0,
|
||||
ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
|
||||
};
|
||||
|
||||
/*
|
||||
0, 1, 0, 0, 0, 1,
|
||||
0, 1, 0, 0, 0, 1,
|
||||
0, 1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 1
|
||||
*/
|
||||
static unsigned char DIGIT_4 [] =
|
||||
{ ON_4 | ON_0,
|
||||
ON_4 | ON_0,
|
||||
ON_4 | ON_0,
|
||||
ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
|
||||
ON_0,
|
||||
ON_0,
|
||||
ON_0,
|
||||
};
|
||||
|
||||
/*
|
||||
0, 1, 1, 1, 1, 1,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 1, 0,
|
||||
*/
|
||||
static unsigned char DIGIT_5 [] =
|
||||
{ ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
|
||||
ON_5,
|
||||
ON_5,
|
||||
ON_4 | ON_3 | ON_2 | ON_1,
|
||||
ON_0,
|
||||
ON_0,
|
||||
ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
|
||||
};
|
||||
|
||||
/*
|
||||
0, 1, 1, 1, 1, 1,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 1, 0,
|
||||
*/
|
||||
static unsigned char DIGIT_6 [] =
|
||||
{ ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
|
||||
ON_5,
|
||||
ON_5,
|
||||
ON_4 | ON_3 | ON_2 | ON_1,
|
||||
ON_5 | ON_0,
|
||||
ON_5 | ON_0,
|
||||
ON_4 | ON_3 | ON_2 | ON_1,
|
||||
};
|
||||
|
||||
/*
|
||||
1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1, 0,
|
||||
0, 0, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0, 0,
|
||||
0, 1, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0, 0
|
||||
*/
|
||||
static unsigned char DIGIT_7 [] =
|
||||
{ ON_5 | ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
|
||||
ON_0,
|
||||
ON_1,
|
||||
ON_2,
|
||||
ON_3,
|
||||
ON_4,
|
||||
ON_5
|
||||
};
|
||||
|
||||
/*
|
||||
0, 1, 1, 1, 1, 1,
|
||||
1, 0, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 1, 0
|
||||
*/
|
||||
static unsigned char DIGIT_8 [] =
|
||||
{ ON_4 | ON_3 | ON_2 | ON_1,
|
||||
ON_5 | ON_0,
|
||||
ON_5 | ON_0,
|
||||
ON_4 | ON_3 | ON_2 | ON_1,
|
||||
ON_5 | ON_0,
|
||||
ON_5 | ON_0,
|
||||
ON_4 | ON_3 | ON_2 | ON_1,
|
||||
};
|
||||
|
||||
/*
|
||||
0, 1, 1, 1, 1, 1,
|
||||
1, 0, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 1, 0
|
||||
*/
|
||||
static unsigned char DIGIT_9 [] =
|
||||
{ ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
|
||||
ON_5 | ON_0,
|
||||
ON_5 | ON_0,
|
||||
ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
|
||||
ON_0,
|
||||
ON_0,
|
||||
ON_4 | ON_3 | ON_2 | ON_1,
|
||||
};
|
||||
|
||||
static unsigned char *DIGITS[] = {
|
||||
DIGIT_0,
|
||||
DIGIT_1,
|
||||
DIGIT_2,
|
||||
DIGIT_3,
|
||||
DIGIT_4,
|
||||
DIGIT_5,
|
||||
DIGIT_6,
|
||||
DIGIT_7,
|
||||
DIGIT_8,
|
||||
DIGIT_9
|
||||
};
|
||||
|
||||
YuvStamper::YuvStamper(uint8_t* pYData,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t stride,
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
uint8_t symbol_width,
|
||||
uint8_t symbol_height):
|
||||
pYData(pYData), mStride(stride),
|
||||
mWidth(width), mHeight(height),
|
||||
mSymbolWidth(symbol_width), mSymbolHeight(symbol_height),
|
||||
mCursor(x, y) {}
|
||||
|
||||
bool YuvStamper::Encode(uint32_t width, uint32_t height, uint32_t stride,
|
||||
uint8_t* pYData, uint8_t* pMsg, size_t msg_len,
|
||||
uint32_t x, uint32_t y)
|
||||
{
|
||||
YuvStamper stamper(pYData, width, height, stride,
|
||||
x, y, sBitSize, sBitSize);
|
||||
|
||||
// Reserve space for a checksum.
|
||||
if (stamper.Capacity() < 8 * (msg_len + sizeof(uint32_t)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
uint32_t crc;
|
||||
uint8_t* pCrc = reinterpret_cast<uint8_t*>(&crc);
|
||||
r_crc32(reinterpret_cast<char*>(pMsg), (int)msg_len, &crc);
|
||||
crc = htonl(crc);
|
||||
|
||||
while (msg_len-- > 0) {
|
||||
if (!stamper.Write8(*pMsg++)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Add checksum after the message.
|
||||
ok = stamper.Write8(*pCrc++) &&
|
||||
stamper.Write8(*pCrc++) &&
|
||||
stamper.Write8(*pCrc++) &&
|
||||
stamper.Write8(*pCrc++);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool YuvStamper::Decode(uint32_t width, uint32_t height, uint32_t stride,
|
||||
uint8_t* pYData, uint8_t* pMsg, size_t msg_len,
|
||||
uint32_t x, uint32_t y)
|
||||
{
|
||||
YuvStamper stamper(pYData, width, height, stride,
|
||||
x, y, sBitSize, sBitSize);
|
||||
|
||||
uint8_t* ptr = pMsg;
|
||||
size_t len = msg_len;
|
||||
uint32_t crc, msg_crc;
|
||||
uint8_t* pCrc = reinterpret_cast<uint8_t*>(&crc);
|
||||
|
||||
// Account for space reserved for the checksum
|
||||
if (stamper.Capacity() < 8 * (len + sizeof(uint32_t))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (len-- > 0) {
|
||||
if(!stamper.Read8(*ptr++)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(stamper.Read8(*pCrc++) &&
|
||||
stamper.Read8(*pCrc++) &&
|
||||
stamper.Read8(*pCrc++) &&
|
||||
stamper.Read8(*pCrc++))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
r_crc32(reinterpret_cast<char*>(pMsg), (int)msg_len, &msg_crc);
|
||||
return crc == htonl(msg_crc);
|
||||
}
|
||||
|
||||
inline uint32_t YuvStamper::Capacity()
|
||||
{
|
||||
// Enforce at least a symbol width and height offset from outer edges.
|
||||
if (mCursor.y + mSymbolHeight > mHeight) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mCursor.x + mSymbolWidth > mWidth && !AdvanceCursor()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Normalize frame integral to sBitSize x sBitSize
|
||||
uint32_t width = mWidth / mSymbolWidth;
|
||||
uint32_t height = mHeight / mSymbolHeight;
|
||||
uint32_t x = mCursor.x / mSymbolWidth;
|
||||
uint32_t y = mCursor.y / mSymbolHeight;
|
||||
|
||||
return (width * height - width * y)- x;
|
||||
}
|
||||
|
||||
bool YuvStamper::Write8(uint8_t value)
|
||||
{
|
||||
// Encode MSB to LSB.
|
||||
uint8_t mask = 0x80;
|
||||
while (mask) {
|
||||
if (!WriteBit(!!(value & mask))) {
|
||||
return false;
|
||||
}
|
||||
mask >>= 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool YuvStamper::WriteBit(bool one)
|
||||
{
|
||||
// A bit is mapped to a sBitSize x sBitSize square of luma data points.
|
||||
uint8_t value = one ? sYOn : sYOff;
|
||||
for (uint32_t y = 0; y < mSymbolHeight; y++) {
|
||||
for (uint32_t x = 0; x < mSymbolWidth; x++) {
|
||||
*(pYData + (mCursor.x + x) + ((mCursor.y + y) * mStride)) = value;
|
||||
}
|
||||
}
|
||||
|
||||
return AdvanceCursor();
|
||||
}
|
||||
|
||||
bool YuvStamper::AdvanceCursor()
|
||||
{
|
||||
mCursor.x += mSymbolWidth;
|
||||
if (mCursor.x + mSymbolWidth > mWidth) {
|
||||
// move to the start of the next row if possible.
|
||||
mCursor.y += mSymbolHeight;
|
||||
if (mCursor.y + mSymbolHeight > mHeight) {
|
||||
// end of frame, do not advance
|
||||
mCursor.y -= mSymbolHeight;
|
||||
mCursor.x -= mSymbolWidth;
|
||||
return false;
|
||||
} else {
|
||||
mCursor.x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool YuvStamper::Read8(uint8_t &value)
|
||||
{
|
||||
uint8_t octet = 0;
|
||||
uint8_t bit = 0;
|
||||
|
||||
for (int i = 8; i > 0; --i) {
|
||||
if (!ReadBit(bit)) {
|
||||
return false;
|
||||
}
|
||||
octet <<= 1;
|
||||
octet |= bit;
|
||||
}
|
||||
|
||||
value = octet;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool YuvStamper::ReadBit(uint8_t &bit)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
for (uint32_t y = 0; y < mSymbolHeight; y++) {
|
||||
for (uint32_t x = 0; x < mSymbolWidth; x++) {
|
||||
sum += *(pYData + mStride * (mCursor.y + y) + mCursor.x + x);
|
||||
}
|
||||
}
|
||||
|
||||
// apply threshold to collected bit square
|
||||
bit = (sum > (sBitThreshold * mSymbolWidth * mSymbolHeight)) ? 1 : 0;
|
||||
return AdvanceCursor();
|
||||
}
|
||||
|
||||
bool YuvStamper::WriteDigits(uint32_t value)
|
||||
{
|
||||
char buf[20];
|
||||
PR_snprintf(buf, sizeof(buf), "%.5u", value);
|
||||
size_t size = strlen(buf);
|
||||
|
||||
if (Capacity() < size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i=0; i < size; ++i) {
|
||||
if (!WriteDigit(buf[i] - '0'))
|
||||
return false;
|
||||
if (!AdvanceCursor()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool YuvStamper::WriteDigit(uint8_t digit) {
|
||||
if (digit > sizeof(DIGITS)/sizeof(DIGITS[0]))
|
||||
return false;
|
||||
|
||||
unsigned char *dig = DIGITS[digit];
|
||||
for (uint32_t row = 0; row < sDigitHeight; ++row) {
|
||||
unsigned char mask = 0x01 << (sDigitWidth - 1);
|
||||
for (uint32_t col = 0; col < sDigitWidth; ++col, mask >>= 1) {
|
||||
if (dig[row] & mask) {
|
||||
for (uint32_t xx=0; xx < sPixelSize; ++xx) {
|
||||
for (uint32_t yy=0; yy < sPixelSize; ++yy) {
|
||||
WritePixel(pYData,
|
||||
mCursor.x + (col * sPixelSize) + xx,
|
||||
mCursor.y + (row * sPixelSize) + yy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void YuvStamper::WritePixel(uint8_t *data, uint32_t x, uint32_t y) {
|
||||
uint8_t *ptr = &data[y * mStride + x];
|
||||
*ptr = (*ptr > sLumaThreshold) ? sLumaMin : sLumaMax;
|
||||
return;
|
||||
}
|
||||
|
||||
} // Namespace mozilla.
|
|
@ -1,76 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class
|
||||
YuvStamper {
|
||||
public:
|
||||
bool WriteDigits(uint32_t value);
|
||||
|
||||
template<typename T>
|
||||
static bool Write(uint32_t width, uint32_t height, uint32_t stride,
|
||||
uint8_t *pYData, const T& value,
|
||||
uint32_t x=0, uint32_t y=0)
|
||||
{
|
||||
YuvStamper stamper(pYData, width, height, stride,
|
||||
x, y,
|
||||
(sDigitWidth + sInterDigit) * sPixelSize,
|
||||
(sDigitHeight + sInterLine) * sPixelSize);
|
||||
return stamper.WriteDigits(value);
|
||||
}
|
||||
|
||||
static bool Encode(uint32_t width, uint32_t height, uint32_t stride,
|
||||
uint8_t* pYData, uint8_t* pMsg, size_t msg_len,
|
||||
uint32_t x = 0, uint32_t y = 0);
|
||||
|
||||
static bool Decode(uint32_t width, uint32_t height, uint32_t stride,
|
||||
uint8_t* pYData, uint8_t* pMsg, size_t msg_len,
|
||||
uint32_t x = 0, uint32_t y = 0);
|
||||
|
||||
private:
|
||||
YuvStamper(uint8_t* pYData,
|
||||
uint32_t width, uint32_t height, uint32_t stride,
|
||||
uint32_t x, uint32_t y,
|
||||
uint8_t symbol_width, uint8_t symbol_height);
|
||||
|
||||
bool WriteDigit(uint8_t digit);
|
||||
void WritePixel(uint8_t* data, uint32_t x, uint32_t y);
|
||||
|
||||
uint32_t Capacity();
|
||||
bool AdvanceCursor();
|
||||
bool WriteBit(bool one);
|
||||
bool Write8(uint8_t value);
|
||||
bool ReadBit(uint8_t &value);
|
||||
bool Read8(uint8_t &bit);
|
||||
|
||||
const static uint8_t sPixelSize = 3;
|
||||
const static uint8_t sDigitWidth = 6;
|
||||
const static uint8_t sDigitHeight = 7;
|
||||
const static uint8_t sInterDigit = 1;
|
||||
const static uint8_t sInterLine = 1;
|
||||
const static uint32_t sBitSize = 4;
|
||||
const static uint32_t sBitThreshold = 60;
|
||||
const static uint8_t sYOn = 0x80;
|
||||
const static uint8_t sYOff = 0;
|
||||
const static uint8_t sLumaThreshold = 96;
|
||||
const static uint8_t sLumaMin = 16;
|
||||
const static uint8_t sLumaMax = 235;
|
||||
|
||||
uint8_t* pYData;
|
||||
uint32_t mStride;
|
||||
uint32_t mWidth;
|
||||
uint32_t mHeight;
|
||||
uint8_t mSymbolWidth;
|
||||
uint8_t mSymbolHeight;
|
||||
|
||||
struct Cursor {
|
||||
Cursor(uint32_t x, uint32_t y):
|
||||
x(x), y(y) {}
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
} mCursor;
|
||||
};
|
||||
|
||||
}
|
Загрузка…
Ссылка в новой задаче