492 lines
18 KiB
C++
492 lines
18 KiB
C++
/*
|
|
* Copyright (C) 2014-2019 Amlogic, Inc. All rights reserved.
|
|
*
|
|
* All information contained herein is Amlogic confidential.
|
|
*
|
|
* This software is provided to you pursuant to Software License Agreement
|
|
* (SLA) with Amlogic Inc ("Amlogic"). This software may be used
|
|
* only in accordance with the terms of this agreement.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification is strictly prohibited without prior written permission from
|
|
* Amlogic.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
#define LOG_TAG "SocketAPI"
|
|
|
|
#include "SubtitleReportAPI.h"
|
|
|
|
#include <SubtitleType.h>
|
|
#include <fcntl.h>
|
|
#include <inttypes.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <utils/CallStack.h>
|
|
|
|
#include <mutex>
|
|
|
|
#include "AmSocketClient.h"
|
|
#include "SubtitleClientLinux.h"
|
|
#include "SubtitleLog.h"
|
|
|
|
int mLastDuration = 0;
|
|
int mSubType = 0;
|
|
int mSubTotal = 0;
|
|
char mSubTypeStr[1024] = {0};
|
|
char mSubLanStr[1024] = {0};
|
|
|
|
typedef struct {
|
|
SubtitleClientLinux *mRemote;
|
|
std::unique_ptr<AmSocketClient> mSocketClient;
|
|
int sId;
|
|
std::mutex mLock; // TODO: maybe we need global lock
|
|
} SubtitleReportContext;
|
|
|
|
typedef enum {
|
|
SUBTITLE_TOTAL_TRACK = 0x53544F54, // 'STOT'
|
|
SUBTITLE_START_PTS = 0x53505453, // 'SPTS'
|
|
SUBTITLE_RENDER_TIME = 0x53524454, // 'SRDT'
|
|
SUBTITLE_SUB_TYPE = 0x53545950, // 'STYP'
|
|
SUBTITLE_TYPE_STRING = 0x54505352, // 'TPSR'
|
|
SUBTITLE_LANG_STRING = 0x4C475352, // 'LGSR'
|
|
SUBTITLE_SUB_DATA = 0x504C4454, // 'PLDT'
|
|
|
|
SUBTITLE_RESET_SERVER = 0x43545244, // 'CDRT'
|
|
SUBTITLE_EXIT_SERVER = 0x43444558 // 'CDEX'
|
|
|
|
} PayloadType;
|
|
|
|
/**
|
|
payload is:
|
|
startFlag : 4bytes
|
|
sessionID : 4Bytes (TBD)
|
|
magic : 4bytes (for double confirm)
|
|
payload size: 4Bytes (indicate the size of payload, size is total_send_bytes - 4*5)
|
|
exclude this and above 4 items.
|
|
payload Type: defined in PayloadType_t
|
|
payload data: TO BE PARSED data
|
|
*/
|
|
|
|
const static unsigned int START_FLAG = 0xF0D0C0B1;
|
|
const static unsigned int MAGIC_FLAG = 0xCFFFFFFB;
|
|
|
|
const static unsigned int HEADER_SIZE = 4 * 5;
|
|
|
|
static void inline makeHeader(char *buf, int sessionId, PayloadType t, int payloadSize) {
|
|
unsigned int val = START_FLAG;
|
|
memcpy(buf, &val, sizeof(val));
|
|
|
|
memcpy(buf + sizeof(int), &sessionId, sizeof(int));
|
|
|
|
val = MAGIC_FLAG; // magic
|
|
memcpy(buf + 2 * sizeof(int), &val, sizeof(int));
|
|
|
|
memcpy(buf + 3 * sizeof(int), &payloadSize, sizeof(int));
|
|
|
|
val = t;
|
|
memcpy(buf + 4 * sizeof(val), &val, sizeof(val));
|
|
}
|
|
|
|
static void socketSendData(SubtitleReportContext *ctx, const char *mbuf, size_t length,
|
|
int64_t pts) {
|
|
if (mbuf == NULL) {
|
|
return;
|
|
}
|
|
unsigned int sub_type;
|
|
float duration = 0;
|
|
int64_t sub_pts = 0;
|
|
int64_t start_time = 0;
|
|
int data_size = length;
|
|
if (length <= 0) {
|
|
SUBTITLE_LOGE("[sendToSubtitleService]not enough data.data_size:%d\n", length);
|
|
return;
|
|
}
|
|
sub_type = CODEC_ID_DVB_SUBTITLE; // streamCodecID;
|
|
if (sub_type == CODEC_ID_DVD_SUBTITLE) {
|
|
mSubType = 0;
|
|
} else if (sub_type == CODEC_ID_HDMV_PGS_SUBTITLE) {
|
|
mSubType = 1;
|
|
} else if (sub_type == CODEC_ID_XSUB) {
|
|
mSubType = 2;
|
|
} else if (sub_type == CODEC_ID_TEXT || sub_type == CODEC_ID_SSA || sub_type == CODEC_ID_ASS) {
|
|
mSubType = 3;
|
|
} else if (sub_type == CODEC_ID_DVB_SUBTITLE) {
|
|
mSubType = 5;
|
|
} else if (sub_type == 0x17005) {
|
|
mSubType = 7;
|
|
} else if (sub_type == CODEC_ID_DVB_TELETEXT) {
|
|
mSubType = 9; // SUBTITLE_DVB_TELETEXT
|
|
} else {
|
|
mSubType = 4;
|
|
}
|
|
// if (mDebug) {
|
|
// SUBTITLE_LOGE("[sendToSubtitleService]sub_type:0x%x, data_size:%d, sub_pts:%" PRId64
|
|
// "\n", sub_type, data_size, pts);
|
|
// }
|
|
|
|
if (sub_type == 0x17000) {
|
|
sub_type = 0x1700a;
|
|
} else if (sub_type == 0x17002) {
|
|
mLastDuration = 0; //(unsigned)pktConvergenceDuration * 90;
|
|
}
|
|
// 0x1780d:mkv internal ass 0x17808:internal UTF-8
|
|
else if (sub_type == 0x1780d || sub_type == 0x17808) {
|
|
mLastDuration = 0; //(unsigned)pktDuration * 90; //time(ms) convert to pts, need *90
|
|
} else if (sub_type == 0x17003) {
|
|
return; // not need to support xsub
|
|
}
|
|
unsigned char sub_header[24] = {0x41, 0x4d, 0x4c, 0x55, 0x77, 0};
|
|
// unsigned char sub_header[24] = {0};
|
|
// unsigned char subInfo_header[10] = {0}; //add info header mSubType, mSubTotal send with
|
|
// subtitle packet.
|
|
sub_header[5] = (sub_type >> 16) & 0xff;
|
|
sub_header[6] = (sub_type >> 8) & 0xff;
|
|
sub_header[7] = sub_type & 0xff;
|
|
sub_header[8] = (data_size >> 24) & 0xff;
|
|
sub_header[9] = (data_size >> 16) & 0xff;
|
|
sub_header[10] = (data_size >> 8) & 0xff;
|
|
sub_header[11] = data_size & 0xff;
|
|
sub_header[12] = (pts >> 56) & 0xff;
|
|
sub_header[13] = (pts >> 48) & 0xff;
|
|
sub_header[14] = (pts >> 40) & 0xff;
|
|
sub_header[15] = (pts >> 32) & 0xff;
|
|
sub_header[16] = (pts >> 24) & 0xff;
|
|
sub_header[17] = (pts >> 16) & 0xff;
|
|
sub_header[18] = (pts >> 8) & 0xff;
|
|
sub_header[19] = pts & 0xff;
|
|
sub_header[20] = (mLastDuration >> 24) & 0xff;
|
|
sub_header[21] = (mLastDuration >> 16) & 0xff;
|
|
sub_header[22] = (mLastDuration >> 8) & 0xff;
|
|
sub_header[23] = mLastDuration & 0xff;
|
|
int size = 24 + data_size + 5 * 4;
|
|
int data_length = 24 + data_size;
|
|
char *data = (char *)malloc(size);
|
|
memset(data, 0, size);
|
|
int sessionId = 1;
|
|
unsigned int val = START_FLAG;
|
|
memcpy(data, &val, sizeof(val));
|
|
memcpy(data + 1 * sizeof(int), &sessionId, sizeof(int));
|
|
int val1 = MAGIC_FLAG; // magic
|
|
memcpy(data + 2 * sizeof(int), &val1, sizeof(int));
|
|
memcpy(data + 3 * sizeof(int), &data_length, sizeof(int));
|
|
int type = SUBTITLE_SUB_DATA;
|
|
memcpy(data + 4 * sizeof(int), &type, sizeof(int));
|
|
memcpy(data + 5 * sizeof(int), sub_header, 24);
|
|
memcpy(data + 5 * sizeof(int) + 24, mbuf, data_size);
|
|
if (ctx->mSocketClient != NULL) {
|
|
usleep(500);
|
|
ctx->mSocketClient->socketSend(data, size);
|
|
} else {
|
|
SUBTITLE_LOGE("[sendToSubtitleService] mClient == NULL\n");
|
|
}
|
|
if (data != nullptr) {
|
|
free(data);
|
|
data = nullptr;
|
|
}
|
|
}
|
|
|
|
// TODO: move all the report API to subtitlebinder
|
|
SubSourceHandle SubSource_Create(int sId) {
|
|
SubtitleReportContext *ctx = new SubtitleReportContext();
|
|
if (ctx == nullptr) return nullptr;
|
|
SUBTITLE_LOGI("SubSource Create %d", sId);
|
|
ctx->mLock.lock();
|
|
SUBTITLE_LOGI("ctx->mSocketClient: %p", ctx->mSocketClient.get());
|
|
if (ctx->mSocketClient == NULL) {
|
|
std::unique_ptr<AmSocketClient> pTemp(new AmSocketClient);
|
|
ctx->mSocketClient = std::move(pTemp); // unique_ptr<AmSocketClient>;//new
|
|
// AmSocketClient();
|
|
// socket may not ready due to 2 process synchr, checking and retry
|
|
int retry = 100;
|
|
while (retry-- >= 0) {
|
|
SUBTITLE_LOGI("socketConnect..., %d", retry);
|
|
if (ctx->mSocketClient->socketConnect() == 0) {
|
|
break;
|
|
}
|
|
usleep(10 * 1000);
|
|
}
|
|
}
|
|
ctx->sId = sId;
|
|
ctx->mLock.unlock();
|
|
SUBTITLE_LOGI_FUNC_OUT();
|
|
return ctx;
|
|
}
|
|
|
|
SubSourceStatus SubSource_Destroy(SubSourceHandle handle) {
|
|
SubtitleReportContext *ctx = (SubtitleReportContext *)handle;
|
|
if (ctx == nullptr) {
|
|
SUBTITLE_LOGE("ctx is null");
|
|
return SUB_STAT_INV;
|
|
}
|
|
|
|
SUBTITLE_LOGI("SubSource destroy %d", ctx->sId);
|
|
|
|
ctx->mLock.lock();
|
|
// ctx->mRemote = nullptr;
|
|
ctx->mSocketClient->socketDisconnect();
|
|
ctx->mSocketClient.reset();
|
|
ctx->mLock.unlock();
|
|
|
|
delete ctx;
|
|
SUBTITLE_LOGI_FUNC_OUT();
|
|
return SUB_STAT_OK;
|
|
}
|
|
|
|
SubSourceStatus SubSource_Reset(SubSourceHandle handle) {
|
|
SubtitleReportContext *ctx = (SubtitleReportContext *)handle;
|
|
if (ctx == nullptr) return SUB_STAT_INV;
|
|
|
|
SUBTITLE_LOGI("SubSource reset %d", ctx->sId);
|
|
|
|
std::lock_guard<std::mutex> guard(ctx->mLock);
|
|
|
|
char buffer[64];
|
|
memset(buffer, 0, 64);
|
|
makeHeader(buffer, ctx->sId, SUBTITLE_RESET_SERVER, 7);
|
|
strcpy(buffer + HEADER_SIZE, "reset\n");
|
|
ctx->mSocketClient->socketSend(buffer, HEADER_SIZE + 7);
|
|
|
|
return SUB_STAT_OK;
|
|
}
|
|
|
|
SubSourceStatus SubSource_Stop(SubSourceHandle handle) {
|
|
SubtitleReportContext *ctx = (SubtitleReportContext *)handle;
|
|
if (ctx == nullptr) return SUB_STAT_INV;
|
|
|
|
SUBTITLE_LOGI("SubSource destroy %d", ctx->sId);
|
|
std::lock_guard<std::mutex> guard(ctx->mLock);
|
|
char buffer[64];
|
|
memset(buffer, 0, 64);
|
|
makeHeader(buffer, ctx->sId, SUBTITLE_EXIT_SERVER, 6);
|
|
strcpy(buffer + HEADER_SIZE, "exit\n");
|
|
ctx->mSocketClient->socketSend(buffer, HEADER_SIZE + 6);
|
|
SUBTITLE_LOGI_FUNC_OUT();
|
|
return SUB_STAT_OK;
|
|
}
|
|
|
|
SubSourceStatus SubSource_ReportRenderTime(SubSourceHandle handle, int64_t timeUs) {
|
|
SubtitleReportContext *ctx = (SubtitleReportContext *)handle;
|
|
static int count = 0;
|
|
if (ctx == nullptr) return SUB_STAT_INV;
|
|
|
|
if (count++ % 1000 == 0)
|
|
SUBTITLE_LOGI("SubSource ReportRenderTime %d 0x%llx", ctx->sId, timeUs);
|
|
|
|
std::lock_guard<std::mutex> guard(ctx->mLock);
|
|
char buffer[64];
|
|
makeHeader(buffer, ctx->sId, SUBTITLE_RENDER_TIME, sizeof(int64_t));
|
|
memcpy(buffer + HEADER_SIZE, &timeUs, sizeof(int64_t));
|
|
ctx->mSocketClient->socketSend(buffer, HEADER_SIZE + sizeof(int64_t));
|
|
return SUB_STAT_OK;
|
|
}
|
|
|
|
SubSourceStatus SubSource_ReportStartPts(SubSourceHandle handle, int64_t pts) {
|
|
SubtitleReportContext *ctx = (SubtitleReportContext *)handle;
|
|
if (ctx == nullptr) return SUB_STAT_INV;
|
|
|
|
SUBTITLE_LOGI("SubSource ReportStartPts %d 0x%llx", ctx->sId, pts);
|
|
|
|
std::lock_guard<std::mutex> guard(ctx->mLock);
|
|
char buffer[64];
|
|
makeHeader(buffer, ctx->sId, SUBTITLE_START_PTS, sizeof(pts));
|
|
memcpy(buffer + HEADER_SIZE, &pts, sizeof(pts));
|
|
ctx->mSocketClient->socketSend(buffer, HEADER_SIZE + sizeof(pts));
|
|
return SUB_STAT_OK;
|
|
}
|
|
|
|
SubSourceStatus SubSource_ReportTotalTracks(SubSourceHandle handle, int trackNum) {
|
|
SubtitleReportContext *ctx = (SubtitleReportContext *)handle;
|
|
if (ctx == nullptr) return SUB_STAT_INV;
|
|
|
|
SUBTITLE_LOGI("SubSource ReportTotalTracks %d 0x%x", ctx->sId, trackNum);
|
|
|
|
std::lock_guard<std::mutex> guard(ctx->mLock);
|
|
char buffer[64];
|
|
makeHeader(buffer, ctx->sId, SUBTITLE_TOTAL_TRACK, sizeof(trackNum));
|
|
memcpy(buffer + HEADER_SIZE, &trackNum, sizeof(trackNum));
|
|
ctx->mSocketClient->socketSend(buffer, HEADER_SIZE + sizeof(trackNum));
|
|
return SUB_STAT_OK;
|
|
}
|
|
|
|
SubSourceStatus SubSource_ReportType(SubSourceHandle handle, int type) {
|
|
SubtitleReportContext *ctx = (SubtitleReportContext *)handle;
|
|
if (ctx == nullptr) return SUB_STAT_INV;
|
|
|
|
SUBTITLE_LOGI("SubSource ReportType %d 0x%x", ctx->sId, type);
|
|
|
|
std::lock_guard<std::mutex> guard(ctx->mLock);
|
|
char buffer[64];
|
|
makeHeader(buffer, ctx->sId, SUBTITLE_SUB_TYPE, sizeof(type));
|
|
memcpy(buffer + HEADER_SIZE, &type, sizeof(type));
|
|
ctx->mSocketClient->socketSend(buffer, HEADER_SIZE + sizeof(type));
|
|
|
|
return SUB_STAT_OK;
|
|
}
|
|
|
|
SubSourceStatus SubSource_ReportSubTypeString(SubSourceHandle handle, const char *type) {
|
|
SubtitleReportContext *ctx = (SubtitleReportContext *)handle;
|
|
std::lock_guard<std::mutex> guard(ctx->mLock);
|
|
if (ctx == nullptr) return SUB_STAT_INV;
|
|
|
|
char *buffer = new char[strlen(type) + 1 + HEADER_SIZE]();
|
|
if (buffer == nullptr) return SUB_STAT_INV;
|
|
|
|
SUBTITLE_LOGI("SubSource ReportTypeString %d %s", ctx->sId, type);
|
|
|
|
makeHeader(buffer, ctx->sId, SUBTITLE_TYPE_STRING, strlen(type) + 1);
|
|
memcpy(buffer + HEADER_SIZE, type, strlen(type));
|
|
ctx->mSocketClient->socketSend(buffer, HEADER_SIZE + sizeof(type) + 1);
|
|
delete[] buffer;
|
|
return SUB_STAT_OK;
|
|
}
|
|
SubSourceStatus SubSource_ReportLauguageString(SubSourceHandle handle, const char *lang) {
|
|
SubtitleReportContext *ctx = (SubtitleReportContext *)handle;
|
|
std::lock_guard<std::mutex> guard(ctx->mLock);
|
|
if (ctx == nullptr) return SUB_STAT_INV;
|
|
SUBTITLE_LOGI("SubSource ReportLangString %d %s", ctx->sId, lang);
|
|
|
|
char *buffer = new char[strlen(lang) + 1 + HEADER_SIZE]();
|
|
if (buffer == nullptr) return SUB_STAT_INV;
|
|
|
|
makeHeader(buffer, ctx->sId, SUBTITLE_LANG_STRING, strlen(lang) + 1);
|
|
memcpy(buffer + HEADER_SIZE, lang, strlen(lang));
|
|
ctx->mSocketClient->socketSend(buffer, HEADER_SIZE + strlen(lang) + 1);
|
|
delete[] buffer;
|
|
return SUB_STAT_OK;
|
|
}
|
|
|
|
// Send subtitle data without durationPts
|
|
SubSourceStatus SubSource_SendData(SubSourceHandle handle, const char *mbuf, int length,
|
|
int64_t pts, enum CodecID sub_type) {
|
|
SubtitleReportContext *ctx = (SubtitleReportContext *)handle;
|
|
if (ctx == nullptr) return SUB_STAT_INV;
|
|
SUBTITLE_LOGI(
|
|
"sId=%d, length=%d,"
|
|
"pts=%" PRId64 ", sub_type=%d",
|
|
ctx->sId, length, pts, sub_type);
|
|
|
|
std::lock_guard<std::mutex> guard(ctx->mLock);
|
|
float duration = 0;
|
|
int64_t sub_pts = 0;
|
|
int64_t start_time = 0;
|
|
int data_size = length;
|
|
if (length <= 0) {
|
|
SUBTITLE_LOGE("[sendToSubtitleService]not enough data.data_size:%d\n", length);
|
|
return SUB_STAT_INV;
|
|
}
|
|
// sub_type = CODEC_ID_DVB_SUBTITLE;//streamCodecID;
|
|
if (sub_type == CODEC_ID_DVD_SUBTITLE) {
|
|
mSubType = 0;
|
|
} else if (sub_type == CODEC_ID_HDMV_PGS_SUBTITLE) {
|
|
mSubType = 1;
|
|
} else if (sub_type == CODEC_ID_XSUB) {
|
|
mSubType = 2;
|
|
} else if (sub_type == CODEC_ID_TEXT || sub_type == CODEC_ID_SSA || sub_type == CODEC_ID_ASS) {
|
|
mSubType = 3;
|
|
} else if (sub_type == CODEC_ID_DVB_SUBTITLE) {
|
|
mSubType = 5;
|
|
} else if (sub_type == CODEC_ID_MOV_TEXT) {
|
|
mSubType = 7;
|
|
} else if (sub_type == CODEC_ID_DVB_TELETEXT) {
|
|
mSubType = 9; // SUBTITLE_DVB_TELETEXT
|
|
} else if (sub_type == CODEC_ID_TTML_SUBTITLE) {
|
|
mSubType = 18; // SUBTITLE_TTML
|
|
} else if (sub_type == CODEC_ID_SMPTE_TTML_SUBTITLE) {
|
|
mSubType = 20; // SUBTITLE_SMPTE_TTML
|
|
} else {
|
|
mSubType = 4;
|
|
}
|
|
|
|
// if (mDebug) {
|
|
// SUBTITLE_LOGE("[sendToSubtitleService]sub_type:0x%x, data_size:%d, sub_pts:%" PRId64 ",
|
|
// durationPts:%" PRId64 "\n", sub_type, data_size, pts, durationPts);
|
|
// }
|
|
|
|
if (sub_type == CODEC_ID_DVD_SUBTITLE) {
|
|
sub_type = static_cast<CodecID>(0x1700a); // Invalid
|
|
}
|
|
// 0x1780d:mkv internal ass 0x17808:internal UTF-8
|
|
else if (sub_type == CODEC_ID_XSUB) {
|
|
return SUB_STAT_INV; // not need to support xsub
|
|
}
|
|
unsigned char sub_header[24] = {0x41, 0x4d, 0x4c, 0x55, 0x77, 0};
|
|
// unsigned char sub_header[24] = {0};
|
|
// unsigned char subInfo_header[10] = {0}; //add info header mSubType, mSubTotal send with
|
|
// subtitle packet.
|
|
sub_header[5] = (sub_type >> 16) & 0xff;
|
|
sub_header[6] = (sub_type >> 8) & 0xff;
|
|
sub_header[7] = sub_type & 0xff;
|
|
sub_header[8] = (data_size >> 24) & 0xff;
|
|
sub_header[9] = (data_size >> 16) & 0xff;
|
|
sub_header[10] = (data_size >> 8) & 0xff;
|
|
sub_header[11] = data_size & 0xff;
|
|
sub_header[12] = (pts >> 56) & 0xff;
|
|
sub_header[13] = (pts >> 48) & 0xff;
|
|
sub_header[14] = (pts >> 40) & 0xff;
|
|
sub_header[15] = (pts >> 32) & 0xff;
|
|
sub_header[16] = (pts >> 24) & 0xff;
|
|
sub_header[17] = (pts >> 16) & 0xff;
|
|
sub_header[18] = (pts >> 8) & 0xff;
|
|
sub_header[19] = pts & 0xff;
|
|
sub_header[20] = (mLastDuration >> 24) & 0xff;
|
|
sub_header[21] = (mLastDuration >> 16) & 0xff;
|
|
sub_header[22] = (mLastDuration >> 8) & 0xff;
|
|
sub_header[23] = mLastDuration & 0xff;
|
|
int size = 24 + data_size + 5 * 4;
|
|
int data_length = 24 + data_size;
|
|
char *data = (char *)malloc(size);
|
|
memset(data, 0, size);
|
|
|
|
SUBTITLE_LOGI("data_length= %d", data_length);
|
|
makeHeader(data, ctx->sId, SUBTITLE_SUB_DATA, data_length);
|
|
|
|
/*int sessionId = ctx->sId;
|
|
unsigned int val = START_FLAG;
|
|
memcpy(data, &val, sizeof(val));
|
|
memcpy(data+1*sizeof(int), &sessionId, sizeof(int));
|
|
int val1 = MAGIC_FLAG; // magic
|
|
memcpy(data+2*sizeof(int), &val1, sizeof(int));
|
|
memcpy(data+3*sizeof(int), &data_length, sizeof(int));
|
|
int type =SUBTITLE_SUB_DATA;
|
|
memcpy(data+4*sizeof(int), &type, sizeof(int));*/
|
|
|
|
memcpy(data + 5 * sizeof(int), sub_header, 24);
|
|
memcpy(data + 5 * sizeof(int) + 24, mbuf, data_size);
|
|
if (ctx->mSocketClient != NULL) {
|
|
usleep(500);
|
|
ctx->mSocketClient->socketSend(data, size);
|
|
} else {
|
|
SUBTITLE_LOGE("[sendToSubtitleService] mClient == NULL\n");
|
|
}
|
|
if (data != nullptr) {
|
|
free(data);
|
|
data = nullptr;
|
|
}
|
|
SUBTITLE_LOGI("end %d %d", ctx->sId, size);
|
|
|
|
return SUB_STAT_OK;
|
|
}
|
|
|
|
// Send subtitle data with durationPts
|
|
SubSourceStatus SubSource_SendDataEx(SubSourceHandle handle, const char *mbuf, int length,
|
|
int64_t pts, int64_t durationPts, enum CodecID sub_type) {
|
|
// protocol socket only supports 32-bit durationPts
|
|
mLastDuration = (int)durationPts;
|
|
return SubSource_SendData(handle, mbuf, length, pts, sub_type);
|
|
}
|
|
|
|
SubSourceStatus SubSource_GetVersion(SubSourceHandle handle, int *version) {
|
|
*version = 2;
|
|
return SUB_STAT_OK;
|
|
}; |