mirror of
https://github.com/tuxbox-neutrino/libstb-hal.git
synced 2025-08-27 15:33:00 +02:00
libeplayer3: run through indent, no binary change
This commit is contained in:
@@ -44,46 +44,53 @@ if (debug_level >= level) printf(x); } while (0)
|
|||||||
|
|
||||||
static const char FILENAME[] = __FILE__;
|
static const char FILENAME[] = __FILE__;
|
||||||
|
|
||||||
static Container_t * AvailableContainer[] = {
|
static Container_t *AvailableContainer[] = {
|
||||||
&FFMPEGContainer,
|
&FFMPEGContainer,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static void printContainerCapabilities() {
|
static void printContainerCapabilities()
|
||||||
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
container_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
container_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
container_printf(10, "Capabilities: ");
|
container_printf(10, "Capabilities: ");
|
||||||
|
|
||||||
for (i = 0; AvailableContainer[i] != NULL; i++)
|
for (i = 0; AvailableContainer[i] != NULL; i++)
|
||||||
for (j = 0; AvailableContainer[i]->Capabilities[j] != NULL; j++)
|
for (j = 0; AvailableContainer[i]->Capabilities[j] != NULL; j++)
|
||||||
container_printf(10, "%s ", AvailableContainer[i]->Capabilities[j]);
|
container_printf(10, "%s ",
|
||||||
|
AvailableContainer[i]->Capabilities[j]);
|
||||||
container_printf(10, "\n");
|
container_printf(10, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int selectContainer(Context_t *context, char * extension __attribute__((unused))) {
|
static int selectContainer(Context_t * context, char *extension
|
||||||
|
__attribute__ ((unused)))
|
||||||
|
{
|
||||||
#if 0
|
#if 0
|
||||||
int i, j;
|
int i, j;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
container_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
container_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
for (i = 0; AvailableContainer[i] != NULL; i++)
|
for (i = 0; AvailableContainer[i] != NULL; i++) {
|
||||||
{
|
for (j = 0; AvailableContainer[i]->Capabilities[j] != NULL; j++)
|
||||||
for (j = 0; AvailableContainer[i]->Capabilities[j] != NULL; j++)
|
if (!strcasecmp
|
||||||
if (!strcasecmp(AvailableContainer[i]->Capabilities[j], extension)) {
|
(AvailableContainer[i]->Capabilities[j], extension)) {
|
||||||
context->container->selectedContainer = AvailableContainer[i];
|
context->container->selectedContainer =
|
||||||
|
AvailableContainer[i];
|
||||||
|
|
||||||
container_printf(10, "Selected Container: %s\n", context->container->selectedContainer->Name);
|
container_printf(10, "Selected Container: %s\n",
|
||||||
ret = 0;
|
context->container->selectedContainer->
|
||||||
break;
|
Name);
|
||||||
}
|
ret = 0;
|
||||||
if (ret == 0)
|
break;
|
||||||
break;
|
}
|
||||||
|
if (ret == 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
container_err("No Container found :-(\n");
|
container_err("No Container found :-(\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -94,28 +101,30 @@ static int selectContainer(Context_t *context, char * extension __attribute__((
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int Command(void *_context, ContainerCmd_t command, void * argument) {
|
static int Command(void *_context, ContainerCmd_t command, void *argument)
|
||||||
Context_t* context = (Context_t*) _context;
|
{
|
||||||
|
Context_t *context = (Context_t *) _context;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
container_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
container_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
switch(command) {
|
switch (command) {
|
||||||
case CONTAINER_ADD: {
|
case CONTAINER_ADD:{
|
||||||
ret = selectContainer(context, (char*) argument);
|
ret = selectContainer(context, (char *) argument);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONTAINER_CAPABILITIES: {
|
case CONTAINER_CAPABILITIES:{
|
||||||
printContainerCapabilities();
|
printContainerCapabilities();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONTAINER_DEL: {
|
case CONTAINER_DEL:{
|
||||||
context->container->selectedContainer = NULL;
|
context->container->selectedContainer = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
container_err("%s::%s ContainerCmd %d not supported!\n", FILENAME, __FUNCTION__, command);
|
container_err("%s::%s ContainerCmd %d not supported!\n", FILENAME,
|
||||||
break;
|
__FUNCTION__, command);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@@ -83,24 +83,23 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x);
|
|||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
typedef struct ass_s {
|
typedef struct ass_s {
|
||||||
unsigned char* data;
|
unsigned char *data;
|
||||||
int len;
|
int len;
|
||||||
unsigned char* extradata;
|
unsigned char *extradata;
|
||||||
int extralen;
|
int extralen;
|
||||||
|
|
||||||
long long int pts;
|
long long int pts;
|
||||||
float duration;
|
float duration;
|
||||||
} ass_t;
|
} ass_t;
|
||||||
|
|
||||||
typedef struct region_s
|
typedef struct region_s {
|
||||||
{
|
|
||||||
unsigned int x;
|
unsigned int x;
|
||||||
unsigned int y;
|
unsigned int y;
|
||||||
unsigned int w;
|
unsigned int w;
|
||||||
unsigned int h;
|
unsigned int h;
|
||||||
time_t undisplay;
|
time_t undisplay;
|
||||||
|
|
||||||
struct region_s* next;
|
struct region_s *next;
|
||||||
} region_t;
|
} region_t;
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
@@ -120,17 +119,17 @@ static ASS_Renderer *ass_renderer;
|
|||||||
//static float ass_font_scale = 0.4; // was: 0.7
|
//static float ass_font_scale = 0.4; // was: 0.7
|
||||||
//static float ass_line_spacing = 0.4; // was: 0.7
|
//static float ass_line_spacing = 0.4; // was: 0.7
|
||||||
|
|
||||||
static unsigned int screen_width = 0;
|
static unsigned int screen_width = 0;
|
||||||
static unsigned int screen_height = 0;
|
static unsigned int screen_height = 0;
|
||||||
static uint32_t *destination = NULL;
|
static uint32_t *destination = NULL;
|
||||||
static int destStride = 0;
|
static int destStride = 0;
|
||||||
static void (*framebufferBlit)(void) = NULL;
|
static void (*framebufferBlit) (void) = NULL;
|
||||||
|
|
||||||
static int needsBlit = 0;
|
static int needsBlit = 0;
|
||||||
|
|
||||||
static ASS_Track* ass_track = NULL;
|
static ASS_Track *ass_track = NULL;
|
||||||
|
|
||||||
static region_t* firstRegion = NULL;
|
static region_t *firstRegion = NULL;
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
@@ -140,7 +139,9 @@ static region_t* firstRegion = NULL;
|
|||||||
/* MISC Functions */
|
/* MISC Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
void ass_msg_callback(int level __attribute__((unused)), const char *format, va_list va, void *ctx __attribute__((unused)))
|
void ass_msg_callback(int level
|
||||||
|
__attribute__ ((unused)), const char *format,
|
||||||
|
va_list va, void *ctx __attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
char *str;
|
char *str;
|
||||||
@@ -149,13 +150,14 @@ void ass_msg_callback(int level __attribute__((unused)), const char *format, va_
|
|||||||
va_copy(dst, va);
|
va_copy(dst, va);
|
||||||
n = vsnprintf(NULL, 0, format, va);
|
n = vsnprintf(NULL, 0, format, va);
|
||||||
if (n > 0 && (str = malloc(n + 1))) {
|
if (n > 0 && (str = malloc(n + 1))) {
|
||||||
vsnprintf(str, n + 1, format, dst);
|
vsnprintf(str, n + 1, format, dst);
|
||||||
ass_printf(100, "%s\n", str);
|
ass_printf(100, "%s\n", str);
|
||||||
free(str);
|
free(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getMutex(int line) {
|
static void getMutex(int line)
|
||||||
|
{
|
||||||
ass_printf(150, "%d requesting mutex\n", line);
|
ass_printf(150, "%d requesting mutex\n", line);
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
@@ -163,7 +165,8 @@ static void getMutex(int line) {
|
|||||||
ass_printf(150, "%d received mutex\n", line);
|
ass_printf(150, "%d received mutex\n", line);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void releaseMutex(int line) {
|
static void releaseMutex(int line)
|
||||||
|
{
|
||||||
pthread_mutex_unlock(&mutex);
|
pthread_mutex_unlock(&mutex);
|
||||||
|
|
||||||
ass_printf(150, "%d released mutex\n", line);
|
ass_printf(150, "%d released mutex\n", line);
|
||||||
@@ -177,46 +180,43 @@ static void releaseMutex(int line) {
|
|||||||
*/
|
*/
|
||||||
void releaseRegions()
|
void releaseRegions()
|
||||||
{
|
{
|
||||||
region_t* next, *old;
|
region_t *next, *old;
|
||||||
Writer_t* writer;
|
Writer_t *writer;
|
||||||
|
|
||||||
if (firstRegion == NULL)
|
if (firstRegion == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
writer = getDefaultFramebufferWriter();
|
writer = getDefaultFramebufferWriter();
|
||||||
|
|
||||||
if (writer == NULL)
|
if (writer == NULL) {
|
||||||
{
|
ass_err("no framebuffer writer found!\n");
|
||||||
ass_err("no framebuffer writer found!\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next = firstRegion;
|
next = firstRegion;
|
||||||
while (next)
|
while (next) {
|
||||||
{
|
if (writer) {
|
||||||
if (writer)
|
WriterFBCallData_t out;
|
||||||
{
|
|
||||||
WriterFBCallData_t out;
|
|
||||||
|
|
||||||
ass_printf(100, "release: w %d h %d x %d y %d\n",
|
ass_printf(100, "release: w %d h %d x %d y %d\n",
|
||||||
next->w, next->h, next->x, next->y);
|
next->w, next->h, next->x, next->y);
|
||||||
|
|
||||||
out.data = NULL;
|
out.data = NULL;
|
||||||
out.Width = next->w;
|
out.Width = next->w;
|
||||||
out.Height = next->h;
|
out.Height = next->h;
|
||||||
out.x = next->x;
|
out.x = next->x;
|
||||||
out.y = next->y;
|
out.y = next->y;
|
||||||
|
|
||||||
out.Screen_Width = screen_width;
|
out.Screen_Width = screen_width;
|
||||||
out.Screen_Height = screen_height;
|
out.Screen_Height = screen_height;
|
||||||
out.destination = destination;
|
out.destination = destination;
|
||||||
out.destStride = destStride;
|
out.destStride = destStride;
|
||||||
|
|
||||||
writer->writeData(&out);
|
writer->writeData(&out);
|
||||||
needsBlit = 1;
|
needsBlit = 1;
|
||||||
}
|
}
|
||||||
old = next;
|
old = next;
|
||||||
next = next->next;
|
next = next->next;
|
||||||
free(old);
|
free(old);
|
||||||
}
|
}
|
||||||
|
|
||||||
firstRegion = NULL;
|
firstRegion = NULL;
|
||||||
@@ -230,67 +230,64 @@ void releaseRegions()
|
|||||||
void checkRegions()
|
void checkRegions()
|
||||||
{
|
{
|
||||||
#define cDeltaTime 2
|
#define cDeltaTime 2
|
||||||
region_t* next, *old, *prev;
|
region_t *next, *old, *prev;
|
||||||
Writer_t* writer;
|
Writer_t *writer;
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
|
|
||||||
if (firstRegion == NULL)
|
if (firstRegion == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
writer = getDefaultFramebufferWriter();
|
writer = getDefaultFramebufferWriter();
|
||||||
|
|
||||||
if (!writer)
|
if (!writer) {
|
||||||
{
|
ass_err("no framebuffer writer found!\n");
|
||||||
ass_err("no framebuffer writer found!\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prev = next = firstRegion;
|
prev = next = firstRegion;
|
||||||
while (next)
|
while (next) {
|
||||||
{
|
if (now > next->undisplay + cDeltaTime) {
|
||||||
if (now > next->undisplay + cDeltaTime)
|
ass_printf(100, "undisplay: %ld > %ld\n", now,
|
||||||
{
|
next->undisplay + cDeltaTime);
|
||||||
ass_printf(100, "undisplay: %ld > %ld\n", now, next->undisplay + cDeltaTime);
|
|
||||||
|
|
||||||
if (writer)
|
if (writer) {
|
||||||
{
|
WriterFBCallData_t out;
|
||||||
WriterFBCallData_t out;
|
|
||||||
|
|
||||||
ass_printf(100, "release: w %d h %d x %d y %d\n",
|
ass_printf(100, "release: w %d h %d x %d y %d\n",
|
||||||
next->w, next->h, next->x, next->y);
|
next->w, next->h, next->x, next->y);
|
||||||
|
|
||||||
out.data = NULL;
|
out.data = NULL;
|
||||||
out.Width = next->w;
|
out.Width = next->w;
|
||||||
out.Height = next->h;
|
out.Height = next->h;
|
||||||
out.x = next->x;
|
out.x = next->x;
|
||||||
out.y = next->y;
|
out.y = next->y;
|
||||||
|
|
||||||
out.Screen_Width = screen_width;
|
out.Screen_Width = screen_width;
|
||||||
out.Screen_Height = screen_height;
|
out.Screen_Height = screen_height;
|
||||||
out.destination = destination;
|
out.destination = destination;
|
||||||
out.destStride = destStride;
|
out.destStride = destStride;
|
||||||
|
|
||||||
writer->writeData(&out);
|
writer->writeData(&out);
|
||||||
needsBlit = 1;
|
needsBlit = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
old = next;
|
old = next;
|
||||||
next = prev->next = next->next;
|
next = prev->next = next->next;
|
||||||
|
|
||||||
if (old == firstRegion)
|
if (old == firstRegion)
|
||||||
firstRegion = next;
|
firstRegion = next;
|
||||||
free(old);
|
free(old);
|
||||||
} else
|
} else {
|
||||||
{
|
prev = next;
|
||||||
prev = next;
|
next = next->next;
|
||||||
next = next->next;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store a display region for later release */
|
/* store a display region for later release */
|
||||||
void storeRegion(unsigned int x, unsigned int y, unsigned int w, unsigned int h, time_t undisplay)
|
void storeRegion(unsigned int x, unsigned int y, unsigned int w,
|
||||||
|
unsigned int h, time_t undisplay)
|
||||||
{
|
{
|
||||||
region_t** new = &firstRegion;
|
region_t **new = &firstRegion;
|
||||||
|
|
||||||
ass_printf(100, "%d %d %d %d %ld\n", x, y, w, h, undisplay);
|
ass_printf(100, "%d %d %d %d %ld\n", x, y, w, h, undisplay);
|
||||||
|
|
||||||
@@ -299,11 +296,11 @@ void storeRegion(unsigned int x, unsigned int y, unsigned int w, unsigned int h,
|
|||||||
|
|
||||||
*new = malloc(sizeof(region_t));
|
*new = malloc(sizeof(region_t));
|
||||||
|
|
||||||
(*new)->next = NULL;
|
(*new)->next = NULL;
|
||||||
(*new)->x = x;
|
(*new)->x = x;
|
||||||
(*new)->y = y;
|
(*new)->y = y;
|
||||||
(*new)->w = w;
|
(*new)->w = w;
|
||||||
(*new)->h = h;
|
(*new)->h = h;
|
||||||
(*new)->undisplay = undisplay;
|
(*new)->undisplay = undisplay;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,89 +308,89 @@ void storeRegion(unsigned int x, unsigned int y, unsigned int w, unsigned int h,
|
|||||||
/* Worker Thread */
|
/* Worker Thread */
|
||||||
/* **************************** */
|
/* **************************** */
|
||||||
|
|
||||||
static void ASSThread(Context_t *context) {
|
static void ASSThread(Context_t * context)
|
||||||
|
{
|
||||||
char threadname[17];
|
char threadname[17];
|
||||||
strncpy(threadname, __func__, sizeof(threadname));
|
strncpy(threadname, __func__, sizeof(threadname));
|
||||||
threadname[16] = 0;
|
threadname[16] = 0;
|
||||||
prctl (PR_SET_NAME, (unsigned long)&threadname);
|
prctl(PR_SET_NAME, (unsigned long) &threadname);
|
||||||
Writer_t* writer;
|
Writer_t *writer;
|
||||||
|
|
||||||
ass_printf(10, "\n");
|
ass_printf(10, "\n");
|
||||||
|
|
||||||
while ( context->playback->isCreationPhase )
|
while (context->playback->isCreationPhase) {
|
||||||
{
|
ass_err("Thread waiting for end of init phase...\n");
|
||||||
ass_err("Thread waiting for end of init phase...\n");
|
usleep(1000);
|
||||||
usleep(1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ass_printf(10, "Running!\n");
|
ass_printf(10, "Running!\n");
|
||||||
|
|
||||||
writer = getDefaultFramebufferWriter();
|
writer = getDefaultFramebufferWriter();
|
||||||
|
|
||||||
if (writer == NULL)
|
if (writer == NULL) {
|
||||||
{
|
ass_err("no framebuffer writer found!\n");
|
||||||
ass_err("no framebuffer writer found!\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( context && context->playback && context->playback->isPlaying ) {
|
while (context && context->playback && context->playback->isPlaying) {
|
||||||
|
|
||||||
//IF MOVIE IS PAUSED, WAIT
|
//IF MOVIE IS PAUSED, WAIT
|
||||||
if (context->playback->isPaused) {
|
if (context->playback->isPaused) {
|
||||||
ass_printf(20, "paused\n");
|
ass_printf(20, "paused\n");
|
||||||
|
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->playback->isSeeking) {
|
if (context->playback->isSeeking) {
|
||||||
ass_printf(10, "seeking\n");
|
ass_printf(10, "seeking\n");
|
||||||
|
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((isContainerRunning) && (ass_track))
|
if ((isContainerRunning) && (ass_track)) {
|
||||||
{
|
ASS_Image *img = NULL;
|
||||||
ASS_Image * img = NULL;
|
int change = 0;
|
||||||
int change = 0;
|
unsigned long int playPts;
|
||||||
unsigned long int playPts;
|
|
||||||
|
|
||||||
if (context && context->playback)
|
if (context && context->playback) {
|
||||||
{
|
if (context->playback->
|
||||||
if (context->playback->Command(context, PLAYBACK_PTS, &playPts) < 0)
|
Command(context, PLAYBACK_PTS, &playPts) < 0)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
//FIXME: durch den sleep bleibt die cpu usage zw. 5 und 13%, ohne
|
||||||
//FIXME: durch den sleep bleibt die cpu usage zw. 5 und 13%, ohne
|
// steigt sie bei Verwendung von subtiteln bis auf 95%.
|
||||||
// steigt sie bei Verwendung von subtiteln bis auf 95%.
|
// ich hoffe dadurch gehen keine subtitle verloren, wenn die playPts
|
||||||
// ich hoffe dadurch gehen keine subtitle verloren, wenn die playPts
|
// durch den sleep verschlafen wird. Besser w<>re es den n<>chsten
|
||||||
// durch den sleep verschlafen wird. Besser w<>re es den n<>chsten
|
// subtitel zeitpunkt zu bestimmen und solange zu schlafen.
|
||||||
// subtitel zeitpunkt zu bestimmen und solange zu schlafen.
|
usleep(10000);
|
||||||
usleep(10000);
|
if (!context->playback->mayWriteToFramebuffer)
|
||||||
if(!context->playback->mayWriteToFramebuffer)
|
|
||||||
continue;
|
continue;
|
||||||
getMutex(__LINE__);
|
getMutex(__LINE__);
|
||||||
checkRegions();
|
checkRegions();
|
||||||
|
|
||||||
if(ass_renderer && ass_track)
|
if (ass_renderer && ass_track)
|
||||||
img = ass_render_frame(ass_renderer, ass_track, playPts / 90.0, &change);
|
img =
|
||||||
|
ass_render_frame(ass_renderer, ass_track,
|
||||||
|
playPts / 90.0, &change);
|
||||||
|
|
||||||
ass_printf(150, "img %p pts %lu %f\n", img, playPts, playPts / 90.0);
|
ass_printf(150, "img %p pts %lu %f\n", img, playPts,
|
||||||
|
playPts / 90.0);
|
||||||
|
|
||||||
if(img && ass_renderer && ass_track)
|
if (img && ass_renderer && ass_track) {
|
||||||
{
|
/* the spec says, that if a new set of regions is present
|
||||||
/* the spec says, that if a new set of regions is present
|
* the complete display switches to the new state. So lets
|
||||||
* the complete display switches to the new state. So lets
|
* release the old regions on display.
|
||||||
* release the old regions on display.
|
*/
|
||||||
*/
|
if (change != 0)
|
||||||
if (change != 0)
|
releaseRegions();
|
||||||
releaseRegions();
|
|
||||||
|
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
time_t undisplay = now + 10;
|
time_t undisplay = now + 10;
|
||||||
|
|
||||||
if (ass_track && ass_track->events)
|
if (ass_track && ass_track->events)
|
||||||
undisplay = now + (ass_track->events->Duration + 500) / 90000;
|
undisplay =
|
||||||
|
now + (ass_track->events->Duration + 500) / 90000;
|
||||||
|
|
||||||
ASS_Image *it;
|
ASS_Image *it;
|
||||||
int x0 = screen_width - 1;
|
int x0 = screen_width - 1;
|
||||||
@@ -401,85 +398,87 @@ static void ASSThread(Context_t *context) {
|
|||||||
int x1 = 0;
|
int x1 = 0;
|
||||||
int y1 = 0;
|
int y1 = 0;
|
||||||
for (it = img; it; it = it->next) {
|
for (it = img; it; it = it->next) {
|
||||||
if (it->w && it->h) {
|
if (it->w && it->h) {
|
||||||
if (it->dst_x < x0)
|
if (it->dst_x < x0)
|
||||||
x0 = it->dst_x;
|
x0 = it->dst_x;
|
||||||
if (it->dst_y < y0)
|
if (it->dst_y < y0)
|
||||||
y0 = it->dst_y;
|
y0 = it->dst_y;
|
||||||
if (it->dst_x + it->w > x1)
|
if (it->dst_x + it->w > x1)
|
||||||
x1 = it->dst_x + it->w;
|
x1 = it->dst_x + it->w;
|
||||||
if (it->dst_y + it->h > y1)
|
if (it->dst_y + it->h > y1)
|
||||||
y1 = it->dst_y + it->h;
|
y1 = it->dst_y + it->h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (x1 > 0 && y1 > 0)
|
if (x1 > 0 && y1 > 0) {
|
||||||
{
|
x1++;
|
||||||
x1++;
|
y1++;
|
||||||
y1++;
|
int x, y;
|
||||||
int x, y;
|
uint32_t *dst =
|
||||||
uint32_t *dst = destination + y0 * destStride/sizeof(uint32_t) + x0;
|
destination + y0 * destStride / sizeof(uint32_t) +
|
||||||
int destStrideDiff = destStride/sizeof(uint32_t) - (x1 - x0);
|
x0;
|
||||||
for (y = y0; y < y1; y++) {
|
int destStrideDiff =
|
||||||
for (x = x0; x < x1; x++)
|
destStride / sizeof(uint32_t) - (x1 - x0);
|
||||||
*dst++ = 0x80808080;
|
for (y = y0; y < y1; y++) {
|
||||||
dst += destStrideDiff;
|
for (x = x0; x < x1; x++)
|
||||||
}
|
*dst++ = 0x80808080;
|
||||||
storeRegion(x0, y0, x1 - x0, y1 - y0, undisplay);
|
dst += destStrideDiff;
|
||||||
|
}
|
||||||
|
storeRegion(x0, y0, x1 - x0, y1 - y0, undisplay);
|
||||||
|
needsBlit = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (context && context->playback
|
||||||
|
&& context->playback->isPlaying && img) {
|
||||||
|
WriterFBCallData_t out;
|
||||||
|
|
||||||
|
ass_printf(100,
|
||||||
|
"w %d h %d s %d x %d y %d c %d chg %d now %ld und %ld\n",
|
||||||
|
img->w, img->h, img->stride, img->dst_x,
|
||||||
|
img->dst_y, img->color, change, now,
|
||||||
|
undisplay);
|
||||||
|
|
||||||
|
/* api docu said w and h can be zero which
|
||||||
|
* means image should not be rendered
|
||||||
|
*/
|
||||||
|
if ((img->w != 0) && (img->h != 0) && writer) {
|
||||||
|
out.data = img->bitmap;
|
||||||
|
out.Width = img->w;
|
||||||
|
out.Height = img->h;
|
||||||
|
out.Stride = img->stride;
|
||||||
|
out.x = img->dst_x;
|
||||||
|
out.y = img->dst_y;
|
||||||
|
out.color = img->color;
|
||||||
|
|
||||||
|
out.Screen_Width = screen_width;
|
||||||
|
out.Screen_Height = screen_height;
|
||||||
|
out.destination = destination;
|
||||||
|
out.destStride = destStride;
|
||||||
|
|
||||||
|
if (context && context->playback
|
||||||
|
&& context->playback->isPlaying && writer)
|
||||||
|
writer->writeData(&out);
|
||||||
|
|
||||||
needsBlit = 1;
|
needsBlit = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next image */
|
||||||
|
img = img->next;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
while (context && context->playback && context->playback->isPlaying && img)
|
releaseMutex(__LINE__);
|
||||||
{
|
} else {
|
||||||
WriterFBCallData_t out;
|
usleep(1000);
|
||||||
|
}
|
||||||
ass_printf(100, "w %d h %d s %d x %d y %d c %d chg %d now %ld und %ld\n",
|
|
||||||
img->w, img->h, img->stride,
|
|
||||||
img->dst_x, img->dst_y, img->color,
|
|
||||||
change, now, undisplay);
|
|
||||||
|
|
||||||
/* api docu said w and h can be zero which
|
|
||||||
* means image should not be rendered
|
|
||||||
*/
|
|
||||||
if ((img->w != 0) && (img->h != 0) && writer)
|
|
||||||
{
|
|
||||||
out.data = img->bitmap;
|
|
||||||
out.Width = img->w;
|
|
||||||
out.Height = img->h;
|
|
||||||
out.Stride = img->stride;
|
|
||||||
out.x = img->dst_x;
|
|
||||||
out.y = img->dst_y;
|
|
||||||
out.color = img->color;
|
|
||||||
|
|
||||||
out.Screen_Width = screen_width;
|
|
||||||
out.Screen_Height = screen_height;
|
|
||||||
out.destination = destination;
|
|
||||||
out.destStride = destStride;
|
|
||||||
|
|
||||||
if(context && context->playback && context->playback->isPlaying && writer)
|
|
||||||
writer->writeData(&out);
|
|
||||||
|
|
||||||
needsBlit = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next image */
|
|
||||||
img = img->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
releaseMutex(__LINE__);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
usleep(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needsBlit && framebufferBlit)
|
if (needsBlit && framebufferBlit)
|
||||||
framebufferBlit();
|
framebufferBlit();
|
||||||
needsBlit = 0;
|
needsBlit = 0;
|
||||||
|
|
||||||
/* cleanup no longer used but not overwritten regions */
|
/* cleanup no longer used but not overwritten regions */
|
||||||
getMutex(__LINE__);
|
getMutex(__LINE__);
|
||||||
checkRegions();
|
checkRegions();
|
||||||
releaseMutex(__LINE__);
|
releaseMutex(__LINE__);
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
if (needsBlit && framebufferBlit)
|
if (needsBlit && framebufferBlit)
|
||||||
framebufferBlit();
|
framebufferBlit();
|
||||||
@@ -495,7 +494,7 @@ static void ASSThread(Context_t *context) {
|
|||||||
/* Container part for ass */
|
/* Container part for ass */
|
||||||
/* **************************** */
|
/* **************************** */
|
||||||
|
|
||||||
int container_ass_init(Context_t *context)
|
int container_ass_init(Context_t * context)
|
||||||
{
|
{
|
||||||
SubtitleOutputDef_t output;
|
SubtitleOutputDef_t output;
|
||||||
|
|
||||||
@@ -504,41 +503,44 @@ int container_ass_init(Context_t *context)
|
|||||||
ass_library = ass_library_init();
|
ass_library = ass_library_init();
|
||||||
|
|
||||||
if (!ass_library) {
|
if (!ass_library) {
|
||||||
ass_err("ass_library_init failed!\n");
|
ass_err("ass_library_init failed!\n");
|
||||||
return cERR_CONTAINER_ASS_ERROR;
|
return cERR_CONTAINER_ASS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug_level >= 100)
|
if (debug_level >= 100)
|
||||||
ass_set_message_cb(ass_library, ass_msg_callback, NULL);
|
ass_set_message_cb(ass_library, ass_msg_callback, NULL);
|
||||||
|
|
||||||
ass_set_extract_fonts( ass_library, 1 );
|
ass_set_extract_fonts(ass_library, 1);
|
||||||
ass_set_style_overrides( ass_library, NULL );
|
ass_set_style_overrides(ass_library, NULL);
|
||||||
|
|
||||||
ass_renderer = ass_renderer_init(ass_library);
|
ass_renderer = ass_renderer_init(ass_library);
|
||||||
|
|
||||||
if (!ass_renderer) {
|
if (!ass_renderer) {
|
||||||
ass_err("ass_renderer_init failed!\n");
|
ass_err("ass_renderer_init failed!\n");
|
||||||
|
|
||||||
if (ass_library)
|
if (ass_library)
|
||||||
ass_library_done(ass_library);
|
ass_library_done(ass_library);
|
||||||
ass_library = NULL;
|
ass_library = NULL;
|
||||||
|
|
||||||
return cERR_CONTAINER_ASS_ERROR;
|
return cERR_CONTAINER_ASS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->output->subtitle->Command(context, OUTPUT_GET_SUBTITLE_OUTPUT, &output);
|
context->output->subtitle->Command(context, OUTPUT_GET_SUBTITLE_OUTPUT,
|
||||||
|
&output);
|
||||||
|
|
||||||
screen_width = output.screen_width;
|
screen_width = output.screen_width;
|
||||||
screen_height = output.screen_height;
|
screen_height = output.screen_height;
|
||||||
destination = output.destination;
|
destination = output.destination;
|
||||||
destStride = output.destStride;
|
destStride = output.destStride;
|
||||||
framebufferBlit = output.framebufferBlit;
|
framebufferBlit = output.framebufferBlit;
|
||||||
|
|
||||||
ass_printf(10, "width %d, height %d\n", screen_width, screen_height);
|
ass_printf(10, "width %d, height %d\n", screen_width, screen_height);
|
||||||
|
|
||||||
ass_set_frame_size(ass_renderer, screen_width, screen_height);
|
ass_set_frame_size(ass_renderer, screen_width, screen_height);
|
||||||
ass_set_margins(ass_renderer, (int)(0.03 * screen_height), (int)(0.03 * screen_height) ,
|
ass_set_margins(ass_renderer, (int) (0.03 * screen_height),
|
||||||
(int)(0.03 * screen_width ), (int)(0.03 * screen_width ) );
|
(int) (0.03 * screen_height),
|
||||||
|
(int) (0.03 * screen_width),
|
||||||
|
(int) (0.03 * screen_width));
|
||||||
|
|
||||||
ass_set_use_margins(ass_renderer, 1);
|
ass_set_use_margins(ass_renderer, 1);
|
||||||
// ass_set_font_scale(ass_renderer, (ass_font_scale * screen_height) / 240.0);
|
// ass_set_font_scale(ass_renderer, (ass_font_scale * screen_height) / 240.0);
|
||||||
@@ -547,79 +549,79 @@ int container_ass_init(Context_t *context)
|
|||||||
// ass_set_line_spacing(ass_renderer, (ass_line_spacing * screen_height) / 240.0);
|
// ass_set_line_spacing(ass_renderer, (ass_line_spacing * screen_height) / 240.0);
|
||||||
ass_set_fonts(ass_renderer, ASS_FONT, "Arial", 0, NULL, 1);
|
ass_set_fonts(ass_renderer, ASS_FONT, "Arial", 0, NULL, 1);
|
||||||
|
|
||||||
ass_set_aspect_ratio( ass_renderer, 1.0, 1.0);
|
ass_set_aspect_ratio(ass_renderer, 1.0, 1.0);
|
||||||
|
|
||||||
isContainerRunning = 1;
|
isContainerRunning = 1;
|
||||||
|
|
||||||
return cERR_CONTAINER_ASS_NO_ERROR;
|
return cERR_CONTAINER_ASS_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int container_ass_process_data(Context_t *context __attribute__((unused)), SubtitleData_t* data)
|
int container_ass_process_data(Context_t * context
|
||||||
|
__attribute__ ((unused)),
|
||||||
|
SubtitleData_t * data)
|
||||||
{
|
{
|
||||||
int first_kiss;
|
int first_kiss;
|
||||||
|
|
||||||
ass_printf(20, ">\n");
|
ass_printf(20, ">\n");
|
||||||
|
|
||||||
if (!isContainerRunning)
|
if (!isContainerRunning) {
|
||||||
{
|
ass_err("Container not running\n");
|
||||||
ass_err("Container not running\n");
|
return cERR_CONTAINER_ASS_ERROR;
|
||||||
return cERR_CONTAINER_ASS_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ass_track == NULL)
|
if (ass_track == NULL) {
|
||||||
{
|
first_kiss = 1;
|
||||||
first_kiss = 1;
|
ass_track = ass_new_track(ass_library);
|
||||||
ass_track = ass_new_track(ass_library);
|
|
||||||
|
|
||||||
if (ass_track == NULL)
|
if (ass_track == NULL) {
|
||||||
{
|
ass_err("error creating ass_track\n");
|
||||||
ass_err("error creating ass_track\n");
|
return cERR_CONTAINER_ASS_ERROR;
|
||||||
return cERR_CONTAINER_ASS_ERROR;
|
}
|
||||||
}
|
ass_track->PlayResX = screen_width;
|
||||||
ass_track->PlayResX = screen_width;
|
ass_track->PlayResY = screen_height;
|
||||||
ass_track->PlayResY = screen_height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((data->extradata) && (first_kiss))
|
if ((data->extradata) && (first_kiss)) {
|
||||||
{
|
ass_printf(30, "processing private %d bytes\n", data->extralen);
|
||||||
ass_printf(30,"processing private %d bytes\n",data->extralen);
|
ass_process_codec_private(ass_track, (char *) data->extradata,
|
||||||
ass_process_codec_private(ass_track, (char*) data->extradata, data->extralen);
|
data->extralen);
|
||||||
ass_printf(30,"processing private done\n");
|
ass_printf(30, "processing private done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->data)
|
if (data->data) {
|
||||||
{
|
ass_printf(30, "processing data %d bytes\n", data->len);
|
||||||
ass_printf(30,"processing data %d bytes\n",data->len);
|
ass_process_data(ass_track, (char *) data->data, data->len);
|
||||||
ass_process_data(ass_track, (char*) data->data, data->len);
|
ass_printf(30, "processing data done\n");
|
||||||
ass_printf(30,"processing data done\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cERR_CONTAINER_ASS_NO_ERROR;
|
return cERR_CONTAINER_ASS_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int container_ass_stop(Context_t *context __attribute__((unused))) {
|
static int container_ass_stop(Context_t * context __attribute__ ((unused)))
|
||||||
|
{
|
||||||
int ret = cERR_CONTAINER_ASS_NO_ERROR;
|
int ret = cERR_CONTAINER_ASS_NO_ERROR;
|
||||||
int wait_time = 20;
|
int wait_time = 20;
|
||||||
Writer_t* writer;
|
Writer_t *writer;
|
||||||
|
|
||||||
ass_printf(10, "\n");
|
ass_printf(10, "\n");
|
||||||
|
|
||||||
if (!isContainerRunning)
|
if (!isContainerRunning) {
|
||||||
{
|
ass_err("Container not running\n");
|
||||||
ass_err("Container not running\n");
|
return cERR_CONTAINER_ASS_ERROR;
|
||||||
return cERR_CONTAINER_ASS_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( (hasPlayThreadStarted != 0) && (--wait_time) > 0 ) {
|
while ((hasPlayThreadStarted != 0) && (--wait_time) > 0) {
|
||||||
ass_printf(10, "Waiting for ass thread to terminate itself, will try another %d times\n", wait_time);
|
ass_printf(10,
|
||||||
|
"Waiting for ass thread to terminate itself, will try another %d times\n",
|
||||||
|
wait_time);
|
||||||
|
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait_time == 0) {
|
if (wait_time == 0) {
|
||||||
ass_err( "Timeout waiting for thread!\n");
|
ass_err("Timeout waiting for thread!\n");
|
||||||
|
|
||||||
ret = cERR_CONTAINER_ASS_ERROR;
|
ret = cERR_CONTAINER_ASS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
getMutex(__LINE__);
|
getMutex(__LINE__);
|
||||||
@@ -627,16 +629,16 @@ static int container_ass_stop(Context_t *context __attribute__((unused))) {
|
|||||||
releaseRegions();
|
releaseRegions();
|
||||||
|
|
||||||
if (ass_track)
|
if (ass_track)
|
||||||
ass_free_track(ass_track);
|
ass_free_track(ass_track);
|
||||||
|
|
||||||
ass_track = NULL;
|
ass_track = NULL;
|
||||||
|
|
||||||
if (ass_renderer)
|
if (ass_renderer)
|
||||||
ass_renderer_done(ass_renderer);
|
ass_renderer_done(ass_renderer);
|
||||||
ass_renderer = NULL;
|
ass_renderer = NULL;
|
||||||
|
|
||||||
if (ass_library)
|
if (ass_library)
|
||||||
ass_library_done(ass_library);
|
ass_library_done(ass_library);
|
||||||
ass_library = NULL;
|
ass_library = NULL;
|
||||||
|
|
||||||
isContainerRunning = 0;
|
isContainerRunning = 0;
|
||||||
@@ -646,7 +648,7 @@ static int container_ass_stop(Context_t *context __attribute__((unused))) {
|
|||||||
writer = getDefaultFramebufferWriter();
|
writer = getDefaultFramebufferWriter();
|
||||||
|
|
||||||
if (writer) {
|
if (writer) {
|
||||||
writer->reset();
|
writer->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseMutex(__LINE__);
|
releaseMutex(__LINE__);
|
||||||
@@ -655,7 +657,8 @@ static int container_ass_stop(Context_t *context __attribute__((unused))) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int container_ass_switch_subtitle(Context_t* context, int* arg __attribute__((unused)))
|
static int container_ass_switch_subtitle(Context_t * context, int *arg
|
||||||
|
__attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
int ret = cERR_CONTAINER_ASS_NO_ERROR;
|
int ret = cERR_CONTAINER_ASS_NO_ERROR;
|
||||||
@@ -663,39 +666,38 @@ static int container_ass_switch_subtitle(Context_t* context, int* arg __attribut
|
|||||||
|
|
||||||
ass_printf(10, "\n");
|
ass_printf(10, "\n");
|
||||||
|
|
||||||
if (!isContainerRunning)
|
if (!isContainerRunning) {
|
||||||
{
|
ass_err("Container not running\n");
|
||||||
ass_err("Container not running\n");
|
return cERR_CONTAINER_ASS_ERROR;
|
||||||
return cERR_CONTAINER_ASS_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( context && context->playback && context->playback->isPlaying ) {
|
if (context && context->playback && context->playback->isPlaying) {
|
||||||
ass_printf(10, "is Playing\n");
|
ass_printf(10, "is Playing\n");
|
||||||
}
|
} else {
|
||||||
else {
|
ass_printf(10, "is NOT Playing\n");
|
||||||
ass_printf(10, "is NOT Playing\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasPlayThreadStarted == 0) {
|
if (hasPlayThreadStarted == 0) {
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
|
||||||
if((error = pthread_create(&PlayThread, &attr, (void *)&ASSThread, context)) != 0) {
|
if ((error =
|
||||||
ass_printf(10, "Error creating thread, error:%d:%s\n", error,strerror(error));
|
pthread_create(&PlayThread, &attr, (void *) &ASSThread,
|
||||||
|
context)) != 0) {
|
||||||
|
ass_printf(10, "Error creating thread, error:%d:%s\n", error,
|
||||||
|
strerror(error));
|
||||||
|
|
||||||
hasPlayThreadStarted = 0;
|
hasPlayThreadStarted = 0;
|
||||||
ret = cERR_CONTAINER_ASS_ERROR;
|
ret = cERR_CONTAINER_ASS_ERROR;
|
||||||
}
|
} else {
|
||||||
else {
|
ass_printf(10, "Created thread\n");
|
||||||
ass_printf(10, "Created thread\n");
|
|
||||||
|
|
||||||
hasPlayThreadStarted = 1;
|
hasPlayThreadStarted = 1;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
ass_printf(10, "A thread already exists!\n");
|
||||||
ass_printf(10, "A thread already exists!\n");
|
|
||||||
|
|
||||||
ret = cERR_CONTAINER_ASS_ERROR;
|
ret = cERR_CONTAINER_ASS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
getMutex(__LINE__);
|
getMutex(__LINE__);
|
||||||
@@ -706,7 +708,7 @@ static int container_ass_switch_subtitle(Context_t* context, int* arg __attribut
|
|||||||
* process_data is called.
|
* process_data is called.
|
||||||
*/
|
*/
|
||||||
if (ass_track)
|
if (ass_track)
|
||||||
ass_free_track(ass_track);
|
ass_free_track(ass_track);
|
||||||
|
|
||||||
ass_track = NULL;
|
ass_track = NULL;
|
||||||
|
|
||||||
@@ -718,36 +720,35 @@ static int container_ass_switch_subtitle(Context_t* context, int* arg __attribut
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int Command(void *_context, ContainerCmd_t command, void * argument)
|
static int Command(void *_context, ContainerCmd_t command, void *argument)
|
||||||
{
|
{
|
||||||
Context_t *context = (Context_t*) _context;
|
Context_t *context = (Context_t *) _context;
|
||||||
int ret = cERR_CONTAINER_ASS_NO_ERROR;
|
int ret = cERR_CONTAINER_ASS_NO_ERROR;
|
||||||
|
|
||||||
ass_printf(50, "Command %d\n", command);
|
ass_printf(50, "Command %d\n", command);
|
||||||
|
|
||||||
switch(command)
|
switch (command) {
|
||||||
{
|
case CONTAINER_INIT:{
|
||||||
case CONTAINER_INIT: {
|
ret = container_ass_init(context);
|
||||||
ret = container_ass_init(context);
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case CONTAINER_STOP:{
|
||||||
case CONTAINER_STOP: {
|
ret = container_ass_stop(context);
|
||||||
ret = container_ass_stop(context);
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case CONTAINER_SWITCH_SUBTITLE:{
|
||||||
case CONTAINER_SWITCH_SUBTITLE: {
|
ret = container_ass_switch_subtitle(context, (int *) argument);
|
||||||
ret = container_ass_switch_subtitle(context, (int*) argument);
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case CONTAINER_DATA:{
|
||||||
case CONTAINER_DATA: {
|
SubtitleData_t *data = (SubtitleData_t *) argument;
|
||||||
SubtitleData_t* data = (SubtitleData_t*) argument;
|
ret = container_ass_process_data(context, data);
|
||||||
ret = container_ass_process_data(context, data);
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
ass_err("ContainerCmd %d not supported!\n", command);
|
ass_err("ContainerCmd %d not supported!\n", command);
|
||||||
ret = cERR_CONTAINER_ASS_ERROR;
|
ret = cERR_CONTAINER_ASS_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ass_printf(50, "exiting with value %d\n", ret);
|
ass_printf(50, "exiting with value %d\n", ret);
|
||||||
@@ -755,7 +756,7 @@ static int Command(void *_context, ContainerCmd_t command, void * argument)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *ASS_Capabilities[] = {"ass", NULL };
|
static char *ASS_Capabilities[] = { "ass", NULL };
|
||||||
|
|
||||||
Container_t ASSContainer = {
|
Container_t ASSContainer = {
|
||||||
"ASS",
|
"ASS",
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -74,7 +74,7 @@ static const char FILENAME[] = "text_srt.c";
|
|||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char * File;
|
char *File;
|
||||||
int Id;
|
int Id;
|
||||||
} SrtTrack_t;
|
} SrtTrack_t;
|
||||||
|
|
||||||
@@ -84,11 +84,11 @@ static pthread_t thread_sub;
|
|||||||
/* Varaibles */
|
/* Varaibles */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static SrtTrack_t * Tracks;
|
static SrtTrack_t *Tracks;
|
||||||
static int TrackCount = 0;
|
static int TrackCount = 0;
|
||||||
static int CurrentTrack = -1; //no as default.
|
static int CurrentTrack = -1; //no as default.
|
||||||
|
|
||||||
FILE * fsub = NULL;
|
FILE *fsub = NULL;
|
||||||
|
|
||||||
static int hasThreadStarted = 0;
|
static int hasThreadStarted = 0;
|
||||||
|
|
||||||
@@ -100,28 +100,29 @@ static int hasThreadStarted = 0;
|
|||||||
/* MISC Functions */
|
/* MISC Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
void data_to_manager(Context_t *context, char* Text, unsigned long long int Pts, double Duration)
|
void data_to_manager(Context_t * context, char *Text,
|
||||||
|
unsigned long long int Pts, double Duration)
|
||||||
{
|
{
|
||||||
srt_printf(20, "--> Text= \"%s\"\n", Text);
|
srt_printf(20, "--> Text= \"%s\"\n", Text);
|
||||||
|
|
||||||
if( context &&
|
if (context && context->playback && context->playback->isPlaying) {
|
||||||
context->playback &&
|
int sl = strlen(Text) - 1;
|
||||||
context->playback->isPlaying){
|
while (sl && (Text[sl] == '\n' || Text[sl] == '\r'))
|
||||||
int sl = strlen(Text)-1;
|
Text[sl--] = '\0'; /*Delete last \n or \r */
|
||||||
while(sl && (Text[sl]=='\n' || Text[sl]=='\r')) Text[sl--]='\0'; /*Delete last \n or \r */
|
unsigned char *line = text_to_ass(Text, Pts, Duration);
|
||||||
unsigned char* line = text_to_ass(Text, Pts, Duration);
|
srt_printf(50, "Sub text is %s\n", Text);
|
||||||
srt_printf(50,"Sub text is %s\n",Text);
|
srt_printf(50, "Sub line is %s\n", line);
|
||||||
srt_printf(50,"Sub line is %s\n",line);
|
SubtitleData_t data;
|
||||||
SubtitleData_t data;
|
data.data = line;
|
||||||
data.data = line;
|
data.len = strlen((char *) line);
|
||||||
data.len = strlen((char*)line);
|
data.extradata = (unsigned char *) DEFAULT_ASS_HEAD;
|
||||||
data.extradata = (unsigned char *) DEFAULT_ASS_HEAD;
|
data.extralen = strlen(DEFAULT_ASS_HEAD);
|
||||||
data.extralen = strlen(DEFAULT_ASS_HEAD);
|
data.pts = Pts * 90;
|
||||||
data.pts = Pts*90;
|
data.duration = Duration;
|
||||||
data.duration = Duration;
|
|
||||||
|
|
||||||
context->container->assContainer->Command(context, CONTAINER_DATA, &data);
|
context->container->assContainer->Command(context, CONTAINER_DATA,
|
||||||
free(line);
|
&data);
|
||||||
|
free(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
srt_printf(20, "<-- Text= \"%s\"\n", Text);
|
srt_printf(20, "<-- Text= \"%s\"\n", Text);
|
||||||
@@ -131,72 +132,83 @@ void data_to_manager(Context_t *context, char* Text, unsigned long long int Pts,
|
|||||||
/* Worker Thread */
|
/* Worker Thread */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static void* SrtSubtitleThread(void *data) {
|
static void *SrtSubtitleThread(void *data)
|
||||||
|
{
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
char Data[MAXLINELENGTH];
|
char Data[MAXLINELENGTH];
|
||||||
unsigned long long int Pts = 0;
|
unsigned long long int Pts = 0;
|
||||||
double Duration = 0;
|
double Duration = 0;
|
||||||
char * Text = NULL;
|
char *Text = NULL;
|
||||||
|
|
||||||
Context_t *context = (Context_t*) data;
|
Context_t *context = (Context_t *) data;
|
||||||
|
|
||||||
srt_printf(10, "\n");
|
srt_printf(10, "\n");
|
||||||
|
|
||||||
while(context && context->playback && context->playback->isPlaying && fsub && fgets(Data, MAXLINELENGTH, fsub)) {
|
while (context && context->playback && context->playback->isPlaying
|
||||||
srt_printf(20, "pos=%d\n", pos);
|
&& fsub && fgets(Data, MAXLINELENGTH, fsub)) {
|
||||||
|
srt_printf(20, "pos=%d\n", pos);
|
||||||
|
|
||||||
if(pos == 0)
|
if (pos == 0) {
|
||||||
{
|
if (Data[0] == '\n' || Data[0] == '\0'
|
||||||
if(Data[0] == '\n' || Data[0] == '\0' || Data[0] == 13 /* ^M */)
|
|| Data[0] == 13 /* ^M */ )
|
||||||
continue; /* Empty line not allowed here */
|
continue; /* Empty line not allowed here */
|
||||||
pos++;
|
pos++;
|
||||||
} else if(pos == 1)
|
} else if (pos == 1) {
|
||||||
{
|
int ret, horIni, minIni, secIni, milIni, horFim, minFim,
|
||||||
int ret, horIni, minIni, secIni, milIni, horFim, minFim, secFim, milFim;
|
secFim, milFim;
|
||||||
|
|
||||||
ret = sscanf(Data, "%d:%d:%d,%d --> %d:%d:%d,%d", &horIni, &minIni, &secIni, &milIni, &horFim, &minFim, &secFim, &milFim);
|
ret =
|
||||||
if (ret!=8) continue; /* Data is not in correct format */
|
sscanf(Data, "%d:%d:%d,%d --> %d:%d:%d,%d", &horIni,
|
||||||
|
&minIni, &secIni, &milIni, &horFim, &minFim,
|
||||||
|
&secFim, &milFim);
|
||||||
|
if (ret != 8)
|
||||||
|
continue; /* Data is not in correct format */
|
||||||
|
|
||||||
Pts = (horIni*3600 + minIni*60 + secIni)*1000 + milIni;
|
Pts = (horIni * 3600 + minIni * 60 + secIni) * 1000 + milIni;
|
||||||
Duration = ((horFim*3600 + minFim*60 + secFim) * 1000 + milFim - Pts) / 1000.0;
|
Duration =
|
||||||
|
((horFim * 3600 + minFim * 60 + secFim) * 1000 + milFim -
|
||||||
|
Pts) / 1000.0;
|
||||||
|
|
||||||
pos++;
|
pos++;
|
||||||
|
|
||||||
} else if(pos == 2) {
|
} else if (pos == 2) {
|
||||||
srt_printf(20, "Data[0] = %d \'%c\'\n", Data[0], Data[0]);
|
srt_printf(20, "Data[0] = %d \'%c\'\n", Data[0], Data[0]);
|
||||||
|
|
||||||
if(Data[0] == '\n' || Data[0] == '\0' || Data[0] == 13 /* ^M */) {
|
if (Data[0] == '\n' || Data[0] == '\0'
|
||||||
if(Text == NULL)
|
|| Data[0] == 13 /* ^M */ ) {
|
||||||
Text = strdup(" \n"); /* better to display at least one character */
|
if (Text == NULL)
|
||||||
|
Text = strdup(" \n"); /* better to display at least one character */
|
||||||
|
|
||||||
/*Hellmaster 1024 since we have waited, we have to check if we are still paying */
|
/*Hellmaster 1024 since we have waited, we have to check if we are still paying */
|
||||||
data_to_manager(context, Text, Pts, Duration);
|
data_to_manager(context, Text, Pts, Duration);
|
||||||
free(Text);
|
free(Text);
|
||||||
Text = NULL;
|
Text = NULL;
|
||||||
pos = 0;
|
pos = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Text) {
|
if (!Text) {
|
||||||
Text = strdup(Data);
|
Text = strdup(Data);
|
||||||
} else {
|
} else {
|
||||||
int length = strlen(Text) /* \0 -> \n */ + strlen(Data) + 2 /* \0 */;
|
int length =
|
||||||
char * tmpText = Text;
|
strlen(Text) /* \0 -> \n */ +strlen(Data) +
|
||||||
Text = (char*)malloc(length);
|
2 /* \0 */ ;
|
||||||
|
char *tmpText = Text;
|
||||||
|
Text = (char *) malloc(length);
|
||||||
|
|
||||||
strcpy(Text, tmpText);
|
strcpy(Text, tmpText);
|
||||||
strcat(Text, Data);
|
strcat(Text, Data);
|
||||||
free(tmpText);
|
free(tmpText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
hasThreadStarted = 0;
|
hasThreadStarted = 0;
|
||||||
|
|
||||||
if(Text) {
|
if (Text) {
|
||||||
data_to_manager(context, Text, Pts, Duration);
|
data_to_manager(context, Text, Pts, Duration);
|
||||||
free(Text);
|
free(Text);
|
||||||
Text = NULL;
|
Text = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
srt_printf(0, "thread has ended\n");
|
srt_printf(0, "thread has ended\n");
|
||||||
@@ -208,58 +220,62 @@ static void* SrtSubtitleThread(void *data) {
|
|||||||
/* Functions */
|
/* Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static void SrtManagerAdd(Context_t *context __attribute__((unused)), SrtTrack_t track) {
|
static void SrtManagerAdd(Context_t * context
|
||||||
srt_printf(10, "%s %d\n",track.File, track.Id);
|
__attribute__ ((unused)), SrtTrack_t track)
|
||||||
|
{
|
||||||
|
srt_printf(10, "%s %d\n", track.File, track.Id);
|
||||||
|
|
||||||
if (Tracks == NULL) {
|
if (Tracks == NULL) {
|
||||||
Tracks = malloc(sizeof(SrtTrack_t) * TRACKWRAP);
|
Tracks = malloc(sizeof(SrtTrack_t) * TRACKWRAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TrackCount < TRACKWRAP) {
|
if (TrackCount < TRACKWRAP) {
|
||||||
Tracks[TrackCount].File = strdup(track.File);
|
Tracks[TrackCount].File = strdup(track.File);
|
||||||
Tracks[TrackCount].Id = track.Id;
|
Tracks[TrackCount].Id = track.Id;
|
||||||
TrackCount++;
|
TrackCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static char ** SrtManagerList(Context_t *context __attribute__((unused))) {
|
static char **SrtManagerList(Context_t * context __attribute__ ((unused)))
|
||||||
char ** tracklist = NULL;
|
{
|
||||||
|
char **tracklist = NULL;
|
||||||
|
|
||||||
srt_printf(10, "\n");
|
srt_printf(10, "\n");
|
||||||
|
|
||||||
if (Tracks != NULL) {
|
if (Tracks != NULL) {
|
||||||
char help[256];
|
char help[256];
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
|
|
||||||
tracklist = malloc(sizeof(char *) * ((TrackCount*2) + 1));
|
tracklist = malloc(sizeof(char *) * ((TrackCount * 2) + 1));
|
||||||
|
|
||||||
for (i = 0, j = 0; i < TrackCount; i++, j+=2) {
|
for (i = 0, j = 0; i < TrackCount; i++, j += 2) {
|
||||||
|
|
||||||
sprintf(help, "%d", Tracks[i].Id);
|
sprintf(help, "%d", Tracks[i].Id);
|
||||||
tracklist[j] = strdup(help);
|
tracklist[j] = strdup(help);
|
||||||
tracklist[j+1] = strdup(Tracks[i].File);
|
tracklist[j + 1] = strdup(Tracks[i].File);
|
||||||
}
|
}
|
||||||
tracklist[j] = NULL;
|
tracklist[j] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tracklist;
|
return tracklist;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void SrtManagerDel(Context_t * context __attribute__((unused))) {
|
static void SrtManagerDel(Context_t * context __attribute__ ((unused)))
|
||||||
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
srt_printf(10, "\n");
|
srt_printf(10, "\n");
|
||||||
|
|
||||||
if(Tracks != NULL) {
|
if (Tracks != NULL) {
|
||||||
for (i = 0; i < TrackCount; i++) {
|
for (i = 0; i < TrackCount; i++) {
|
||||||
if (Tracks[i].File != NULL)
|
if (Tracks[i].File != NULL)
|
||||||
free(Tracks[i].File);
|
free(Tracks[i].File);
|
||||||
Tracks[i].File = NULL;
|
Tracks[i].File = NULL;
|
||||||
}
|
}
|
||||||
free(Tracks);
|
free(Tracks);
|
||||||
Tracks = NULL;
|
Tracks = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackCount = 0;
|
TrackCount = 0;
|
||||||
@@ -267,31 +283,30 @@ static void SrtManagerDel(Context_t * context __attribute__((unused))) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int SrtGetSubtitle(Context_t *context, char * Filename) {
|
static int SrtGetSubtitle(Context_t * context, char *Filename)
|
||||||
|
{
|
||||||
struct dirent *dirzeiger;
|
struct dirent *dirzeiger;
|
||||||
DIR * dir;
|
DIR *dir;
|
||||||
int i = TEXTSRTOFFSET;
|
int i = TEXTSRTOFFSET;
|
||||||
char * copyFilename = NULL;
|
char *copyFilename = NULL;
|
||||||
char * FilenameExtension = NULL;
|
char *FilenameExtension = NULL;
|
||||||
char * FilenameFolder = NULL;
|
char *FilenameFolder = NULL;
|
||||||
char * FilenameShort = NULL;
|
char *FilenameShort = NULL;
|
||||||
|
|
||||||
srt_printf(10, "\n");
|
srt_printf(10, "\n");
|
||||||
|
|
||||||
if (Filename == NULL)
|
if (Filename == NULL) {
|
||||||
{
|
srt_err("Filename NULL\n");
|
||||||
srt_err("Filename NULL\n");
|
return cERR_SRT_ERROR;
|
||||||
return cERR_SRT_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
srt_printf(10, "file: %s\n", Filename);
|
srt_printf(10, "file: %s\n", Filename);
|
||||||
|
|
||||||
copyFilename = strdup(Filename);
|
copyFilename = strdup(Filename);
|
||||||
|
|
||||||
if (copyFilename == NULL)
|
if (copyFilename == NULL) {
|
||||||
{
|
srt_err("copyFilename NULL\n");
|
||||||
srt_err("copyFilename NULL\n");
|
return cERR_SRT_ERROR;
|
||||||
return cERR_SRT_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FilenameFolder = dirname(copyFilename);
|
FilenameFolder = dirname(copyFilename);
|
||||||
@@ -300,11 +315,10 @@ static int SrtGetSubtitle(Context_t *context, char * Filename) {
|
|||||||
|
|
||||||
FilenameExtension = getExtension(copyFilename);
|
FilenameExtension = getExtension(copyFilename);
|
||||||
|
|
||||||
if (FilenameExtension == NULL)
|
if (FilenameExtension == NULL) {
|
||||||
{
|
srt_err("FilenameExtension NULL\n");
|
||||||
srt_err("FilenameExtension NULL\n");
|
free(copyFilename);
|
||||||
free(copyFilename);
|
return cERR_SRT_ERROR;
|
||||||
return cERR_SRT_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
srt_printf(10, "ext: %s\n", FilenameExtension);
|
srt_printf(10, "ext: %s\n", FilenameExtension);
|
||||||
@@ -312,84 +326,94 @@ static int SrtGetSubtitle(Context_t *context, char * Filename) {
|
|||||||
FilenameShort = basename(copyFilename);
|
FilenameShort = basename(copyFilename);
|
||||||
|
|
||||||
/* cut extension */
|
/* cut extension */
|
||||||
FilenameShort[strlen(FilenameShort) - strlen(FilenameExtension) - 1] = '\0';
|
FilenameShort[strlen(FilenameShort) - strlen(FilenameExtension) - 1] =
|
||||||
|
'\0';
|
||||||
|
|
||||||
srt_printf(10, "basename: %s\n", FilenameShort);
|
srt_printf(10, "basename: %s\n", FilenameShort);
|
||||||
srt_printf(10, "%s\n%s | %s | %s\n", copyFilename, FilenameFolder, FilenameShort, FilenameExtension);
|
srt_printf(10, "%s\n%s | %s | %s\n", copyFilename, FilenameFolder,
|
||||||
|
FilenameShort, FilenameExtension);
|
||||||
|
|
||||||
if((dir = opendir(FilenameFolder)) != NULL) {
|
if ((dir = opendir(FilenameFolder)) != NULL) {
|
||||||
while((dirzeiger = readdir(dir)) != NULL) {
|
while ((dirzeiger = readdir(dir)) != NULL) {
|
||||||
char subtitleFilename[PATH_MAX];
|
char subtitleFilename[PATH_MAX];
|
||||||
char *subtitleExtension = NULL;
|
char *subtitleExtension = NULL;
|
||||||
|
|
||||||
srt_printf(20, "%s\n",(*dirzeiger).d_name);
|
srt_printf(20, "%s\n", (*dirzeiger).d_name);
|
||||||
|
|
||||||
strcpy(subtitleFilename, (*dirzeiger).d_name);
|
strcpy(subtitleFilename, (*dirzeiger).d_name);
|
||||||
|
|
||||||
// Extension of Relativ Subtitle File Name
|
// Extension of Relativ Subtitle File Name
|
||||||
subtitleExtension = getExtension(subtitleFilename);
|
subtitleExtension = getExtension(subtitleFilename);
|
||||||
|
|
||||||
if (subtitleExtension == NULL)
|
if (subtitleExtension == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strcmp(subtitleExtension, "srt") != 0)
|
if (strcmp(subtitleExtension, "srt") != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* cut extension */
|
/* cut extension */
|
||||||
subtitleFilename[strlen(subtitleFilename) - strlen(subtitleExtension) - 1] = '\0';
|
subtitleFilename[strlen(subtitleFilename) -
|
||||||
|
strlen(subtitleExtension) - 1] = '\0';
|
||||||
|
|
||||||
srt_printf(10, "%s %s\n", FilenameShort, subtitleFilename);
|
srt_printf(10, "%s %s\n", FilenameShort, subtitleFilename);
|
||||||
|
|
||||||
if (strncmp(FilenameShort, subtitleFilename,strlen(FilenameShort)) == 0)
|
if (strncmp
|
||||||
{
|
(FilenameShort, subtitleFilename,
|
||||||
char absSubtitleFileName[PATH_MAX];
|
strlen(FilenameShort)) == 0) {
|
||||||
/* found something of interest, so now make an absolut path name */
|
char absSubtitleFileName[PATH_MAX];
|
||||||
|
/* found something of interest, so now make an absolut path name */
|
||||||
|
|
||||||
sprintf(absSubtitleFileName, "%s/%s.%s", FilenameFolder, subtitleFilename, subtitleExtension);
|
sprintf(absSubtitleFileName, "%s/%s.%s", FilenameFolder,
|
||||||
|
subtitleFilename, subtitleExtension);
|
||||||
|
|
||||||
srt_printf(10, "SRT: %s [%s]\n", subtitleExtension, subtitleFilename);
|
srt_printf(10, "SRT: %s [%s]\n", subtitleExtension,
|
||||||
srt_printf(10, "\t->%s\n", absSubtitleFileName);
|
subtitleFilename);
|
||||||
|
srt_printf(10, "\t->%s\n", absSubtitleFileName);
|
||||||
|
|
||||||
SrtTrack_t SrtSubtitle = {
|
SrtTrack_t SrtSubtitle = {
|
||||||
absSubtitleFileName,
|
absSubtitleFileName,
|
||||||
i,
|
i,
|
||||||
};
|
};
|
||||||
|
|
||||||
SrtManagerAdd(context, SrtSubtitle);
|
SrtManagerAdd(context, SrtSubtitle);
|
||||||
|
|
||||||
Track_t Subtitle;
|
Track_t Subtitle;
|
||||||
memset(&Subtitle, 0, sizeof(Subtitle));
|
memset(&Subtitle, 0, sizeof(Subtitle));
|
||||||
Subtitle.Name = subtitleExtension;
|
Subtitle.Name = subtitleExtension;
|
||||||
Subtitle.Encoding = "S_TEXT/SRT";
|
Subtitle.Encoding = "S_TEXT/SRT";
|
||||||
Subtitle.Id = i++,
|
Subtitle.Id = i++,
|
||||||
context->manager->subtitle->Command(context, MANAGER_ADD, &Subtitle);
|
context->manager->subtitle->Command(context,
|
||||||
}
|
MANAGER_ADD,
|
||||||
} /* while */
|
&Subtitle);
|
||||||
|
}
|
||||||
|
} /* while */
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
} /* if dir */
|
}
|
||||||
|
/* if dir */
|
||||||
free(copyFilename);
|
free(copyFilename);
|
||||||
|
|
||||||
srt_printf(10, "<\n");
|
srt_printf(10, "<\n");
|
||||||
return cERR_SRT_NO_ERROR;
|
return cERR_SRT_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SrtOpenSubtitle(Context_t *context __attribute__((unused)), int pid) {
|
static int SrtOpenSubtitle(Context_t * context
|
||||||
|
__attribute__ ((unused)), int pid)
|
||||||
|
{
|
||||||
srt_printf(10, "\n");
|
srt_printf(10, "\n");
|
||||||
|
|
||||||
if(pid < TEXTSRTOFFSET) {
|
if (pid < TEXTSRTOFFSET) {
|
||||||
srt_err("trackid not for us\n");
|
srt_err("trackid not for us\n");
|
||||||
return cERR_SRT_ERROR;
|
return cERR_SRT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int trackid;
|
int trackid;
|
||||||
for (trackid = 0; trackid < TrackCount; trackid++)
|
for (trackid = 0; trackid < TrackCount; trackid++)
|
||||||
if (Tracks[trackid].Id == pid)
|
if (Tracks[trackid].Id == pid)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(trackid == TrackCount) {
|
if (trackid == TrackCount) {
|
||||||
srt_err("trackid not for us\n");
|
srt_err("trackid not for us\n");
|
||||||
return cERR_SRT_ERROR;
|
return cERR_SRT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
srt_printf(10, "%s\n", Tracks[trackid].File);
|
srt_printf(10, "%s\n", Tracks[trackid].File);
|
||||||
@@ -398,19 +422,19 @@ static int SrtOpenSubtitle(Context_t *context __attribute__((unused)), int pid)
|
|||||||
|
|
||||||
srt_printf(10, "%s\n", fsub ? "fsub!=NULL" : "fsub==NULL");
|
srt_printf(10, "%s\n", fsub ? "fsub!=NULL" : "fsub==NULL");
|
||||||
|
|
||||||
if(!fsub)
|
if (!fsub) {
|
||||||
{
|
srt_err("cannot open file %s\n", Tracks[trackid].File);
|
||||||
srt_err("cannot open file %s\n", Tracks[trackid].File);
|
return cERR_SRT_ERROR;
|
||||||
return cERR_SRT_ERROR;
|
|
||||||
}
|
}
|
||||||
return cERR_SRT_NO_ERROR;
|
return cERR_SRT_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SrtCloseSubtitle(Context_t *context __attribute__((unused))) {
|
static int SrtCloseSubtitle(Context_t * context __attribute__ ((unused)))
|
||||||
|
{
|
||||||
srt_printf(10, "\n");
|
srt_printf(10, "\n");
|
||||||
|
|
||||||
if(fsub)
|
if (fsub)
|
||||||
fclose(fsub);
|
fclose(fsub);
|
||||||
|
|
||||||
/* this closes the thread! */
|
/* this closes the thread! */
|
||||||
fsub = NULL;
|
fsub = NULL;
|
||||||
@@ -420,27 +444,29 @@ static int SrtCloseSubtitle(Context_t *context __attribute__((unused))) {
|
|||||||
return cERR_SRT_NO_ERROR;
|
return cERR_SRT_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SrtSwitchSubtitle(Context_t *context, int* arg) {
|
static int SrtSwitchSubtitle(Context_t * context, int *arg)
|
||||||
|
{
|
||||||
int ret = cERR_SRT_NO_ERROR;
|
int ret = cERR_SRT_NO_ERROR;
|
||||||
|
|
||||||
srt_printf(10, "arg:%d\n", *arg);
|
srt_printf(10, "arg:%d\n", *arg);
|
||||||
|
|
||||||
ret = SrtCloseSubtitle(context);
|
ret = SrtCloseSubtitle(context);
|
||||||
|
|
||||||
if (( (ret |= SrtOpenSubtitle(context, *arg)) == cERR_SRT_NO_ERROR) && (!hasThreadStarted))
|
if (((ret |= SrtOpenSubtitle(context, *arg)) == cERR_SRT_NO_ERROR)
|
||||||
{
|
&& (!hasThreadStarted)) {
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
pthread_create (&thread_sub, &attr, &SrtSubtitleThread, context);
|
pthread_create(&thread_sub, &attr, &SrtSubtitleThread, context);
|
||||||
|
|
||||||
hasThreadStarted = 1;
|
hasThreadStarted = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SrtDel(Context_t *context) {
|
static int SrtDel(Context_t * context)
|
||||||
|
{
|
||||||
int ret = cERR_SRT_NO_ERROR;
|
int ret = cERR_SRT_NO_ERROR;
|
||||||
|
|
||||||
srt_printf(10, "\n");
|
srt_printf(10, "\n");
|
||||||
@@ -451,29 +477,30 @@ static int SrtDel(Context_t *context) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Command(void *_context, ContainerCmd_t command, void * argument) {
|
static int Command(void *_context, ContainerCmd_t command, void *argument)
|
||||||
Context_t *context = (Context_t*) _context;
|
{
|
||||||
|
Context_t *context = (Context_t *) _context;
|
||||||
int ret = cERR_SRT_NO_ERROR;
|
int ret = cERR_SRT_NO_ERROR;
|
||||||
|
|
||||||
srt_printf(10, "\n");
|
srt_printf(10, "\n");
|
||||||
|
|
||||||
switch(command) {
|
switch (command) {
|
||||||
case CONTAINER_INIT: {
|
case CONTAINER_INIT:{
|
||||||
char * filename = (char *)argument;
|
char *filename = (char *) argument;
|
||||||
ret = SrtGetSubtitle(context, filename);
|
ret = SrtGetSubtitle(context, filename);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONTAINER_DEL: {
|
case CONTAINER_DEL:{
|
||||||
ret = SrtDel(context);
|
ret = SrtDel(context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONTAINER_SWITCH_SUBTITLE: {
|
case CONTAINER_SWITCH_SUBTITLE:{
|
||||||
ret = SrtSwitchSubtitle(context, (int*) argument);
|
ret = SrtSwitchSubtitle(context, (int *) argument);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
srt_err("ConatinerCmd not supported! %d\n", command);
|
srt_err("ConatinerCmd not supported! %d\n", command);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
srt_printf(10, "ret = %d\n", ret);
|
srt_printf(10, "ret = %d\n", ret);
|
||||||
|
@@ -78,7 +78,7 @@ static const char FILENAME[] = "text_ssa.c";
|
|||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char * File;
|
char *File;
|
||||||
int Id;
|
int Id;
|
||||||
} SsaTrack_t;
|
} SsaTrack_t;
|
||||||
|
|
||||||
@@ -88,9 +88,9 @@ typedef struct {
|
|||||||
|
|
||||||
static pthread_t thread_sub;
|
static pthread_t thread_sub;
|
||||||
|
|
||||||
static SsaTrack_t * Tracks;
|
static SsaTrack_t *Tracks;
|
||||||
static int TrackCount = 0;
|
static int TrackCount = 0;
|
||||||
FILE * fssa = NULL;
|
FILE *fssa = NULL;
|
||||||
|
|
||||||
static int hasThreadStarted = 0;
|
static int hasThreadStarted = 0;
|
||||||
|
|
||||||
@@ -110,44 +110,40 @@ char *SSAgetLine()
|
|||||||
|
|
||||||
k = tamAux = 0;
|
k = tamAux = 0;
|
||||||
|
|
||||||
if(SSA_BUFFER_SIZE>0)
|
if (SSA_BUFFER_SIZE > 0) {
|
||||||
{
|
|
||||||
|
|
||||||
strInput = (char*)malloc(1*sizeof(char));
|
strInput = (char *) malloc(1 * sizeof(char));
|
||||||
strInput[0]='\0';
|
strInput[0] = '\0';
|
||||||
|
|
||||||
while(tamAux!=1)
|
while (tamAux != 1) {
|
||||||
{
|
|
||||||
|
|
||||||
if((ch = fgetc(fssa))!=EOF)
|
if ((ch = fgetc(fssa)) != EOF) {
|
||||||
{
|
ungetc(ch, fssa);
|
||||||
ungetc(ch , fssa);
|
fgets(c, SSA_BUFFER_SIZE, fssa);
|
||||||
fgets(c, SSA_BUFFER_SIZE, fssa);
|
strAux = (char *) strchr(c, '\n');
|
||||||
strAux = (char*)strchr(c,'\n');
|
tam = strlen(c);
|
||||||
tam = strlen(c);
|
if (strAux != NULL) {
|
||||||
if(strAux != NULL)
|
tamAux = strlen(strAux);
|
||||||
{
|
tam--;
|
||||||
tamAux = strlen(strAux);
|
}
|
||||||
tam--;
|
|
||||||
}
|
|
||||||
|
|
||||||
k = k + tam;
|
k = k + tam;
|
||||||
strInput = (char*)realloc(strInput, (k+1)*sizeof(char));
|
strInput =
|
||||||
|
(char *) realloc(strInput, (k + 1) * sizeof(char));
|
||||||
|
|
||||||
if(k!=tam)
|
if (k != tam)
|
||||||
strncat(strInput, c, tam);
|
strncat(strInput, c, tam);
|
||||||
else
|
else
|
||||||
strncpy(strInput, c, tam);
|
strncpy(strInput, c, tam);
|
||||||
|
|
||||||
strInput[k] = '\0';
|
strInput[k] = '\0';
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
tamAux = 1;
|
||||||
tamAux = 1;
|
fclose(fssa);
|
||||||
fclose(fssa);
|
fssa = NULL;
|
||||||
fssa = NULL;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,54 +154,55 @@ char *SSAgetLine()
|
|||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Worker Thread */
|
/* Worker Thread */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
static void* SsaSubtitleThread(void *Data) {
|
static void *SsaSubtitleThread(void *Data)
|
||||||
Context_t *context = (Context_t*) Data;
|
{
|
||||||
char * head =malloc(sizeof(char)*1);
|
Context_t *context = (Context_t *) Data;
|
||||||
|
char *head = malloc(sizeof(char) * 1);
|
||||||
|
|
||||||
ssa_printf(10, "\n");
|
ssa_printf(10, "\n");
|
||||||
head[0]='\0';
|
head[0] = '\0';
|
||||||
|
|
||||||
|
|
||||||
while ( context && context->playback && context->playback->isPlaying && fssa ) {
|
while (context && context->playback && context->playback->isPlaying
|
||||||
char *line = NULL;
|
&& fssa) {
|
||||||
|
char *line = NULL;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
line = SSAgetLine();
|
||||||
line = SSAgetLine();
|
if (strncmp(line, "Dialogue: ", 10)) {
|
||||||
if(strncmp(line,"Dialogue: ",10)) {
|
int head_len = strlen(head);
|
||||||
int head_len = strlen(head);
|
int line_len = strlen(line);
|
||||||
int line_len = strlen(line);
|
head = realloc(head, line_len + head_len + 2);
|
||||||
head = realloc(head, line_len + head_len +2);
|
memcpy(head + head_len, line, sizeof(char) * line_len + 1);
|
||||||
memcpy(head + head_len, line, sizeof(char)*line_len+1);
|
head[head_len + line_len] = '\n';
|
||||||
head[head_len + line_len] = '\n';
|
head[head_len + line_len + 1] = '\0';
|
||||||
head[head_len + line_len + 1] = '\0';
|
}
|
||||||
}
|
} while (strncmp(line, "Dialogue: ", 10) != 0 && fssa);
|
||||||
} while (strncmp(line,"Dialogue: ",10)!=0 && fssa);
|
|
||||||
|
|
||||||
/*Hellmaster 1024 since we have waited, we have to check if we are still paying */
|
/*Hellmaster 1024 since we have waited, we have to check if we are still paying */
|
||||||
if( context &&
|
if (context && context->playback && context->playback->isPlaying) {
|
||||||
context->playback &&
|
SubtitleData_t data;
|
||||||
context->playback->isPlaying) {
|
|
||||||
SubtitleData_t data;
|
|
||||||
|
|
||||||
data.data = (unsigned char*) line;
|
data.data = (unsigned char *) line;
|
||||||
data.len = strlen(line);
|
data.len = strlen(line);
|
||||||
data.extradata = (unsigned char*) head;
|
data.extradata = (unsigned char *) head;
|
||||||
data.extralen = strlen(head);
|
data.extralen = strlen(head);
|
||||||
data.pts = 0;
|
data.pts = 0;
|
||||||
data.duration = 0.0;
|
data.duration = 0.0;
|
||||||
context->container->assContainer->Command(context, CONTAINER_DATA, &data);
|
context->container->assContainer->Command(context,
|
||||||
}
|
CONTAINER_DATA,
|
||||||
free(line);
|
&data);
|
||||||
line = NULL;
|
}
|
||||||
continue;
|
free(line);
|
||||||
|
line = NULL;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasThreadStarted = 0;
|
hasThreadStarted = 0;
|
||||||
|
|
||||||
if(head) {
|
if (head) {
|
||||||
free(head);
|
free(head);
|
||||||
head = NULL;
|
head = NULL;
|
||||||
}
|
}
|
||||||
ssa_printf(0, "thread has ended\n");
|
ssa_printf(0, "thread has ended\n");
|
||||||
|
|
||||||
@@ -217,88 +214,91 @@ static void* SsaSubtitleThread(void *Data) {
|
|||||||
/* Functions */
|
/* Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static void SsaManagerAdd(Context_t *context __attribute__((unused)), SsaTrack_t track) {
|
static void SsaManagerAdd(Context_t * context
|
||||||
|
__attribute__ ((unused)), SsaTrack_t track)
|
||||||
|
{
|
||||||
ssa_printf(10, "%s %d\n", track.File, track.Id);
|
ssa_printf(10, "%s %d\n", track.File, track.Id);
|
||||||
|
|
||||||
if (Tracks == NULL) {
|
if (Tracks == NULL) {
|
||||||
Tracks = malloc(sizeof(SsaTrack_t) * TRACKWRAP);
|
Tracks = malloc(sizeof(SsaTrack_t) * TRACKWRAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TrackCount < TRACKWRAP) {
|
if (TrackCount < TRACKWRAP) {
|
||||||
Tracks[TrackCount].File = strdup(track.File);
|
Tracks[TrackCount].File = strdup(track.File);
|
||||||
Tracks[TrackCount].Id = track.Id;
|
Tracks[TrackCount].Id = track.Id;
|
||||||
TrackCount++;
|
TrackCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static char ** SsaManagerList(Context_t *context __attribute__((unused))) {
|
static char **SsaManagerList(Context_t * context __attribute__ ((unused)))
|
||||||
char ** tracklist = NULL;
|
{
|
||||||
|
char **tracklist = NULL;
|
||||||
|
|
||||||
ssa_printf(10, "\n");
|
ssa_printf(10, "\n");
|
||||||
|
|
||||||
if (Tracks != NULL) {
|
if (Tracks != NULL) {
|
||||||
char help[256];
|
char help[256];
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
|
|
||||||
tracklist = malloc(sizeof(char *) * ((TrackCount*2) + 1));
|
tracklist = malloc(sizeof(char *) * ((TrackCount * 2) + 1));
|
||||||
|
|
||||||
for (i = 0, j = 0; i < TrackCount; i++, j+=2) {
|
for (i = 0, j = 0; i < TrackCount; i++, j += 2) {
|
||||||
|
|
||||||
sprintf(help, "%d", Tracks[i].Id);
|
sprintf(help, "%d", Tracks[i].Id);
|
||||||
tracklist[j] = strdup(help);
|
tracklist[j] = strdup(help);
|
||||||
tracklist[j+1] = strdup(Tracks[i].File);
|
tracklist[j + 1] = strdup(Tracks[i].File);
|
||||||
}
|
}
|
||||||
tracklist[j] = NULL;
|
tracklist[j] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tracklist;
|
return tracklist;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void SsaManagerDel(Context_t * context __attribute__((unused))) {
|
static void SsaManagerDel(Context_t * context __attribute__ ((unused)))
|
||||||
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
ssa_printf(10, "\n");
|
ssa_printf(10, "\n");
|
||||||
|
|
||||||
if(Tracks != NULL) {
|
if (Tracks != NULL) {
|
||||||
for (i = 0; i < TrackCount; i++) {
|
for (i = 0; i < TrackCount; i++) {
|
||||||
if (Tracks[i].File != NULL)
|
if (Tracks[i].File != NULL)
|
||||||
free(Tracks[i].File);
|
free(Tracks[i].File);
|
||||||
Tracks[i].File = NULL;
|
Tracks[i].File = NULL;
|
||||||
}
|
}
|
||||||
free(Tracks);
|
free(Tracks);
|
||||||
Tracks = NULL;
|
Tracks = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackCount = 0;
|
TrackCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SsaGetSubtitle(Context_t *context, char * Filename) {
|
static int SsaGetSubtitle(Context_t * context, char *Filename)
|
||||||
|
{
|
||||||
struct dirent *dirzeiger;
|
struct dirent *dirzeiger;
|
||||||
DIR * dir;
|
DIR *dir;
|
||||||
int i = TEXTSSAOFFSET;
|
int i = TEXTSSAOFFSET;
|
||||||
char * copyFilename = NULL;
|
char *copyFilename = NULL;
|
||||||
char * FilenameExtension = NULL;
|
char *FilenameExtension = NULL;
|
||||||
char * FilenameFolder = NULL;
|
char *FilenameFolder = NULL;
|
||||||
char * FilenameShort = NULL;
|
char *FilenameShort = NULL;
|
||||||
|
|
||||||
ssa_printf(10, "\n");
|
ssa_printf(10, "\n");
|
||||||
|
|
||||||
if (Filename == NULL)
|
if (Filename == NULL) {
|
||||||
{
|
ssa_err("Filename NULL\n");
|
||||||
ssa_err("Filename NULL\n");
|
return cERR_SSA_ERROR;
|
||||||
return cERR_SSA_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ssa_printf(10, "file: %s\n", Filename);
|
ssa_printf(10, "file: %s\n", Filename);
|
||||||
|
|
||||||
copyFilename = strdup(Filename);
|
copyFilename = strdup(Filename);
|
||||||
|
|
||||||
if (copyFilename == NULL)
|
if (copyFilename == NULL) {
|
||||||
{
|
ssa_err("copyFilename NULL\n");
|
||||||
ssa_err("copyFilename NULL\n");
|
return cERR_SSA_ERROR;
|
||||||
return cERR_SSA_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FilenameFolder = dirname(copyFilename);
|
FilenameFolder = dirname(copyFilename);
|
||||||
@@ -307,11 +307,10 @@ static int SsaGetSubtitle(Context_t *context, char * Filename) {
|
|||||||
|
|
||||||
FilenameExtension = getExtension(copyFilename);
|
FilenameExtension = getExtension(copyFilename);
|
||||||
|
|
||||||
if (FilenameExtension == NULL)
|
if (FilenameExtension == NULL) {
|
||||||
{
|
ssa_err("FilenameExtension NULL\n");
|
||||||
ssa_err("FilenameExtension NULL\n");
|
free(copyFilename);
|
||||||
free(copyFilename);
|
return cERR_SSA_ERROR;
|
||||||
return cERR_SSA_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ssa_printf(10, "ext: %s\n", FilenameExtension);
|
ssa_printf(10, "ext: %s\n", FilenameExtension);
|
||||||
@@ -319,84 +318,94 @@ static int SsaGetSubtitle(Context_t *context, char * Filename) {
|
|||||||
FilenameShort = basename(copyFilename);
|
FilenameShort = basename(copyFilename);
|
||||||
|
|
||||||
/* cut extension */
|
/* cut extension */
|
||||||
FilenameShort[strlen(FilenameShort) - strlen(FilenameExtension) - 1] = '\0';
|
FilenameShort[strlen(FilenameShort) - strlen(FilenameExtension) - 1] =
|
||||||
|
'\0';
|
||||||
|
|
||||||
ssa_printf(10, "basename: %s\n", FilenameShort);
|
ssa_printf(10, "basename: %s\n", FilenameShort);
|
||||||
ssa_printf(10, "%s\n%s | %s | %s\n", copyFilename, FilenameFolder, FilenameShort, FilenameExtension);
|
ssa_printf(10, "%s\n%s | %s | %s\n", copyFilename, FilenameFolder,
|
||||||
|
FilenameShort, FilenameExtension);
|
||||||
|
|
||||||
if((dir = opendir(FilenameFolder)) != NULL) {
|
if ((dir = opendir(FilenameFolder)) != NULL) {
|
||||||
while((dirzeiger = readdir(dir)) != NULL) {
|
while ((dirzeiger = readdir(dir)) != NULL) {
|
||||||
char subtitleFilename[PATH_MAX];
|
char subtitleFilename[PATH_MAX];
|
||||||
char *subtitleExtension = NULL;
|
char *subtitleExtension = NULL;
|
||||||
|
|
||||||
ssa_printf(20, "%s\n",(*dirzeiger).d_name);
|
ssa_printf(20, "%s\n", (*dirzeiger).d_name);
|
||||||
|
|
||||||
strcpy(subtitleFilename, (*dirzeiger).d_name);
|
strcpy(subtitleFilename, (*dirzeiger).d_name);
|
||||||
|
|
||||||
// Extension of Relativ Subtitle File Name
|
// Extension of Relativ Subtitle File Name
|
||||||
subtitleExtension = getExtension(subtitleFilename);
|
subtitleExtension = getExtension(subtitleFilename);
|
||||||
|
|
||||||
if (subtitleExtension == NULL)
|
if (subtitleExtension == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( strcmp(subtitleExtension, "ssa") != 0 && strcmp(subtitleExtension, "ass") != 0 )
|
if (strcmp(subtitleExtension, "ssa") != 0
|
||||||
continue;
|
&& strcmp(subtitleExtension, "ass") != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* cut extension */
|
/* cut extension */
|
||||||
subtitleFilename[strlen(subtitleFilename) - strlen(subtitleExtension) - 1] = '\0';
|
subtitleFilename[strlen(subtitleFilename) -
|
||||||
|
strlen(subtitleExtension) - 1] = '\0';
|
||||||
|
|
||||||
ssa_printf(10, "%s %s\n", FilenameShort, subtitleFilename);
|
ssa_printf(10, "%s %s\n", FilenameShort, subtitleFilename);
|
||||||
|
|
||||||
if (strncmp(FilenameShort, subtitleFilename,strlen(FilenameShort)) == 0)
|
if (strncmp
|
||||||
{
|
(FilenameShort, subtitleFilename,
|
||||||
char absSubtitleFileName[PATH_MAX];
|
strlen(FilenameShort)) == 0) {
|
||||||
/* found something of interest, so now make an absolut path name */
|
char absSubtitleFileName[PATH_MAX];
|
||||||
|
/* found something of interest, so now make an absolut path name */
|
||||||
|
|
||||||
sprintf(absSubtitleFileName, "%s/%s.%s", FilenameFolder, subtitleFilename, subtitleExtension);
|
sprintf(absSubtitleFileName, "%s/%s.%s", FilenameFolder,
|
||||||
|
subtitleFilename, subtitleExtension);
|
||||||
|
|
||||||
ssa_printf(10, "SSA: %s [%s]\n", subtitleExtension, subtitleFilename);
|
ssa_printf(10, "SSA: %s [%s]\n", subtitleExtension,
|
||||||
ssa_printf(10, "\t->%s\n", absSubtitleFileName);
|
subtitleFilename);
|
||||||
|
ssa_printf(10, "\t->%s\n", absSubtitleFileName);
|
||||||
|
|
||||||
SsaTrack_t SsaSubtitle = {
|
SsaTrack_t SsaSubtitle = {
|
||||||
absSubtitleFileName,
|
absSubtitleFileName,
|
||||||
i,
|
i,
|
||||||
};
|
};
|
||||||
|
|
||||||
SsaManagerAdd(context, SsaSubtitle);
|
SsaManagerAdd(context, SsaSubtitle);
|
||||||
|
|
||||||
Track_t Subtitle;
|
Track_t Subtitle;
|
||||||
memset(&Subtitle, 0, sizeof(Subtitle));
|
memset(&Subtitle, 0, sizeof(Subtitle));
|
||||||
Subtitle.Name = subtitleExtension;
|
Subtitle.Name = subtitleExtension;
|
||||||
Subtitle.Encoding = "S_TEXT/SSA";
|
Subtitle.Encoding = "S_TEXT/SSA";
|
||||||
Subtitle.Id = i++;
|
Subtitle.Id = i++;
|
||||||
context->manager->subtitle->Command(context, MANAGER_ADD, &Subtitle);
|
context->manager->subtitle->Command(context, MANAGER_ADD,
|
||||||
}
|
&Subtitle);
|
||||||
} /* while */
|
}
|
||||||
|
} /* while */
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
} /* if dir */
|
}
|
||||||
|
/* if dir */
|
||||||
free(copyFilename);
|
free(copyFilename);
|
||||||
|
|
||||||
ssa_printf(10, "<\n");
|
ssa_printf(10, "<\n");
|
||||||
return cERR_SSA_NO_ERROR;
|
return cERR_SSA_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SsaOpenSubtitle(Context_t *context __attribute__((unused)), int pid) {
|
static int SsaOpenSubtitle(Context_t * context
|
||||||
|
__attribute__ ((unused)), int pid)
|
||||||
|
{
|
||||||
ssa_printf(10, "\n");
|
ssa_printf(10, "\n");
|
||||||
|
|
||||||
if(pid < TEXTSSAOFFSET) {
|
if (pid < TEXTSSAOFFSET) {
|
||||||
ssa_err("trackid not for us\n");
|
ssa_err("trackid not for us\n");
|
||||||
return cERR_SSA_ERROR;
|
return cERR_SSA_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int trackid;
|
int trackid;
|
||||||
for (trackid = 0; trackid < TrackCount; trackid++)
|
for (trackid = 0; trackid < TrackCount; trackid++)
|
||||||
if (Tracks[trackid].Id == pid)
|
if (Tracks[trackid].Id == pid)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(trackid == TrackCount) {
|
if (trackid == TrackCount) {
|
||||||
ssa_err("trackid not for us\n");
|
ssa_err("trackid not for us\n");
|
||||||
return cERR_SSA_ERROR;
|
return cERR_SSA_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssa_printf(10, "%s\n", Tracks[trackid].File);
|
ssa_printf(10, "%s\n", Tracks[trackid].File);
|
||||||
@@ -405,19 +414,19 @@ static int SsaOpenSubtitle(Context_t *context __attribute__((unused)), int pid)
|
|||||||
|
|
||||||
ssa_printf(10, "%s\n", fssa ? "fssa!=NULL" : "fssa==NULL");
|
ssa_printf(10, "%s\n", fssa ? "fssa!=NULL" : "fssa==NULL");
|
||||||
|
|
||||||
if (!fssa)
|
if (!fssa) {
|
||||||
{
|
ssa_err("cannot open file %s\n", Tracks[trackid].File);
|
||||||
ssa_err("cannot open file %s\n", Tracks[trackid].File);
|
return cERR_SSA_ERROR;
|
||||||
return cERR_SSA_ERROR;
|
|
||||||
}
|
}
|
||||||
return cERR_SSA_NO_ERROR;
|
return cERR_SSA_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SsaCloseSubtitle(Context_t *context __attribute__((unused))) {
|
static int SsaCloseSubtitle(Context_t * context __attribute__ ((unused)))
|
||||||
|
{
|
||||||
ssa_printf(10, "\n");
|
ssa_printf(10, "\n");
|
||||||
|
|
||||||
if(fssa)
|
if (fssa)
|
||||||
fclose(fssa);
|
fclose(fssa);
|
||||||
|
|
||||||
/* this closes the thread! */
|
/* this closes the thread! */
|
||||||
fssa = NULL;
|
fssa = NULL;
|
||||||
@@ -427,27 +436,29 @@ static int SsaCloseSubtitle(Context_t *context __attribute__((unused))) {
|
|||||||
return cERR_SSA_NO_ERROR;
|
return cERR_SSA_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SsaSwitchSubtitle(Context_t *context, int* arg) {
|
static int SsaSwitchSubtitle(Context_t * context, int *arg)
|
||||||
|
{
|
||||||
int ret = cERR_SSA_NO_ERROR;
|
int ret = cERR_SSA_NO_ERROR;
|
||||||
|
|
||||||
ssa_printf(10, "\n");
|
ssa_printf(10, "\n");
|
||||||
|
|
||||||
ret = SsaCloseSubtitle(context);
|
ret = SsaCloseSubtitle(context);
|
||||||
|
|
||||||
if (((ret |= SsaOpenSubtitle(context, *arg)) == cERR_SSA_NO_ERROR) && (!hasThreadStarted))
|
if (((ret |= SsaOpenSubtitle(context, *arg)) == cERR_SSA_NO_ERROR)
|
||||||
{
|
&& (!hasThreadStarted)) {
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
pthread_create (&thread_sub, &attr, &SsaSubtitleThread, context);
|
pthread_create(&thread_sub, &attr, &SsaSubtitleThread, context);
|
||||||
|
|
||||||
hasThreadStarted = 1;
|
hasThreadStarted = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SsaDel(Context_t *context) {
|
static int SsaDel(Context_t * context)
|
||||||
|
{
|
||||||
int ret = cERR_SSA_NO_ERROR;
|
int ret = cERR_SSA_NO_ERROR;
|
||||||
|
|
||||||
ssa_printf(10, "\n");
|
ssa_printf(10, "\n");
|
||||||
@@ -459,29 +470,30 @@ static int SsaDel(Context_t *context) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Command(void *_context, ContainerCmd_t command, void * argument) {
|
static int Command(void *_context, ContainerCmd_t command, void *argument)
|
||||||
Context_t *context = (Context_t*) _context;
|
{
|
||||||
|
Context_t *context = (Context_t *) _context;
|
||||||
int ret = cERR_SSA_NO_ERROR;
|
int ret = cERR_SSA_NO_ERROR;
|
||||||
|
|
||||||
ssa_printf(10, "\n");
|
ssa_printf(10, "\n");
|
||||||
|
|
||||||
switch(command) {
|
switch (command) {
|
||||||
case CONTAINER_INIT: {
|
case CONTAINER_INIT:{
|
||||||
char * filename = (char *)argument;
|
char *filename = (char *) argument;
|
||||||
ret = SsaGetSubtitle(context, filename);
|
ret = SsaGetSubtitle(context, filename);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONTAINER_DEL: {
|
case CONTAINER_DEL:{
|
||||||
ret = SsaDel(context);
|
ret = SsaDel(context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONTAINER_SWITCH_SUBTITLE: {
|
case CONTAINER_SWITCH_SUBTITLE:{
|
||||||
ret = SsaSwitchSubtitle(context, (int*) argument);
|
ret = SsaSwitchSubtitle(context, (int *) argument);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
ssa_err("ConatinerCmd not supported! %d\n", command);
|
ssa_err("ConatinerCmd not supported! %d\n", command);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssa_printf(10, "ret = %d\n", ret);
|
ssa_printf(10, "ret = %d\n", ret);
|
||||||
|
@@ -22,36 +22,36 @@
|
|||||||
|
|
||||||
#define AAC_HEADER_LENGTH 7
|
#define AAC_HEADER_LENGTH 7
|
||||||
|
|
||||||
static inline int aac_get_sample_rate_index (uint32_t sample_rate)
|
static inline int aac_get_sample_rate_index(uint32_t sample_rate)
|
||||||
{
|
{
|
||||||
if (96000 <= sample_rate)
|
if (96000 <= sample_rate)
|
||||||
return 0;
|
return 0;
|
||||||
else if (88200 <= sample_rate)
|
else if (88200 <= sample_rate)
|
||||||
return 1;
|
return 1;
|
||||||
else if (64000 <= sample_rate)
|
else if (64000 <= sample_rate)
|
||||||
return 2;
|
return 2;
|
||||||
else if (48000 <= sample_rate)
|
else if (48000 <= sample_rate)
|
||||||
return 3;
|
return 3;
|
||||||
else if (44100 <= sample_rate)
|
else if (44100 <= sample_rate)
|
||||||
return 4;
|
return 4;
|
||||||
else if (32000 <= sample_rate)
|
else if (32000 <= sample_rate)
|
||||||
return 5;
|
return 5;
|
||||||
else if (24000 <= sample_rate)
|
else if (24000 <= sample_rate)
|
||||||
return 6;
|
return 6;
|
||||||
else if (22050 <= sample_rate)
|
else if (22050 <= sample_rate)
|
||||||
return 7;
|
return 7;
|
||||||
else if (16000 <= sample_rate)
|
else if (16000 <= sample_rate)
|
||||||
return 8;
|
return 8;
|
||||||
else if (12000 <= sample_rate)
|
else if (12000 <= sample_rate)
|
||||||
return 9;
|
return 9;
|
||||||
else if (11025 <= sample_rate)
|
else if (11025 <= sample_rate)
|
||||||
return 10;
|
return 10;
|
||||||
else if (8000 <= sample_rate)
|
else if (8000 <= sample_rate)
|
||||||
return 11;
|
return 11;
|
||||||
else if (7350 <= sample_rate)
|
else if (7350 <= sample_rate)
|
||||||
return 12;
|
return 12;
|
||||||
else
|
else
|
||||||
return 13;
|
return 13;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -8,11 +8,12 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
typedef struct Context_s {
|
typedef struct Context_s {
|
||||||
PlaybackHandler_t * playback;
|
PlaybackHandler_t *playback;
|
||||||
ContainerHandler_t * container;
|
ContainerHandler_t *container;
|
||||||
OutputHandler_t * output;
|
OutputHandler_t *output;
|
||||||
ManagerHandler_t * manager;
|
ManagerHandler_t *manager;
|
||||||
} Context_t;
|
} Context_t;
|
||||||
|
|
||||||
int container_ffmpeg_update_tracks(Context_t *context, char *filename, int initial);
|
int container_ffmpeg_update_tracks(Context_t * context, char *filename,
|
||||||
|
int initial);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -4,29 +4,29 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CONTAINER_INIT,
|
CONTAINER_INIT,
|
||||||
CONTAINER_ADD,
|
CONTAINER_ADD,
|
||||||
CONTAINER_CAPABILITIES,
|
CONTAINER_CAPABILITIES,
|
||||||
CONTAINER_PLAY,
|
CONTAINER_PLAY,
|
||||||
CONTAINER_STOP,
|
CONTAINER_STOP,
|
||||||
CONTAINER_SEEK,
|
CONTAINER_SEEK,
|
||||||
CONTAINER_SEEK_ABS,
|
CONTAINER_SEEK_ABS,
|
||||||
CONTAINER_LENGTH,
|
CONTAINER_LENGTH,
|
||||||
CONTAINER_DEL,
|
CONTAINER_DEL,
|
||||||
CONTAINER_SWITCH_AUDIO,
|
CONTAINER_SWITCH_AUDIO,
|
||||||
CONTAINER_SWITCH_SUBTITLE,
|
CONTAINER_SWITCH_SUBTITLE,
|
||||||
CONTAINER_SWITCH_DVBSUBTITLE,
|
CONTAINER_SWITCH_DVBSUBTITLE,
|
||||||
CONTAINER_SWITCH_TELETEXT,
|
CONTAINER_SWITCH_TELETEXT,
|
||||||
CONTAINER_INFO,
|
CONTAINER_INFO,
|
||||||
CONTAINER_STATUS,
|
CONTAINER_STATUS,
|
||||||
CONTAINER_LAST_PTS,
|
CONTAINER_LAST_PTS,
|
||||||
CONTAINER_DATA
|
CONTAINER_DATA
|
||||||
} ContainerCmd_t;
|
} ContainerCmd_t;
|
||||||
|
|
||||||
typedef struct Container_s {
|
typedef struct Container_s {
|
||||||
char * Name;
|
char *Name;
|
||||||
int (* Command) (/*Context_t*/void *, ContainerCmd_t, void *);
|
int (*Command) ( /*Context_t */ void *, ContainerCmd_t, void *);
|
||||||
char ** Capabilities;
|
char **Capabilities;
|
||||||
|
|
||||||
} Container_t;
|
} Container_t;
|
||||||
|
|
||||||
@@ -34,13 +34,13 @@ typedef struct Container_s {
|
|||||||
extern Container_t FFMPEGContainer;
|
extern Container_t FFMPEGContainer;
|
||||||
|
|
||||||
typedef struct ContainerHandler_s {
|
typedef struct ContainerHandler_s {
|
||||||
char * Name;
|
char *Name;
|
||||||
Container_t * selectedContainer;
|
Container_t *selectedContainer;
|
||||||
Container_t * textSrtContainer;
|
Container_t *textSrtContainer;
|
||||||
Container_t * textSsaContainer;
|
Container_t *textSsaContainer;
|
||||||
Container_t * assContainer;
|
Container_t *assContainer;
|
||||||
|
|
||||||
int (* Command) (/*Context_t*/void *, ContainerCmd_t, void *);
|
int (*Command) ( /*Context_t */ void *, ContainerCmd_t, void *);
|
||||||
} ContainerHandler_t;
|
} ContainerHandler_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -8,11 +8,10 @@ static inline void Hexdump(unsigned char *Data, int length)
|
|||||||
{
|
{
|
||||||
|
|
||||||
int k;
|
int k;
|
||||||
for (k = 0; k < length; k++)
|
for (k = 0; k < length; k++) {
|
||||||
{
|
printf("%02x ", Data[k]);
|
||||||
printf("%02x ", Data[k]);
|
if (((k + 1) & 31) == 0)
|
||||||
if (((k+1)&31)==0)
|
printf("\n");
|
||||||
printf("\n");
|
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
@@ -11,35 +11,34 @@
|
|||||||
|
|
||||||
/* metatdata map list:
|
/* metatdata map list:
|
||||||
*/
|
*/
|
||||||
char* metadata_map[] =
|
char *metadata_map[] = {
|
||||||
{
|
/* our tags ffmpeg tag / id3v2 */
|
||||||
/* our tags ffmpeg tag / id3v2 */
|
"Title", "TIT2",
|
||||||
"Title", "TIT2",
|
"Title", "TT2",
|
||||||
"Title", "TT2",
|
"Artist", "TPE1",
|
||||||
"Artist", "TPE1",
|
"Artist", "TP1",
|
||||||
"Artist", "TP1",
|
"AlbumArtist", "TPE2",
|
||||||
"AlbumArtist", "TPE2",
|
"AlbumArtist", "TP2",
|
||||||
"AlbumArtist", "TP2",
|
"Album", "TALB",
|
||||||
"Album", "TALB",
|
"Album", "TAL",
|
||||||
"Album", "TAL",
|
"Year", "TDRL", /* fixme */
|
||||||
"Year", "TDRL", /* fixme */
|
"Year", "TDRC", /* fixme */
|
||||||
"Year", "TDRC", /* fixme */
|
"Comment", "unknown",
|
||||||
"Comment", "unknown",
|
"Track", "TRCK",
|
||||||
"Track", "TRCK",
|
"Track", "TRK",
|
||||||
"Track", "TRK",
|
"Copyright", "TCOP",
|
||||||
"Copyright", "TCOP",
|
"Composer", "TCOM",
|
||||||
"Composer", "TCOM",
|
"Genre", "TCON",
|
||||||
"Genre", "TCON",
|
"Genre", "TCO",
|
||||||
"Genre", "TCO",
|
"EncodedBy", "TENC",
|
||||||
"EncodedBy", "TENC",
|
"EncodedBy", "TEN",
|
||||||
"EncodedBy", "TEN",
|
"Language", "TLAN",
|
||||||
"Language", "TLAN",
|
"Performer", "TPE3",
|
||||||
"Performer", "TPE3",
|
"Performer", "TP3",
|
||||||
"Performer", "TP3",
|
"Publisher", "TPUB",
|
||||||
"Publisher", "TPUB",
|
"Encoder", "TSSE",
|
||||||
"Encoder", "TSSE",
|
"Disc", "TPOS",
|
||||||
"Disc", "TPOS",
|
NULL
|
||||||
NULL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -22,62 +22,62 @@ typedef enum {
|
|||||||
} eTrackTypeEplayer;
|
} eTrackTypeEplayer;
|
||||||
|
|
||||||
typedef struct Track_s {
|
typedef struct Track_s {
|
||||||
char * Name;
|
char *Name;
|
||||||
char * Encoding;
|
char *Encoding;
|
||||||
int Id;
|
int Id;
|
||||||
|
|
||||||
/* new field for ffmpeg - add at the end so no problem
|
/* new field for ffmpeg - add at the end so no problem
|
||||||
* can occur with not changed srt saa container
|
* can occur with not changed srt saa container
|
||||||
*/
|
*/
|
||||||
char* language;
|
char *language;
|
||||||
|
|
||||||
/* length of track */
|
/* length of track */
|
||||||
long long int duration;
|
long long int duration;
|
||||||
unsigned int frame_rate;
|
unsigned int frame_rate;
|
||||||
unsigned int TimeScale;
|
unsigned int TimeScale;
|
||||||
int version;
|
int version;
|
||||||
long long int pts;
|
long long int pts;
|
||||||
|
|
||||||
/* for later use: */
|
/* for later use: */
|
||||||
eTrackTypeEplayer type;
|
eTrackTypeEplayer type;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
|
||||||
/* stream from ffmpeg */
|
/* stream from ffmpeg */
|
||||||
void * stream;
|
void *stream;
|
||||||
/* codec extra data (header or some other stuff) */
|
/* codec extra data (header or some other stuff) */
|
||||||
void * extraData;
|
void *extraData;
|
||||||
int extraSize;
|
int extraSize;
|
||||||
|
|
||||||
uint8_t* aacbuf;
|
uint8_t *aacbuf;
|
||||||
unsigned int aacbuflen;
|
unsigned int aacbuflen;
|
||||||
int have_aacheader;
|
int have_aacheader;
|
||||||
|
|
||||||
/* If player2 or the elf do not support decoding of audio codec set this.
|
/* If player2 or the elf do not support decoding of audio codec set this.
|
||||||
* AVCodec is than used for softdecoding and stream will be injected as PCM */
|
* AVCodec is than used for softdecoding and stream will be injected as PCM */
|
||||||
int inject_as_pcm;
|
int inject_as_pcm;
|
||||||
int inject_raw_pcm;
|
int inject_raw_pcm;
|
||||||
|
|
||||||
int pending;
|
int pending;
|
||||||
} Track_t;
|
} Track_t;
|
||||||
|
|
||||||
typedef struct Manager_s {
|
typedef struct Manager_s {
|
||||||
char * Name;
|
char *Name;
|
||||||
int (* Command) (/*Context_t*/void *, ManagerCmd_t, void *);
|
int (*Command) ( /*Context_t */ void *, ManagerCmd_t, void *);
|
||||||
char ** Capabilities;
|
char **Capabilities;
|
||||||
|
|
||||||
} Manager_t;
|
} Manager_t;
|
||||||
|
|
||||||
typedef struct ManagerHandler_s {
|
typedef struct ManagerHandler_s {
|
||||||
char * Name;
|
char *Name;
|
||||||
Manager_t * audio;
|
Manager_t *audio;
|
||||||
Manager_t * video;
|
Manager_t *video;
|
||||||
Manager_t * subtitle;
|
Manager_t *subtitle;
|
||||||
Manager_t * dvbsubtitle;
|
Manager_t *dvbsubtitle;
|
||||||
Manager_t * teletext;
|
Manager_t *teletext;
|
||||||
} ManagerHandler_t;
|
} ManagerHandler_t;
|
||||||
|
|
||||||
void freeTrack(Track_t* track);
|
void freeTrack(Track_t * track);
|
||||||
void copyTrack(Track_t* to, Track_t* from);
|
void copyTrack(Track_t * to, Track_t * from);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -9,11 +9,10 @@
|
|||||||
/* Types */
|
/* Types */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
typedef struct BitPacker_s
|
typedef struct BitPacker_s {
|
||||||
{
|
unsigned char *Ptr; /* write pointer */
|
||||||
unsigned char* Ptr; /* write pointer */
|
unsigned int BitBuffer; /* bitreader shifter */
|
||||||
unsigned int BitBuffer; /* bitreader shifter */
|
int Remaining; /* number of remaining in the shifter */
|
||||||
int Remaining; /* number of remaining in the shifter */
|
|
||||||
} BitPacker_t;
|
} BitPacker_t;
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
@@ -37,54 +36,52 @@ void FlushBits(BitPacker_t * ld);
|
|||||||
/* MISC Functions */
|
/* MISC Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static inline char *getExtension(char * name)
|
static inline char *getExtension(char *name)
|
||||||
{
|
{
|
||||||
if (name) {
|
if (name) {
|
||||||
char *ext = strrchr(name, '.');
|
char *ext = strrchr(name, '.');
|
||||||
if (ext)
|
if (ext)
|
||||||
return ext + 1;
|
return ext + 1;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the function returns the base name */
|
/* the function returns the base name */
|
||||||
static inline char * basename(char * name)
|
static inline char *basename(char *name)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
while(name[i] != 0)
|
while (name[i] != 0) {
|
||||||
{
|
if (name[i] == '/')
|
||||||
if(name[i] == '/')
|
pos = i;
|
||||||
pos = i;
|
i++;
|
||||||
i++;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(name[pos] == '/')
|
if (name[pos] == '/')
|
||||||
pos++;
|
pos++;
|
||||||
|
|
||||||
return name + pos;
|
return name + pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the function returns the directry name */
|
/* the function returns the directry name */
|
||||||
static inline char * dirname(char * name)
|
static inline char *dirname(char *name)
|
||||||
{
|
{
|
||||||
static char path[100];
|
static char path[100];
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
while((name[i] != 0) && (i < sizeof(path)))
|
while ((name[i] != 0) && (i < sizeof(path))) {
|
||||||
{
|
if (name[i] == '/')
|
||||||
if(name[i] == '/')
|
pos = i;
|
||||||
pos = i;
|
path[i] = name[i];
|
||||||
path[i] = name[i];
|
i++;
|
||||||
i++;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
path[i] = 0;
|
path[i] = 0;
|
||||||
path[pos] = 0;
|
path[pos] = 0;
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -32,30 +32,29 @@ typedef enum {
|
|||||||
OUTPUT_SET_SUBTITLE_OUTPUT
|
OUTPUT_SET_SUBTITLE_OUTPUT
|
||||||
} OutputCmd_t;
|
} OutputCmd_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
unsigned char *data;
|
||||||
unsigned char* data;
|
unsigned int len;
|
||||||
unsigned int len;
|
|
||||||
|
|
||||||
unsigned char* extradata;
|
unsigned char *extradata;
|
||||||
unsigned int extralen;
|
unsigned int extralen;
|
||||||
|
|
||||||
unsigned long long int pts;
|
unsigned long long int pts;
|
||||||
|
|
||||||
float frameRate;
|
float frameRate;
|
||||||
unsigned int timeScale;
|
unsigned int timeScale;
|
||||||
|
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
|
|
||||||
char* type;
|
char *type;
|
||||||
} AudioVideoOut_t;
|
} AudioVideoOut_t;
|
||||||
|
|
||||||
typedef struct Output_s {
|
typedef struct Output_s {
|
||||||
char * Name;
|
char *Name;
|
||||||
int (* Command) (/*Context_t*/void *, OutputCmd_t, void *);
|
int (*Command) ( /*Context_t */ void *, OutputCmd_t, void *);
|
||||||
int (* Write) (/*Context_t*/void *, void* privateData);
|
int (*Write) ( /*Context_t */ void *, void *privateData);
|
||||||
char ** Capabilities;
|
char **Capabilities;
|
||||||
|
|
||||||
} Output_t;
|
} Output_t;
|
||||||
|
|
||||||
@@ -64,13 +63,13 @@ extern Output_t SubtitleOutput;
|
|||||||
extern Output_t PipeOutput;
|
extern Output_t PipeOutput;
|
||||||
|
|
||||||
typedef struct OutputHandler_s {
|
typedef struct OutputHandler_s {
|
||||||
char * Name;
|
char *Name;
|
||||||
Output_t * audio;
|
Output_t *audio;
|
||||||
Output_t * video;
|
Output_t *video;
|
||||||
Output_t * subtitle;
|
Output_t *subtitle;
|
||||||
Output_t * dvbsubtitle;
|
Output_t *dvbsubtitle;
|
||||||
Output_t * teletext;
|
Output_t *teletext;
|
||||||
int (* Command) (/*Context_t*/void *, OutputCmd_t, void *);
|
int (*Command) ( /*Context_t */ void *, OutputCmd_t, void *);
|
||||||
} OutputHandler_t;
|
} OutputHandler_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -20,8 +20,7 @@
|
|||||||
#ifndef pcm_h_
|
#ifndef pcm_h_
|
||||||
#define pcm_h_
|
#define pcm_h_
|
||||||
|
|
||||||
typedef struct pcmPrivateData_s
|
typedef struct pcmPrivateData_s {
|
||||||
{
|
|
||||||
int uNoOfChannels;
|
int uNoOfChannels;
|
||||||
int uSampleRate;
|
int uSampleRate;
|
||||||
int uBitsPerSample;
|
int uBitsPerSample;
|
||||||
|
@@ -26,7 +26,8 @@
|
|||||||
#define VC1_VIDEO_PES_START_CODE 0xfd
|
#define VC1_VIDEO_PES_START_CODE 0xfd
|
||||||
#define AAC_AUDIO_PES_START_CODE 0xcf
|
#define AAC_AUDIO_PES_START_CODE 0xcf
|
||||||
|
|
||||||
int InsertPesHeader (unsigned char *data, int size, unsigned char stream_id, unsigned long long int pts, int pic_start_code);
|
int InsertPesHeader(unsigned char *data, int size, unsigned char stream_id,
|
||||||
|
unsigned long long int pts, int pic_start_code);
|
||||||
int InsertVideoPrivateDataHeader(unsigned char *data, int payload_size);
|
int InsertVideoPrivateDataHeader(unsigned char *data, int payload_size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -2,10 +2,18 @@
|
|||||||
#define PLAYBACK_H_
|
#define PLAYBACK_H_
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
typedef enum {PLAYBACK_OPEN, PLAYBACK_CLOSE, PLAYBACK_PLAY, PLAYBACK_STOP, PLAYBACK_PAUSE, PLAYBACK_CONTINUE, PLAYBACK_FLUSH, PLAYBACK_TERM, PLAYBACK_FASTFORWARD, PLAYBACK_SEEK, PLAYBACK_SEEK_ABS, PLAYBACK_PTS, PLAYBACK_LENGTH, PLAYBACK_SWITCH_AUDIO, PLAYBACK_SWITCH_SUBTITLE, PLAYBACK_INFO, PLAYBACK_SLOWMOTION, PLAYBACK_FASTBACKWARD, PLAYBACK_GET_FRAME_COUNT, PLAYBACK_SWITCH_TELETEXT, PLAYBACK_SWITCH_DVBSUBTITLE, PLAYBACK_FRAMEBUFFER_LOCK, PLAYBACK_FRAMEBUFFER_UNLOCK} PlaybackCmd_t;
|
typedef enum { PLAYBACK_OPEN, PLAYBACK_CLOSE, PLAYBACK_PLAY, PLAYBACK_STOP,
|
||||||
|
PLAYBACK_PAUSE, PLAYBACK_CONTINUE, PLAYBACK_FLUSH, PLAYBACK_TERM,
|
||||||
|
PLAYBACK_FASTFORWARD, PLAYBACK_SEEK, PLAYBACK_SEEK_ABS,
|
||||||
|
PLAYBACK_PTS, PLAYBACK_LENGTH, PLAYBACK_SWITCH_AUDIO,
|
||||||
|
PLAYBACK_SWITCH_SUBTITLE, PLAYBACK_INFO, PLAYBACK_SLOWMOTION,
|
||||||
|
PLAYBACK_FASTBACKWARD, PLAYBACK_GET_FRAME_COUNT,
|
||||||
|
PLAYBACK_SWITCH_TELETEXT, PLAYBACK_SWITCH_DVBSUBTITLE,
|
||||||
|
PLAYBACK_FRAMEBUFFER_LOCK,
|
||||||
|
PLAYBACK_FRAMEBUFFER_UNLOCK } PlaybackCmd_t;
|
||||||
|
|
||||||
typedef struct PlaybackHandler_s {
|
typedef struct PlaybackHandler_s {
|
||||||
char * Name;
|
char *Name;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@@ -31,9 +39,9 @@ typedef struct PlaybackHandler_s {
|
|||||||
unsigned char mayWriteToFramebuffer;
|
unsigned char mayWriteToFramebuffer;
|
||||||
unsigned char abortRequested;
|
unsigned char abortRequested;
|
||||||
|
|
||||||
int (* Command) (/*Context_t*/void *, PlaybackCmd_t, void *);
|
int (*Command) ( /*Context_t */ void *, PlaybackCmd_t, void *);
|
||||||
char * uri;
|
char *uri;
|
||||||
unsigned char noprobe; /* hack: only minimal probing in av_find_stream_info */
|
unsigned char noprobe; /* hack: only minimal probing in av_find_stream_info */
|
||||||
unsigned long long readCount;
|
unsigned long long readCount;
|
||||||
} PlaybackHandler_t;
|
} PlaybackHandler_t;
|
||||||
|
|
||||||
|
@@ -33,93 +33,95 @@ Style: Default,Arial,64,16777215,0,16777215,0,0,0,2,2,2,2,20,20,10,0\n\n\
|
|||||||
[Events]\n\
|
[Events]\n\
|
||||||
Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n\n\n"
|
Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n\n\n"
|
||||||
|
|
||||||
static inline unsigned char* text_to_ass(char *text, long long int pts, double duration)
|
static inline unsigned char *text_to_ass(char *text, long long int pts,
|
||||||
|
double duration)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
unsigned int x,pos=0;
|
unsigned int x, pos = 0;
|
||||||
for(x=0;x<strlen(text);x++){
|
for (x = 0; x < strlen(text); x++) {
|
||||||
if(text[x]=='\n'){
|
if (text[x] == '\n') {
|
||||||
buf[pos++]='\\';
|
buf[pos++] = '\\';
|
||||||
buf[pos++]='N';
|
buf[pos++] = 'N';
|
||||||
}else if(text[x]!='\r')buf[pos++]=text[x];
|
} else if (text[x] != '\r')
|
||||||
}
|
buf[pos++] = text[x];
|
||||||
buf[pos++]='\0';
|
}
|
||||||
int len = 80 + strlen(buf);
|
buf[pos++] = '\0';
|
||||||
long long int end_pts = pts + (duration * 1000.0);
|
int len = 80 + strlen(buf);
|
||||||
char* line = (char*)malloc( sizeof(char) * len );
|
long long int end_pts = pts + (duration * 1000.0);
|
||||||
int sc = pts / 10;
|
char *line = (char *) malloc(sizeof(char) * len);
|
||||||
int ec = end_pts / 10;
|
int sc = pts / 10;
|
||||||
int sh, sm, ss, eh, em, es;
|
int ec = end_pts / 10;
|
||||||
sh = sc/360000; sc -= 360000*sh;
|
int sh, sm, ss, eh, em, es;
|
||||||
sm = sc/ 6000; sc -= 6000*sm;
|
sh = sc / 360000;
|
||||||
ss = sc/ 100; sc -= 100*ss;
|
sc -= 360000 * sh;
|
||||||
eh = ec/360000; ec -= 360000*eh;
|
sm = sc / 6000;
|
||||||
em = ec/ 6000; ec -= 6000*em;
|
sc -= 6000 * sm;
|
||||||
es = ec/ 100; ec -= 100*es;
|
ss = sc / 100;
|
||||||
snprintf(line,len,"Dialogue: Marked=0,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,Default,NTP,0000,0000,0000,!Effect,%s\n",
|
sc -= 100 * ss;
|
||||||
sh, sm, ss, sc, eh, em, es, ec, buf);
|
eh = ec / 360000;
|
||||||
|
ec -= 360000 * eh;
|
||||||
|
em = ec / 6000;
|
||||||
|
ec -= 6000 * em;
|
||||||
|
es = ec / 100;
|
||||||
|
ec -= 100 * es;
|
||||||
|
snprintf(line, len,
|
||||||
|
"Dialogue: Marked=0,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,Default,NTP,0000,0000,0000,!Effect,%s\n",
|
||||||
|
sh, sm, ss, sc, eh, em, es, ec, buf);
|
||||||
|
|
||||||
return (unsigned char*)line;
|
return (unsigned char *) line;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
eSub_Gfx,
|
eSub_Gfx,
|
||||||
eSub_Txt
|
eSub_Txt
|
||||||
} SubType_t;
|
} SubType_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
unsigned char *data;
|
||||||
unsigned char* data;
|
int len;
|
||||||
int len;
|
|
||||||
} SubText_t;
|
} SubText_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
unsigned char *data;
|
||||||
unsigned char* data;
|
unsigned int Width;
|
||||||
unsigned int Width;
|
unsigned int Height;
|
||||||
unsigned int Height;
|
unsigned int Stride;
|
||||||
unsigned int Stride;
|
unsigned int x;
|
||||||
unsigned int x;
|
unsigned int y;
|
||||||
unsigned int y;
|
unsigned int color;
|
||||||
unsigned int color;
|
|
||||||
} SubGfx_t;
|
} SubGfx_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
SubType_t type;
|
||||||
SubType_t type;
|
long long int pts;
|
||||||
long long int pts;
|
float duration;
|
||||||
float duration;
|
|
||||||
|
|
||||||
union
|
union {
|
||||||
{
|
SubText_t text;
|
||||||
SubText_t text;
|
SubGfx_t gfx;
|
||||||
SubGfx_t gfx;
|
|
||||||
} u;
|
} u;
|
||||||
} SubtitleOut_t;
|
} SubtitleOut_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
unsigned char *data;
|
||||||
unsigned char* data;
|
int len;
|
||||||
int len;
|
|
||||||
|
|
||||||
unsigned char* extradata;
|
unsigned char *extradata;
|
||||||
int extralen;
|
int extralen;
|
||||||
|
|
||||||
long long int pts;
|
long long int pts;
|
||||||
float duration;
|
float duration;
|
||||||
} SubtitleData_t;
|
} SubtitleData_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
uint32_t *destination;
|
||||||
uint32_t *destination;
|
unsigned int screen_width;
|
||||||
unsigned int screen_width;
|
unsigned int screen_height;
|
||||||
unsigned int screen_height;
|
unsigned int destStride;
|
||||||
unsigned int destStride;
|
|
||||||
|
|
||||||
void (*framebufferBlit)(void);
|
void (*framebufferBlit) (void);
|
||||||
} SubtitleOutputDef_t;
|
} SubtitleOutputDef_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -4,52 +4,52 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef enum { eNone, eAudio, eVideo, eGfx} eWriterType_t;
|
typedef enum { eNone, eAudio, eVideo, eGfx } eWriterType_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int fd;
|
int fd;
|
||||||
unsigned char* data;
|
unsigned char *data;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
unsigned long long int Pts;
|
unsigned long long int Pts;
|
||||||
unsigned char* private_data;
|
unsigned char *private_data;
|
||||||
unsigned int private_size;
|
unsigned int private_size;
|
||||||
unsigned int FrameRate;
|
unsigned int FrameRate;
|
||||||
unsigned int FrameScale;
|
unsigned int FrameScale;
|
||||||
unsigned int Width;
|
unsigned int Width;
|
||||||
unsigned int Height;
|
unsigned int Height;
|
||||||
unsigned char Version;
|
unsigned char Version;
|
||||||
} WriterAVCallData_t;
|
} WriterAVCallData_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char* data;
|
unsigned char *data;
|
||||||
unsigned int Width;
|
unsigned int Width;
|
||||||
unsigned int Height;
|
unsigned int Height;
|
||||||
unsigned int Stride;
|
unsigned int Stride;
|
||||||
unsigned int color;
|
unsigned int color;
|
||||||
|
|
||||||
unsigned int x; /* dst x ->given by ass */
|
unsigned int x; /* dst x ->given by ass */
|
||||||
unsigned int y; /* dst y ->given by ass */
|
unsigned int y; /* dst y ->given by ass */
|
||||||
|
|
||||||
/* destination values if we use a shared framebuffer */
|
/* destination values if we use a shared framebuffer */
|
||||||
int fd;
|
int fd;
|
||||||
unsigned int Screen_Width;
|
unsigned int Screen_Width;
|
||||||
unsigned int Screen_Height;
|
unsigned int Screen_Height;
|
||||||
uint32_t *destination;
|
uint32_t *destination;
|
||||||
unsigned int destStride;
|
unsigned int destStride;
|
||||||
} WriterFBCallData_t;
|
} WriterFBCallData_t;
|
||||||
|
|
||||||
typedef struct WriterCaps_s {
|
typedef struct WriterCaps_s {
|
||||||
char* name;
|
char *name;
|
||||||
eWriterType_t type;
|
eWriterType_t type;
|
||||||
char* textEncoding;
|
char *textEncoding;
|
||||||
/* fixme: revise if this is an enum! */
|
/* fixme: revise if this is an enum! */
|
||||||
int dvbEncoding;
|
int dvbEncoding;
|
||||||
} WriterCaps_t;
|
} WriterCaps_t;
|
||||||
|
|
||||||
typedef struct Writer_s {
|
typedef struct Writer_s {
|
||||||
int (* reset) ();
|
int (*reset) ();
|
||||||
int (* writeData) (void*);
|
int (*writeData) (void *);
|
||||||
int (* writeReverseData) (void*);
|
int (*writeReverseData) (void *);
|
||||||
WriterCaps_t *caps;
|
WriterCaps_t *caps;
|
||||||
} Writer_t;
|
} Writer_t;
|
||||||
|
|
||||||
@@ -79,10 +79,10 @@ extern Writer_t WriterFramebuffer;
|
|||||||
extern Writer_t WriterPipe;
|
extern Writer_t WriterPipe;
|
||||||
extern Writer_t WriterDVBSubtitle;
|
extern Writer_t WriterDVBSubtitle;
|
||||||
|
|
||||||
Writer_t* getWriter(char* encoding);
|
Writer_t *getWriter(char *encoding);
|
||||||
|
|
||||||
Writer_t* getDefaultVideoWriter();
|
Writer_t *getDefaultVideoWriter();
|
||||||
Writer_t* getDefaultAudioWriter();
|
Writer_t *getDefaultAudioWriter();
|
||||||
Writer_t* getDefaultFramebufferWriter();
|
Writer_t *getDefaultFramebufferWriter();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -65,9 +65,9 @@ static const char FILENAME[] = __FILE__;
|
|||||||
/* Varaibles */
|
/* Varaibles */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static Track_t * Tracks = NULL;
|
static Track_t *Tracks = NULL;
|
||||||
static int TrackCount = 0;
|
static int TrackCount = 0;
|
||||||
static int CurrentTrack = 0; //TRACK[0] as default.
|
static int CurrentTrack = 0; //TRACK[0] as default.
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
@@ -77,191 +77,208 @@ static int CurrentTrack = 0; //TRACK[0] as default.
|
|||||||
/* Functions */
|
/* Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static int ManagerAdd(Context_t *context, Track_t track) {
|
static int ManagerAdd(Context_t * context, Track_t track)
|
||||||
|
{
|
||||||
|
|
||||||
audio_mgr_printf(10, "%s::%s name=\"%s\" encoding=\"%s\" id=%d\n", FILENAME, __FUNCTION__, track.Name, track.Encoding, track.Id);
|
audio_mgr_printf(10, "%s::%s name=\"%s\" encoding=\"%s\" id=%d\n",
|
||||||
|
FILENAME, __FUNCTION__, track.Name, track.Encoding,
|
||||||
|
track.Id);
|
||||||
|
|
||||||
if (Tracks == NULL) {
|
if (Tracks == NULL) {
|
||||||
Tracks = malloc(sizeof(Track_t) * TRACKWRAP);
|
Tracks = malloc(sizeof(Track_t) * TRACKWRAP);
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < TRACKWRAP; i++)
|
for (i = 0; i < TRACKWRAP; i++)
|
||||||
Tracks[i].Id = -1;
|
Tracks[i].Id = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tracks == NULL)
|
if (Tracks == NULL) {
|
||||||
{
|
audio_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
||||||
audio_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
return cERR_AUDIO_MGR_ERROR;
|
||||||
return cERR_AUDIO_MGR_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < TRACKWRAP; i++) {
|
for (i = 0; i < TRACKWRAP; i++) {
|
||||||
if (Tracks[i].Id == track.Id) {
|
if (Tracks[i].Id == track.Id) {
|
||||||
Tracks[i].pending = 0;
|
Tracks[i].pending = 0;
|
||||||
return cERR_AUDIO_MGR_NO_ERROR;
|
return cERR_AUDIO_MGR_NO_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TrackCount < TRACKWRAP) {
|
if (TrackCount < TRACKWRAP) {
|
||||||
copyTrack(&Tracks[TrackCount], &track);
|
copyTrack(&Tracks[TrackCount], &track);
|
||||||
TrackCount++;
|
TrackCount++;
|
||||||
} else {
|
} else {
|
||||||
audio_mgr_err("%s:%s TrackCount out if range %d - %d\n", FILENAME, __FUNCTION__, TrackCount, TRACKWRAP);
|
audio_mgr_err("%s:%s TrackCount out if range %d - %d\n", FILENAME,
|
||||||
return cERR_AUDIO_MGR_ERROR;
|
__FUNCTION__, TrackCount, TRACKWRAP);
|
||||||
|
return cERR_AUDIO_MGR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TrackCount > 0)
|
if (TrackCount > 0)
|
||||||
context->playback->isAudio = 1;
|
context->playback->isAudio = 1;
|
||||||
|
|
||||||
audio_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
audio_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
return cERR_AUDIO_MGR_NO_ERROR;
|
return cERR_AUDIO_MGR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char ** ManagerList(Context_t *context __attribute__((unused))) {
|
static char **ManagerList(Context_t * context __attribute__ ((unused)))
|
||||||
|
{
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
char ** tracklist = NULL;
|
char **tracklist = NULL;
|
||||||
|
|
||||||
audio_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
audio_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
if (Tracks != NULL) {
|
if (Tracks != NULL) {
|
||||||
|
|
||||||
tracklist = malloc(sizeof(char *) * ((TrackCount*2) + 1));
|
tracklist = malloc(sizeof(char *) * ((TrackCount * 2) + 1));
|
||||||
|
|
||||||
if (tracklist == NULL)
|
if (tracklist == NULL) {
|
||||||
{
|
audio_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
||||||
audio_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0, j = 0; i < TrackCount; i++, j+=2) {
|
for (i = 0, j = 0; i < TrackCount; i++, j += 2) {
|
||||||
if (Tracks[i].pending)
|
if (Tracks[i].pending)
|
||||||
continue;
|
continue;
|
||||||
size_t len = strlen(Tracks[i].Name) + 20;
|
size_t len = strlen(Tracks[i].Name) + 20;
|
||||||
char tmp[len];
|
char tmp[len];
|
||||||
snprintf(tmp, len, "%d %s\n", Tracks[i].Id, Tracks[i].Name);
|
snprintf(tmp, len, "%d %s\n", Tracks[i].Id, Tracks[i].Name);
|
||||||
tracklist[j] = strdup(tmp);
|
tracklist[j] = strdup(tmp);
|
||||||
tracklist[j+1] = strdup(Tracks[i].Encoding);
|
tracklist[j + 1] = strdup(Tracks[i].Encoding);
|
||||||
}
|
}
|
||||||
tracklist[j] = NULL;
|
tracklist[j] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
audio_mgr_printf(10, "%s::%s return %p (%d - %d)\n", FILENAME, __FUNCTION__, tracklist, j, TrackCount);
|
audio_mgr_printf(10, "%s::%s return %p (%d - %d)\n", FILENAME,
|
||||||
|
__FUNCTION__, tracklist, j, TrackCount);
|
||||||
|
|
||||||
return tracklist;
|
return tracklist;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ManagerDel(Context_t * context) {
|
static int ManagerDel(Context_t * context)
|
||||||
|
{
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
audio_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
audio_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
if(Tracks != NULL) {
|
if (Tracks != NULL) {
|
||||||
for (i = 0; i < TrackCount; i++) {
|
for (i = 0; i < TrackCount; i++) {
|
||||||
freeTrack(&Tracks[i]);
|
freeTrack(&Tracks[i]);
|
||||||
}
|
}
|
||||||
free(Tracks);
|
free(Tracks);
|
||||||
Tracks = NULL;
|
Tracks = NULL;
|
||||||
} else
|
} else {
|
||||||
{
|
audio_mgr_err("%s::%s nothing to delete!\n", FILENAME,
|
||||||
audio_mgr_err("%s::%s nothing to delete!\n", FILENAME, __FUNCTION__);
|
__FUNCTION__);
|
||||||
return cERR_AUDIO_MGR_ERROR;
|
return cERR_AUDIO_MGR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackCount = 0;
|
TrackCount = 0;
|
||||||
CurrentTrack = 0;
|
CurrentTrack = 0;
|
||||||
context->playback->isAudio = 0;
|
context->playback->isAudio = 0;
|
||||||
|
|
||||||
audio_mgr_printf(10, "%s::%s return no error\n", FILENAME, __FUNCTION__);
|
audio_mgr_printf(10, "%s::%s return no error\n", FILENAME,
|
||||||
|
__FUNCTION__);
|
||||||
|
|
||||||
return cERR_AUDIO_MGR_NO_ERROR;
|
return cERR_AUDIO_MGR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int Command(void *_context, ManagerCmd_t command, void * argument) {
|
static int Command(void *_context, ManagerCmd_t command, void *argument)
|
||||||
Context_t *context = (Context_t*) _context;
|
{
|
||||||
|
Context_t *context = (Context_t *) _context;
|
||||||
int ret = cERR_AUDIO_MGR_NO_ERROR;
|
int ret = cERR_AUDIO_MGR_NO_ERROR;
|
||||||
|
|
||||||
audio_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
audio_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
switch(command) {
|
switch (command) {
|
||||||
case MANAGER_ADD: {
|
case MANAGER_ADD:{
|
||||||
Track_t * track = argument;
|
Track_t *track = argument;
|
||||||
|
|
||||||
ret = ManagerAdd(context, *track);
|
ret = ManagerAdd(context, *track);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MANAGER_LIST: {
|
case MANAGER_LIST:{
|
||||||
container_ffmpeg_update_tracks(context, context->playback->uri, 0);
|
container_ffmpeg_update_tracks(context, context->playback->uri,
|
||||||
*((char***)argument) = (char **)ManagerList(context);
|
0);
|
||||||
break;
|
*((char ***) argument) = (char **) ManagerList(context);
|
||||||
}
|
break;
|
||||||
case MANAGER_GET: {
|
}
|
||||||
audio_mgr_printf(20, "%s::%s MANAGER_GET\n", FILENAME, __FUNCTION__);
|
case MANAGER_GET:{
|
||||||
|
audio_mgr_printf(20, "%s::%s MANAGER_GET\n", FILENAME,
|
||||||
|
__FUNCTION__);
|
||||||
|
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
*((int*)argument) = (int)Tracks[CurrentTrack].Id;
|
*((int *) argument) = (int) Tracks[CurrentTrack].Id;
|
||||||
else
|
else
|
||||||
*((int*)argument) = (int)-1;
|
*((int *) argument) = (int) -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MANAGER_GET_TRACK: {
|
case MANAGER_GET_TRACK:{
|
||||||
audio_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", FILENAME, __FUNCTION__);
|
audio_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", FILENAME,
|
||||||
|
__FUNCTION__);
|
||||||
|
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
*((Track_t**)argument) = (Track_t*) &Tracks[CurrentTrack];
|
*((Track_t **) argument) =
|
||||||
else
|
(Track_t *) & Tracks[CurrentTrack];
|
||||||
*((Track_t**)argument) = NULL;
|
else
|
||||||
break;
|
*((Track_t **) argument) = NULL;
|
||||||
}
|
break;
|
||||||
case MANAGER_GETENCODING: {
|
}
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
case MANAGER_GETENCODING:{
|
||||||
*((char**)argument) = (char *)strdup(Tracks[CurrentTrack].Encoding);
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
else
|
*((char **) argument) =
|
||||||
*((char**)argument) = (char *)strdup("");
|
(char *) strdup(Tracks[CurrentTrack].Encoding);
|
||||||
break;
|
else
|
||||||
}
|
*((char **) argument) = (char *) strdup("");
|
||||||
case MANAGER_GETNAME: {
|
break;
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
}
|
||||||
*((char**)argument) = (char *)strdup(Tracks[CurrentTrack].Name);
|
case MANAGER_GETNAME:{
|
||||||
else
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
*((char**)argument) = (char *)strdup("");
|
*((char **) argument) =
|
||||||
break;
|
(char *) strdup(Tracks[CurrentTrack].Name);
|
||||||
}
|
else
|
||||||
case MANAGER_SET: {
|
*((char **) argument) = (char *) strdup("");
|
||||||
int i;
|
break;
|
||||||
audio_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", FILENAME, __FUNCTION__, *((int*)argument));
|
}
|
||||||
|
case MANAGER_SET:{
|
||||||
|
int i;
|
||||||
|
audio_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", FILENAME,
|
||||||
|
__FUNCTION__, *((int *) argument));
|
||||||
|
|
||||||
for (i = 0; i < TrackCount; i++)
|
for (i = 0; i < TrackCount; i++)
|
||||||
if (Tracks[i].Id == *((int*)argument)) {
|
if (Tracks[i].Id == *((int *) argument)) {
|
||||||
CurrentTrack = i;
|
CurrentTrack = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == TrackCount) {
|
if (i == TrackCount) {
|
||||||
audio_mgr_err("%s::%s track id %d unknown\n", FILENAME, __FUNCTION__, *((int*)argument));
|
audio_mgr_err("%s::%s track id %d unknown\n", FILENAME,
|
||||||
ret = cERR_AUDIO_MGR_ERROR;
|
__FUNCTION__, *((int *) argument));
|
||||||
}
|
ret = cERR_AUDIO_MGR_ERROR;
|
||||||
break;
|
}
|
||||||
}
|
break;
|
||||||
case MANAGER_DEL: {
|
}
|
||||||
ret = ManagerDel(context);
|
case MANAGER_DEL:{
|
||||||
break;
|
ret = ManagerDel(context);
|
||||||
}
|
break;
|
||||||
case MANAGER_INIT_UPDATE: {
|
}
|
||||||
int i;
|
case MANAGER_INIT_UPDATE:{
|
||||||
for (i = 0; i < TrackCount; i++)
|
int i;
|
||||||
|
for (i = 0; i < TrackCount; i++)
|
||||||
Tracks[i].pending = 1;
|
Tracks[i].pending = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
audio_mgr_err("%s::%s ContainerCmd %d not supported!\n", FILENAME, __FUNCTION__, command);
|
audio_mgr_err("%s::%s ContainerCmd %d not supported!\n", FILENAME,
|
||||||
ret = cERR_AUDIO_MGR_ERROR;
|
__FUNCTION__, command);
|
||||||
break;
|
ret = cERR_AUDIO_MGR_ERROR;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
audio_mgr_printf(10, "%s:%s: returning %d\n", FILENAME, __FUNCTION__,ret);
|
audio_mgr_printf(10, "%s:%s: returning %d\n", FILENAME, __FUNCTION__,
|
||||||
|
ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -65,7 +65,7 @@ static const char FILENAME[] = __FILE__;
|
|||||||
/* Varaibles */
|
/* Varaibles */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static Track_t * Tracks = NULL;
|
static Track_t *Tracks = NULL;
|
||||||
static int TrackCount = 0;
|
static int TrackCount = 0;
|
||||||
static int CurrentTrack = -1;
|
static int CurrentTrack = -1;
|
||||||
|
|
||||||
@@ -77,191 +77,213 @@ static int CurrentTrack = -1;
|
|||||||
/* Functions */
|
/* Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static int ManagerAdd(Context_t *context, Track_t track) {
|
static int ManagerAdd(Context_t * context, Track_t track)
|
||||||
|
{
|
||||||
|
|
||||||
dvbsubtitle_mgr_printf(10, "%s::%s name=\"%s\" encoding=\"%s\" id=%d\n", FILENAME, __FUNCTION__, track.Name, track.Encoding, track.Id);
|
dvbsubtitle_mgr_printf(10,
|
||||||
|
"%s::%s name=\"%s\" encoding=\"%s\" id=%d\n",
|
||||||
|
FILENAME, __FUNCTION__, track.Name,
|
||||||
|
track.Encoding, track.Id);
|
||||||
|
|
||||||
if (Tracks == NULL) {
|
if (Tracks == NULL) {
|
||||||
Tracks = malloc(sizeof(Track_t) * TRACKWRAP);
|
Tracks = malloc(sizeof(Track_t) * TRACKWRAP);
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < TRACKWRAP; i++)
|
for (i = 0; i < TRACKWRAP; i++)
|
||||||
Tracks[i].Id = -1;
|
Tracks[i].Id = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tracks == NULL)
|
if (Tracks == NULL) {
|
||||||
{
|
dvbsubtitle_mgr_err("%s:%s malloc failed\n", FILENAME,
|
||||||
dvbsubtitle_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
__FUNCTION__);
|
||||||
return cERR_DVBSUBTITLE_MGR_ERROR;
|
return cERR_DVBSUBTITLE_MGR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < TRACKWRAP; i++) {
|
for (i = 0; i < TRACKWRAP; i++) {
|
||||||
if (Tracks[i].Id == track.Id) {
|
if (Tracks[i].Id == track.Id) {
|
||||||
Tracks[i].pending = 0;
|
Tracks[i].pending = 0;
|
||||||
return cERR_DVBSUBTITLE_MGR_NO_ERROR;
|
return cERR_DVBSUBTITLE_MGR_NO_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TrackCount < TRACKWRAP) {
|
if (TrackCount < TRACKWRAP) {
|
||||||
copyTrack(&Tracks[TrackCount], &track);
|
copyTrack(&Tracks[TrackCount], &track);
|
||||||
TrackCount++;
|
TrackCount++;
|
||||||
} else {
|
} else {
|
||||||
dvbsubtitle_mgr_err("%s:%s TrackCount out if range %d - %d\n", FILENAME, __FUNCTION__, TrackCount, TRACKWRAP);
|
dvbsubtitle_mgr_err("%s:%s TrackCount out if range %d - %d\n",
|
||||||
return cERR_DVBSUBTITLE_MGR_ERROR;
|
FILENAME, __FUNCTION__, TrackCount, TRACKWRAP);
|
||||||
|
return cERR_DVBSUBTITLE_MGR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TrackCount > 0)
|
if (TrackCount > 0)
|
||||||
context->playback->isDvbSubtitle = 1;
|
context->playback->isDvbSubtitle = 1;
|
||||||
|
|
||||||
dvbsubtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
dvbsubtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
return cERR_DVBSUBTITLE_MGR_NO_ERROR;
|
return cERR_DVBSUBTITLE_MGR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char ** ManagerList(Context_t *context __attribute__((unused))) {
|
static char **ManagerList(Context_t * context __attribute__ ((unused)))
|
||||||
|
{
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
char ** tracklist = NULL;
|
char **tracklist = NULL;
|
||||||
|
|
||||||
dvbsubtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
dvbsubtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
if (Tracks != NULL) {
|
if (Tracks != NULL) {
|
||||||
|
|
||||||
tracklist = malloc(sizeof(char *) * ((TrackCount*2) + 1));
|
tracklist = malloc(sizeof(char *) * ((TrackCount * 2) + 1));
|
||||||
|
|
||||||
if (tracklist == NULL)
|
if (tracklist == NULL) {
|
||||||
{
|
dvbsubtitle_mgr_err("%s:%s malloc failed\n", FILENAME,
|
||||||
dvbsubtitle_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
__FUNCTION__);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0, j = 0; i < TrackCount; i++, j+=2) {
|
for (i = 0, j = 0; i < TrackCount; i++, j += 2) {
|
||||||
if (Tracks[i].pending)
|
if (Tracks[i].pending)
|
||||||
continue;
|
continue;
|
||||||
size_t len = strlen(Tracks[i].Name) + 20;
|
size_t len = strlen(Tracks[i].Name) + 20;
|
||||||
char tmp[len];
|
char tmp[len];
|
||||||
snprintf(tmp, len, "%d %s\n", Tracks[i].Id, Tracks[i].Name);
|
snprintf(tmp, len, "%d %s\n", Tracks[i].Id, Tracks[i].Name);
|
||||||
tracklist[j] = strdup(tmp);
|
tracklist[j] = strdup(tmp);
|
||||||
tracklist[j+1] = strdup(Tracks[i].Encoding);
|
tracklist[j + 1] = strdup(Tracks[i].Encoding);
|
||||||
}
|
}
|
||||||
tracklist[j] = NULL;
|
tracklist[j] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dvbsubtitle_mgr_printf(10, "%s::%s return %p (%d - %d)\n", FILENAME, __FUNCTION__, tracklist, j, TrackCount);
|
dvbsubtitle_mgr_printf(10, "%s::%s return %p (%d - %d)\n", FILENAME,
|
||||||
|
__FUNCTION__, tracklist, j, TrackCount);
|
||||||
|
|
||||||
return tracklist;
|
return tracklist;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ManagerDel(Context_t * context) {
|
static int ManagerDel(Context_t * context)
|
||||||
|
{
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
dvbsubtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
dvbsubtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
if(Tracks != NULL) {
|
if (Tracks != NULL) {
|
||||||
for (i = 0; i < TrackCount; i++) {
|
for (i = 0; i < TrackCount; i++) {
|
||||||
freeTrack(&Tracks[i]);
|
freeTrack(&Tracks[i]);
|
||||||
}
|
}
|
||||||
free(Tracks);
|
free(Tracks);
|
||||||
Tracks = NULL;
|
Tracks = NULL;
|
||||||
} else
|
} else {
|
||||||
{
|
dvbsubtitle_mgr_err("%s::%s nothing to delete!\n", FILENAME,
|
||||||
dvbsubtitle_mgr_err("%s::%s nothing to delete!\n", FILENAME, __FUNCTION__);
|
__FUNCTION__);
|
||||||
return cERR_DVBSUBTITLE_MGR_ERROR;
|
return cERR_DVBSUBTITLE_MGR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackCount = 0;
|
TrackCount = 0;
|
||||||
CurrentTrack = -1;
|
CurrentTrack = -1;
|
||||||
context->playback->isDvbSubtitle = 0;
|
context->playback->isDvbSubtitle = 0;
|
||||||
|
|
||||||
dvbsubtitle_mgr_printf(10, "%s::%s return no error\n", FILENAME, __FUNCTION__);
|
dvbsubtitle_mgr_printf(10, "%s::%s return no error\n", FILENAME,
|
||||||
|
__FUNCTION__);
|
||||||
|
|
||||||
return cERR_DVBSUBTITLE_MGR_NO_ERROR;
|
return cERR_DVBSUBTITLE_MGR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int Command(void *_context, ManagerCmd_t command, void * argument) {
|
static int Command(void *_context, ManagerCmd_t command, void *argument)
|
||||||
Context_t *context = (Context_t*) _context;
|
{
|
||||||
|
Context_t *context = (Context_t *) _context;
|
||||||
int ret = cERR_DVBSUBTITLE_MGR_NO_ERROR;
|
int ret = cERR_DVBSUBTITLE_MGR_NO_ERROR;
|
||||||
|
|
||||||
dvbsubtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
dvbsubtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
switch(command) {
|
switch (command) {
|
||||||
case MANAGER_ADD: {
|
case MANAGER_ADD:{
|
||||||
Track_t * track = argument;
|
Track_t *track = argument;
|
||||||
|
|
||||||
ret = ManagerAdd(context, *track);
|
ret = ManagerAdd(context, *track);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MANAGER_LIST: {
|
case MANAGER_LIST:{
|
||||||
container_ffmpeg_update_tracks(context, context->playback->uri, 0);
|
container_ffmpeg_update_tracks(context, context->playback->uri,
|
||||||
*((char***)argument) = (char **)ManagerList(context);
|
0);
|
||||||
break;
|
*((char ***) argument) = (char **) ManagerList(context);
|
||||||
}
|
break;
|
||||||
case MANAGER_GET: {
|
}
|
||||||
dvbsubtitle_mgr_printf(20, "%s::%s MANAGER_GET\n", FILENAME, __FUNCTION__);
|
case MANAGER_GET:{
|
||||||
|
dvbsubtitle_mgr_printf(20, "%s::%s MANAGER_GET\n", FILENAME,
|
||||||
|
__FUNCTION__);
|
||||||
|
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
*((int*)argument) = (int)Tracks[CurrentTrack].Id;
|
*((int *) argument) = (int) Tracks[CurrentTrack].Id;
|
||||||
else
|
else
|
||||||
*((int*)argument) = (int)-1;
|
*((int *) argument) = (int) -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MANAGER_GET_TRACK: {
|
case MANAGER_GET_TRACK:{
|
||||||
dvbsubtitle_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", FILENAME, __FUNCTION__);
|
dvbsubtitle_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n",
|
||||||
|
FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
*((Track_t**)argument) = (Track_t*) &Tracks[CurrentTrack];
|
*((Track_t **) argument) =
|
||||||
else
|
(Track_t *) & Tracks[CurrentTrack];
|
||||||
*((Track_t**)argument) = NULL;
|
else
|
||||||
break;
|
*((Track_t **) argument) = NULL;
|
||||||
}
|
break;
|
||||||
case MANAGER_GETENCODING: {
|
}
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
case MANAGER_GETENCODING:{
|
||||||
*((char**)argument) = (char *)strdup(Tracks[CurrentTrack].Encoding);
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
else
|
*((char **) argument) =
|
||||||
*((char**)argument) = (char *)strdup("");
|
(char *) strdup(Tracks[CurrentTrack].Encoding);
|
||||||
break;
|
else
|
||||||
}
|
*((char **) argument) = (char *) strdup("");
|
||||||
case MANAGER_GETNAME: {
|
break;
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
}
|
||||||
*((char**)argument) = (char *)strdup(Tracks[CurrentTrack].Name);
|
case MANAGER_GETNAME:{
|
||||||
else
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
*((char**)argument) = (char *)strdup("");
|
*((char **) argument) =
|
||||||
break;
|
(char *) strdup(Tracks[CurrentTrack].Name);
|
||||||
}
|
else
|
||||||
case MANAGER_SET: {
|
*((char **) argument) = (char *) strdup("");
|
||||||
int i;
|
break;
|
||||||
dvbsubtitle_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", FILENAME, __FUNCTION__, *((int*)argument));
|
}
|
||||||
|
case MANAGER_SET:{
|
||||||
|
int i;
|
||||||
|
dvbsubtitle_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n",
|
||||||
|
FILENAME, __FUNCTION__,
|
||||||
|
*((int *) argument));
|
||||||
|
|
||||||
for (i = 0; i < TrackCount; i++)
|
for (i = 0; i < TrackCount; i++)
|
||||||
if (Tracks[i].Id == *((int*)argument)) {
|
if (Tracks[i].Id == *((int *) argument)) {
|
||||||
CurrentTrack = i;
|
CurrentTrack = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == TrackCount) {
|
if (i == TrackCount) {
|
||||||
dvbsubtitle_mgr_err("%s::%s track id %d unknown\n", FILENAME, __FUNCTION__, *((int*)argument));
|
dvbsubtitle_mgr_err("%s::%s track id %d unknown\n",
|
||||||
ret = cERR_DVBSUBTITLE_MGR_ERROR;
|
FILENAME, __FUNCTION__,
|
||||||
}
|
*((int *) argument));
|
||||||
break;
|
ret = cERR_DVBSUBTITLE_MGR_ERROR;
|
||||||
}
|
}
|
||||||
case MANAGER_DEL: {
|
break;
|
||||||
ret = ManagerDel(context);
|
}
|
||||||
break;
|
case MANAGER_DEL:{
|
||||||
}
|
ret = ManagerDel(context);
|
||||||
case MANAGER_INIT_UPDATE: {
|
break;
|
||||||
int i;
|
}
|
||||||
for (i = 0; i < TrackCount; i++)
|
case MANAGER_INIT_UPDATE:{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < TrackCount; i++)
|
||||||
Tracks[i].pending = 1;
|
Tracks[i].pending = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
dvbsubtitle_mgr_err("%s::%s ContainerCmd %d not supported!\n", FILENAME, __FUNCTION__, command);
|
dvbsubtitle_mgr_err("%s::%s ContainerCmd %d not supported!\n",
|
||||||
ret = cERR_DVBSUBTITLE_MGR_ERROR;
|
FILENAME, __FUNCTION__, command);
|
||||||
break;
|
ret = cERR_DVBSUBTITLE_MGR_ERROR;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dvbsubtitle_mgr_printf(10, "%s:%s: returning %d\n", FILENAME, __FUNCTION__,ret);
|
dvbsubtitle_mgr_printf(10, "%s:%s: returning %d\n", FILENAME,
|
||||||
|
__FUNCTION__, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -47,9 +47,7 @@ ManagerHandler_t ManagerHandler = {
|
|||||||
"ManagerHandler",
|
"ManagerHandler",
|
||||||
&AudioManager,
|
&AudioManager,
|
||||||
&VideoManager,
|
&VideoManager,
|
||||||
&SubtitleManager
|
&SubtitleManager, &DvbSubtitleManager, &TeletextManager
|
||||||
, &DvbSubtitleManager
|
|
||||||
, &TeletextManager
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
@@ -59,38 +57,38 @@ ManagerHandler_t ManagerHandler = {
|
|||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Functions */
|
/* Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
void copyTrack(Track_t* to, Track_t* from)
|
void copyTrack(Track_t * to, Track_t * from)
|
||||||
{
|
{
|
||||||
*to = *from;
|
*to = *from;
|
||||||
|
|
||||||
if (from->Name != NULL)
|
if (from->Name != NULL)
|
||||||
to->Name = strdup(from->Name);
|
to->Name = strdup(from->Name);
|
||||||
else
|
else
|
||||||
to->Name = strdup("Unknown");
|
to->Name = strdup("Unknown");
|
||||||
|
|
||||||
if (from->Encoding != NULL)
|
if (from->Encoding != NULL)
|
||||||
to->Encoding = strdup(from->Encoding);
|
to->Encoding = strdup(from->Encoding);
|
||||||
else
|
else
|
||||||
to->Encoding = strdup("Unknown");
|
to->Encoding = strdup("Unknown");
|
||||||
|
|
||||||
if (from->language != NULL)
|
if (from->language != NULL)
|
||||||
to->language = strdup(from->language);
|
to->language = strdup(from->language);
|
||||||
else
|
else
|
||||||
to->language = strdup("Unknown");
|
to->language = strdup("Unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeTrack(Track_t* track)
|
void freeTrack(Track_t * track)
|
||||||
{
|
{
|
||||||
if (track->Name != NULL)
|
if (track->Name != NULL)
|
||||||
free(track->Name);
|
free(track->Name);
|
||||||
|
|
||||||
if (track->Encoding != NULL)
|
if (track->Encoding != NULL)
|
||||||
free(track->Encoding);
|
free(track->Encoding);
|
||||||
|
|
||||||
if (track->language != NULL)
|
if (track->language != NULL)
|
||||||
free(track->language);
|
free(track->language);
|
||||||
|
|
||||||
if (track->aacbuf != NULL)
|
if (track->aacbuf != NULL)
|
||||||
free(track->aacbuf);
|
free(track->aacbuf);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -64,9 +64,9 @@ static const char FILENAME[] = __FILE__;
|
|||||||
/* Varaibles */
|
/* Varaibles */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static Track_t * Tracks = NULL;
|
static Track_t *Tracks = NULL;
|
||||||
static int TrackCount = 0;
|
static int TrackCount = 0;
|
||||||
static int CurrentTrack = -1; //no as default.
|
static int CurrentTrack = -1; //no as default.
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
@@ -76,194 +76,208 @@ static int CurrentTrack = -1; //no as default.
|
|||||||
/* Functions */
|
/* Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static int ManagerAdd(Context_t *context, Track_t track) {
|
static int ManagerAdd(Context_t * context, Track_t track)
|
||||||
|
{
|
||||||
|
|
||||||
subtitle_mgr_printf(10, "%s::%s %s %s %d\n", FILENAME, __FUNCTION__, track.Name, track.Encoding, track.Id);
|
subtitle_mgr_printf(10, "%s::%s %s %s %d\n", FILENAME, __FUNCTION__,
|
||||||
|
track.Name, track.Encoding, track.Id);
|
||||||
|
|
||||||
if (Tracks == NULL) {
|
if (Tracks == NULL) {
|
||||||
Tracks = malloc(sizeof(Track_t) * TRACKWRAP);
|
Tracks = malloc(sizeof(Track_t) * TRACKWRAP);
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < TRACKWRAP; i++)
|
for (i = 0; i < TRACKWRAP; i++)
|
||||||
Tracks[i].Id = -1;
|
Tracks[i].Id = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tracks == NULL)
|
if (Tracks == NULL) {
|
||||||
{
|
subtitle_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
||||||
subtitle_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
return cERR_SUBTITLE_MGR_ERROR;
|
||||||
return cERR_SUBTITLE_MGR_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < TRACKWRAP; i++) {
|
for (i = 0; i < TRACKWRAP; i++) {
|
||||||
if (Tracks[i].Id == track.Id) {
|
if (Tracks[i].Id == track.Id) {
|
||||||
Tracks[i].pending = 0;
|
Tracks[i].pending = 0;
|
||||||
return cERR_SUBTITLE_MGR_NO_ERROR;
|
return cERR_SUBTITLE_MGR_NO_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TrackCount < TRACKWRAP) {
|
if (TrackCount < TRACKWRAP) {
|
||||||
copyTrack(&Tracks[TrackCount], &track);
|
copyTrack(&Tracks[TrackCount], &track);
|
||||||
TrackCount++;
|
TrackCount++;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
subtitle_mgr_err("%s:%s TrackCount out if range %d - %d\n", FILENAME, __FUNCTION__, TrackCount, TRACKWRAP);
|
subtitle_mgr_err("%s:%s TrackCount out if range %d - %d\n",
|
||||||
return cERR_SUBTITLE_MGR_ERROR;
|
FILENAME, __FUNCTION__, TrackCount, TRACKWRAP);
|
||||||
|
return cERR_SUBTITLE_MGR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TrackCount > 0)
|
if (TrackCount > 0)
|
||||||
context->playback->isSubtitle = 1;
|
context->playback->isSubtitle = 1;
|
||||||
|
|
||||||
subtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
subtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
return cERR_SUBTITLE_MGR_NO_ERROR;
|
return cERR_SUBTITLE_MGR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char ** ManagerList(Context_t *context __attribute__((unused))) {
|
static char **ManagerList(Context_t * context __attribute__ ((unused)))
|
||||||
char ** tracklist = NULL;
|
{
|
||||||
|
char **tracklist = NULL;
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
|
|
||||||
subtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
subtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
if (Tracks != NULL) {
|
if (Tracks != NULL) {
|
||||||
tracklist = malloc(sizeof(char *) * ((TrackCount*2) + 1));
|
tracklist = malloc(sizeof(char *) * ((TrackCount * 2) + 1));
|
||||||
|
|
||||||
if (tracklist == NULL)
|
if (tracklist == NULL) {
|
||||||
{
|
subtitle_mgr_err("%s:%s malloc failed\n", FILENAME,
|
||||||
subtitle_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
__FUNCTION__);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0, j = 0; i < TrackCount; i++, j+=2) {
|
for (i = 0, j = 0; i < TrackCount; i++, j += 2) {
|
||||||
if (Tracks[i].pending)
|
if (Tracks[i].pending)
|
||||||
continue;
|
continue;
|
||||||
size_t len = strlen(Tracks[i].Name) + 20;
|
size_t len = strlen(Tracks[i].Name) + 20;
|
||||||
char tmp[len];
|
char tmp[len];
|
||||||
snprintf(tmp, len, "%d %s\n", Tracks[i].Id, Tracks[i].Name);
|
snprintf(tmp, len, "%d %s\n", Tracks[i].Id, Tracks[i].Name);
|
||||||
tracklist[j] = strdup(tmp);
|
tracklist[j] = strdup(tmp);
|
||||||
tracklist[j+1] = strdup(Tracks[i].Encoding);
|
tracklist[j + 1] = strdup(Tracks[i].Encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
tracklist[j] = NULL;
|
tracklist[j] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
subtitle_mgr_printf(10, "%s::%s return %p (%d - %d)\n", FILENAME, __FUNCTION__, tracklist, j, TrackCount);
|
subtitle_mgr_printf(10, "%s::%s return %p (%d - %d)\n", FILENAME,
|
||||||
|
__FUNCTION__, tracklist, j, TrackCount);
|
||||||
|
|
||||||
return tracklist;
|
return tracklist;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ManagerDel(Context_t * context) {
|
static int ManagerDel(Context_t * context)
|
||||||
|
{
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
subtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
subtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
if(Tracks != NULL) {
|
if (Tracks != NULL) {
|
||||||
for (i = 0; i < TrackCount; i++) {
|
for (i = 0; i < TrackCount; i++) {
|
||||||
freeTrack(&Tracks[i]);
|
freeTrack(&Tracks[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(Tracks);
|
free(Tracks);
|
||||||
Tracks = NULL;
|
Tracks = NULL;
|
||||||
} else
|
} else {
|
||||||
{
|
subtitle_mgr_err("%s::%s nothing to delete!\n", FILENAME,
|
||||||
subtitle_mgr_err("%s::%s nothing to delete!\n", FILENAME, __FUNCTION__);
|
__FUNCTION__);
|
||||||
return cERR_SUBTITLE_MGR_ERROR;
|
return cERR_SUBTITLE_MGR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackCount = 0;
|
TrackCount = 0;
|
||||||
CurrentTrack = -1;
|
CurrentTrack = -1;
|
||||||
context->playback->isSubtitle = 0;
|
context->playback->isSubtitle = 0;
|
||||||
|
|
||||||
subtitle_mgr_printf(10, "%s::%s return no error\n", FILENAME, __FUNCTION__);
|
subtitle_mgr_printf(10, "%s::%s return no error\n", FILENAME,
|
||||||
|
__FUNCTION__);
|
||||||
|
|
||||||
return cERR_SUBTITLE_MGR_NO_ERROR;
|
return cERR_SUBTITLE_MGR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Command(void *_context, ManagerCmd_t command, void * argument) {
|
static int Command(void *_context, ManagerCmd_t command, void *argument)
|
||||||
Context_t *context = (Context_t*) _context;
|
{
|
||||||
|
Context_t *context = (Context_t *) _context;
|
||||||
int ret = cERR_SUBTITLE_MGR_NO_ERROR;
|
int ret = cERR_SUBTITLE_MGR_NO_ERROR;
|
||||||
|
|
||||||
subtitle_mgr_printf(50, "%s::%s %d\n", FILENAME, __FUNCTION__, command);
|
subtitle_mgr_printf(50, "%s::%s %d\n", FILENAME, __FUNCTION__,
|
||||||
|
command);
|
||||||
|
|
||||||
switch(command) {
|
switch (command) {
|
||||||
case MANAGER_ADD: {
|
case MANAGER_ADD:{
|
||||||
Track_t * track = argument;
|
Track_t *track = argument;
|
||||||
ret = ManagerAdd(context, *track);
|
ret = ManagerAdd(context, *track);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MANAGER_LIST: {
|
case MANAGER_LIST:{
|
||||||
container_ffmpeg_update_tracks(context, context->playback->uri, 0);
|
container_ffmpeg_update_tracks(context, context->playback->uri,
|
||||||
*((char***)argument) = (char **)ManagerList(context);
|
0);
|
||||||
break;
|
*((char ***) argument) = (char **) ManagerList(context);
|
||||||
}
|
break;
|
||||||
case MANAGER_GET: {
|
}
|
||||||
if (TrackCount > 0 && CurrentTrack >= 0)
|
case MANAGER_GET:{
|
||||||
*((int*)argument) = (int)Tracks[CurrentTrack].Id;
|
if (TrackCount > 0 && CurrentTrack >= 0)
|
||||||
else
|
*((int *) argument) = (int) Tracks[CurrentTrack].Id;
|
||||||
*((int*)argument) = (int)-1;
|
else
|
||||||
break;
|
*((int *) argument) = (int) -1;
|
||||||
}
|
break;
|
||||||
case MANAGER_GET_TRACK: {
|
}
|
||||||
//subtitle_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", FILENAME, __FUNCTION__);
|
case MANAGER_GET_TRACK:{
|
||||||
|
//subtitle_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
if ((TrackCount > 0) && (CurrentTrack >= 0)) {
|
||||||
{
|
subtitle_mgr_printf(120, "return %d, %p\n", CurrentTrack,
|
||||||
subtitle_mgr_printf(120, "return %d, %p\n", CurrentTrack, &Tracks[CurrentTrack]);
|
&Tracks[CurrentTrack]);
|
||||||
*((Track_t**)argument) = (Track_t*) &Tracks[CurrentTrack];
|
*((Track_t **) argument) =
|
||||||
}
|
(Track_t *) & Tracks[CurrentTrack];
|
||||||
else
|
} else {
|
||||||
{
|
subtitle_mgr_printf(20, "return NULL\n");
|
||||||
subtitle_mgr_printf(20, "return NULL\n");
|
*((Track_t **) argument) = NULL;
|
||||||
*((Track_t**)argument) = NULL;
|
}
|
||||||
}
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case MANAGER_GETENCODING:{
|
||||||
case MANAGER_GETENCODING: {
|
if (TrackCount > 0 && CurrentTrack >= 0)
|
||||||
if (TrackCount > 0 && CurrentTrack >= 0)
|
*((char **) argument) =
|
||||||
*((char**)argument) = (char *)strdup(Tracks[CurrentTrack].Encoding);
|
(char *) strdup(Tracks[CurrentTrack].Encoding);
|
||||||
else
|
else
|
||||||
*((char**)argument) = (char *)strdup("");
|
*((char **) argument) = (char *) strdup("");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MANAGER_GETNAME: {
|
case MANAGER_GETNAME:{
|
||||||
if (TrackCount > 0 && CurrentTrack >= 0)
|
if (TrackCount > 0 && CurrentTrack >= 0)
|
||||||
*((char**)argument) = (char *)strdup(Tracks[CurrentTrack].Name);
|
*((char **) argument) =
|
||||||
else
|
(char *) strdup(Tracks[CurrentTrack].Name);
|
||||||
*((char**)argument) = (char *)strdup("");
|
else
|
||||||
break;
|
*((char **) argument) = (char *) strdup("");
|
||||||
}
|
break;
|
||||||
case MANAGER_SET: {
|
}
|
||||||
int i;
|
case MANAGER_SET:{
|
||||||
subtitle_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", FILENAME, __FUNCTION__, *((int*)argument));
|
int i;
|
||||||
|
subtitle_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", FILENAME,
|
||||||
|
__FUNCTION__, *((int *) argument));
|
||||||
|
|
||||||
for (i = 0; i < TrackCount; i++)
|
for (i = 0; i < TrackCount; i++)
|
||||||
if (Tracks[i].Id == *((int*)argument)) {
|
if (Tracks[i].Id == *((int *) argument)) {
|
||||||
CurrentTrack = i;
|
CurrentTrack = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == TrackCount) {
|
if (i == TrackCount) {
|
||||||
subtitle_mgr_err("%s::%s track id %d unknown\n", FILENAME, __FUNCTION__, *((int*)argument));
|
subtitle_mgr_err("%s::%s track id %d unknown\n", FILENAME,
|
||||||
ret = cERR_SUBTITLE_MGR_ERROR;
|
__FUNCTION__, *((int *) argument));
|
||||||
}
|
ret = cERR_SUBTITLE_MGR_ERROR;
|
||||||
break;
|
}
|
||||||
}
|
break;
|
||||||
case MANAGER_DEL: {
|
}
|
||||||
ret = ManagerDel(context);
|
case MANAGER_DEL:{
|
||||||
break;
|
ret = ManagerDel(context);
|
||||||
}
|
break;
|
||||||
case MANAGER_INIT_UPDATE: {
|
}
|
||||||
int i;
|
case MANAGER_INIT_UPDATE:{
|
||||||
for (i = 0; i < TrackCount; i++)
|
int i;
|
||||||
|
for (i = 0; i < TrackCount; i++)
|
||||||
Tracks[i].pending = 1;
|
Tracks[i].pending = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
subtitle_mgr_err("%s:%s: ConatinerCmd not supported!", FILENAME, __FUNCTION__);
|
subtitle_mgr_err("%s:%s: ConatinerCmd not supported!", FILENAME,
|
||||||
ret = cERR_SUBTITLE_MGR_ERROR;
|
__FUNCTION__);
|
||||||
break;
|
ret = cERR_SUBTITLE_MGR_ERROR;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
subtitle_mgr_printf(50, "%s:%s: returning %d\n", FILENAME, __FUNCTION__,ret);
|
subtitle_mgr_printf(50, "%s:%s: returning %d\n", FILENAME,
|
||||||
|
__FUNCTION__, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -65,7 +65,7 @@ static const char FILENAME[] = __FILE__;
|
|||||||
/* Varaibles */
|
/* Varaibles */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static Track_t * Tracks = NULL;
|
static Track_t *Tracks = NULL;
|
||||||
static int TrackCount = 0;
|
static int TrackCount = 0;
|
||||||
static int CurrentTrack = -1;
|
static int CurrentTrack = -1;
|
||||||
|
|
||||||
@@ -77,191 +77,209 @@ static int CurrentTrack = -1;
|
|||||||
/* Functions */
|
/* Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static int ManagerAdd(Context_t *context, Track_t track) {
|
static int ManagerAdd(Context_t * context, Track_t track)
|
||||||
|
{
|
||||||
|
|
||||||
teletext_mgr_printf(10, "%s::%s name=\"%s\" encoding=\"%s\" id=%d\n", FILENAME, __FUNCTION__, track.Name, track.Encoding, track.Id);
|
teletext_mgr_printf(10, "%s::%s name=\"%s\" encoding=\"%s\" id=%d\n",
|
||||||
|
FILENAME, __FUNCTION__, track.Name, track.Encoding,
|
||||||
|
track.Id);
|
||||||
|
|
||||||
if (Tracks == NULL) {
|
if (Tracks == NULL) {
|
||||||
Tracks = malloc(sizeof(Track_t) * TRACKWRAP);
|
Tracks = malloc(sizeof(Track_t) * TRACKWRAP);
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < TRACKWRAP; i++)
|
for (i = 0; i < TRACKWRAP; i++)
|
||||||
Tracks[i].Id = -1;
|
Tracks[i].Id = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tracks == NULL)
|
if (Tracks == NULL) {
|
||||||
{
|
teletext_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
||||||
teletext_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
return cERR_TELETEXT_MGR_ERROR;
|
||||||
return cERR_TELETEXT_MGR_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < TRACKWRAP; i++) {
|
for (i = 0; i < TRACKWRAP; i++) {
|
||||||
if (Tracks[i].Id == track.Id) {
|
if (Tracks[i].Id == track.Id) {
|
||||||
Tracks[i].pending = 0;
|
Tracks[i].pending = 0;
|
||||||
return cERR_TELETEXT_MGR_NO_ERROR;
|
return cERR_TELETEXT_MGR_NO_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TrackCount < TRACKWRAP) {
|
if (TrackCount < TRACKWRAP) {
|
||||||
copyTrack(&Tracks[TrackCount], &track);
|
copyTrack(&Tracks[TrackCount], &track);
|
||||||
TrackCount++;
|
TrackCount++;
|
||||||
} else {
|
} else {
|
||||||
teletext_mgr_err("%s:%s TrackCount out if range %d - %d\n", FILENAME, __FUNCTION__, TrackCount, TRACKWRAP);
|
teletext_mgr_err("%s:%s TrackCount out if range %d - %d\n",
|
||||||
return cERR_TELETEXT_MGR_ERROR;
|
FILENAME, __FUNCTION__, TrackCount, TRACKWRAP);
|
||||||
|
return cERR_TELETEXT_MGR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TrackCount > 0)
|
if (TrackCount > 0)
|
||||||
context->playback->isTeletext = 1;
|
context->playback->isTeletext = 1;
|
||||||
|
|
||||||
teletext_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
teletext_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
return cERR_TELETEXT_MGR_NO_ERROR;
|
return cERR_TELETEXT_MGR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char ** ManagerList(Context_t *context __attribute__((unused))) {
|
static char **ManagerList(Context_t * context __attribute__ ((unused)))
|
||||||
|
{
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
char ** tracklist = NULL;
|
char **tracklist = NULL;
|
||||||
|
|
||||||
teletext_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
teletext_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
if (Tracks != NULL) {
|
if (Tracks != NULL) {
|
||||||
|
|
||||||
tracklist = malloc(sizeof(char *) * ((TrackCount*2) + 1));
|
tracklist = malloc(sizeof(char *) * ((TrackCount * 2) + 1));
|
||||||
|
|
||||||
if (tracklist == NULL)
|
if (tracklist == NULL) {
|
||||||
{
|
teletext_mgr_err("%s:%s malloc failed\n", FILENAME,
|
||||||
teletext_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
__FUNCTION__);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0, j = 0; i < TrackCount; i++, j+=2) {
|
for (i = 0, j = 0; i < TrackCount; i++, j += 2) {
|
||||||
if (Tracks[i].pending)
|
if (Tracks[i].pending)
|
||||||
continue;
|
continue;
|
||||||
size_t len = strlen(Tracks[i].Name) + 20;
|
size_t len = strlen(Tracks[i].Name) + 20;
|
||||||
char tmp[len];
|
char tmp[len];
|
||||||
snprintf(tmp, len, "%d %s\n", Tracks[i].Id, Tracks[i].Name);
|
snprintf(tmp, len, "%d %s\n", Tracks[i].Id, Tracks[i].Name);
|
||||||
tracklist[j] = strdup(tmp);
|
tracklist[j] = strdup(tmp);
|
||||||
tracklist[j+1] = strdup(Tracks[i].Encoding);
|
tracklist[j + 1] = strdup(Tracks[i].Encoding);
|
||||||
}
|
}
|
||||||
tracklist[j] = NULL;
|
tracklist[j] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
teletext_mgr_printf(10, "%s::%s return %p (%d - %d)\n", FILENAME, __FUNCTION__, tracklist, j, TrackCount);
|
teletext_mgr_printf(10, "%s::%s return %p (%d - %d)\n", FILENAME,
|
||||||
|
__FUNCTION__, tracklist, j, TrackCount);
|
||||||
|
|
||||||
return tracklist;
|
return tracklist;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ManagerDel(Context_t * context) {
|
static int ManagerDel(Context_t * context)
|
||||||
|
{
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
teletext_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
teletext_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
if(Tracks != NULL) {
|
if (Tracks != NULL) {
|
||||||
for (i = 0; i < TrackCount; i++) {
|
for (i = 0; i < TrackCount; i++) {
|
||||||
freeTrack(&Tracks[i]);
|
freeTrack(&Tracks[i]);
|
||||||
}
|
}
|
||||||
free(Tracks);
|
free(Tracks);
|
||||||
Tracks = NULL;
|
Tracks = NULL;
|
||||||
} else
|
} else {
|
||||||
{
|
teletext_mgr_err("%s::%s nothing to delete!\n", FILENAME,
|
||||||
teletext_mgr_err("%s::%s nothing to delete!\n", FILENAME, __FUNCTION__);
|
__FUNCTION__);
|
||||||
return cERR_TELETEXT_MGR_ERROR;
|
return cERR_TELETEXT_MGR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackCount = 0;
|
TrackCount = 0;
|
||||||
CurrentTrack = -1;
|
CurrentTrack = -1;
|
||||||
context->playback->isTeletext = 0;
|
context->playback->isTeletext = 0;
|
||||||
|
|
||||||
teletext_mgr_printf(10, "%s::%s return no error\n", FILENAME, __FUNCTION__);
|
teletext_mgr_printf(10, "%s::%s return no error\n", FILENAME,
|
||||||
|
__FUNCTION__);
|
||||||
|
|
||||||
return cERR_TELETEXT_MGR_NO_ERROR;
|
return cERR_TELETEXT_MGR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int Command(void *_context, ManagerCmd_t command, void * argument) {
|
static int Command(void *_context, ManagerCmd_t command, void *argument)
|
||||||
Context_t *context = (Context_t*) _context;
|
{
|
||||||
|
Context_t *context = (Context_t *) _context;
|
||||||
int ret = cERR_TELETEXT_MGR_NO_ERROR;
|
int ret = cERR_TELETEXT_MGR_NO_ERROR;
|
||||||
|
|
||||||
teletext_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
teletext_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
switch(command) {
|
switch (command) {
|
||||||
case MANAGER_ADD: {
|
case MANAGER_ADD:{
|
||||||
Track_t * track = argument;
|
Track_t *track = argument;
|
||||||
|
|
||||||
ret = ManagerAdd(context, *track);
|
ret = ManagerAdd(context, *track);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MANAGER_LIST: {
|
case MANAGER_LIST:{
|
||||||
container_ffmpeg_update_tracks(context, context->playback->uri, 0);
|
container_ffmpeg_update_tracks(context, context->playback->uri,
|
||||||
*((char***)argument) = (char **)ManagerList(context);
|
0);
|
||||||
break;
|
*((char ***) argument) = (char **) ManagerList(context);
|
||||||
}
|
break;
|
||||||
case MANAGER_GET: {
|
}
|
||||||
teletext_mgr_printf(20, "%s::%s MANAGER_GET\n", FILENAME, __FUNCTION__);
|
case MANAGER_GET:{
|
||||||
|
teletext_mgr_printf(20, "%s::%s MANAGER_GET\n", FILENAME,
|
||||||
|
__FUNCTION__);
|
||||||
|
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
*((int*)argument) = (int)Tracks[CurrentTrack].Id;
|
*((int *) argument) = (int) Tracks[CurrentTrack].Id;
|
||||||
else
|
else
|
||||||
*((int*)argument) = (int)-1;
|
*((int *) argument) = (int) -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MANAGER_GET_TRACK: {
|
case MANAGER_GET_TRACK:{
|
||||||
teletext_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", FILENAME, __FUNCTION__);
|
teletext_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", FILENAME,
|
||||||
|
__FUNCTION__);
|
||||||
|
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
*((Track_t**)argument) = (Track_t*) &Tracks[CurrentTrack];
|
*((Track_t **) argument) =
|
||||||
else
|
(Track_t *) & Tracks[CurrentTrack];
|
||||||
*((Track_t**)argument) = NULL;
|
else
|
||||||
break;
|
*((Track_t **) argument) = NULL;
|
||||||
}
|
break;
|
||||||
case MANAGER_GETENCODING: {
|
}
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
case MANAGER_GETENCODING:{
|
||||||
*((char**)argument) = (char *)strdup(Tracks[CurrentTrack].Encoding);
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
else
|
*((char **) argument) =
|
||||||
*((char**)argument) = (char *)strdup("");
|
(char *) strdup(Tracks[CurrentTrack].Encoding);
|
||||||
break;
|
else
|
||||||
}
|
*((char **) argument) = (char *) strdup("");
|
||||||
case MANAGER_GETNAME: {
|
break;
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
}
|
||||||
*((char**)argument) = (char *)strdup(Tracks[CurrentTrack].Name);
|
case MANAGER_GETNAME:{
|
||||||
else
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
*((char**)argument) = (char *)strdup("");
|
*((char **) argument) =
|
||||||
break;
|
(char *) strdup(Tracks[CurrentTrack].Name);
|
||||||
}
|
else
|
||||||
case MANAGER_SET: {
|
*((char **) argument) = (char *) strdup("");
|
||||||
int i;
|
break;
|
||||||
teletext_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", FILENAME, __FUNCTION__, *((int*)argument));
|
}
|
||||||
|
case MANAGER_SET:{
|
||||||
|
int i;
|
||||||
|
teletext_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", FILENAME,
|
||||||
|
__FUNCTION__, *((int *) argument));
|
||||||
|
|
||||||
for (i = 0; i < TrackCount; i++)
|
for (i = 0; i < TrackCount; i++)
|
||||||
if (Tracks[i].Id == *((int*)argument)) {
|
if (Tracks[i].Id == *((int *) argument)) {
|
||||||
CurrentTrack = i;
|
CurrentTrack = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == TrackCount) {
|
if (i == TrackCount) {
|
||||||
teletext_mgr_err("%s::%s track id %d unknown\n", FILENAME, __FUNCTION__, *((int*)argument));
|
teletext_mgr_err("%s::%s track id %d unknown\n", FILENAME,
|
||||||
ret = cERR_TELETEXT_MGR_ERROR;
|
__FUNCTION__, *((int *) argument));
|
||||||
}
|
ret = cERR_TELETEXT_MGR_ERROR;
|
||||||
break;
|
}
|
||||||
}
|
break;
|
||||||
case MANAGER_DEL: {
|
}
|
||||||
ret = ManagerDel(context);
|
case MANAGER_DEL:{
|
||||||
break;
|
ret = ManagerDel(context);
|
||||||
}
|
break;
|
||||||
case MANAGER_INIT_UPDATE: {
|
}
|
||||||
int i;
|
case MANAGER_INIT_UPDATE:{
|
||||||
for (i = 0; i < TrackCount; i++)
|
int i;
|
||||||
|
for (i = 0; i < TrackCount; i++)
|
||||||
Tracks[i].pending = 1;
|
Tracks[i].pending = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
teletext_mgr_err("%s::%s ContainerCmd %d not supported!\n", FILENAME, __FUNCTION__, command);
|
teletext_mgr_err("%s::%s ContainerCmd %d not supported!\n",
|
||||||
ret = cERR_TELETEXT_MGR_ERROR;
|
FILENAME, __FUNCTION__, command);
|
||||||
break;
|
ret = cERR_TELETEXT_MGR_ERROR;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
teletext_mgr_printf(10, "%s:%s: returning %d\n", FILENAME, __FUNCTION__,ret);
|
teletext_mgr_printf(10, "%s:%s: returning %d\n", FILENAME,
|
||||||
|
__FUNCTION__, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -64,9 +64,9 @@ static const char FILENAME[] = __FILE__;
|
|||||||
/* Varaibles */
|
/* Varaibles */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static Track_t * Tracks = NULL;
|
static Track_t *Tracks = NULL;
|
||||||
static int TrackCount = 0;
|
static int TrackCount = 0;
|
||||||
static int CurrentTrack = 0; //TRACK[0] as default.
|
static int CurrentTrack = 0; //TRACK[0] as default.
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
@@ -76,186 +76,198 @@ static int CurrentTrack = 0; //TRACK[0] as default.
|
|||||||
/* Functions */
|
/* Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static int ManagerAdd(Context_t *context, Track_t track) {
|
static int ManagerAdd(Context_t * context, Track_t track)
|
||||||
|
{
|
||||||
video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
if (Tracks == NULL) {
|
if (Tracks == NULL) {
|
||||||
Tracks = malloc(sizeof(Track_t) * TRACKWRAP);
|
Tracks = malloc(sizeof(Track_t) * TRACKWRAP);
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < TRACKWRAP; i++)
|
for (i = 0; i < TRACKWRAP; i++)
|
||||||
Tracks[i].Id = -1;
|
Tracks[i].Id = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tracks == NULL)
|
if (Tracks == NULL) {
|
||||||
{
|
video_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
||||||
video_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
return cERR_VIDEO_MGR_ERROR;
|
||||||
return cERR_VIDEO_MGR_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < TRACKWRAP; i++) {
|
for (i = 0; i < TRACKWRAP; i++) {
|
||||||
if (Tracks[i].Id == track.Id) {
|
if (Tracks[i].Id == track.Id) {
|
||||||
Tracks[i].pending = 0;
|
Tracks[i].pending = 0;
|
||||||
return cERR_VIDEO_MGR_NO_ERROR;
|
return cERR_VIDEO_MGR_NO_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TrackCount < TRACKWRAP) {
|
if (TrackCount < TRACKWRAP) {
|
||||||
copyTrack(&Tracks[TrackCount], &track);
|
copyTrack(&Tracks[TrackCount], &track);
|
||||||
|
|
||||||
TrackCount++;
|
TrackCount++;
|
||||||
} else {
|
} else {
|
||||||
video_mgr_err("%s:%s TrackCount out if range %d - %d\n", FILENAME, __FUNCTION__, TrackCount, TRACKWRAP);
|
video_mgr_err("%s:%s TrackCount out if range %d - %d\n", FILENAME,
|
||||||
return cERR_VIDEO_MGR_ERROR;
|
__FUNCTION__, TrackCount, TRACKWRAP);
|
||||||
|
return cERR_VIDEO_MGR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TrackCount > 0)
|
if (TrackCount > 0)
|
||||||
context->playback->isVideo = 1;
|
context->playback->isVideo = 1;
|
||||||
|
|
||||||
video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
return cERR_VIDEO_MGR_NO_ERROR;
|
return cERR_VIDEO_MGR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char ** ManagerList(Context_t *context __attribute__((unused))) {
|
static char **ManagerList(Context_t * context __attribute__ ((unused)))
|
||||||
|
{
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
char ** tracklist = NULL;
|
char **tracklist = NULL;
|
||||||
|
|
||||||
video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
if (Tracks != NULL) {
|
if (Tracks != NULL) {
|
||||||
|
|
||||||
tracklist = malloc(sizeof(char *) * ((TrackCount*2) + 1));
|
tracklist = malloc(sizeof(char *) * ((TrackCount * 2) + 1));
|
||||||
|
|
||||||
if (tracklist == NULL)
|
if (tracklist == NULL) {
|
||||||
{
|
video_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
||||||
video_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__);
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0, j = 0; i < TrackCount; i++, j+=2) {
|
for (i = 0, j = 0; i < TrackCount; i++, j += 2) {
|
||||||
if (Tracks[i].pending)
|
if (Tracks[i].pending)
|
||||||
continue;
|
continue;
|
||||||
size_t len = strlen(Tracks[i].Name) + 20;
|
size_t len = strlen(Tracks[i].Name) + 20;
|
||||||
char tmp[len];
|
char tmp[len];
|
||||||
snprintf(tmp, len, "%d %s\n", Tracks[i].Id, Tracks[i].Name);
|
snprintf(tmp, len, "%d %s\n", Tracks[i].Id, Tracks[i].Name);
|
||||||
tracklist[j] = strdup(tmp);
|
tracklist[j] = strdup(tmp);
|
||||||
tracklist[j+1] = strdup(Tracks[i].Encoding);
|
tracklist[j + 1] = strdup(Tracks[i].Encoding);
|
||||||
}
|
}
|
||||||
tracklist[j] = NULL;
|
tracklist[j] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
video_mgr_printf(10, "%s::%s return %p (%d - %d)\n", FILENAME, __FUNCTION__, tracklist, j, TrackCount);
|
video_mgr_printf(10, "%s::%s return %p (%d - %d)\n", FILENAME,
|
||||||
|
__FUNCTION__, tracklist, j, TrackCount);
|
||||||
|
|
||||||
return tracklist;
|
return tracklist;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ManagerDel(Context_t * context) {
|
static int ManagerDel(Context_t * context)
|
||||||
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
if(Tracks != NULL) {
|
if (Tracks != NULL) {
|
||||||
for (i = 0; i < TrackCount; i++) {
|
for (i = 0; i < TrackCount; i++) {
|
||||||
freeTrack(&Tracks[i]);
|
freeTrack(&Tracks[i]);
|
||||||
}
|
}
|
||||||
free(Tracks);
|
free(Tracks);
|
||||||
Tracks = NULL;
|
Tracks = NULL;
|
||||||
} else
|
} else {
|
||||||
{
|
video_mgr_err("%s::%s nothing to delete!\n", FILENAME,
|
||||||
video_mgr_err("%s::%s nothing to delete!\n", FILENAME, __FUNCTION__);
|
__FUNCTION__);
|
||||||
return cERR_VIDEO_MGR_ERROR;
|
return cERR_VIDEO_MGR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackCount = 0;
|
TrackCount = 0;
|
||||||
CurrentTrack = 0;
|
CurrentTrack = 0;
|
||||||
context->playback->isVideo = 0;
|
context->playback->isVideo = 0;
|
||||||
|
|
||||||
video_mgr_printf(10, "%s::%s return no error\n", FILENAME, __FUNCTION__);
|
video_mgr_printf(10, "%s::%s return no error\n", FILENAME,
|
||||||
|
__FUNCTION__);
|
||||||
|
|
||||||
return cERR_VIDEO_MGR_NO_ERROR;
|
return cERR_VIDEO_MGR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Command(void *_context, ManagerCmd_t command, void * argument) {
|
static int Command(void *_context, ManagerCmd_t command, void *argument)
|
||||||
Context_t *context = (Context_t*) _context;
|
{
|
||||||
|
Context_t *context = (Context_t *) _context;
|
||||||
int ret = cERR_VIDEO_MGR_NO_ERROR;
|
int ret = cERR_VIDEO_MGR_NO_ERROR;
|
||||||
|
|
||||||
video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
switch(command) {
|
switch (command) {
|
||||||
case MANAGER_ADD: {
|
case MANAGER_ADD:{
|
||||||
Track_t * track = argument;
|
Track_t *track = argument;
|
||||||
ret = ManagerAdd(context, *track);
|
ret = ManagerAdd(context, *track);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MANAGER_LIST: {
|
case MANAGER_LIST:{
|
||||||
container_ffmpeg_update_tracks(context, context->playback->uri, 0);
|
container_ffmpeg_update_tracks(context, context->playback->uri,
|
||||||
*((char***)argument) = (char **)ManagerList(context);
|
0);
|
||||||
break;
|
*((char ***) argument) = (char **) ManagerList(context);
|
||||||
}
|
break;
|
||||||
case MANAGER_GET: {
|
}
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
case MANAGER_GET:{
|
||||||
*((int*)argument) = (int)Tracks[CurrentTrack].Id;
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
else
|
*((int *) argument) = (int) Tracks[CurrentTrack].Id;
|
||||||
*((int*)argument) = (int)-1;
|
else
|
||||||
break;
|
*((int *) argument) = (int) -1;
|
||||||
}
|
break;
|
||||||
case MANAGER_GET_TRACK: {
|
}
|
||||||
video_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", FILENAME, __FUNCTION__);
|
case MANAGER_GET_TRACK:{
|
||||||
|
video_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", FILENAME,
|
||||||
|
__FUNCTION__);
|
||||||
|
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
*((Track_t**)argument) = (Track_t*) &Tracks[CurrentTrack];
|
*((Track_t **) argument) =
|
||||||
else
|
(Track_t *) & Tracks[CurrentTrack];
|
||||||
*((Track_t**)argument) = NULL;
|
else
|
||||||
break;
|
*((Track_t **) argument) = NULL;
|
||||||
}
|
break;
|
||||||
case MANAGER_GETENCODING: {
|
}
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
case MANAGER_GETENCODING:{
|
||||||
*((char**)argument) = (char *)strdup(Tracks[CurrentTrack].Encoding);
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
else
|
*((char **) argument) =
|
||||||
*((char**)argument) = (char *)strdup("");
|
(char *) strdup(Tracks[CurrentTrack].Encoding);
|
||||||
break;
|
else
|
||||||
}
|
*((char **) argument) = (char *) strdup("");
|
||||||
case MANAGER_GETNAME: {
|
break;
|
||||||
if ((TrackCount > 0) && (CurrentTrack >=0))
|
}
|
||||||
*((char**)argument) = (char *)strdup(Tracks[CurrentTrack].Name);
|
case MANAGER_GETNAME:{
|
||||||
else
|
if ((TrackCount > 0) && (CurrentTrack >= 0))
|
||||||
*((char**)argument) = (char *)strdup("");
|
*((char **) argument) =
|
||||||
break;
|
(char *) strdup(Tracks[CurrentTrack].Name);
|
||||||
}
|
else
|
||||||
case MANAGER_SET: {
|
*((char **) argument) = (char *) strdup("");
|
||||||
int i;
|
break;
|
||||||
|
}
|
||||||
|
case MANAGER_SET:{
|
||||||
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < TrackCount; i++)
|
for (i = 0; i < TrackCount; i++)
|
||||||
if (Tracks[i].Id == *((int*)argument)) {
|
if (Tracks[i].Id == *((int *) argument)) {
|
||||||
CurrentTrack = i;
|
CurrentTrack = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == TrackCount)
|
if (i == TrackCount) {
|
||||||
{
|
video_mgr_err("%s::%s track id %d unknown\n", FILENAME,
|
||||||
video_mgr_err("%s::%s track id %d unknown\n", FILENAME, __FUNCTION__, *((int*)argument));
|
__FUNCTION__, *((int *) argument));
|
||||||
ret = cERR_VIDEO_MGR_ERROR;
|
ret = cERR_VIDEO_MGR_ERROR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MANAGER_DEL: {
|
case MANAGER_DEL:{
|
||||||
ret = ManagerDel(context);
|
ret = ManagerDel(context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MANAGER_INIT_UPDATE: {
|
case MANAGER_INIT_UPDATE:{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < TrackCount; i++)
|
for (i = 0; i < TrackCount; i++)
|
||||||
Tracks[i].pending = 1;
|
Tracks[i].pending = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
video_mgr_err("%s::%s ContainerCmd %d not supported!\n", FILENAME, __FUNCTION__, command);
|
video_mgr_err("%s::%s ContainerCmd %d not supported!\n", FILENAME,
|
||||||
ret = cERR_VIDEO_MGR_ERROR;
|
__FUNCTION__, command);
|
||||||
break;
|
ret = cERR_VIDEO_MGR_ERROR;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
video_mgr_printf(10, "%s:%s: returning %d\n", FILENAME, __FUNCTION__,ret);
|
video_mgr_printf(10, "%s:%s: returning %d\n", FILENAME, __FUNCTION__,
|
||||||
|
ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -53,7 +53,7 @@ if (debug_level >= level) fprintf(stderr, x); } while (0)
|
|||||||
#define cERR_OUTPUT_NO_ERROR 0
|
#define cERR_OUTPUT_NO_ERROR 0
|
||||||
#define cERR_OUTPUT_INTERNAL_ERROR -1
|
#define cERR_OUTPUT_INTERNAL_ERROR -1
|
||||||
|
|
||||||
static const char* FILENAME = "output.c";
|
static const char *FILENAME = "output.c";
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Types */
|
/* Types */
|
||||||
@@ -63,7 +63,7 @@ static const char* FILENAME = "output.c";
|
|||||||
/* Varaibles */
|
/* Varaibles */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static Output_t * AvailableOutput[] = {
|
static Output_t *AvailableOutput[] = {
|
||||||
&LinuxDvbOutput,
|
&LinuxDvbOutput,
|
||||||
&SubtitleOutput,
|
&SubtitleOutput,
|
||||||
&PipeOutput,
|
&PipeOutput,
|
||||||
@@ -78,18 +78,19 @@ static Output_t * AvailableOutput[] = {
|
|||||||
/* MISC Functions */
|
/* MISC Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static void printOutputCapabilities() {
|
static void printOutputCapabilities()
|
||||||
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
output_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
output_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
output_printf(10, "Capabilities:\n");
|
output_printf(10, "Capabilities:\n");
|
||||||
|
|
||||||
for (i = 0; AvailableOutput[i] != NULL; i++) {
|
for (i = 0; AvailableOutput[i] != NULL; i++) {
|
||||||
output_printf(10, "\t%s : ", AvailableOutput[i]->Name);
|
output_printf(10, "\t%s : ", AvailableOutput[i]->Name);
|
||||||
|
|
||||||
for (j = 0; AvailableOutput[i]->Capabilities[j] != NULL; j++)
|
for (j = 0; AvailableOutput[i]->Capabilities[j] != NULL; j++)
|
||||||
output_printf(10, "%s ", AvailableOutput[i]->Capabilities[j]);
|
output_printf(10, "%s ", AvailableOutput[i]->Capabilities[j]);
|
||||||
output_printf(10, "\n");
|
output_printf(10, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,301 +98,451 @@ static void printOutputCapabilities() {
|
|||||||
/* Output Functions */
|
/* Output Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static void OutputAdd(Context_t *context, char * port) {
|
static void OutputAdd(Context_t * context, char *port)
|
||||||
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
output_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
output_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
for (i = 0; AvailableOutput[i] != NULL; i++)
|
for (i = 0; AvailableOutput[i] != NULL; i++)
|
||||||
for (j = 0; AvailableOutput[i]->Capabilities[j] != NULL; j++)
|
for (j = 0; AvailableOutput[i]->Capabilities[j] != NULL; j++)
|
||||||
if (!strcmp(AvailableOutput[i]->Capabilities[j], port)) {
|
if (!strcmp(AvailableOutput[i]->Capabilities[j], port)) {
|
||||||
if (!strcmp("audio", port)) {
|
if (!strcmp("audio", port)) {
|
||||||
context->output->audio = AvailableOutput[i];
|
context->output->audio = AvailableOutput[i];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!strcmp("video", port)) {
|
if (!strcmp("video", port)) {
|
||||||
context->output->video = AvailableOutput[i];
|
context->output->video = AvailableOutput[i];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!strcmp("subtitle", port)) {
|
if (!strcmp("subtitle", port)) {
|
||||||
context->output->subtitle = AvailableOutput[i];
|
context->output->subtitle = AvailableOutput[i];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!strcmp("dvbsubtitle", port)) {
|
if (!strcmp("dvbsubtitle", port)) {
|
||||||
context->output->dvbsubtitle = AvailableOutput[i];
|
context->output->dvbsubtitle = AvailableOutput[i];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!strcmp("teletext", port)) {
|
if (!strcmp("teletext", port)) {
|
||||||
context->output->teletext = AvailableOutput[i];
|
context->output->teletext = AvailableOutput[i];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OutputDel(Context_t *context, char * port) {
|
static void OutputDel(Context_t * context, char *port)
|
||||||
|
{
|
||||||
output_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
output_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||||
|
|
||||||
if (!strcmp("audio", port))
|
if (!strcmp("audio", port))
|
||||||
context->output->audio = NULL;
|
context->output->audio = NULL;
|
||||||
else if (!strcmp("video", port))
|
else if (!strcmp("video", port))
|
||||||
context->output->video = NULL;
|
context->output->video = NULL;
|
||||||
else if (!strcmp("subtitle", port))
|
else if (!strcmp("subtitle", port))
|
||||||
context->output->subtitle = NULL;
|
context->output->subtitle = NULL;
|
||||||
else if (!strcmp("dvbsubtitle", port))
|
else if (!strcmp("dvbsubtitle", port))
|
||||||
context->output->dvbsubtitle = NULL;
|
context->output->dvbsubtitle = NULL;
|
||||||
else if (!strcmp("teletext", port))
|
else if (!strcmp("teletext", port))
|
||||||
context->output->teletext = NULL;
|
context->output->teletext = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Command(void *_context, OutputCmd_t command, void * argument) {
|
static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||||
Context_t *context = (Context_t*) _context;
|
{
|
||||||
|
Context_t *context = (Context_t *) _context;
|
||||||
int ret = cERR_OUTPUT_NO_ERROR;
|
int ret = cERR_OUTPUT_NO_ERROR;
|
||||||
|
|
||||||
output_printf(10, "%s::%s Command %d\n", FILENAME, __FUNCTION__, command);
|
output_printf(10, "%s::%s Command %d\n", FILENAME, __FUNCTION__,
|
||||||
|
command);
|
||||||
|
|
||||||
switch(command) {
|
switch (command) {
|
||||||
case OUTPUT_OPEN: {
|
case OUTPUT_OPEN:{
|
||||||
if (context && context->playback ) {
|
if (context && context->playback) {
|
||||||
if (context->playback->isVideo)
|
if (context->playback->isVideo)
|
||||||
ret |= context->output->video->Command(context, OUTPUT_OPEN, "video");
|
ret |=
|
||||||
if (context->playback->isAudio)
|
context->output->video->Command(context,
|
||||||
ret |= context->output->audio->Command(context, OUTPUT_OPEN, "audio");
|
OUTPUT_OPEN,
|
||||||
if (context->playback->isSubtitle)
|
"video");
|
||||||
ret |= context->output->subtitle->Command(context, OUTPUT_OPEN, "subtitle");
|
if (context->playback->isAudio)
|
||||||
if (context->playback->isDvbSubtitle)
|
ret |=
|
||||||
ret |= context->output->dvbsubtitle->Command(context, command, "dvbsubtitle");
|
context->output->audio->Command(context,
|
||||||
if (context->playback->isTeletext)
|
OUTPUT_OPEN,
|
||||||
ret |= context->output->teletext->Command(context, command, "teletext");
|
"audio");
|
||||||
} else
|
if (context->playback->isSubtitle)
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
ret |=
|
||||||
break;
|
context->output->subtitle->Command(context,
|
||||||
}
|
OUTPUT_OPEN,
|
||||||
case OUTPUT_CLOSE: {
|
"subtitle");
|
||||||
if (context && context->playback ) {
|
|
||||||
if (context->playback->isVideo)
|
|
||||||
ret |= context->output->video->Command(context, OUTPUT_CLOSE, "video");
|
|
||||||
if (context->playback->isAudio)
|
|
||||||
ret |= context->output->audio->Command(context, OUTPUT_CLOSE, "audio");
|
|
||||||
if (context->playback->isSubtitle)
|
|
||||||
ret |= context->output->subtitle->Command(context, OUTPUT_CLOSE, "subtitle");
|
|
||||||
if (context->playback->isDvbSubtitle)
|
|
||||||
ret |= context->output->dvbsubtitle->Command(context, command, "dvbsubtitle");
|
|
||||||
if (context->playback->isTeletext)
|
|
||||||
ret |= context->output->teletext->Command(context, command, "teletext");
|
|
||||||
} else
|
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OUTPUT_ADD: {
|
|
||||||
OutputAdd(context, (char*) argument);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OUTPUT_DEL: {
|
|
||||||
OutputDel(context, (char*) argument);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OUTPUT_CAPABILITIES: {
|
|
||||||
printOutputCapabilities();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OUTPUT_PLAY: { // 4
|
|
||||||
if (context && context->playback ) {
|
|
||||||
if (context->playback->isVideo)
|
|
||||||
ret = context->output->video->Command(context, OUTPUT_PLAY, "video");
|
|
||||||
|
|
||||||
if (!ret) { // success or not executed, dunn care
|
|
||||||
if (context->playback->isAudio)
|
|
||||||
ret = context->output->audio->Command(context, OUTPUT_PLAY, "audio");
|
|
||||||
|
|
||||||
if (!ret) { // success or not executed, dunn care
|
|
||||||
if (context->playback->isSubtitle)
|
|
||||||
ret = context->output->subtitle->Command(context, OUTPUT_PLAY, "subtitle");
|
|
||||||
}
|
|
||||||
if (context->playback->isDvbSubtitle)
|
if (context->playback->isDvbSubtitle)
|
||||||
ret |= context->output->dvbsubtitle->Command(context, command, "dvbsubtitle");
|
ret |=
|
||||||
|
context->output->dvbsubtitle->Command(context,
|
||||||
|
command,
|
||||||
|
"dvbsubtitle");
|
||||||
if (context->playback->isTeletext)
|
if (context->playback->isTeletext)
|
||||||
ret |= context->output->teletext->Command(context, command, "teletext");
|
ret |=
|
||||||
}
|
context->output->teletext->Command(context,
|
||||||
} else
|
command,
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
"teletext");
|
||||||
break;
|
} else
|
||||||
}
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
case OUTPUT_STOP: {
|
break;
|
||||||
if (context && context->playback ) {
|
}
|
||||||
if (context->playback->isVideo)
|
case OUTPUT_CLOSE:{
|
||||||
ret |= context->output->video->Command(context, OUTPUT_STOP, "video");
|
if (context && context->playback) {
|
||||||
if (context->playback->isAudio)
|
if (context->playback->isVideo)
|
||||||
ret |= context->output->audio->Command(context, OUTPUT_STOP, "audio");
|
ret |=
|
||||||
if (context->playback->isSubtitle)
|
context->output->video->Command(context,
|
||||||
ret |= context->output->subtitle->Command(context, OUTPUT_STOP, "subtitle");
|
OUTPUT_CLOSE,
|
||||||
if (context->playback->isDvbSubtitle)
|
"video");
|
||||||
ret |= context->output->dvbsubtitle->Command(context, command, "dvbsubtitle");
|
if (context->playback->isAudio)
|
||||||
if (context->playback->isTeletext)
|
ret |=
|
||||||
ret |= context->output->teletext->Command(context, command, "teletext");
|
context->output->audio->Command(context,
|
||||||
} else
|
OUTPUT_CLOSE,
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
"audio");
|
||||||
break;
|
if (context->playback->isSubtitle)
|
||||||
}
|
ret |=
|
||||||
case OUTPUT_FLUSH: {
|
context->output->subtitle->Command(context,
|
||||||
if (context && context->playback ) {
|
OUTPUT_CLOSE,
|
||||||
if (context->playback->isVideo)
|
"subtitle");
|
||||||
ret |= context->output->video->Command(context, OUTPUT_FLUSH, "video");
|
if (context->playback->isDvbSubtitle)
|
||||||
if (context->playback->isAudio)
|
ret |=
|
||||||
ret |= context->output->audio->Command(context, OUTPUT_FLUSH, "audio");
|
context->output->dvbsubtitle->Command(context,
|
||||||
//if (context->playback->isSubtitle)
|
command,
|
||||||
// ret |= context->output->subtitle->Command(context, OUTPUT_FLUSH, "subtitle");
|
"dvbsubtitle");
|
||||||
} else
|
if (context->playback->isTeletext)
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
ret |=
|
||||||
break;
|
context->output->teletext->Command(context,
|
||||||
}
|
command,
|
||||||
case OUTPUT_PAUSE: {
|
"teletext");
|
||||||
if (context && context->playback ) {
|
} else
|
||||||
if (context->playback->isVideo)
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
ret |= context->output->video->Command(context, OUTPUT_PAUSE, "video");
|
break;
|
||||||
if (context->playback->isAudio)
|
}
|
||||||
ret |= context->output->audio->Command(context, OUTPUT_PAUSE, "audio");
|
case OUTPUT_ADD:{
|
||||||
//if (context->playback->isSubtitle)
|
OutputAdd(context, (char *) argument);
|
||||||
// ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle");
|
break;
|
||||||
} else
|
}
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
case OUTPUT_DEL:{
|
||||||
break;
|
OutputDel(context, (char *) argument);
|
||||||
}
|
break;
|
||||||
case OUTPUT_FASTFORWARD: {
|
}
|
||||||
if (context && context->playback ) {
|
case OUTPUT_CAPABILITIES:{
|
||||||
if (context->playback->isVideo)
|
printOutputCapabilities();
|
||||||
ret |= context->output->video->Command(context, OUTPUT_FASTFORWARD, "video");
|
break;
|
||||||
if (context->playback->isAudio)
|
}
|
||||||
ret |= context->output->audio->Command(context, OUTPUT_FASTFORWARD, "audio");
|
case OUTPUT_PLAY:{ // 4
|
||||||
//if (context->playback->isSubtitle)
|
if (context && context->playback) {
|
||||||
// ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle");
|
if (context->playback->isVideo)
|
||||||
} else
|
ret =
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
context->output->video->Command(context,
|
||||||
break;
|
OUTPUT_PLAY,
|
||||||
}
|
"video");
|
||||||
case OUTPUT_REVERSE: {
|
|
||||||
if (context && context->playback ) {
|
if (!ret) { // success or not executed, dunn care
|
||||||
if (context->playback->isVideo)
|
if (context->playback->isAudio)
|
||||||
ret |= context->output->video->Command(context, OUTPUT_REVERSE, "video");
|
ret =
|
||||||
if (context->playback->isAudio)
|
context->output->audio->Command(context,
|
||||||
ret |= context->output->audio->Command(context, OUTPUT_REVERSE, "audio");
|
OUTPUT_PLAY,
|
||||||
} else
|
"audio");
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
|
||||||
break;
|
if (!ret) { // success or not executed, dunn care
|
||||||
}
|
if (context->playback->isSubtitle)
|
||||||
case OUTPUT_CONTINUE: {
|
ret =
|
||||||
if (context && context->playback ) {
|
context->output->subtitle->Command(context,
|
||||||
if (context->playback->isVideo)
|
OUTPUT_PLAY,
|
||||||
ret |= context->output->video->Command(context, OUTPUT_CONTINUE, "video");
|
"subtitle");
|
||||||
if (context->playback->isAudio)
|
}
|
||||||
ret |= context->output->audio->Command(context, OUTPUT_CONTINUE, "audio");
|
if (context->playback->isDvbSubtitle)
|
||||||
//if (context->playback->isSubtitle)
|
ret |=
|
||||||
// ret |= context->output->subtitle->Command(context, OUTPUT_CONTINUE, "subtitle");
|
context->output->dvbsubtitle->Command(context,
|
||||||
if (context->playback->isDvbSubtitle)
|
command,
|
||||||
ret |= context->output->dvbsubtitle->Command(context, command, "dvbsubtitle");
|
"dvbsubtitle");
|
||||||
if (context->playback->isTeletext)
|
if (context->playback->isTeletext)
|
||||||
ret |= context->output->teletext->Command(context, command, "teletext");
|
ret |=
|
||||||
} else
|
context->output->teletext->Command(context,
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
command,
|
||||||
break;
|
"teletext");
|
||||||
}
|
}
|
||||||
case OUTPUT_AVSYNC: {
|
} else
|
||||||
if (context && context->playback ) {
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
if (context->playback->isVideo && context->playback->isAudio)
|
break;
|
||||||
ret |= context->output->audio->Command(context, OUTPUT_AVSYNC, "audio");
|
}
|
||||||
} else
|
case OUTPUT_STOP:{
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
if (context && context->playback) {
|
||||||
break;
|
if (context->playback->isVideo)
|
||||||
}
|
ret |=
|
||||||
case OUTPUT_CLEAR: {
|
context->output->video->Command(context,
|
||||||
if (context && context->playback ) {
|
OUTPUT_STOP,
|
||||||
if (context->playback->isVideo && (argument == NULL || *(char *) argument == 'v'))
|
"video");
|
||||||
ret |= context->output->video->Command(context, OUTPUT_CLEAR, "video");
|
if (context->playback->isAudio)
|
||||||
if (context->playback->isAudio && (argument == NULL || *(char *) argument == 'a'))
|
ret |=
|
||||||
ret |= context->output->audio->Command(context, OUTPUT_CLEAR, "audio");
|
context->output->audio->Command(context,
|
||||||
//if (context->playback->isSubtitle && (argument == NULL || *(char *) argument == 's'))
|
OUTPUT_STOP,
|
||||||
// ret |= context->output->subtitle->Command(context, OUTPUT_CLEAR, "subtitle");
|
"audio");
|
||||||
if (context->playback->isDvbSubtitle)
|
if (context->playback->isSubtitle)
|
||||||
ret |= context->output->dvbsubtitle->Command(context, command, "dvbsubtitle");
|
ret |=
|
||||||
if (context->playback->isTeletext)
|
context->output->subtitle->Command(context,
|
||||||
ret |= context->output->teletext->Command(context, command, "teletext");
|
OUTPUT_STOP,
|
||||||
} else
|
"subtitle");
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
if (context->playback->isDvbSubtitle)
|
||||||
break;
|
ret |=
|
||||||
}
|
context->output->dvbsubtitle->Command(context,
|
||||||
case OUTPUT_PTS: {
|
command,
|
||||||
if (context && context->playback ) {
|
"dvbsubtitle");
|
||||||
if (context->playback->isVideo)
|
if (context->playback->isTeletext)
|
||||||
return context->output->video->Command(context, OUTPUT_PTS, argument);
|
ret |=
|
||||||
if (context->playback->isAudio)
|
context->output->teletext->Command(context,
|
||||||
return context->output->audio->Command(context, OUTPUT_PTS, argument);
|
command,
|
||||||
//if (context->playback->isSubtitle)
|
"teletext");
|
||||||
// return context->output->subtitle->Command(context, OUTPUT_PTS, "subtitle");
|
} else
|
||||||
} else
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case OUTPUT_FLUSH:{
|
||||||
case OUTPUT_SWITCH: {
|
if (context && context->playback) {
|
||||||
if (context && context->playback ) {
|
if (context->playback->isVideo)
|
||||||
if (context->playback->isAudio)
|
ret |=
|
||||||
return context->output->audio->Command(context, OUTPUT_SWITCH, "audio");
|
context->output->video->Command(context,
|
||||||
if (context->playback->isVideo)
|
OUTPUT_FLUSH,
|
||||||
return context->output->video->Command(context, OUTPUT_SWITCH, "video");
|
"video");
|
||||||
if (context->playback->isDvbSubtitle)
|
if (context->playback->isAudio)
|
||||||
ret |= context->output->dvbsubtitle->Command(context, command, "dvbsubtitle");
|
ret |=
|
||||||
if (context->playback->isTeletext)
|
context->output->audio->Command(context,
|
||||||
ret |= context->output->teletext->Command(context, command, "teletext");
|
OUTPUT_FLUSH,
|
||||||
} else
|
"audio");
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
//if (context->playback->isSubtitle)
|
||||||
break;
|
// ret |= context->output->subtitle->Command(context, OUTPUT_FLUSH, "subtitle");
|
||||||
}
|
} else
|
||||||
case OUTPUT_SLOWMOTION: {
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
if (context && context->playback ) {
|
break;
|
||||||
if (context->playback->isVideo)
|
}
|
||||||
ret |= context->output->video->Command(context, OUTPUT_SLOWMOTION, "video");
|
case OUTPUT_PAUSE:{
|
||||||
if (context->playback->isAudio)
|
if (context && context->playback) {
|
||||||
ret |= context->output->audio->Command(context, OUTPUT_SLOWMOTION, "audio");
|
if (context->playback->isVideo)
|
||||||
//if (context->playback->isSubtitle)
|
ret |=
|
||||||
// ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle");
|
context->output->video->Command(context,
|
||||||
} else
|
OUTPUT_PAUSE,
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
"video");
|
||||||
break;
|
if (context->playback->isAudio)
|
||||||
}
|
ret |=
|
||||||
case OUTPUT_AUDIOMUTE: {
|
context->output->audio->Command(context,
|
||||||
if (context && context->playback ) {
|
OUTPUT_PAUSE,
|
||||||
if (context->playback->isAudio)
|
"audio");
|
||||||
ret |= context->output->audio->Command(context, OUTPUT_AUDIOMUTE, (char*) argument);
|
//if (context->playback->isSubtitle)
|
||||||
} else
|
// ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle");
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
} else
|
||||||
break;
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
}
|
break;
|
||||||
case OUTPUT_DISCONTINUITY_REVERSE: {
|
}
|
||||||
if (context && context->playback ) {
|
case OUTPUT_FASTFORWARD:{
|
||||||
if (context->playback->isVideo)
|
if (context && context->playback) {
|
||||||
ret |= context->output->video->Command(context, OUTPUT_DISCONTINUITY_REVERSE, (void*) argument);
|
if (context->playback->isVideo)
|
||||||
} else
|
ret |=
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
context->output->video->Command(context,
|
||||||
break;
|
OUTPUT_FASTFORWARD,
|
||||||
}
|
"video");
|
||||||
case OUTPUT_GET_FRAME_COUNT: {
|
if (context->playback->isAudio)
|
||||||
if (context && context->playback ) {
|
ret |=
|
||||||
if (context->playback->isVideo)
|
context->output->audio->Command(context,
|
||||||
return context->output->video->Command(context, OUTPUT_GET_FRAME_COUNT, argument);
|
OUTPUT_FASTFORWARD,
|
||||||
if (context->playback->isAudio)
|
"audio");
|
||||||
return context->output->audio->Command(context, OUTPUT_GET_FRAME_COUNT, argument);
|
//if (context->playback->isSubtitle)
|
||||||
//if (context->playback->isSubtitle)
|
// ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle");
|
||||||
// return context->output->subtitle->Command(context, OUTPUT_GET_FRAME_COUNT, "subtitle");
|
} else
|
||||||
} else
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case OUTPUT_REVERSE:{
|
||||||
|
if (context && context->playback) {
|
||||||
|
if (context->playback->isVideo)
|
||||||
|
ret |=
|
||||||
|
context->output->video->Command(context,
|
||||||
|
OUTPUT_REVERSE,
|
||||||
|
"video");
|
||||||
|
if (context->playback->isAudio)
|
||||||
|
ret |=
|
||||||
|
context->output->audio->Command(context,
|
||||||
|
OUTPUT_REVERSE,
|
||||||
|
"audio");
|
||||||
|
} else
|
||||||
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OUTPUT_CONTINUE:{
|
||||||
|
if (context && context->playback) {
|
||||||
|
if (context->playback->isVideo)
|
||||||
|
ret |=
|
||||||
|
context->output->video->Command(context,
|
||||||
|
OUTPUT_CONTINUE,
|
||||||
|
"video");
|
||||||
|
if (context->playback->isAudio)
|
||||||
|
ret |=
|
||||||
|
context->output->audio->Command(context,
|
||||||
|
OUTPUT_CONTINUE,
|
||||||
|
"audio");
|
||||||
|
//if (context->playback->isSubtitle)
|
||||||
|
// ret |= context->output->subtitle->Command(context, OUTPUT_CONTINUE, "subtitle");
|
||||||
|
if (context->playback->isDvbSubtitle)
|
||||||
|
ret |=
|
||||||
|
context->output->dvbsubtitle->Command(context,
|
||||||
|
command,
|
||||||
|
"dvbsubtitle");
|
||||||
|
if (context->playback->isTeletext)
|
||||||
|
ret |=
|
||||||
|
context->output->teletext->Command(context,
|
||||||
|
command,
|
||||||
|
"teletext");
|
||||||
|
} else
|
||||||
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OUTPUT_AVSYNC:{
|
||||||
|
if (context && context->playback) {
|
||||||
|
if (context->playback->isVideo
|
||||||
|
&& context->playback->isAudio)
|
||||||
|
ret |=
|
||||||
|
context->output->audio->Command(context,
|
||||||
|
OUTPUT_AVSYNC,
|
||||||
|
"audio");
|
||||||
|
} else
|
||||||
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OUTPUT_CLEAR:{
|
||||||
|
if (context && context->playback) {
|
||||||
|
if (context->playback->isVideo
|
||||||
|
&& (argument == NULL || *(char *) argument == 'v'))
|
||||||
|
ret |=
|
||||||
|
context->output->video->Command(context,
|
||||||
|
OUTPUT_CLEAR,
|
||||||
|
"video");
|
||||||
|
if (context->playback->isAudio
|
||||||
|
&& (argument == NULL || *(char *) argument == 'a'))
|
||||||
|
ret |=
|
||||||
|
context->output->audio->Command(context,
|
||||||
|
OUTPUT_CLEAR,
|
||||||
|
"audio");
|
||||||
|
//if (context->playback->isSubtitle && (argument == NULL || *(char *) argument == 's'))
|
||||||
|
// ret |= context->output->subtitle->Command(context, OUTPUT_CLEAR, "subtitle");
|
||||||
|
if (context->playback->isDvbSubtitle)
|
||||||
|
ret |=
|
||||||
|
context->output->dvbsubtitle->Command(context,
|
||||||
|
command,
|
||||||
|
"dvbsubtitle");
|
||||||
|
if (context->playback->isTeletext)
|
||||||
|
ret |=
|
||||||
|
context->output->teletext->Command(context,
|
||||||
|
command,
|
||||||
|
"teletext");
|
||||||
|
} else
|
||||||
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OUTPUT_PTS:{
|
||||||
|
if (context && context->playback) {
|
||||||
|
if (context->playback->isVideo)
|
||||||
|
return context->output->video->Command(context,
|
||||||
|
OUTPUT_PTS,
|
||||||
|
argument);
|
||||||
|
if (context->playback->isAudio)
|
||||||
|
return context->output->audio->Command(context,
|
||||||
|
OUTPUT_PTS,
|
||||||
|
argument);
|
||||||
|
//if (context->playback->isSubtitle)
|
||||||
|
// return context->output->subtitle->Command(context, OUTPUT_PTS, "subtitle");
|
||||||
|
} else
|
||||||
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OUTPUT_SWITCH:{
|
||||||
|
if (context && context->playback) {
|
||||||
|
if (context->playback->isAudio)
|
||||||
|
return context->output->audio->Command(context,
|
||||||
|
OUTPUT_SWITCH,
|
||||||
|
"audio");
|
||||||
|
if (context->playback->isVideo)
|
||||||
|
return context->output->video->Command(context,
|
||||||
|
OUTPUT_SWITCH,
|
||||||
|
"video");
|
||||||
|
if (context->playback->isDvbSubtitle)
|
||||||
|
ret |=
|
||||||
|
context->output->dvbsubtitle->Command(context,
|
||||||
|
command,
|
||||||
|
"dvbsubtitle");
|
||||||
|
if (context->playback->isTeletext)
|
||||||
|
ret |=
|
||||||
|
context->output->teletext->Command(context,
|
||||||
|
command,
|
||||||
|
"teletext");
|
||||||
|
} else
|
||||||
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OUTPUT_SLOWMOTION:{
|
||||||
|
if (context && context->playback) {
|
||||||
|
if (context->playback->isVideo)
|
||||||
|
ret |=
|
||||||
|
context->output->video->Command(context,
|
||||||
|
OUTPUT_SLOWMOTION,
|
||||||
|
"video");
|
||||||
|
if (context->playback->isAudio)
|
||||||
|
ret |=
|
||||||
|
context->output->audio->Command(context,
|
||||||
|
OUTPUT_SLOWMOTION,
|
||||||
|
"audio");
|
||||||
|
//if (context->playback->isSubtitle)
|
||||||
|
// ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle");
|
||||||
|
} else
|
||||||
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OUTPUT_AUDIOMUTE:{
|
||||||
|
if (context && context->playback) {
|
||||||
|
if (context->playback->isAudio)
|
||||||
|
ret |=
|
||||||
|
context->output->audio->Command(context,
|
||||||
|
OUTPUT_AUDIOMUTE,
|
||||||
|
(char *) argument);
|
||||||
|
} else
|
||||||
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OUTPUT_DISCONTINUITY_REVERSE:{
|
||||||
|
if (context && context->playback) {
|
||||||
|
if (context->playback->isVideo)
|
||||||
|
ret |=
|
||||||
|
context->output->video->Command(context,
|
||||||
|
OUTPUT_DISCONTINUITY_REVERSE,
|
||||||
|
(void *) argument);
|
||||||
|
} else
|
||||||
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OUTPUT_GET_FRAME_COUNT:{
|
||||||
|
if (context && context->playback) {
|
||||||
|
if (context->playback->isVideo)
|
||||||
|
return context->output->video->Command(context,
|
||||||
|
OUTPUT_GET_FRAME_COUNT,
|
||||||
|
argument);
|
||||||
|
if (context->playback->isAudio)
|
||||||
|
return context->output->audio->Command(context,
|
||||||
|
OUTPUT_GET_FRAME_COUNT,
|
||||||
|
argument);
|
||||||
|
//if (context->playback->isSubtitle)
|
||||||
|
// return context->output->subtitle->Command(context, OUTPUT_GET_FRAME_COUNT, "subtitle");
|
||||||
|
} else
|
||||||
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
output_err("%s::%s OutputCmd %d not supported!\n", FILENAME, __FUNCTION__, command);
|
output_err("%s::%s OutputCmd %d not supported!\n", FILENAME,
|
||||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
__FUNCTION__, command);
|
||||||
break;
|
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
output_printf(10, "%s::%s exiting with value %d\n", FILENAME, __FUNCTION__, ret);
|
output_printf(10, "%s::%s exiting with value %d\n", FILENAME,
|
||||||
|
__FUNCTION__, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -401,7 +552,7 @@ OutputHandler_t OutputHandler = {
|
|||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL, // dvbsubtitle
|
NULL, // dvbsubtitle
|
||||||
NULL, // teletext
|
NULL, // teletext
|
||||||
&Command
|
&Command
|
||||||
};
|
};
|
||||||
|
@@ -70,24 +70,28 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x );
|
|||||||
#define cERR_PIPE_NO_ERROR 0
|
#define cERR_PIPE_NO_ERROR 0
|
||||||
#define cERR_PIPE_ERROR -1
|
#define cERR_PIPE_ERROR -1
|
||||||
|
|
||||||
static const char TELETEXTPIPE[] = "/tmp/.eplayer3_teletext";
|
static const char TELETEXTPIPE[] = "/tmp/.eplayer3_teletext";
|
||||||
static const char DVBSUBTITLEPIPE[] = "/tmp/.eplayer3_dvbsubtitle";
|
static const char DVBSUBTITLEPIPE[] = "/tmp/.eplayer3_dvbsubtitle";
|
||||||
|
|
||||||
static int teletextfd = -1;
|
static int teletextfd = -1;
|
||||||
static int dvbsubtitlefd = -1;
|
static int dvbsubtitlefd = -1;
|
||||||
|
|
||||||
pthread_mutex_t Pipemutex;
|
pthread_mutex_t Pipemutex;
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
int PipeStop(Context_t *context, char * type);
|
int PipeStop(Context_t * context, char *type);
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* MISC Functions */
|
/* MISC Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
void getPipeMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) {
|
void getPipeMutex(const char *filename
|
||||||
|
__attribute__ ((unused)), const char *function
|
||||||
|
__attribute__ ((unused)), int line
|
||||||
|
__attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
|
||||||
pipe_printf(250, "requesting mutex\n");
|
pipe_printf(250, "requesting mutex\n");
|
||||||
|
|
||||||
@@ -96,46 +100,52 @@ void getPipeMutex(const char *filename __attribute__((unused)), const char *func
|
|||||||
pipe_printf(250, "received mutex\n");
|
pipe_printf(250, "received mutex\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void releasePipeMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) {
|
void releasePipeMutex(const char *filename
|
||||||
|
__attribute__ ((unused)), const char *function
|
||||||
|
__attribute__ ((unused)), int line
|
||||||
|
__attribute__ ((unused)))
|
||||||
|
{
|
||||||
pthread_mutex_unlock(&Pipemutex);
|
pthread_mutex_unlock(&Pipemutex);
|
||||||
|
|
||||||
pipe_printf(250, "released mutex\n");
|
pipe_printf(250, "released mutex\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PipeOpen(Context_t *context __attribute__((unused)), char * type) {
|
int PipeOpen(Context_t * context __attribute__ ((unused)), char *type)
|
||||||
|
{
|
||||||
unsigned char teletext = !strcmp("teletext", type);
|
unsigned char teletext = !strcmp("teletext", type);
|
||||||
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
|
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
|
||||||
|
|
||||||
pipe_printf(10, "t%d d%d\n", teletext, dvbsubtitle);
|
pipe_printf(10, "t%d d%d\n", teletext, dvbsubtitle);
|
||||||
|
|
||||||
if (teletext && teletextfd == -1) {
|
if (teletext && teletextfd == -1) {
|
||||||
mkfifo(TELETEXTPIPE, 0644);
|
mkfifo(TELETEXTPIPE, 0644);
|
||||||
teletextfd = open(TELETEXTPIPE, O_RDWR | O_NONBLOCK);
|
teletextfd = open(TELETEXTPIPE, O_RDWR | O_NONBLOCK);
|
||||||
|
|
||||||
if (teletextfd < 0)
|
if (teletextfd < 0) {
|
||||||
{
|
pipe_err("failed to open %s - errno %d\n", TELETEXTPIPE,
|
||||||
pipe_err("failed to open %s - errno %d\n", TELETEXTPIPE, errno);
|
errno);
|
||||||
pipe_err("%s\n", strerror(errno));
|
pipe_err("%s\n", strerror(errno));
|
||||||
return cERR_PIPE_ERROR;
|
return cERR_PIPE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dvbsubtitle && dvbsubtitlefd == -1) {
|
if (dvbsubtitle && dvbsubtitlefd == -1) {
|
||||||
mkfifo(DVBSUBTITLEPIPE, 0644);
|
mkfifo(DVBSUBTITLEPIPE, 0644);
|
||||||
dvbsubtitlefd = open(DVBSUBTITLEPIPE, O_RDWR | O_NONBLOCK);
|
dvbsubtitlefd = open(DVBSUBTITLEPIPE, O_RDWR | O_NONBLOCK);
|
||||||
|
|
||||||
if (dvbsubtitlefd < 0)
|
if (dvbsubtitlefd < 0) {
|
||||||
{
|
pipe_err("failed to open %s - errno %d\n", DVBSUBTITLEPIPE,
|
||||||
pipe_err("failed to open %s - errno %d\n", DVBSUBTITLEPIPE, errno);
|
errno);
|
||||||
pipe_err("%s\n", strerror(errno));
|
pipe_err("%s\n", strerror(errno));
|
||||||
return cERR_PIPE_ERROR;
|
return cERR_PIPE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cERR_PIPE_NO_ERROR;
|
return cERR_PIPE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PipeClose(Context_t *context, char * type) {
|
int PipeClose(Context_t * context, char *type)
|
||||||
|
{
|
||||||
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
|
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
|
||||||
unsigned char teletext = !strcmp("teletext", type);
|
unsigned char teletext = !strcmp("teletext", type);
|
||||||
|
|
||||||
@@ -147,22 +157,24 @@ int PipeClose(Context_t *context, char * type) {
|
|||||||
*/
|
*/
|
||||||
PipeStop(context, type);
|
PipeStop(context, type);
|
||||||
|
|
||||||
getPipeMutex(FILENAME, __FUNCTION__,__LINE__);
|
getPipeMutex(FILENAME, __FUNCTION__, __LINE__);
|
||||||
|
|
||||||
if (dvbsubtitle && dvbsubtitlefd != -1) {
|
if (dvbsubtitle && dvbsubtitlefd != -1) {
|
||||||
close(dvbsubtitlefd);
|
close(dvbsubtitlefd);
|
||||||
dvbsubtitlefd = -1;
|
dvbsubtitlefd = -1;
|
||||||
}
|
}
|
||||||
if (teletext && teletextfd != -1) {
|
if (teletext && teletextfd != -1) {
|
||||||
close(teletextfd);
|
close(teletextfd);
|
||||||
teletextfd = -1;
|
teletextfd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
releasePipeMutex(FILENAME, __FUNCTION__,__LINE__);
|
releasePipeMutex(FILENAME, __FUNCTION__, __LINE__);
|
||||||
return cERR_PIPE_NO_ERROR;
|
return cERR_PIPE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PipePlay(Context_t *context __attribute__((unused)), char * type __attribute__((unused))) {
|
int PipePlay(Context_t * context __attribute__ ((unused)), char *type
|
||||||
|
__attribute__ ((unused)))
|
||||||
|
{
|
||||||
int ret = cERR_PIPE_NO_ERROR;
|
int ret = cERR_PIPE_NO_ERROR;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -179,7 +191,9 @@ int PipePlay(Context_t *context __attribute__((unused)), char * type __attribut
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PipeStop(Context_t *context __attribute__((unused)), char * type __attribute__((unused))) {
|
int PipeStop(Context_t * context __attribute__ ((unused)), char *type
|
||||||
|
__attribute__ ((unused)))
|
||||||
|
{
|
||||||
int ret = cERR_PIPE_NO_ERROR;
|
int ret = cERR_PIPE_NO_ERROR;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -188,38 +202,40 @@ int PipeStop(Context_t *context __attribute__((unused)), char * type __attribut
|
|||||||
|
|
||||||
pipe_printf(10, "t%d d%d\n", teletext, dvbsubtitle);
|
pipe_printf(10, "t%d d%d\n", teletext, dvbsubtitle);
|
||||||
|
|
||||||
getPipeMutex(FILENAME, __FUNCTION__,__LINE__);
|
getPipeMutex(FILENAME, __FUNCTION__, __LINE__);
|
||||||
|
|
||||||
if (dvbsubtitle && dvbsubtitlefd != -1) {
|
if (dvbsubtitle && dvbsubtitlefd != -1) {
|
||||||
}
|
}
|
||||||
if (teletext && teletextfd != -1) {
|
if (teletext && teletextfd != -1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
releasePipeMutex(FILENAME, __FUNCTION__,__LINE__);
|
releasePipeMutex(FILENAME, __FUNCTION__, __LINE__);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PipeFlush(Context_t *context __attribute__((unused)), char * type) {
|
int PipeFlush(Context_t * context __attribute__ ((unused)), char *type)
|
||||||
|
{
|
||||||
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
|
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
|
||||||
unsigned char teletext = !strcmp("teletext", type);
|
unsigned char teletext = !strcmp("teletext", type);
|
||||||
|
|
||||||
pipe_printf(10, "t%d d%d\n", teletext, dvbsubtitle);
|
pipe_printf(10, "t%d d%d\n", teletext, dvbsubtitle);
|
||||||
|
|
||||||
if ( (dvbsubtitle && dvbsubtitlefd != -1) || (teletext && teletextfd != -1) ) {
|
if ((dvbsubtitle && dvbsubtitlefd != -1)
|
||||||
getPipeMutex(FILENAME, __FUNCTION__,__LINE__);
|
|| (teletext && teletextfd != -1)) {
|
||||||
|
getPipeMutex(FILENAME, __FUNCTION__, __LINE__);
|
||||||
|
|
||||||
if (dvbsubtitle && dvbsubtitlefd != -1) {
|
if (dvbsubtitle && dvbsubtitlefd != -1) {
|
||||||
char buf[65536];
|
char buf[65536];
|
||||||
while(0 < read(dvbsubtitlefd, buf, sizeof(buf)));
|
while (0 < read(dvbsubtitlefd, buf, sizeof(buf)));
|
||||||
}
|
}
|
||||||
if (teletext && teletextfd != -1) {
|
if (teletext && teletextfd != -1) {
|
||||||
char buf[65536];
|
char buf[65536];
|
||||||
while(0 < read(teletextfd, buf, sizeof(buf)));
|
while (0 < read(teletextfd, buf, sizeof(buf)));
|
||||||
}
|
}
|
||||||
|
|
||||||
releasePipeMutex(FILENAME, __FUNCTION__,__LINE__);
|
releasePipeMutex(FILENAME, __FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe_printf(10, "exiting\n");
|
pipe_printf(10, "exiting\n");
|
||||||
@@ -227,26 +243,28 @@ int PipeFlush(Context_t *context __attribute__((unused)), char * type) {
|
|||||||
return cERR_PIPE_NO_ERROR;
|
return cERR_PIPE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PipeClear(Context_t *context __attribute__((unused)), char * type) {
|
int PipeClear(Context_t * context __attribute__ ((unused)), char *type)
|
||||||
|
{
|
||||||
int ret = cERR_PIPE_NO_ERROR;
|
int ret = cERR_PIPE_NO_ERROR;
|
||||||
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
|
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
|
||||||
unsigned char teletext = !strcmp("teletext", type);
|
unsigned char teletext = !strcmp("teletext", type);
|
||||||
|
|
||||||
pipe_printf(10, "v%d a%d\n", dvbsubtitle, teletext);
|
pipe_printf(10, "v%d a%d\n", dvbsubtitle, teletext);
|
||||||
|
|
||||||
if ( (dvbsubtitle && dvbsubtitlefd != -1) || (teletext && teletextfd != -1) ) {
|
if ((dvbsubtitle && dvbsubtitlefd != -1)
|
||||||
getPipeMutex(FILENAME, __FUNCTION__,__LINE__);
|
|| (teletext && teletextfd != -1)) {
|
||||||
|
getPipeMutex(FILENAME, __FUNCTION__, __LINE__);
|
||||||
|
|
||||||
if (dvbsubtitle && dvbsubtitlefd != -1) {
|
if (dvbsubtitle && dvbsubtitlefd != -1) {
|
||||||
char buf[65536];
|
char buf[65536];
|
||||||
while(0 < read(dvbsubtitlefd, buf, sizeof(buf)));
|
while (0 < read(dvbsubtitlefd, buf, sizeof(buf)));
|
||||||
}
|
}
|
||||||
if (teletext && teletextfd != -1) {
|
if (teletext && teletextfd != -1) {
|
||||||
char buf[65536];
|
char buf[65536];
|
||||||
while(0 < read(teletextfd, buf, sizeof(buf)));
|
while (0 < read(teletextfd, buf, sizeof(buf)));
|
||||||
}
|
}
|
||||||
|
|
||||||
releasePipeMutex(FILENAME, __FUNCTION__,__LINE__);
|
releasePipeMutex(FILENAME, __FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe_printf(10, "exiting\n");
|
pipe_printf(10, "exiting\n");
|
||||||
@@ -254,23 +272,26 @@ int PipeClear(Context_t *context __attribute__((unused)), char * type) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PipeSwitch(Context_t *context __attribute__((unused)), char * type __attribute__((unused))) {
|
int PipeSwitch(Context_t * context __attribute__ ((unused)), char *type
|
||||||
|
__attribute__ ((unused)))
|
||||||
|
{
|
||||||
#if 0
|
#if 0
|
||||||
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
|
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
|
||||||
unsigned char teletext = !strcmp("teletext", type);
|
unsigned char teletext = !strcmp("teletext", type);
|
||||||
|
|
||||||
pipe_printf(10, "v%d a%d\n", dvbsubtitle, teletext);
|
pipe_printf(10, "v%d a%d\n", dvbsubtitle, teletext);
|
||||||
|
|
||||||
if ( (dvbsubtitle && dvbsubtitlefd != -1) || (teletext && teletextfd != -1) ) {
|
if ((dvbsubtitle && dvbsubtitlefd != -1)
|
||||||
getPipeMutex(FILENAME, __FUNCTION__,__LINE__);
|
|| (teletext && teletextfd != -1)) {
|
||||||
|
getPipeMutex(FILENAME, __FUNCTION__, __LINE__);
|
||||||
|
|
||||||
if (teletext && teletextfd != -1) {
|
if (teletext && teletextfd != -1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dvbsubtitle && dvbsubtitlefd != -1) {
|
if (dvbsubtitle && dvbsubtitlefd != -1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
releasePipeMutex(FILENAME, __FUNCTION__,__LINE__);
|
releasePipeMutex(FILENAME, __FUNCTION__, __LINE__);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,11 +300,12 @@ int PipeSwitch(Context_t *context __attribute__((unused)), char * type __attrib
|
|||||||
return cERR_PIPE_NO_ERROR;
|
return cERR_PIPE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writePESDataTeletext(int fd, unsigned char *data, size_t data_len)
|
static int writePESDataTeletext(int fd, unsigned char *data,
|
||||||
|
size_t data_len)
|
||||||
{
|
{
|
||||||
unsigned int len = 0;
|
unsigned int len = 0;
|
||||||
if (data_len > 0) {
|
if (data_len > 0) {
|
||||||
len = data_len + 39;
|
len = data_len + 39;
|
||||||
char header[45];
|
char header[45];
|
||||||
memset(header, 0, sizeof(header));
|
memset(header, 0, sizeof(header));
|
||||||
header[2] = 0x01;
|
header[2] = 0x01;
|
||||||
@@ -299,17 +321,18 @@ static int writePESDataTeletext(int fd, unsigned char *data, size_t data_len)
|
|||||||
if (len != iov[0].iov_len + iov[1].iov_len) {
|
if (len != iov[0].iov_len + iov[1].iov_len) {
|
||||||
// writing to pipe failed, clear it.
|
// writing to pipe failed, clear it.
|
||||||
char buf[65536];
|
char buf[65536];
|
||||||
while(0 < read(fd, buf, sizeof(buf)));
|
while (0 < read(fd, buf, sizeof(buf)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writePESDataDvbsubtitle(int fd, unsigned char *data, size_t data_len, int64_t pts)
|
static int writePESDataDvbsubtitle(int fd, unsigned char *data,
|
||||||
|
size_t data_len, int64_t pts)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
if (data_len > 0) {
|
if (data_len > 0) {
|
||||||
len = data_len + 10;
|
len = data_len + 10;
|
||||||
char header[16];
|
char header[16];
|
||||||
memset(header, 0, sizeof(header));
|
memset(header, 0, sizeof(header));
|
||||||
header[2] = 0x01;
|
header[2] = 0x01;
|
||||||
@@ -318,16 +341,16 @@ static int writePESDataDvbsubtitle(int fd, unsigned char *data, size_t data_len,
|
|||||||
header[5] = len & 0xff;
|
header[5] = len & 0xff;
|
||||||
|
|
||||||
if (pts) {
|
if (pts) {
|
||||||
header[7] = 0x80;
|
header[7] = 0x80;
|
||||||
header[13] = 0x01 | ((pts << 1) & 0xff);
|
header[13] = 0x01 | ((pts << 1) & 0xff);
|
||||||
pts >>= 7;
|
pts >>= 7;
|
||||||
header[12] = pts & 0xff;
|
header[12] = pts & 0xff;
|
||||||
pts >>=8;
|
pts >>= 8;
|
||||||
header[11] = 0x01 | ((pts << 1) & 0xff);
|
header[11] = 0x01 | ((pts << 1) & 0xff);
|
||||||
pts >>= 7;
|
pts >>= 7;
|
||||||
header[10] = pts & 0xff;
|
header[10] = pts & 0xff;
|
||||||
pts >>=8;
|
pts >>= 8;
|
||||||
header[9] = 0x21 | ((pts << 1) & 0xff);
|
header[9] = 0x21 | ((pts << 1) & 0xff);
|
||||||
}
|
}
|
||||||
header[8] = 14 - 9;
|
header[8] = 14 - 9;
|
||||||
header[14] = 0x20;
|
header[14] = 0x20;
|
||||||
@@ -337,104 +360,105 @@ static int writePESDataDvbsubtitle(int fd, unsigned char *data, size_t data_len,
|
|||||||
iov[1].iov_base = data;
|
iov[1].iov_base = data;
|
||||||
iov[1].iov_len = data_len;
|
iov[1].iov_len = data_len;
|
||||||
len = writev(fd, iov, 2);
|
len = writev(fd, iov, 2);
|
||||||
if (len != (int)(iov[0].iov_len + iov[1].iov_len)) {
|
if (len != (int) (iov[0].iov_len + iov[1].iov_len)) {
|
||||||
// writing to pipe failed, clear it.
|
// writing to pipe failed, clear it.
|
||||||
char buf[65536];
|
char buf[65536];
|
||||||
while(0 < read(fd, buf, sizeof(buf)));
|
while (0 < read(fd, buf, sizeof(buf)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Write(void *_context __attribute__((unused)), void* _out)
|
static int Write(void *_context __attribute__ ((unused)), void *_out)
|
||||||
{
|
{
|
||||||
AudioVideoOut_t *out = (AudioVideoOut_t*) _out;
|
AudioVideoOut_t *out = (AudioVideoOut_t *) _out;
|
||||||
int ret = cERR_PIPE_NO_ERROR;
|
int ret = cERR_PIPE_NO_ERROR;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
unsigned char dvbsubtitle;
|
unsigned char dvbsubtitle;
|
||||||
unsigned char teletext;
|
unsigned char teletext;
|
||||||
|
|
||||||
if (out == NULL)
|
if (out == NULL) {
|
||||||
{
|
pipe_err("null pointer passed\n");
|
||||||
pipe_err("null pointer passed\n");
|
return cERR_PIPE_ERROR;
|
||||||
return cERR_PIPE_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dvbsubtitle = !strcmp("dvbsubtitle", out->type);
|
dvbsubtitle = !strcmp("dvbsubtitle", out->type);
|
||||||
teletext = !strcmp("teletext", out->type);
|
teletext = !strcmp("teletext", out->type);
|
||||||
|
|
||||||
pipe_printf(20, "DataLength=%u PrivateLength=%u Pts=%llu FrameRate=%f\n",
|
pipe_printf(20,
|
||||||
out->len, out->extralen, out->pts, out->frameRate);
|
"DataLength=%u PrivateLength=%u Pts=%llu FrameRate=%f\n",
|
||||||
|
out->len, out->extralen, out->pts, out->frameRate);
|
||||||
pipe_printf(20, "v%d a%d\n", dvbsubtitle, teletext);
|
pipe_printf(20, "v%d a%d\n", dvbsubtitle, teletext);
|
||||||
|
|
||||||
if (dvbsubtitle) {
|
if (dvbsubtitle) {
|
||||||
res = writePESDataDvbsubtitle(dvbsubtitlefd, out->data, out->len, out->pts);
|
res =
|
||||||
|
writePESDataDvbsubtitle(dvbsubtitlefd, out->data, out->len,
|
||||||
|
out->pts);
|
||||||
|
|
||||||
if (res <= 0)
|
if (res <= 0) {
|
||||||
{
|
ret = cERR_PIPE_ERROR;
|
||||||
ret = cERR_PIPE_ERROR;
|
}
|
||||||
}
|
|
||||||
} else if (teletext) {
|
} else if (teletext) {
|
||||||
res = writePESDataTeletext(teletextfd, out->data, out->len);
|
res = writePESDataTeletext(teletextfd, out->data, out->len);
|
||||||
|
|
||||||
if (res <= 0)
|
if (res <= 0) {
|
||||||
{
|
ret = cERR_PIPE_ERROR;
|
||||||
ret = cERR_PIPE_ERROR;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int reset(Context_t *context __attribute__((unused)))
|
static int reset(Context_t * context __attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
int ret = cERR_PIPE_NO_ERROR;
|
int ret = cERR_PIPE_NO_ERROR;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Command(void *_context, OutputCmd_t command, void * argument) {
|
static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||||
Context_t* context = (Context_t*) _context;
|
{
|
||||||
|
Context_t *context = (Context_t *) _context;
|
||||||
int ret = cERR_PIPE_NO_ERROR;
|
int ret = cERR_PIPE_NO_ERROR;
|
||||||
|
|
||||||
pipe_printf(50, "Command %d\n", command);
|
pipe_printf(50, "Command %d\n", command);
|
||||||
|
|
||||||
switch(command) {
|
switch (command) {
|
||||||
case OUTPUT_OPEN: {
|
case OUTPUT_OPEN:{
|
||||||
ret = PipeOpen(context, (char*)argument);
|
ret = PipeOpen(context, (char *) argument);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_CLOSE: {
|
case OUTPUT_CLOSE:{
|
||||||
ret = PipeClose(context, (char*)argument);
|
ret = PipeClose(context, (char *) argument);
|
||||||
reset(context);
|
reset(context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_PLAY: { // 4
|
case OUTPUT_PLAY:{ // 4
|
||||||
ret = PipePlay(context, (char*)argument);
|
ret = PipePlay(context, (char *) argument);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_STOP: {
|
case OUTPUT_STOP:{
|
||||||
reset(context);
|
reset(context);
|
||||||
ret = PipeStop(context, (char*)argument);
|
ret = PipeStop(context, (char *) argument);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_FLUSH: {
|
case OUTPUT_FLUSH:{
|
||||||
ret = PipeFlush(context, (char*)argument);
|
ret = PipeFlush(context, (char *) argument);
|
||||||
reset(context);
|
reset(context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_CLEAR: {
|
case OUTPUT_CLEAR:{
|
||||||
ret = PipeClear(context, (char*)argument);
|
ret = PipeClear(context, (char *) argument);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_SWITCH: {
|
case OUTPUT_SWITCH:{
|
||||||
ret = PipeSwitch(context, (char*)argument);
|
ret = PipeSwitch(context, (char *) argument);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
pipe_err("ContainerCmd %d not supported!\n", command);
|
pipe_err("ContainerCmd %d not supported!\n", command);
|
||||||
ret = cERR_PIPE_ERROR;
|
ret = cERR_PIPE_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe_printf(50, "exiting with value %d\n", ret);
|
pipe_printf(50, "exiting with value %d\n", ret);
|
||||||
|
@@ -81,9 +81,9 @@ Number, Style, Name,, MarginL, MarginR, MarginV, Effect,, Text
|
|||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
struct sub_t {
|
struct sub_t {
|
||||||
char * text;
|
char *text;
|
||||||
unsigned long long int pts;
|
unsigned long long int pts;
|
||||||
unsigned long int milliDuration;
|
unsigned long int milliDuration;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -95,19 +95,19 @@ static pthread_mutex_t mutex;
|
|||||||
|
|
||||||
static pthread_t thread_sub;
|
static pthread_t thread_sub;
|
||||||
|
|
||||||
void* clientData = NULL;
|
void *clientData = NULL;
|
||||||
void (*clientFunction) (long int, size_t, char *, void *);
|
void (*clientFunction) (long int, size_t, char *, void *);
|
||||||
|
|
||||||
static struct sub_t subPuffer[PUFFERSIZE];
|
static struct sub_t subPuffer[PUFFERSIZE];
|
||||||
static int readPointer = 0;
|
static int readPointer = 0;
|
||||||
static int writePointer = 0;
|
static int writePointer = 0;
|
||||||
static int hasThreadStarted = 0;
|
static int hasThreadStarted = 0;
|
||||||
static int isSubtitleOpened = 0;
|
static int isSubtitleOpened = 0;
|
||||||
static int screen_width = 0;
|
static int screen_width = 0;
|
||||||
static int screen_height = 0;
|
static int screen_height = 0;
|
||||||
static int destStride = 0;
|
static int destStride = 0;
|
||||||
static void (*framebufferBlit) = NULL;
|
static void (*framebufferBlit) = NULL;
|
||||||
static uint32_t *destination = NULL;
|
static uint32_t *destination = NULL;
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
@@ -116,7 +116,8 @@ static uint32_t *destination = NULL;
|
|||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* MISC Functions */
|
/* MISC Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
static void getMutex(int line) {
|
static void getMutex(int line)
|
||||||
|
{
|
||||||
subtitle_printf(100, "%d requesting mutex\n", line);
|
subtitle_printf(100, "%d requesting mutex\n", line);
|
||||||
|
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
@@ -124,24 +125,26 @@ static void getMutex(int line) {
|
|||||||
subtitle_printf(100, "%d received mutex\n", line);
|
subtitle_printf(100, "%d received mutex\n", line);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void releaseMutex(int line) {
|
static void releaseMutex(int line)
|
||||||
|
{
|
||||||
pthread_mutex_unlock(&mutex);
|
pthread_mutex_unlock(&mutex);
|
||||||
|
|
||||||
subtitle_printf(100, "%d released mutex\n", line);
|
subtitle_printf(100, "%d released mutex\n", line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void replace_all(char ** string, char * search, char * replace) {
|
void replace_all(char **string, char *search, char *replace)
|
||||||
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
char * ptr = NULL;
|
char *ptr = NULL;
|
||||||
char tempString[512];
|
char tempString[512];
|
||||||
char newString[512];
|
char newString[512];
|
||||||
|
|
||||||
newString[0] = '\0';
|
newString[0] = '\0';
|
||||||
|
|
||||||
if ((string == NULL) || (*string == NULL) || (search == NULL) || (replace == NULL))
|
if ((string == NULL) || (*string == NULL) || (search == NULL)
|
||||||
{
|
|| (replace == NULL)) {
|
||||||
subtitle_err("null pointer passed\n");
|
subtitle_err("null pointer passed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(tempString, *string, 511);
|
strncpy(tempString, *string, 511);
|
||||||
@@ -150,35 +153,35 @@ void replace_all(char ** string, char * search, char * replace) {
|
|||||||
free(*string);
|
free(*string);
|
||||||
|
|
||||||
while ((ptr = strstr(tempString, search)) != NULL) {
|
while ((ptr = strstr(tempString, search)) != NULL) {
|
||||||
len = ptr - tempString;
|
len = ptr - tempString;
|
||||||
strncpy(newString, tempString, len);
|
strncpy(newString, tempString, len);
|
||||||
newString[len] = '\0';
|
newString[len] = '\0';
|
||||||
strcat(newString, replace);
|
strcat(newString, replace);
|
||||||
|
|
||||||
len += strlen(search);
|
len += strlen(search);
|
||||||
strcat(newString, tempString+len);
|
strcat(newString, tempString + len);
|
||||||
|
|
||||||
strcpy(tempString, newString);
|
strcpy(tempString, newString);
|
||||||
}
|
}
|
||||||
|
|
||||||
subtitle_printf(20, "strdup in line %d\n", __LINE__);
|
subtitle_printf(20, "strdup in line %d\n", __LINE__);
|
||||||
|
|
||||||
if(newString[0] != '\0')
|
if (newString[0] != '\0')
|
||||||
*string = strdup(newString);
|
*string = strdup(newString);
|
||||||
else
|
else
|
||||||
*string = strdup(tempString);
|
*string = strdup(tempString);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int subtitle_ParseASS (char **Line) {
|
int subtitle_ParseASS(char **Line)
|
||||||
char* Text;
|
{
|
||||||
int i;
|
char *Text;
|
||||||
char* ptr1;
|
int i;
|
||||||
|
char *ptr1;
|
||||||
|
|
||||||
if ((Line == NULL) || (*Line == NULL))
|
if ((Line == NULL) || (*Line == NULL)) {
|
||||||
{
|
subtitle_err("null pointer passed\n");
|
||||||
subtitle_err("null pointer passed\n");
|
return cERR_SUBTITLE_ERROR;
|
||||||
return cERR_SUBTITLE_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Text = strdup(*Line);
|
Text = strdup(*Line);
|
||||||
@@ -187,12 +190,12 @@ int subtitle_ParseASS (char **Line) {
|
|||||||
|
|
||||||
ptr1 = Text;
|
ptr1 = Text;
|
||||||
|
|
||||||
for (i=0; i < 9 && *ptr1 != '\0'; ptr1++) {
|
for (i = 0; i < 9 && *ptr1 != '\0'; ptr1++) {
|
||||||
|
|
||||||
subtitle_printf(20, "%s",ptr1);
|
subtitle_printf(20, "%s", ptr1);
|
||||||
|
|
||||||
if (*ptr1 == ',')
|
if (*ptr1 == ',')
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(*Line);
|
free(*Line);
|
||||||
@@ -210,12 +213,12 @@ int subtitle_ParseASS (char **Line) {
|
|||||||
return cERR_SUBTITLE_NO_ERROR;
|
return cERR_SUBTITLE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int subtitle_ParseSRT (char **Line) {
|
int subtitle_ParseSRT(char **Line)
|
||||||
|
{
|
||||||
|
|
||||||
if ((Line == NULL) || (*Line == NULL))
|
if ((Line == NULL) || (*Line == NULL)) {
|
||||||
{
|
subtitle_err("null pointer passed\n");
|
||||||
subtitle_err("null pointer passed\n");
|
return cERR_SUBTITLE_ERROR;
|
||||||
return cERR_SUBTITLE_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
subtitle_printf(20, "-> Text=%s\n", *Line);
|
subtitle_printf(20, "-> Text=%s\n", *Line);
|
||||||
@@ -237,12 +240,12 @@ int subtitle_ParseSRT (char **Line) {
|
|||||||
return cERR_SUBTITLE_NO_ERROR;
|
return cERR_SUBTITLE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int subtitle_ParseSSA (char **Line) {
|
int subtitle_ParseSSA(char **Line)
|
||||||
|
{
|
||||||
|
|
||||||
if ((Line == NULL) || (*Line == NULL))
|
if ((Line == NULL) || (*Line == NULL)) {
|
||||||
{
|
subtitle_err("null pointer passed\n");
|
||||||
subtitle_err("null pointer passed\n");
|
return cERR_SUBTITLE_ERROR;
|
||||||
return cERR_SUBTITLE_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
subtitle_printf(20, "-> Text=%s\n", *Line);
|
subtitle_printf(20, "-> Text=%s\n", *Line);
|
||||||
@@ -264,79 +267,76 @@ int subtitle_ParseSSA (char **Line) {
|
|||||||
return cERR_SUBTITLE_NO_ERROR;
|
return cERR_SUBTITLE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addSub(Context_t *context, char * text, unsigned long long int pts, unsigned long int milliDuration) {
|
void addSub(Context_t * context, char *text, unsigned long long int pts,
|
||||||
|
unsigned long int milliDuration)
|
||||||
|
{
|
||||||
int count = 20;
|
int count = 20;
|
||||||
|
|
||||||
subtitle_printf(50, "index %d\n", writePointer);
|
subtitle_printf(50, "index %d\n", writePointer);
|
||||||
|
|
||||||
if(context && context->playback && !context->playback->isPlaying)
|
if (context && context->playback && !context->playback->isPlaying) {
|
||||||
{
|
subtitle_err("1. aborting ->no playback\n");
|
||||||
subtitle_err("1. aborting ->no playback\n");
|
return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text == NULL)
|
if (text == NULL) {
|
||||||
{
|
subtitle_err("null pointer passed\n");
|
||||||
subtitle_err("null pointer passed\n");
|
return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pts == 0)
|
if (pts == 0) {
|
||||||
{
|
subtitle_err("pts 0\n");
|
||||||
subtitle_err("pts 0\n");
|
return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (milliDuration == 0)
|
if (milliDuration == 0) {
|
||||||
{
|
subtitle_err("duration 0\n");
|
||||||
subtitle_err("duration 0\n");
|
return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (subPuffer[writePointer].text != NULL) {
|
while (subPuffer[writePointer].text != NULL) {
|
||||||
//List is full, wait till we got some free space
|
//List is full, wait till we got some free space
|
||||||
|
|
||||||
if(context && context->playback && !context->playback->isPlaying)
|
if (context && context->playback && !context->playback->isPlaying) {
|
||||||
{
|
subtitle_err("2. aborting ->no playback\n");
|
||||||
subtitle_err("2. aborting ->no playback\n");
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* konfetti: we dont want to block forever here. if no buffer
|
/* konfetti: we dont want to block forever here. if no buffer
|
||||||
* is available we start ring from the beginning and loose some stuff
|
* is available we start ring from the beginning and loose some stuff
|
||||||
* which is acceptable!
|
* which is acceptable!
|
||||||
*/
|
*/
|
||||||
subtitle_printf(10, "waiting on free buffer %d - %d (%d) ...\n", writePointer, readPointer, count);
|
subtitle_printf(10, "waiting on free buffer %d - %d (%d) ...\n",
|
||||||
usleep(10000);
|
writePointer, readPointer, count);
|
||||||
count--;
|
usleep(10000);
|
||||||
|
count--;
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0) {
|
||||||
{
|
subtitle_err("abort waiting on buffer...\n");
|
||||||
subtitle_err("abort waiting on buffer...\n");
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
subtitle_printf(20, "from mkv: %s pts:%lld milliDuration:%lud\n",text,pts,milliDuration);
|
subtitle_printf(20, "from mkv: %s pts:%lld milliDuration:%lud\n", text,
|
||||||
|
pts, milliDuration);
|
||||||
|
|
||||||
getMutex(__LINE__);
|
getMutex(__LINE__);
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0) {
|
||||||
{
|
int i;
|
||||||
int i;
|
subtitle_err("freeing not delivered data\n");
|
||||||
subtitle_err("freeing not delivered data\n");
|
|
||||||
|
|
||||||
//Reset all
|
//Reset all
|
||||||
readPointer = 0;
|
readPointer = 0;
|
||||||
writePointer = 0;
|
writePointer = 0;
|
||||||
|
|
||||||
for (i = 0; i < PUFFERSIZE; i++) {
|
for (i = 0; i < PUFFERSIZE; i++) {
|
||||||
if (subPuffer[i].text != NULL)
|
if (subPuffer[i].text != NULL)
|
||||||
free(subPuffer[i].text);
|
free(subPuffer[i].text);
|
||||||
subPuffer[i].text = NULL;
|
subPuffer[i].text = NULL;
|
||||||
subPuffer[i].pts = 0;
|
subPuffer[i].pts = 0;
|
||||||
subPuffer[i].milliDuration = 0;
|
subPuffer[i].milliDuration = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
subPuffer[writePointer].text = strdup(text);
|
subPuffer[writePointer].text = strdup(text);
|
||||||
@@ -346,15 +346,14 @@ void addSub(Context_t *context, char * text, unsigned long long int pts, unsign
|
|||||||
writePointer++;
|
writePointer++;
|
||||||
|
|
||||||
if (writePointer == PUFFERSIZE)
|
if (writePointer == PUFFERSIZE)
|
||||||
writePointer = 0;
|
writePointer = 0;
|
||||||
|
|
||||||
if (writePointer == readPointer)
|
if (writePointer == readPointer) {
|
||||||
{
|
/* this should not happen, and means that there is nor reader or
|
||||||
/* this should not happen, and means that there is nor reader or
|
* the reader has performance probs ;)
|
||||||
* the reader has performance probs ;)
|
* the recovery is done at startup of this function - but next time
|
||||||
* the recovery is done at startup of this function - but next time
|
*/
|
||||||
*/
|
subtitle_err("ups something went wrong. no more readers? \n");
|
||||||
subtitle_err("ups something went wrong. no more readers? \n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseMutex(__LINE__);
|
releaseMutex(__LINE__);
|
||||||
@@ -362,26 +361,26 @@ void addSub(Context_t *context, char * text, unsigned long long int pts, unsign
|
|||||||
subtitle_printf(10, "<\n");
|
subtitle_printf(10, "<\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int getNextSub(char ** text, unsigned long long int * pts, long int * milliDuration) {
|
int getNextSub(char **text, unsigned long long int *pts,
|
||||||
|
long int *milliDuration)
|
||||||
|
{
|
||||||
|
|
||||||
subtitle_printf(50, "index %d\n", readPointer);
|
subtitle_printf(50, "index %d\n", readPointer);
|
||||||
|
|
||||||
if (text == NULL)
|
if (text == NULL) {
|
||||||
{
|
subtitle_err("null pointer passed\n");
|
||||||
subtitle_err("null pointer passed\n");
|
return cERR_SUBTITLE_ERROR;
|
||||||
return cERR_SUBTITLE_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getMutex(__LINE__);
|
getMutex(__LINE__);
|
||||||
|
|
||||||
if (subPuffer[readPointer].text == NULL)
|
if (subPuffer[readPointer].text == NULL) {
|
||||||
{
|
/* this is acutally not an error, because it may happen
|
||||||
/* this is acutally not an error, because it may happen
|
* that there is no subtitle for a while
|
||||||
* that there is no subtitle for a while
|
*/
|
||||||
*/
|
subtitle_printf(200, "null in subPuffer\n");
|
||||||
subtitle_printf(200, "null in subPuffer\n");
|
releaseMutex(__LINE__);
|
||||||
releaseMutex(__LINE__);
|
return cERR_SUBTITLE_ERROR;
|
||||||
return cERR_SUBTITLE_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*text = strdup(subPuffer[readPointer].text);
|
*text = strdup(subPuffer[readPointer].text);
|
||||||
@@ -397,20 +396,20 @@ int getNextSub(char ** text, unsigned long long int * pts, long int * milliDurat
|
|||||||
readPointer++;
|
readPointer++;
|
||||||
|
|
||||||
if (readPointer == PUFFERSIZE)
|
if (readPointer == PUFFERSIZE)
|
||||||
readPointer = 0;
|
readPointer = 0;
|
||||||
|
|
||||||
if (writePointer == readPointer)
|
if (writePointer == readPointer) {
|
||||||
{
|
/* this may happen, in normal case the reader is ones ahead the
|
||||||
/* this may happen, in normal case the reader is ones ahead the
|
* writer. So this is the normal case that we eat the data
|
||||||
* writer. So this is the normal case that we eat the data
|
* and have the reader reached.
|
||||||
* and have the reader reached.
|
*/
|
||||||
*/
|
subtitle_printf(20,
|
||||||
subtitle_printf(20, "ups something went wrong. no more writers? \n");
|
"ups something went wrong. no more writers? \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseMutex(__LINE__);
|
releaseMutex(__LINE__);
|
||||||
|
|
||||||
subtitle_printf(20, "readPointer %d\n",readPointer);
|
subtitle_printf(20, "readPointer %d\n", readPointer);
|
||||||
subtitle_printf(10, "<\n");
|
subtitle_printf(10, "<\n");
|
||||||
|
|
||||||
return cERR_SUBTITLE_NO_ERROR;
|
return cERR_SUBTITLE_NO_ERROR;
|
||||||
@@ -420,93 +419,98 @@ int getNextSub(char ** text, unsigned long long int * pts, long int * milliDurat
|
|||||||
/* Worker Thread */
|
/* Worker Thread */
|
||||||
/* **************************** */
|
/* **************************** */
|
||||||
|
|
||||||
static void* SubtitleThread(void* data) {
|
static void *SubtitleThread(void *data)
|
||||||
Context_t *context = (Context_t*) data;
|
{
|
||||||
char * subText = NULL;
|
Context_t *context = (Context_t *) data;
|
||||||
long int subMilliDuration = 0;
|
char *subText = NULL;
|
||||||
unsigned long long int subPts = 0;
|
long int subMilliDuration = 0;
|
||||||
unsigned long long int Pts = 0;
|
unsigned long long int subPts = 0;
|
||||||
|
unsigned long long int Pts = 0;
|
||||||
|
|
||||||
subtitle_printf(10, "\n");
|
subtitle_printf(10, "\n");
|
||||||
|
|
||||||
while ( context->playback->isCreationPhase ) {
|
while (context->playback->isCreationPhase) {
|
||||||
subtitle_err("Thread waiting for end of init phase...\n");
|
subtitle_err("Thread waiting for end of init phase...\n");
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
subtitle_printf(10, "done\n");
|
subtitle_printf(10, "done\n");
|
||||||
|
|
||||||
while ( context &&
|
while (context && context->playback && context->playback->isPlaying) {
|
||||||
context->playback &&
|
|
||||||
context->playback->isPlaying) {
|
|
||||||
|
|
||||||
int curtrackid = -1;
|
int curtrackid = -1;
|
||||||
|
|
||||||
if (context && context->manager && context->manager->subtitle)
|
if (context && context->manager && context->manager->subtitle)
|
||||||
context->manager->subtitle->Command(context, MANAGER_GET, &curtrackid);
|
context->manager->subtitle->Command(context, MANAGER_GET,
|
||||||
|
&curtrackid);
|
||||||
|
|
||||||
subtitle_printf(50, "curtrackid %d\n", curtrackid);
|
subtitle_printf(50, "curtrackid %d\n", curtrackid);
|
||||||
|
|
||||||
if (curtrackid >= 0) {
|
if (curtrackid >= 0) {
|
||||||
if (getNextSub(&subText, &subPts, &subMilliDuration) != 0) {
|
if (getNextSub(&subText, &subPts, &subMilliDuration) != 0) {
|
||||||
usleep(500000);
|
usleep(500000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context && context->playback)
|
if (context && context->playback)
|
||||||
context->playback->Command(context, PLAYBACK_PTS, &Pts);
|
context->playback->Command(context, PLAYBACK_PTS, &Pts);
|
||||||
else return NULL;
|
else
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if(Pts > subPts) {
|
if (Pts > subPts) {
|
||||||
subtitle_printf(10,"subtitle is to late, ignoring\n");
|
subtitle_printf(10, "subtitle is to late, ignoring\n");
|
||||||
if(subText != NULL)
|
if (subText != NULL)
|
||||||
free(subText);
|
free(subText);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
subtitle_printf(20, "Pts:%llu < subPts%llu duration %ld\n", Pts, subPts,subMilliDuration);
|
subtitle_printf(20, "Pts:%llu < subPts%llu duration %ld\n",
|
||||||
|
Pts, subPts, subMilliDuration);
|
||||||
|
|
||||||
while ( context &&
|
while (context &&
|
||||||
context->playback &&
|
context->playback &&
|
||||||
context->playback->isPlaying &&
|
context->playback->isPlaying && Pts < subPts) {
|
||||||
Pts < subPts) {
|
|
||||||
|
|
||||||
unsigned long int diff = subPts - Pts;
|
unsigned long int diff = subPts - Pts;
|
||||||
diff = (diff*1000)/90.0;
|
diff = (diff * 1000) / 90.0;
|
||||||
|
|
||||||
subtitle_printf(50, "DIFF: %lud\n", diff);
|
subtitle_printf(50, "DIFF: %lud\n", diff);
|
||||||
|
|
||||||
if(diff > 100)
|
if (diff > 100)
|
||||||
usleep(diff);
|
usleep(diff);
|
||||||
|
|
||||||
if (context && context->playback)
|
if (context && context->playback)
|
||||||
context->playback->Command(context, PLAYBACK_PTS, &Pts);
|
context->playback->Command(context, PLAYBACK_PTS,
|
||||||
else
|
&Pts);
|
||||||
{
|
else {
|
||||||
subtitle_err("no playback ? terminated?\n");
|
subtitle_err("no playback ? terminated?\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
subtitle_printf(20, "cur: %llu wanted: %llu\n", Pts, subPts);
|
subtitle_printf(20, "cur: %llu wanted: %llu\n", Pts,
|
||||||
}
|
subPts);
|
||||||
|
}
|
||||||
|
|
||||||
if ( context &&
|
if (context &&
|
||||||
context->playback &&
|
context->playback &&
|
||||||
context->playback->isPlaying &&
|
context->playback->isPlaying && subText != NULL) {
|
||||||
subText != NULL ) {
|
|
||||||
|
|
||||||
if(clientFunction != NULL)
|
if (clientFunction != NULL)
|
||||||
clientFunction(subMilliDuration, strlen(subText), subText, clientData);
|
clientFunction(subMilliDuration, strlen(subText),
|
||||||
else
|
subText, clientData);
|
||||||
subtitle_printf(10, "writing Sub failed (%ld) (%d) \"%s\"\n", subMilliDuration, strlen(subText), subText);
|
else
|
||||||
|
subtitle_printf(10,
|
||||||
|
"writing Sub failed (%ld) (%d) \"%s\"\n",
|
||||||
|
subMilliDuration, strlen(subText),
|
||||||
|
subText);
|
||||||
|
|
||||||
free(subText);
|
free(subText);
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* trackID >= 0 */
|
} /* trackID >= 0 */
|
||||||
else //Wait
|
else //Wait
|
||||||
usleep(500000);
|
usleep(500000);
|
||||||
|
|
||||||
} /* outer while */
|
} /* outer while */
|
||||||
|
|
||||||
subtitle_printf(0, "has ended\n");
|
subtitle_printf(0, "has ended\n");
|
||||||
|
|
||||||
@@ -519,71 +523,69 @@ static void* SubtitleThread(void* data) {
|
|||||||
/* Functions */
|
/* Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static int Write(void* _context, void *data) {
|
static int Write(void *_context, void *data)
|
||||||
Context_t * context = (Context_t *) _context;
|
{
|
||||||
char * Encoding = NULL;
|
Context_t *context = (Context_t *) _context;
|
||||||
char * Text;
|
char *Encoding = NULL;
|
||||||
SubtitleOut_t * out;
|
char *Text;
|
||||||
|
SubtitleOut_t *out;
|
||||||
int DataLength;
|
int DataLength;
|
||||||
unsigned long long int Pts;
|
unsigned long long int Pts;
|
||||||
float Duration;
|
float Duration;
|
||||||
|
|
||||||
subtitle_printf(10, "\n");
|
subtitle_printf(10, "\n");
|
||||||
|
|
||||||
if (data == NULL)
|
if (data == NULL) {
|
||||||
{
|
subtitle_err("null pointer passed\n");
|
||||||
subtitle_err("null pointer passed\n");
|
return cERR_SUBTITLE_ERROR;
|
||||||
return cERR_SUBTITLE_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out = (SubtitleOut_t*) data;
|
out = (SubtitleOut_t *) data;
|
||||||
|
|
||||||
if (out->type == eSub_Txt)
|
if (out->type == eSub_Txt) {
|
||||||
{
|
Text = strdup((const char *) out->u.text.data);
|
||||||
Text = strdup((const char*) out->u.text.data);
|
} else {
|
||||||
} else
|
|
||||||
{
|
|
||||||
/* fixme handle gfx subs from container_ass and send it to
|
/* fixme handle gfx subs from container_ass and send it to
|
||||||
* the callback. this must be implemented also in e2/neutrino
|
* the callback. this must be implemented also in e2/neutrino
|
||||||
* then.
|
* then.
|
||||||
*/
|
*/
|
||||||
subtitle_err("subtitle gfx currently not handled\n");
|
subtitle_err("subtitle gfx currently not handled\n");
|
||||||
return cERR_SUBTITLE_ERROR;
|
return cERR_SUBTITLE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataLength = out->u.text.len;
|
DataLength = out->u.text.len;
|
||||||
Pts = out->pts;
|
Pts = out->pts;
|
||||||
Duration = out->duration;
|
Duration = out->duration;
|
||||||
|
|
||||||
context->manager->subtitle->Command(context, MANAGER_GETENCODING, &Encoding);
|
context->manager->subtitle->Command(context, MANAGER_GETENCODING,
|
||||||
|
&Encoding);
|
||||||
|
|
||||||
if (Encoding == NULL)
|
if (Encoding == NULL) {
|
||||||
{
|
subtitle_err("encoding unknown\n");
|
||||||
subtitle_err("encoding unknown\n");
|
free(Text);
|
||||||
free(Text);
|
return cERR_SUBTITLE_ERROR;
|
||||||
return cERR_SUBTITLE_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
subtitle_printf(20, "Encoding:%s Text:%s Len:%d\n", Encoding,Text, DataLength);
|
subtitle_printf(20, "Encoding:%s Text:%s Len:%d\n", Encoding, Text,
|
||||||
|
DataLength);
|
||||||
|
|
||||||
if ( !strncmp("S_TEXT/SSA", Encoding, 10) ||
|
if (!strncmp("S_TEXT/SSA", Encoding, 10) ||
|
||||||
!strncmp("S_SSA", Encoding, 5))
|
!strncmp("S_SSA", Encoding, 5))
|
||||||
subtitle_ParseSSA(&Text);
|
subtitle_ParseSSA(&Text);
|
||||||
|
|
||||||
else if(!strncmp("S_TEXT/ASS", Encoding, 10) ||
|
else if (!strncmp("S_TEXT/ASS", Encoding, 10) ||
|
||||||
!strncmp("S_AAS", Encoding, 5))
|
!strncmp("S_AAS", Encoding, 5))
|
||||||
subtitle_ParseASS(&Text);
|
subtitle_ParseASS(&Text);
|
||||||
|
|
||||||
else if(!strncmp("S_TEXT/SRT", Encoding, 10) ||
|
else if (!strncmp("S_TEXT/SRT", Encoding, 10) ||
|
||||||
!strncmp("S_SRT", Encoding, 5))
|
!strncmp("S_SRT", Encoding, 5))
|
||||||
subtitle_ParseSRT(&Text);
|
subtitle_ParseSRT(&Text);
|
||||||
else
|
else {
|
||||||
{
|
subtitle_err("unknown encoding %s\n", Encoding);
|
||||||
subtitle_err("unknown encoding %s\n", Encoding);
|
return cERR_SUBTITLE_ERROR;
|
||||||
return cERR_SUBTITLE_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
subtitle_printf(10, "Text:%s Duration:%f\n", Text,Duration);
|
subtitle_printf(10, "Text:%s Duration:%f\n", Text, Duration);
|
||||||
|
|
||||||
addSub(context, Text, Pts, Duration * 1000);
|
addSub(context, Text, Pts, Duration * 1000);
|
||||||
|
|
||||||
@@ -595,15 +597,15 @@ static int Write(void* _context, void *data) {
|
|||||||
return cERR_SUBTITLE_NO_ERROR;
|
return cERR_SUBTITLE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int subtitle_Open(Context_t* context __attribute__((unused))) {
|
static int subtitle_Open(Context_t * context __attribute__ ((unused)))
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
subtitle_printf(10, "\n");
|
subtitle_printf(10, "\n");
|
||||||
|
|
||||||
if (isSubtitleOpened == 1)
|
if (isSubtitleOpened == 1) {
|
||||||
{
|
subtitle_err("already opened! ignoring\n");
|
||||||
subtitle_err("already opened! ignoring\n");
|
return cERR_SUBTITLE_ERROR;
|
||||||
return cERR_SUBTITLE_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getMutex(__LINE__);
|
getMutex(__LINE__);
|
||||||
@@ -613,9 +615,9 @@ static int subtitle_Open(Context_t* context __attribute__((unused))) {
|
|||||||
writePointer = 0;
|
writePointer = 0;
|
||||||
|
|
||||||
for (i = 0; i < PUFFERSIZE; i++) {
|
for (i = 0; i < PUFFERSIZE; i++) {
|
||||||
subPuffer[i].text = NULL;
|
subPuffer[i].text = NULL;
|
||||||
subPuffer[i].pts = 0;
|
subPuffer[i].pts = 0;
|
||||||
subPuffer[i].milliDuration = 0;
|
subPuffer[i].milliDuration = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
isSubtitleOpened = 1;
|
isSubtitleOpened = 1;
|
||||||
@@ -627,7 +629,8 @@ static int subtitle_Open(Context_t* context __attribute__((unused))) {
|
|||||||
return cERR_SUBTITLE_NO_ERROR;
|
return cERR_SUBTITLE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int subtitle_Close(Context_t* context __attribute__((unused))) {
|
static int subtitle_Close(Context_t * context __attribute__ ((unused)))
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
subtitle_printf(10, "\n");
|
subtitle_printf(10, "\n");
|
||||||
@@ -639,12 +642,12 @@ static int subtitle_Close(Context_t* context __attribute__((unused))) {
|
|||||||
writePointer = 0;
|
writePointer = 0;
|
||||||
|
|
||||||
for (i = 0; i < PUFFERSIZE; i++) {
|
for (i = 0; i < PUFFERSIZE; i++) {
|
||||||
if (subPuffer[i].text != NULL)
|
if (subPuffer[i].text != NULL)
|
||||||
free(subPuffer[i].text);
|
free(subPuffer[i].text);
|
||||||
|
|
||||||
subPuffer[i].text = NULL;
|
subPuffer[i].text = NULL;
|
||||||
subPuffer[i].pts = 0;
|
subPuffer[i].pts = 0;
|
||||||
subPuffer[i].milliDuration = 0;
|
subPuffer[i].milliDuration = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
isSubtitleOpened = 0;
|
isSubtitleOpened = 0;
|
||||||
@@ -656,31 +659,28 @@ static int subtitle_Close(Context_t* context __attribute__((unused))) {
|
|||||||
return cERR_SUBTITLE_NO_ERROR;
|
return cERR_SUBTITLE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int subtitle_Play(Context_t* context) {
|
static int subtitle_Play(Context_t * context)
|
||||||
|
{
|
||||||
subtitle_printf(10, "\n");
|
subtitle_printf(10, "\n");
|
||||||
|
|
||||||
if (hasThreadStarted == 0)
|
if (hasThreadStarted == 0) {
|
||||||
{
|
pthread_attr_t attr;
|
||||||
pthread_attr_t attr;
|
|
||||||
|
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
|
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
|
||||||
if (pthread_create (&thread_sub, &attr, &SubtitleThread, (void*) context) != 0)
|
if (pthread_create
|
||||||
{
|
(&thread_sub, &attr, &SubtitleThread, (void *) context) != 0) {
|
||||||
subtitle_err("Error creating thread\n");
|
subtitle_err("Error creating thread\n");
|
||||||
hasThreadStarted = 0;
|
hasThreadStarted = 0;
|
||||||
} else
|
} else {
|
||||||
{
|
subtitle_printf(10, "Created thread\n");
|
||||||
subtitle_printf(10, "Created thread\n");
|
hasThreadStarted = 1;
|
||||||
hasThreadStarted = 1;
|
}
|
||||||
}
|
} else {
|
||||||
}
|
subtitle_err("thread already created.\n");
|
||||||
else
|
return cERR_SUBTITLE_ERROR;
|
||||||
{
|
|
||||||
subtitle_err("thread already created.\n");
|
|
||||||
return cERR_SUBTITLE_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
subtitle_printf(10, "<\n");
|
subtitle_printf(10, "<\n");
|
||||||
@@ -688,21 +688,24 @@ static int subtitle_Play(Context_t* context) {
|
|||||||
return cERR_SUBTITLE_NO_ERROR;
|
return cERR_SUBTITLE_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int subtitle_Stop(Context_t* context __attribute__((unused))) {
|
static int subtitle_Stop(Context_t * context __attribute__ ((unused)))
|
||||||
|
{
|
||||||
int wait_time = 20;
|
int wait_time = 20;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
subtitle_printf(10, "\n");
|
subtitle_printf(10, "\n");
|
||||||
|
|
||||||
while ( (hasThreadStarted != 0) && (--wait_time) > 0 ) {
|
while ((hasThreadStarted != 0) && (--wait_time) > 0) {
|
||||||
subtitle_printf(10, "Waiting for subtitle thread to terminate itself, will try another %d times\n", wait_time);
|
subtitle_printf(10,
|
||||||
usleep(100000);
|
"Waiting for subtitle thread to terminate itself, will try another %d times\n",
|
||||||
|
wait_time);
|
||||||
|
usleep(100000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait_time == 0) {
|
if (wait_time == 0) {
|
||||||
subtitle_err("Timeout waiting for thread!\n");
|
subtitle_err("Timeout waiting for thread!\n");
|
||||||
|
|
||||||
return cERR_SUBTITLE_ERROR;
|
return cERR_SUBTITLE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasThreadStarted = 0;
|
hasThreadStarted = 0;
|
||||||
@@ -718,12 +721,12 @@ static int subtitle_Stop(Context_t* context __attribute__((unused))) {
|
|||||||
writePointer = 0;
|
writePointer = 0;
|
||||||
|
|
||||||
for (i = 0; i < PUFFERSIZE; i++) {
|
for (i = 0; i < PUFFERSIZE; i++) {
|
||||||
if (subPuffer[i].text != NULL)
|
if (subPuffer[i].text != NULL)
|
||||||
free(subPuffer[i].text);
|
free(subPuffer[i].text);
|
||||||
|
|
||||||
subPuffer[i].text = NULL;
|
subPuffer[i].text = NULL;
|
||||||
subPuffer[i].pts = 0;
|
subPuffer[i].pts = 0;
|
||||||
subPuffer[i].milliDuration = 0;
|
subPuffer[i].milliDuration = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseMutex(__LINE__);
|
releaseMutex(__LINE__);
|
||||||
@@ -740,87 +743,88 @@ void subtitle_SignalConnect(void (*fkt) (long int, size_t, char *, void *))
|
|||||||
clientFunction = fkt;
|
clientFunction = fkt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void subtitle_SignalConnectBuffer(void* data)
|
void subtitle_SignalConnectBuffer(void *data)
|
||||||
{
|
{
|
||||||
subtitle_printf(10, "%p\n", data);
|
subtitle_printf(10, "%p\n", data);
|
||||||
|
|
||||||
clientData = data;
|
clientData = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Command(void *_context, OutputCmd_t command, void * argument) {
|
static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||||
Context_t *context = (Context_t*) _context;
|
{
|
||||||
|
Context_t *context = (Context_t *) _context;
|
||||||
int ret = cERR_SUBTITLE_NO_ERROR;
|
int ret = cERR_SUBTITLE_NO_ERROR;
|
||||||
|
|
||||||
subtitle_printf(50, "%d\n", command);
|
subtitle_printf(50, "%d\n", command);
|
||||||
|
|
||||||
switch(command) {
|
switch (command) {
|
||||||
case OUTPUT_OPEN: {
|
case OUTPUT_OPEN:{
|
||||||
ret = subtitle_Open(context);
|
ret = subtitle_Open(context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_CLOSE: {
|
case OUTPUT_CLOSE:{
|
||||||
ret = subtitle_Close(context);
|
ret = subtitle_Close(context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_PLAY: {
|
case OUTPUT_PLAY:{
|
||||||
ret = subtitle_Play(context);
|
ret = subtitle_Play(context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_STOP: {
|
case OUTPUT_STOP:{
|
||||||
ret = subtitle_Stop(context);
|
ret = subtitle_Stop(context);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_SWITCH: {
|
case OUTPUT_SWITCH:{
|
||||||
subtitle_err("Subtitle Switch not implemented\n");
|
subtitle_err("Subtitle Switch not implemented\n");
|
||||||
ret = cERR_SUBTITLE_ERROR;
|
ret = cERR_SUBTITLE_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_GET_SUBTITLE_OUTPUT: {
|
case OUTPUT_GET_SUBTITLE_OUTPUT:{
|
||||||
SubtitleOutputDef_t* out = (SubtitleOutputDef_t*)argument;
|
SubtitleOutputDef_t *out = (SubtitleOutputDef_t *) argument;
|
||||||
out->screen_width = screen_width;
|
out->screen_width = screen_width;
|
||||||
out->screen_height = screen_height;
|
out->screen_height = screen_height;
|
||||||
out->framebufferBlit = framebufferBlit;
|
out->framebufferBlit = framebufferBlit;
|
||||||
out->destination = destination;
|
out->destination = destination;
|
||||||
out->destStride = destStride;
|
out->destStride = destStride;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_SET_SUBTITLE_OUTPUT: {
|
case OUTPUT_SET_SUBTITLE_OUTPUT:{
|
||||||
SubtitleOutputDef_t* out = (SubtitleOutputDef_t*)argument;
|
SubtitleOutputDef_t *out = (SubtitleOutputDef_t *) argument;
|
||||||
screen_width = out->screen_width;
|
screen_width = out->screen_width;
|
||||||
screen_height = out->screen_height;
|
screen_height = out->screen_height;
|
||||||
framebufferBlit = out->framebufferBlit;
|
framebufferBlit = out->framebufferBlit;
|
||||||
destination = out->destination;
|
destination = out->destination;
|
||||||
destStride = out->destStride;
|
destStride = out->destStride;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_SUBTITLE_REGISTER_FUNCTION: {
|
case OUTPUT_SUBTITLE_REGISTER_FUNCTION:{
|
||||||
subtitle_SignalConnect(argument);
|
subtitle_SignalConnect(argument);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_SUBTITLE_REGISTER_BUFFER: {
|
case OUTPUT_SUBTITLE_REGISTER_BUFFER:{
|
||||||
subtitle_SignalConnectBuffer(argument);
|
subtitle_SignalConnectBuffer(argument);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_FLUSH: {
|
case OUTPUT_FLUSH:{
|
||||||
subtitle_err("Subtitle Flush not implemented\n");
|
subtitle_err("Subtitle Flush not implemented\n");
|
||||||
ret = cERR_SUBTITLE_ERROR;
|
ret = cERR_SUBTITLE_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_PAUSE: {
|
case OUTPUT_PAUSE:{
|
||||||
subtitle_err("Subtitle Pause not implemented\n");
|
subtitle_err("Subtitle Pause not implemented\n");
|
||||||
ret = cERR_SUBTITLE_ERROR;
|
ret = cERR_SUBTITLE_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OUTPUT_CONTINUE: {
|
case OUTPUT_CONTINUE:{
|
||||||
subtitle_err("Subtitle Continue not implemented\n");
|
subtitle_err("Subtitle Continue not implemented\n");
|
||||||
ret = cERR_SUBTITLE_ERROR;
|
ret = cERR_SUBTITLE_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
subtitle_err("OutputCmd %d not supported!\n", command);
|
subtitle_err("OutputCmd %d not supported!\n", command);
|
||||||
ret = cERR_SUBTITLE_ERROR;
|
ret = cERR_SUBTITLE_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
subtitle_printf(50, "exiting with value %d\n", ret);
|
subtitle_printf(50, "exiting with value %d\n", ret);
|
||||||
|
@@ -189,11 +189,12 @@ else
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static unsigned char DefaultAACHeader[] = {
|
static unsigned char DefaultAACHeader[] = {
|
||||||
0xff,
|
0xff,
|
||||||
0xf1,
|
0xf1,
|
||||||
/*0x00, 0x00*/0x50, //((Profile & 0x03) << 6) | (SampleIndex << 2) | ((Channels >> 2) & 0x01);s
|
/*0x00, 0x00 */ 0x50,
|
||||||
0x80, //(Channels & 0x03) << 6;
|
//((Profile & 0x03) << 6) | (SampleIndex << 2) | ((Channels >> 2) & 0x01);s
|
||||||
|
0x80, //(Channels & 0x03) << 6;
|
||||||
0x00,
|
0x00,
|
||||||
0x1f,
|
0x1f,
|
||||||
0xfc
|
0xfc
|
||||||
@@ -211,51 +212,48 @@ static int reset()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writeData(void* _call)
|
static int writeData(void *_call)
|
||||||
{
|
{
|
||||||
WriterAVCallData_t* call = (WriterAVCallData_t*) _call;
|
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||||
|
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
unsigned char ExtraData[AAC_HEADER_LENGTH];
|
unsigned char ExtraData[AAC_HEADER_LENGTH];
|
||||||
unsigned int PacketLength;
|
unsigned int PacketLength;
|
||||||
|
|
||||||
aac_printf(10, "\n");
|
aac_printf(10, "\n");
|
||||||
|
|
||||||
if (call == NULL)
|
if (call == NULL) {
|
||||||
{
|
aac_err("call data is NULL...\n");
|
||||||
aac_err("call data is NULL...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aac_printf(10, "AudioPts %lld\n", call->Pts);
|
aac_printf(10, "AudioPts %lld\n", call->Pts);
|
||||||
|
|
||||||
PacketLength = call->len + AAC_HEADER_LENGTH;
|
PacketLength = call->len + AAC_HEADER_LENGTH;
|
||||||
|
|
||||||
if ((call->data == NULL) || (call->len <= 0))
|
if ((call->data == NULL) || (call->len <= 0)) {
|
||||||
{
|
aac_err("parsing NULL Data. ignoring...\n");
|
||||||
aac_err("parsing NULL Data. ignoring...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call->fd < 0)
|
if (call->fd < 0) {
|
||||||
{
|
aac_err("file pointer < 0. ignoring ...\n");
|
||||||
aac_err("file pointer < 0. ignoring ...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call->private_data == NULL)
|
if (call->private_data == NULL) {
|
||||||
{
|
aac_printf(10, "private_data = NULL\n");
|
||||||
aac_printf(10, "private_data = NULL\n");
|
memcpy(ExtraData, DefaultAACHeader, AAC_HEADER_LENGTH);
|
||||||
memcpy (ExtraData, DefaultAACHeader, AAC_HEADER_LENGTH);
|
} else
|
||||||
}
|
memcpy(ExtraData, call->private_data, AAC_HEADER_LENGTH);
|
||||||
else
|
|
||||||
memcpy (ExtraData, call->private_data, AAC_HEADER_LENGTH);
|
|
||||||
|
|
||||||
ExtraData[3] |= (PacketLength >> 11) & 0x3;
|
ExtraData[3] |= (PacketLength >> 11) & 0x3;
|
||||||
ExtraData[4] = (PacketLength >> 3) & 0xff;
|
ExtraData[4] = (PacketLength >> 3) & 0xff;
|
||||||
ExtraData[5] |= (PacketLength << 5) & 0xe0;
|
ExtraData[5] |= (PacketLength << 5) & 0xe0;
|
||||||
|
|
||||||
unsigned int HeaderLength = InsertPesHeader (PesHeader, PacketLength, AAC_AUDIO_PES_START_CODE, call->Pts, 0);
|
unsigned int HeaderLength =
|
||||||
|
InsertPesHeader(PesHeader, PacketLength, AAC_AUDIO_PES_START_CODE,
|
||||||
|
call->Pts, 0);
|
||||||
|
|
||||||
struct iovec iov[3];
|
struct iovec iov[3];
|
||||||
iov[0].iov_base = PesHeader;
|
iov[0].iov_base = PesHeader;
|
||||||
|
@@ -91,38 +91,37 @@ static int reset()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writeData(void* _call)
|
static int writeData(void *_call)
|
||||||
{
|
{
|
||||||
WriterAVCallData_t* call = (WriterAVCallData_t*) _call;
|
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||||
|
|
||||||
ac3_printf(10, "\n");
|
ac3_printf(10, "\n");
|
||||||
|
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
|
|
||||||
if (call == NULL)
|
if (call == NULL) {
|
||||||
{
|
ac3_err("call data is NULL...\n");
|
||||||
ac3_err("call data is NULL...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ac3_printf(10, "AudioPts %lld\n", call->Pts);
|
ac3_printf(10, "AudioPts %lld\n", call->Pts);
|
||||||
|
|
||||||
if ((call->data == NULL) || (call->len <= 0))
|
if ((call->data == NULL) || (call->len <= 0)) {
|
||||||
{
|
ac3_err("parsing NULL Data. ignoring...\n");
|
||||||
ac3_err("parsing NULL Data. ignoring...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call->fd < 0)
|
if (call->fd < 0) {
|
||||||
{
|
ac3_err("file pointer < 0. ignoring ...\n");
|
||||||
ac3_err("file pointer < 0. ignoring ...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
|
|
||||||
iov[0].iov_base = PesHeader;
|
iov[0].iov_base = PesHeader;
|
||||||
iov[0].iov_len = InsertPesHeader (PesHeader, call->len, PRIVATE_STREAM_1_PES_START_CODE, call->Pts, 0);
|
iov[0].iov_len =
|
||||||
|
InsertPesHeader(PesHeader, call->len,
|
||||||
|
PRIVATE_STREAM_1_PES_START_CODE, call->Pts, 0);
|
||||||
iov[1].iov_base = call->data;
|
iov[1].iov_base = call->data;
|
||||||
iov[1].iov_len = call->len;
|
iov[1].iov_len = call->len;
|
||||||
|
|
||||||
|
@@ -91,36 +91,34 @@ static int reset()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writeData(void* _call)
|
static int writeData(void *_call)
|
||||||
{
|
{
|
||||||
WriterAVCallData_t* call = (WriterAVCallData_t*) _call;
|
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||||
|
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
unsigned char FakeHeaders[64]; // 64bytes should be enough to make the fake headers
|
unsigned char FakeHeaders[64]; // 64bytes should be enough to make the fake headers
|
||||||
unsigned int FakeHeaderLength;
|
unsigned int FakeHeaderLength;
|
||||||
unsigned char Version = 5;
|
unsigned char Version = 5;
|
||||||
unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE;
|
unsigned int FakeStartCode =
|
||||||
unsigned int usecPerFrame = 41708; /* Hellmaster1024: default value */
|
(Version << 8) | PES_VERSION_FAKE_START_CODE;
|
||||||
BitPacker_t ld = {FakeHeaders, 0, 32};
|
unsigned int usecPerFrame = 41708; /* Hellmaster1024: default value */
|
||||||
|
BitPacker_t ld = { FakeHeaders, 0, 32 };
|
||||||
|
|
||||||
divx_printf(10, "\n");
|
divx_printf(10, "\n");
|
||||||
|
|
||||||
if (call == NULL)
|
if (call == NULL) {
|
||||||
{
|
divx_err("call data is NULL...\n");
|
||||||
divx_err("call data is NULL...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((call->data == NULL) || (call->len <= 0))
|
if ((call->data == NULL) || (call->len <= 0)) {
|
||||||
{
|
divx_err("parsing NULL Data. ignoring...\n");
|
||||||
divx_err("parsing NULL Data. ignoring...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call->fd < 0)
|
if (call->fd < 0) {
|
||||||
{
|
divx_err("file pointer < 0. ignoring ...\n");
|
||||||
divx_err("file pointer < 0. ignoring ...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
divx_printf(10, "AudioPts %lld\n", call->Pts);
|
divx_printf(10, "AudioPts %lld\n", call->Pts);
|
||||||
@@ -136,20 +134,22 @@ static int writeData(void* _call)
|
|||||||
PutBits(&ld, 0x0, 8);
|
PutBits(&ld, 0x0, 8);
|
||||||
PutBits(&ld, 0x0, 8);
|
PutBits(&ld, 0x0, 8);
|
||||||
*/
|
*/
|
||||||
PutBits(&ld, 0x1b0, 32); // startcode
|
PutBits(&ld, 0x1b0, 32); // startcode
|
||||||
PutBits(&ld, 0, 8); // profile = reserved
|
PutBits(&ld, 0, 8); // profile = reserved
|
||||||
PutBits(&ld, 0x1b2, 32); // startcode (user data)
|
PutBits(&ld, 0x1b2, 32); // startcode (user data)
|
||||||
PutBits(&ld, 0x53545443, 32); // STTC - an embedded ST timecode from an avi file
|
PutBits(&ld, 0x53545443, 32); // STTC - an embedded ST timecode from an avi file
|
||||||
PutBits(&ld, usecPerFrame , 32);
|
PutBits(&ld, usecPerFrame, 32);
|
||||||
// microseconds per frame
|
// microseconds per frame
|
||||||
FlushBits(&ld);
|
FlushBits(&ld);
|
||||||
|
|
||||||
FakeHeaderLength = (ld.Ptr - (FakeHeaders));
|
FakeHeaderLength = (ld.Ptr - (FakeHeaders));
|
||||||
|
|
||||||
struct iovec iov[4];
|
struct iovec iov[4];
|
||||||
int ic = 0;
|
int ic = 0;
|
||||||
iov[ic].iov_base = PesHeader;
|
iov[ic].iov_base = PesHeader;
|
||||||
iov[ic++].iov_len = InsertPesHeader (PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, FakeStartCode);
|
iov[ic++].iov_len =
|
||||||
|
InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE,
|
||||||
|
call->Pts, FakeStartCode);
|
||||||
iov[ic].iov_base = FakeHeaders;
|
iov[ic].iov_base = FakeHeaders;
|
||||||
iov[ic++].iov_len = FakeHeaderLength;
|
iov[ic++].iov_len = FakeHeaderLength;
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ static int writeData(void* _call)
|
|||||||
iov[ic].iov_base = call->private_data;
|
iov[ic].iov_base = call->private_data;
|
||||||
iov[ic++].iov_len = call->private_size;
|
iov[ic++].iov_len = call->private_size;
|
||||||
|
|
||||||
initialHeader = 0;
|
initialHeader = 0;
|
||||||
}
|
}
|
||||||
iov[ic].iov_base = call->data;
|
iov[ic].iov_base = call->data;
|
||||||
iov[ic++].iov_len = call->len;
|
iov[ic++].iov_len = call->len;
|
||||||
|
@@ -50,10 +50,10 @@
|
|||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Makros/Constants */
|
/* Makros/Constants */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
#define PES_AUDIO_PRIVATE_HEADER_SIZE 16 // consider maximum private header size.
|
#define PES_AUDIO_PRIVATE_HEADER_SIZE 16 // consider maximum private header size.
|
||||||
#define PES_AUDIO_HEADER_SIZE (32 + PES_AUDIO_PRIVATE_HEADER_SIZE)
|
#define PES_AUDIO_HEADER_SIZE (32 + PES_AUDIO_PRIVATE_HEADER_SIZE)
|
||||||
#define PES_AUDIO_PACKET_SIZE 2028
|
#define PES_AUDIO_PACKET_SIZE 2028
|
||||||
#define SPDIF_AUDIO_PACKET_SIZE (1024 * sizeof(unsigned int) * 2) // stereo 32bit samples.
|
#define SPDIF_AUDIO_PACKET_SIZE (1024 * sizeof(unsigned int) * 2) // stereo 32bit samples.
|
||||||
|
|
||||||
#define DTS_DEBUG
|
#define DTS_DEBUG
|
||||||
|
|
||||||
@@ -93,52 +93,51 @@ static int reset()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writeData(void* _call)
|
static int writeData(void *_call)
|
||||||
{
|
{
|
||||||
WriterAVCallData_t* call = (WriterAVCallData_t*) _call;
|
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||||
|
|
||||||
unsigned char PesHeader[PES_AUDIO_HEADER_SIZE];
|
unsigned char PesHeader[PES_AUDIO_HEADER_SIZE];
|
||||||
|
|
||||||
dts_printf(10, "\n");
|
dts_printf(10, "\n");
|
||||||
|
|
||||||
if (call == NULL)
|
if (call == NULL) {
|
||||||
{
|
dts_err("call data is NULL...\n");
|
||||||
dts_err("call data is NULL...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dts_printf(10, "AudioPts %lld\n", call->Pts);
|
dts_printf(10, "AudioPts %lld\n", call->Pts);
|
||||||
|
|
||||||
if ((call->data == NULL) || (call->len <= 0))
|
if ((call->data == NULL) || (call->len <= 0)) {
|
||||||
{
|
dts_err("parsing NULL Data. ignoring...\n");
|
||||||
dts_err("parsing NULL Data. ignoring...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call->fd < 0)
|
if (call->fd < 0) {
|
||||||
{
|
dts_err("file pointer < 0. ignoring ...\n");
|
||||||
dts_err("file pointer < 0. ignoring ...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// #define DO_BYTESWAP
|
// #define DO_BYTESWAP
|
||||||
#ifdef DO_BYTESWAP
|
#ifdef DO_BYTESWAP
|
||||||
unsigned char *Data = (unsigned char *) malloc(call->len);
|
unsigned char *Data = (unsigned char *) malloc(call->len);
|
||||||
memcpy(Data, call->data, call->len);
|
memcpy(Data, call->data, call->len);
|
||||||
|
|
||||||
/* 16-bit byte swap all data before injecting it */
|
/* 16-bit byte swap all data before injecting it */
|
||||||
for (i=0; i< call->len; i+=2)
|
for (i = 0; i < call->len; i += 2) {
|
||||||
{
|
unsigned char Tmp = Data[i];
|
||||||
unsigned char Tmp = Data[i];
|
Data[i] = Data[i + 1];
|
||||||
Data[i] = Data[i+1];
|
Data[i + 1] = Tmp;
|
||||||
Data[i+1] = Tmp;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
|
|
||||||
iov[0].iov_base = PesHeader;
|
iov[0].iov_base = PesHeader;
|
||||||
iov[0].iov_len = InsertPesHeader (PesHeader, call->len, MPEG_AUDIO_PES_START_CODE/*PRIVATE_STREAM_1_PES_START_CODE*/, call->Pts, 0);
|
iov[0].iov_len =
|
||||||
|
InsertPesHeader(PesHeader, call->len,
|
||||||
|
MPEG_AUDIO_PES_START_CODE
|
||||||
|
/*PRIVATE_STREAM_1_PES_START_CODE */ , call->Pts,
|
||||||
|
0);
|
||||||
#ifdef DO_BYTESPWAP
|
#ifdef DO_BYTESPWAP
|
||||||
iov[1].iov_base = Data;
|
iov[1].iov_base = Data;
|
||||||
#else
|
#else
|
||||||
|
@@ -89,37 +89,36 @@ static int reset()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writeData(void* _call)
|
static int writeData(void *_call)
|
||||||
{
|
{
|
||||||
WriterAVCallData_t* call = (WriterAVCallData_t*) _call;
|
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||||
|
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
|
|
||||||
flac_printf(10, "\n");
|
flac_printf(10, "\n");
|
||||||
|
|
||||||
if (call == NULL)
|
if (call == NULL) {
|
||||||
{
|
flac_err("call data is NULL...\n");
|
||||||
flac_err("call data is NULL...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flac_printf(10, "AudioPts %lld\n", call->Pts);
|
flac_printf(10, "AudioPts %lld\n", call->Pts);
|
||||||
|
|
||||||
if ((call->data == NULL) || (call->len <= 0))
|
if ((call->data == NULL) || (call->len <= 0)) {
|
||||||
{
|
flac_err("parsing NULL Data. ignoring...\n");
|
||||||
flac_err("parsing NULL Data. ignoring...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call->fd < 0)
|
if (call->fd < 0) {
|
||||||
{
|
flac_err("file pointer < 0. ignoring ...\n");
|
||||||
flac_err("file pointer < 0. ignoring ...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
iov[0].iov_base = PesHeader;
|
iov[0].iov_base = PesHeader;
|
||||||
iov[0].iov_len = InsertPesHeader (PesHeader, call->len , MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
|
iov[0].iov_len =
|
||||||
|
InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE,
|
||||||
|
call->Pts, 0);
|
||||||
iov[1].iov_base = call->data;
|
iov[1].iov_base = call->data;
|
||||||
iov[1].iov_len = call->len;
|
iov[1].iov_len = call->len;
|
||||||
|
|
||||||
@@ -137,7 +136,7 @@ static WriterCaps_t caps_flac = {
|
|||||||
"flac",
|
"flac",
|
||||||
eAudio,
|
eAudio,
|
||||||
"A_FLAC",
|
"A_FLAC",
|
||||||
AUDIO_ENCODING_LPCM //AUDIO_ENCODING_FLAC
|
AUDIO_ENCODING_LPCM //AUDIO_ENCODING_FLAC
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Writer_s WriterAudioFLAC = {
|
struct Writer_s WriterAudioFLAC = {
|
||||||
|
@@ -95,95 +95,93 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x);
|
|||||||
|
|
||||||
static int reset()
|
static int reset()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writeData(void* _call)
|
static int writeData(void *_call)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
WriterFBCallData_t* call = (WriterFBCallData_t*) _call;
|
WriterFBCallData_t *call = (WriterFBCallData_t *) _call;
|
||||||
|
|
||||||
fb_printf(100, "\n");
|
fb_printf(100, "\n");
|
||||||
|
|
||||||
if (!call)
|
if (!call) {
|
||||||
{
|
fb_err("call data is NULL...\n");
|
||||||
fb_err("call data is NULL...\n");
|
return 0;
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
if (!call->destination) {
|
||||||
|
fb_err("frame buffer == NULL. ignoring ...\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dst_stride = call->destStride / sizeof(uint32_t);
|
||||||
|
int dst_delta = dst_stride - call->Width;
|
||||||
|
uint32_t *dst = call->destination + call->y * dst_stride + call->x;
|
||||||
|
|
||||||
|
if (call->data) {
|
||||||
|
int src_delta = call->Stride - call->Width;
|
||||||
|
unsigned char *src = call->data;
|
||||||
|
static uint32_t last_color = 0, colortable[256];
|
||||||
|
|
||||||
|
if (last_color != call->color) {
|
||||||
|
// call->color is rgba, our spark frame buffer is argb
|
||||||
|
uint32_t c = call->color >> 8, a = 255 - (call->color & 0xff);
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
uint32_t k = (a * i) >> 8;
|
||||||
|
colortable[i] = k ? (c | (k << 24)) : 0;
|
||||||
|
}
|
||||||
|
last_color = call->color;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!call->destination)
|
fb_printf(100, "x %d\n", call->x);
|
||||||
{
|
fb_printf(100, "y %d\n", call->y);
|
||||||
fb_err("frame buffer == NULL. ignoring ...\n");
|
fb_printf(100, "width %d\n", call->Width);
|
||||||
return 0;
|
fb_printf(100, "height %d\n", call->Height);
|
||||||
|
fb_printf(100, "stride %d\n", call->Stride);
|
||||||
|
fb_printf(100, "color 0x%.8x\n", call->color);
|
||||||
|
fb_printf(100, "data %p\n", call->data);
|
||||||
|
fb_printf(100, "dest %p\n", call->destination);
|
||||||
|
fb_printf(100, "dest.stride %d\n", call->destStride);
|
||||||
|
|
||||||
|
unsigned char *src_final = src + call->Height * call->Width;
|
||||||
|
for (; src < src_final; dst += dst_delta, src += src_delta) {
|
||||||
|
u_char *src_end = src + call->Width;
|
||||||
|
for (; src < src_end; dst++, src++) {
|
||||||
|
uint32_t c = colortable[*src];
|
||||||
|
if (c)
|
||||||
|
*dst = c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
int dst_stride = call->destStride/sizeof(uint32_t);
|
uint32_t *dst_final =
|
||||||
int dst_delta = dst_stride - call->Width;
|
dst + call->Width + call->Height * dst_stride;
|
||||||
uint32_t *dst = call->destination + call->y * dst_stride + call->x;
|
for (; dst < dst_final; dst += dst_delta) {
|
||||||
|
uint32_t *dst_end = dst + call->Width;
|
||||||
if (call->data)
|
for (; dst < dst_end; dst++)
|
||||||
{
|
*dst = 0;
|
||||||
int src_delta = call->Stride - call->Width;
|
|
||||||
unsigned char *src = call->data;
|
|
||||||
static uint32_t last_color = 0, colortable[256];
|
|
||||||
|
|
||||||
if (last_color != call->color) {
|
|
||||||
// call->color is rgba, our spark frame buffer is argb
|
|
||||||
uint32_t c = call->color >> 8, a = 255 - (call->color & 0xff);
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
uint32_t k = (a * i) >> 8;
|
|
||||||
colortable[i] = k ? (c | (k << 24)) : 0;
|
|
||||||
}
|
|
||||||
last_color = call->color;
|
|
||||||
}
|
|
||||||
|
|
||||||
fb_printf(100, "x %d\n", call->x);
|
|
||||||
fb_printf(100, "y %d\n", call->y);
|
|
||||||
fb_printf(100, "width %d\n", call->Width);
|
|
||||||
fb_printf(100, "height %d\n", call->Height);
|
|
||||||
fb_printf(100, "stride %d\n", call->Stride);
|
|
||||||
fb_printf(100, "color 0x%.8x\n", call->color);
|
|
||||||
fb_printf(100, "data %p\n", call->data);
|
|
||||||
fb_printf(100, "dest %p\n", call->destination);
|
|
||||||
fb_printf(100, "dest.stride %d\n", call->destStride);
|
|
||||||
|
|
||||||
unsigned char *src_final = src + call->Height * call->Width;
|
|
||||||
for (; src < src_final; dst += dst_delta, src += src_delta) {
|
|
||||||
u_char *src_end = src + call->Width;
|
|
||||||
for (; src < src_end; dst++, src++) {
|
|
||||||
uint32_t c = colortable[*src];
|
|
||||||
if (c)
|
|
||||||
*dst = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
uint32_t *dst_final = dst + call->Width + call->Height * dst_stride;
|
|
||||||
for (; dst < dst_final; dst += dst_delta) {
|
|
||||||
uint32_t *dst_end = dst + call->Width;
|
|
||||||
for (; dst < dst_end; dst++)
|
|
||||||
*dst = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fb_printf(100, "< %d\n", res);
|
fb_printf(100, "< %d\n", res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Writer Definition */
|
/* Writer Definition */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
static WriterCaps_t caps = {
|
static WriterCaps_t caps = {
|
||||||
"framebuffer",
|
"framebuffer",
|
||||||
eGfx,
|
eGfx,
|
||||||
"framebuffer",
|
"framebuffer",
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Writer_s WriterFramebuffer = {
|
struct Writer_s WriterFramebuffer = {
|
||||||
&reset,
|
&reset,
|
||||||
&writeData,
|
&writeData,
|
||||||
NULL,
|
NULL,
|
||||||
&caps
|
&caps
|
||||||
};
|
};
|
||||||
|
@@ -89,47 +89,49 @@ static int reset()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writeData(void* _call)
|
static int writeData(void *_call)
|
||||||
{
|
{
|
||||||
WriterAVCallData_t* call = (WriterAVCallData_t*) _call;
|
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||||
|
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
h263_printf(10, "\n");
|
h263_printf(10, "\n");
|
||||||
|
|
||||||
if (call == NULL)
|
if (call == NULL) {
|
||||||
{
|
h263_err("call data is NULL...\n");
|
||||||
h263_err("call data is NULL...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h263_printf(10, "VideoPts %lld\n", call->Pts);
|
h263_printf(10, "VideoPts %lld\n", call->Pts);
|
||||||
|
|
||||||
if ((call->data == NULL) || (call->len <= 0))
|
if ((call->data == NULL) || (call->len <= 0)) {
|
||||||
{
|
h263_err("NULL Data. ignoring...\n");
|
||||||
h263_err("NULL Data. ignoring...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call->fd < 0)
|
if (call->fd < 0) {
|
||||||
{
|
h263_err("file pointer < 0. ignoring ...\n");
|
||||||
h263_err("file pointer < 0. ignoring ...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int HeaderLength = InsertPesHeader(PesHeader, call->len, H263_VIDEO_PES_START_CODE, call->Pts,0);
|
int HeaderLength =
|
||||||
|
InsertPesHeader(PesHeader, call->len, H263_VIDEO_PES_START_CODE,
|
||||||
|
call->Pts, 0);
|
||||||
|
|
||||||
int PrivateHeaderLength = InsertVideoPrivateDataHeader (&PesHeader[HeaderLength], call->len);
|
int PrivateHeaderLength =
|
||||||
|
InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], call->len);
|
||||||
|
|
||||||
int PesLength = PesHeader[PES_LENGTH_BYTE_0] + (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength;
|
int PesLength =
|
||||||
|
PesHeader[PES_LENGTH_BYTE_0] +
|
||||||
|
(PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength;
|
||||||
|
|
||||||
PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff;
|
PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff;
|
||||||
PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff;
|
PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff;
|
||||||
PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength;
|
PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength;
|
||||||
PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT;
|
PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT;
|
||||||
|
|
||||||
HeaderLength += PrivateHeaderLength;
|
HeaderLength += PrivateHeaderLength;
|
||||||
|
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
iov[0].iov_base = PesHeader;
|
iov[0].iov_base = PesHeader;
|
||||||
|
@@ -75,24 +75,24 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x);
|
|||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Types */
|
/* Types */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
typedef struct avcC_s
|
typedef struct avcC_s {
|
||||||
{
|
unsigned char Version; /* configurationVersion */
|
||||||
unsigned char Version; /* configurationVersion */
|
unsigned char Profile; /* AVCProfileIndication */
|
||||||
unsigned char Profile; /* AVCProfileIndication */
|
unsigned char Compatibility; /* profile_compatibility */
|
||||||
unsigned char Compatibility; /* profile_compatibility */
|
unsigned char Level; /* AVCLevelIndication */
|
||||||
unsigned char Level; /* AVCLevelIndication */
|
unsigned char NalLengthMinusOne; /* held in bottom two bits */
|
||||||
unsigned char NalLengthMinusOne; /* held in bottom two bits */
|
unsigned char NumParamSets; /* held in bottom 5 bits */
|
||||||
unsigned char NumParamSets; /* held in bottom 5 bits */
|
unsigned char Params[1]; /* {length,params}{length,params}...sequence then picture */
|
||||||
unsigned char Params[1]; /* {length,params}{length,params}...sequence then picture*/
|
|
||||||
} avcC_t;
|
} avcC_t;
|
||||||
|
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Varaibles */
|
/* Varaibles */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
const unsigned char Head[] = {0, 0, 0, 1};
|
const unsigned char Head[] = { 0, 0, 0, 1 };
|
||||||
|
|
||||||
static int initialHeader = 1;
|
static int initialHeader = 1;
|
||||||
static unsigned int NalLengthBytes = 1;
|
static unsigned int NalLengthBytes = 1;
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
@@ -108,271 +108,309 @@ static int reset()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writeData(void* _call)
|
static int writeData(void *_call)
|
||||||
{
|
{
|
||||||
WriterAVCallData_t* call = (WriterAVCallData_t*) _call;
|
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||||
|
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
unsigned long long int VideoPts;
|
unsigned long long int VideoPts;
|
||||||
unsigned int TimeDelta;
|
unsigned int TimeDelta;
|
||||||
unsigned int TimeScale;
|
unsigned int TimeScale;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int ic = 0;
|
int ic = 0;
|
||||||
struct iovec iov[128];
|
struct iovec iov[128];
|
||||||
h264_printf(10, "\n");
|
h264_printf(10, "\n");
|
||||||
|
|
||||||
if (call == NULL)
|
if (call == NULL) {
|
||||||
{
|
h264_err("call data is NULL...\n");
|
||||||
h264_err("call data is NULL...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeDelta = call->FrameRate;
|
TimeDelta = call->FrameRate;
|
||||||
TimeScale = call->FrameScale;
|
TimeScale = call->FrameScale;
|
||||||
VideoPts = call->Pts;
|
VideoPts = call->Pts;
|
||||||
|
|
||||||
h264_printf(10, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale);
|
h264_printf(10, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta,
|
||||||
|
TimeScale);
|
||||||
|
|
||||||
if ((call->data == NULL) || (call->len <= 0))
|
if ((call->data == NULL) || (call->len <= 0)) {
|
||||||
{
|
h264_err("NULL Data. ignoring...\n");
|
||||||
h264_err("NULL Data. ignoring...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call->fd < 0)
|
if (call->fd < 0) {
|
||||||
{
|
h264_err("file pointer < 0. ignoring ...\n");
|
||||||
h264_err("file pointer < 0. ignoring ...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if((call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) ||
|
if ((call->len > 3)
|
||||||
(call->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff)))
|
&&
|
||||||
{
|
((call->data[0] == 0x00 && call->data[1] == 0x00
|
||||||
|
&& call->data[2] == 0x00 && call->data[3] == 0x01)
|
||||||
|
|| (call->data[0] == 0xff && call->data[1] == 0xff
|
||||||
|
&& call->data[2] == 0xff && call->data[3] == 0xff))) {
|
||||||
unsigned int PacketLength = 0;
|
unsigned int PacketLength = 0;
|
||||||
unsigned int FakeStartCode = (call->Version << 8) | PES_VERSION_FAKE_START_CODE;
|
unsigned int FakeStartCode =
|
||||||
|
(call->Version << 8) | PES_VERSION_FAKE_START_CODE;
|
||||||
iov[ic++].iov_base = PesHeader;
|
iov[ic++].iov_base = PesHeader;
|
||||||
if (initialHeader) {
|
if (initialHeader) {
|
||||||
initialHeader = 0;
|
initialHeader = 0;
|
||||||
iov[ic].iov_base = call->private_data;
|
iov[ic].iov_base = call->private_data;
|
||||||
iov[ic++].iov_len = call->private_size;
|
iov[ic++].iov_len = call->private_size;
|
||||||
PacketLength += call->private_size;
|
PacketLength += call->private_size;
|
||||||
}
|
}
|
||||||
iov[ic].iov_base = call->data;
|
iov[ic].iov_base = call->data;
|
||||||
iov[ic++].iov_len = call->len;
|
iov[ic++].iov_len = call->len;
|
||||||
PacketLength += call->len;
|
PacketLength += call->len;
|
||||||
/*Hellmaster1024: some packets will only be accepted by the player if we send one byte more than
|
/*Hellmaster1024: some packets will only be accepted by the player if we send one byte more than
|
||||||
data is available. The content of this byte does not matter. It will be ignored
|
data is available. The content of this byte does not matter. It will be ignored
|
||||||
by the player */
|
by the player */
|
||||||
iov[ic].iov_base = "";
|
iov[ic].iov_base = "";
|
||||||
iov[ic++].iov_len = 1;
|
iov[ic++].iov_len = 1;
|
||||||
iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, call->Pts, FakeStartCode);
|
iov[0].iov_len =
|
||||||
|
InsertPesHeader(PesHeader, PacketLength,
|
||||||
|
MPEG_VIDEO_PES_START_CODE, call->Pts,
|
||||||
|
FakeStartCode);
|
||||||
return writev(call->fd, iov, ic);
|
return writev(call->fd, iov, ic);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initialHeader)
|
if (initialHeader) {
|
||||||
{
|
avcC_t *avcCHeader = (avcC_t *) call->private_data;
|
||||||
avcC_t* avcCHeader = (avcC_t*)call->private_data;
|
unsigned int i;
|
||||||
unsigned int i;
|
unsigned int ParamSets;
|
||||||
unsigned int ParamSets;
|
unsigned int ParamOffset;
|
||||||
unsigned int ParamOffset;
|
unsigned int InitialHeaderLength = 0;
|
||||||
unsigned int InitialHeaderLength = 0;
|
unsigned int ParametersLength;
|
||||||
unsigned int ParametersLength;
|
|
||||||
|
|
||||||
if (avcCHeader == NULL) {
|
if (avcCHeader == NULL) {
|
||||||
h264_err("private_data NULL\n");
|
h264_err("private_data NULL\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avcCHeader->Version != 1)
|
if (avcCHeader->Version != 1)
|
||||||
h264_err("Error unknown avcC version (%x). Expect problems.\n", avcCHeader->Version);
|
h264_err("Error unknown avcC version (%x). Expect problems.\n",
|
||||||
|
avcCHeader->Version);
|
||||||
|
|
||||||
ParametersLength = 0;
|
ParametersLength = 0;
|
||||||
|
|
||||||
unsigned char HeaderData[19];
|
unsigned char HeaderData[19];
|
||||||
HeaderData[ParametersLength++] = 0x00; // Start code
|
HeaderData[ParametersLength++] = 0x00; // Start code
|
||||||
HeaderData[ParametersLength++] = 0x00;
|
HeaderData[ParametersLength++] = 0x00;
|
||||||
HeaderData[ParametersLength++] = 0x01;
|
HeaderData[ParametersLength++] = 0x01;
|
||||||
HeaderData[ParametersLength++] = NALU_TYPE_PLAYER2_CONTAINER_PARAMETERS;
|
HeaderData[ParametersLength++] =
|
||||||
// Container message version - changes when/if we vary the format of the message
|
NALU_TYPE_PLAYER2_CONTAINER_PARAMETERS;
|
||||||
HeaderData[ParametersLength++] = CONTAINER_PARAMETERS_VERSION;
|
// Container message version - changes when/if we vary the format of the message
|
||||||
HeaderData[ParametersLength++] = 0xff; // Field separator
|
HeaderData[ParametersLength++] = CONTAINER_PARAMETERS_VERSION;
|
||||||
|
HeaderData[ParametersLength++] = 0xff; // Field separator
|
||||||
|
|
||||||
if( TimeDelta == 0xffffffff )
|
if (TimeDelta == 0xffffffff)
|
||||||
TimeDelta = (TimeScale > 1000) ? 1001 : 1;
|
TimeDelta = (TimeScale > 1000) ? 1001 : 1;
|
||||||
|
|
||||||
HeaderData[ParametersLength++] = (TimeScale >> 24) & 0xff; // Output the timescale
|
HeaderData[ParametersLength++] = (TimeScale >> 24) & 0xff; // Output the timescale
|
||||||
HeaderData[ParametersLength++] = (TimeScale >> 16) & 0xff;
|
HeaderData[ParametersLength++] = (TimeScale >> 16) & 0xff;
|
||||||
HeaderData[ParametersLength++] = 0xff;
|
HeaderData[ParametersLength++] = 0xff;
|
||||||
HeaderData[ParametersLength++] = (TimeScale >> 8) & 0xff;
|
HeaderData[ParametersLength++] = (TimeScale >> 8) & 0xff;
|
||||||
HeaderData[ParametersLength++] = TimeScale & 0xff;
|
HeaderData[ParametersLength++] = TimeScale & 0xff;
|
||||||
HeaderData[ParametersLength++] = 0xff;
|
HeaderData[ParametersLength++] = 0xff;
|
||||||
|
|
||||||
HeaderData[ParametersLength++] = (TimeDelta >> 24) & 0xff; // Output frame period
|
HeaderData[ParametersLength++] = (TimeDelta >> 24) & 0xff; // Output frame period
|
||||||
HeaderData[ParametersLength++] = (TimeDelta >> 16) & 0xff;
|
HeaderData[ParametersLength++] = (TimeDelta >> 16) & 0xff;
|
||||||
HeaderData[ParametersLength++] = 0xff;
|
HeaderData[ParametersLength++] = 0xff;
|
||||||
HeaderData[ParametersLength++] = (TimeDelta >> 8) & 0xff;
|
HeaderData[ParametersLength++] = (TimeDelta >> 8) & 0xff;
|
||||||
HeaderData[ParametersLength++] = TimeDelta & 0xff;
|
HeaderData[ParametersLength++] = TimeDelta & 0xff;
|
||||||
HeaderData[ParametersLength++] = 0xff;
|
HeaderData[ParametersLength++] = 0xff;
|
||||||
HeaderData[ParametersLength++] = 0x80; // Rsbp trailing bits
|
HeaderData[ParametersLength++] = 0x80; // Rsbp trailing bits
|
||||||
|
|
||||||
assert(ParametersLength <= sizeof(HeaderData));
|
assert(ParametersLength <= sizeof(HeaderData));
|
||||||
|
|
||||||
ic = 0;
|
ic = 0;
|
||||||
iov[ic].iov_base = PesHeader;
|
iov[ic].iov_base = PesHeader;
|
||||||
iov[ic++].iov_len = InsertPesHeader (PesHeader, ParametersLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
|
iov[ic++].iov_len =
|
||||||
|
InsertPesHeader(PesHeader, ParametersLength,
|
||||||
|
MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE,
|
||||||
|
0);
|
||||||
iov[ic].iov_base = HeaderData;
|
iov[ic].iov_base = HeaderData;
|
||||||
iov[ic++].iov_len = ParametersLength;
|
iov[ic++].iov_len = ParametersLength;
|
||||||
len = writev(call->fd, iov, ic);
|
len = writev(call->fd, iov, ic);
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
NalLengthBytes = (avcCHeader->NalLengthMinusOne & 0x03) + 1;
|
NalLengthBytes = (avcCHeader->NalLengthMinusOne & 0x03) + 1;
|
||||||
ParamSets = avcCHeader->NumParamSets & 0x1f;
|
ParamSets = avcCHeader->NumParamSets & 0x1f;
|
||||||
|
|
||||||
h264_printf(20, "avcC contents:\n");
|
h264_printf(20, "avcC contents:\n");
|
||||||
h264_printf(20, " version: %d\n", avcCHeader->Version);
|
h264_printf(20, " version: %d\n",
|
||||||
h264_printf(20, " profile: %d\n", avcCHeader->Profile);
|
avcCHeader->Version);
|
||||||
h264_printf(20, " profile compatibility: %d\n", avcCHeader->Compatibility);
|
h264_printf(20, " profile: %d\n",
|
||||||
h264_printf(20, " level: %d\n", avcCHeader->Level);
|
avcCHeader->Profile);
|
||||||
h264_printf(20, " nal length bytes: %d\n", NalLengthBytes);
|
h264_printf(20, " profile compatibility: %d\n",
|
||||||
h264_printf(20, " number of sequence param sets: %d\n", ParamSets);
|
avcCHeader->Compatibility);
|
||||||
|
h264_printf(20, " level: %d\n",
|
||||||
|
avcCHeader->Level);
|
||||||
|
h264_printf(20, " nal length bytes: %d\n",
|
||||||
|
NalLengthBytes);
|
||||||
|
h264_printf(20, " number of sequence param sets: %d\n",
|
||||||
|
ParamSets);
|
||||||
|
|
||||||
ParamOffset = 0;
|
ParamOffset = 0;
|
||||||
ic = 0;
|
ic = 0;
|
||||||
iov[ic++].iov_base = PesHeader;
|
iov[ic++].iov_base = PesHeader;
|
||||||
for (i = 0; i < ParamSets; i++) {
|
for (i = 0; i < ParamSets; i++) {
|
||||||
unsigned int PsLength = (avcCHeader->Params[ParamOffset] << 8) + avcCHeader->Params[ParamOffset+1];
|
unsigned int PsLength =
|
||||||
|
(avcCHeader->Params[ParamOffset] << 8) +
|
||||||
|
avcCHeader->Params[ParamOffset + 1];
|
||||||
|
|
||||||
h264_printf(20, " sps %d has length %d\n", i, PsLength);
|
h264_printf(20, " sps %d has length %d\n", i,
|
||||||
|
PsLength);
|
||||||
iov[ic].iov_base = (char *)Head;
|
|
||||||
iov[ic++].iov_len = sizeof(Head);
|
|
||||||
InitialHeaderLength += sizeof(Head);
|
|
||||||
iov[ic].iov_base = &avcCHeader->Params[ParamOffset+2];
|
|
||||||
iov[ic++].iov_len = PsLength;
|
|
||||||
InitialHeaderLength += PsLength;
|
|
||||||
ParamOffset += PsLength+2;
|
|
||||||
}
|
|
||||||
|
|
||||||
ParamSets = avcCHeader->Params[ParamOffset];
|
|
||||||
|
|
||||||
h264_printf(20, " number of picture param sets: %d\n", ParamSets);
|
|
||||||
|
|
||||||
ParamOffset++;
|
|
||||||
for (i = 0; i < ParamSets; i++) {
|
|
||||||
unsigned int PsLength = (avcCHeader->Params[ParamOffset] << 8) + avcCHeader->Params[ParamOffset+1];
|
|
||||||
|
|
||||||
h264_printf (20, " pps %d has length %d\n", i, PsLength);
|
|
||||||
|
|
||||||
iov[ic].iov_base = (char *) Head;
|
iov[ic].iov_base = (char *) Head;
|
||||||
iov[ic++].iov_len = sizeof(Head);
|
iov[ic++].iov_len = sizeof(Head);
|
||||||
InitialHeaderLength += sizeof(Head);
|
InitialHeaderLength += sizeof(Head);
|
||||||
iov[ic].iov_base = &avcCHeader->Params[ParamOffset+2];
|
iov[ic].iov_base = &avcCHeader->Params[ParamOffset + 2];
|
||||||
iov[ic++].iov_len = PsLength;
|
iov[ic++].iov_len = PsLength;
|
||||||
InitialHeaderLength += PsLength;
|
InitialHeaderLength += PsLength;
|
||||||
ParamOffset += PsLength+2;
|
ParamOffset += PsLength + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
iov[0].iov_len = InsertPesHeader (PesHeader, InitialHeaderLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
|
ParamSets = avcCHeader->Params[ParamOffset];
|
||||||
|
|
||||||
|
h264_printf(20, " number of picture param sets: %d\n",
|
||||||
|
ParamSets);
|
||||||
|
|
||||||
|
ParamOffset++;
|
||||||
|
for (i = 0; i < ParamSets; i++) {
|
||||||
|
unsigned int PsLength =
|
||||||
|
(avcCHeader->Params[ParamOffset] << 8) +
|
||||||
|
avcCHeader->Params[ParamOffset + 1];
|
||||||
|
|
||||||
|
h264_printf(20, " pps %d has length %d\n", i,
|
||||||
|
PsLength);
|
||||||
|
|
||||||
|
iov[ic].iov_base = (char *) Head;
|
||||||
|
iov[ic++].iov_len = sizeof(Head);
|
||||||
|
InitialHeaderLength += sizeof(Head);
|
||||||
|
iov[ic].iov_base = &avcCHeader->Params[ParamOffset + 2];
|
||||||
|
iov[ic++].iov_len = PsLength;
|
||||||
|
InitialHeaderLength += PsLength;
|
||||||
|
ParamOffset += PsLength + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
iov[0].iov_len =
|
||||||
|
InsertPesHeader(PesHeader, InitialHeaderLength,
|
||||||
|
MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE,
|
||||||
|
0);
|
||||||
ssize_t l = writev(call->fd, iov, ic);
|
ssize_t l = writev(call->fd, iov, ic);
|
||||||
if (l < 0)
|
if (l < 0)
|
||||||
return l;
|
return l;
|
||||||
len += l;
|
len += l;
|
||||||
|
|
||||||
initialHeader = 0;
|
initialHeader = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int SampleSize = call->len;
|
unsigned int SampleSize = call->len;
|
||||||
unsigned int NalStart = 0;
|
unsigned int NalStart = 0;
|
||||||
unsigned int VideoPosition = 0;
|
unsigned int VideoPosition = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
unsigned int NalLength;
|
unsigned int NalLength;
|
||||||
unsigned char NalData[4];
|
unsigned char NalData[4];
|
||||||
int NalPresent = 1;
|
int NalPresent = 1;
|
||||||
|
|
||||||
memcpy (NalData, call->data + VideoPosition, NalLengthBytes);
|
memcpy(NalData, call->data + VideoPosition, NalLengthBytes);
|
||||||
VideoPosition += NalLengthBytes;
|
VideoPosition += NalLengthBytes;
|
||||||
NalStart += NalLengthBytes;
|
NalStart += NalLengthBytes;
|
||||||
switch(NalLengthBytes) {
|
switch (NalLengthBytes) {
|
||||||
case 1: NalLength = (NalData[0]); break;
|
case 1:
|
||||||
case 2: NalLength = (NalData[0] << 8) | (NalData[1]); break;
|
NalLength = (NalData[0]);
|
||||||
case 3: NalLength = (NalData[0] << 16) | (NalData[1] << 8) | (NalData[2]); break;
|
break;
|
||||||
default: NalLength = (NalData[0] << 24) | (NalData[1] << 16) | (NalData[2] << 8) | (NalData[3]); break;
|
case 2:
|
||||||
}
|
NalLength = (NalData[0] << 8) | (NalData[1]);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
NalLength =
|
||||||
|
(NalData[0] << 16) | (NalData[1] << 8) | (NalData[2]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NalLength =
|
||||||
|
(NalData[0] << 24) | (NalData[1] << 16) | (NalData[2] << 8)
|
||||||
|
| (NalData[3]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
h264_printf(20, "NalStart = %u + NalLength = %u > SampleSize = %u\n", NalStart, NalLength, SampleSize);
|
h264_printf(20,
|
||||||
|
"NalStart = %u + NalLength = %u > SampleSize = %u\n",
|
||||||
|
NalStart, NalLength, SampleSize);
|
||||||
|
|
||||||
if (NalStart + NalLength > SampleSize) {
|
if (NalStart + NalLength > SampleSize) {
|
||||||
h264_printf(20, "nal length past end of buffer - size %u frame offset %u left %u\n",
|
h264_printf(20,
|
||||||
NalLength, NalStart , SampleSize - NalStart );
|
"nal length past end of buffer - size %u frame offset %u left %u\n",
|
||||||
|
NalLength, NalStart, SampleSize - NalStart);
|
||||||
|
|
||||||
NalStart = SampleSize;
|
NalStart = SampleSize;
|
||||||
} else {
|
} else {
|
||||||
NalStart += NalLength;
|
NalStart += NalLength;
|
||||||
ic = 0;
|
ic = 0;
|
||||||
iov[ic++].iov_base = PesHeader;
|
iov[ic++].iov_base = PesHeader;
|
||||||
|
|
||||||
if (NalPresent) {
|
if (NalPresent) {
|
||||||
NalPresent = 0;
|
NalPresent = 0;
|
||||||
iov[ic].iov_base = (char *)Head;
|
iov[ic].iov_base = (char *) Head;
|
||||||
iov[ic++].iov_len = sizeof(Head);
|
iov[ic++].iov_len = sizeof(Head);
|
||||||
}
|
}
|
||||||
|
|
||||||
iov[ic].iov_base = call->data + VideoPosition;
|
iov[ic].iov_base = call->data + VideoPosition;
|
||||||
iov[ic++].iov_len = NalLength;
|
iov[ic++].iov_len = NalLength;
|
||||||
VideoPosition += NalLength;
|
VideoPosition += NalLength;
|
||||||
|
|
||||||
h264_printf (20, " pts=%llu\n", VideoPts);
|
h264_printf(20, " pts=%llu\n", VideoPts);
|
||||||
|
|
||||||
iov[0].iov_len = InsertPesHeader (PesHeader, NalLength, MPEG_VIDEO_PES_START_CODE, VideoPts, 0);
|
iov[0].iov_len =
|
||||||
ssize_t l = writev(call->fd, iov, ic);
|
InsertPesHeader(PesHeader, NalLength,
|
||||||
if (l < 0)
|
MPEG_VIDEO_PES_START_CODE, VideoPts, 0);
|
||||||
return l;
|
ssize_t l = writev(call->fd, iov, ic);
|
||||||
len += l;
|
if (l < 0)
|
||||||
|
return l;
|
||||||
|
len += l;
|
||||||
|
|
||||||
VideoPts = INVALID_PTS_VALUE;
|
VideoPts = INVALID_PTS_VALUE;
|
||||||
}
|
}
|
||||||
} while (NalStart < SampleSize);
|
} while (NalStart < SampleSize);
|
||||||
|
|
||||||
if (len < 0)
|
if (len < 0) {
|
||||||
{
|
h264_err("error writing data errno = %d\n", errno);
|
||||||
h264_err("error writing data errno = %d\n", errno);
|
h264_err("%s\n", strerror(errno));
|
||||||
h264_err("%s\n", strerror(errno));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h264_printf (10, "< len %d\n", len);
|
h264_printf(10, "< len %d\n", len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writeReverseData(void* _call)
|
static int writeReverseData(void *_call)
|
||||||
{
|
{
|
||||||
WriterAVCallData_t* call = (WriterAVCallData_t*) _call;
|
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||||
|
|
||||||
h264_printf(10, "\n");
|
h264_printf(10, "\n");
|
||||||
|
|
||||||
if (call == NULL)
|
if (call == NULL) {
|
||||||
{
|
h264_err("call data is NULL...\n");
|
||||||
h264_err("call data is NULL...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h264_printf(10, "VideoPts %lld\n", call->Pts);
|
h264_printf(10, "VideoPts %lld\n", call->Pts);
|
||||||
|
|
||||||
if ((call->data == NULL) || (call->len <= 0))
|
if ((call->data == NULL) || (call->len <= 0)) {
|
||||||
{
|
h264_err("NULL Data. ignoring...\n");
|
||||||
h264_err("NULL Data. ignoring...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call->fd < 0)
|
if (call->fd < 0) {
|
||||||
{
|
h264_err("file pointer < 0. ignoring ...\n");
|
||||||
h264_err("file pointer < 0. ignoring ...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
/* Writer Definition */
|
/* Writer Definition */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
@@ -72,35 +72,33 @@ void PutBits(BitPacker_t * ld, unsigned int code, unsigned int length)
|
|||||||
|
|
||||||
#ifdef DEBUG_PUTBITS
|
#ifdef DEBUG_PUTBITS
|
||||||
if (ld->debug)
|
if (ld->debug)
|
||||||
dprintf("code = %d, length = %d, bit_buf = 0x%x, bit_left = %d\n", code, length, bit_buf, bit_left);
|
dprintf("code = %d, length = %d, bit_buf = 0x%x, bit_left = %d\n",
|
||||||
#endif /* DEBUG_PUTBITS */
|
code, length, bit_buf, bit_left);
|
||||||
|
#endif /* DEBUG_PUTBITS */
|
||||||
|
|
||||||
if (length < bit_left)
|
if (length < bit_left) {
|
||||||
{
|
/* fits into current buffer */
|
||||||
/* fits into current buffer */
|
bit_buf = (bit_buf << length) | code;
|
||||||
bit_buf = (bit_buf << length) | code;
|
bit_left -= length;
|
||||||
bit_left -= length;
|
} else {
|
||||||
}
|
/* doesn't fit */
|
||||||
else
|
bit_buf <<= bit_left;
|
||||||
{
|
bit_buf |= code >> (length - bit_left);
|
||||||
/* doesn't fit */
|
ld->Ptr[0] = (char) (bit_buf >> 24);
|
||||||
bit_buf <<= bit_left;
|
ld->Ptr[1] = (char) (bit_buf >> 16);
|
||||||
bit_buf |= code >> (length - bit_left);
|
ld->Ptr[2] = (char) (bit_buf >> 8);
|
||||||
ld->Ptr[0] = (char)(bit_buf >> 24);
|
ld->Ptr[3] = (char) bit_buf;
|
||||||
ld->Ptr[1] = (char)(bit_buf >> 16);
|
ld->Ptr += 4;
|
||||||
ld->Ptr[2] = (char)(bit_buf >> 8);
|
length -= bit_left;
|
||||||
ld->Ptr[3] = (char)bit_buf;
|
bit_buf = code & ((1 << length) - 1);
|
||||||
ld->Ptr += 4;
|
bit_left = 32 - length;
|
||||||
length -= bit_left;
|
bit_buf = code;
|
||||||
bit_buf = code & ((1 << length) - 1);
|
|
||||||
bit_left = 32 - length;
|
|
||||||
bit_buf = code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_PUTBITS
|
#ifdef DEBUG_PUTBITS
|
||||||
if (ld->debug)
|
if (ld->debug)
|
||||||
dprintf("bit_left = %d, bit_buf = 0x%x\n", bit_left, bit_buf);
|
dprintf("bit_left = %d, bit_buf = 0x%x\n", bit_left, bit_buf);
|
||||||
#endif /* DEBUG_PUTBITS */
|
#endif /* DEBUG_PUTBITS */
|
||||||
|
|
||||||
/* writeback */
|
/* writeback */
|
||||||
ld->BitBuffer = bit_buf;
|
ld->BitBuffer = bit_buf;
|
||||||
@@ -110,15 +108,14 @@ void PutBits(BitPacker_t * ld, unsigned int code, unsigned int length)
|
|||||||
void FlushBits(BitPacker_t * ld)
|
void FlushBits(BitPacker_t * ld)
|
||||||
{
|
{
|
||||||
ld->BitBuffer <<= ld->Remaining;
|
ld->BitBuffer <<= ld->Remaining;
|
||||||
while (ld->Remaining < 32)
|
while (ld->Remaining < 32) {
|
||||||
{
|
|
||||||
#ifdef DEBUG_PUTBITS
|
#ifdef DEBUG_PUTBITS
|
||||||
if (ld->debug)
|
if (ld->debug)
|
||||||
dprintf("flushing 0x%2.2x\n", ld->BitBuffer >> 24);
|
dprintf("flushing 0x%2.2x\n", ld->BitBuffer >> 24);
|
||||||
#endif /* DEBUG_PUTBITS */
|
#endif /* DEBUG_PUTBITS */
|
||||||
*ld->Ptr++ = ld->BitBuffer >> 24;
|
*ld->Ptr++ = ld->BitBuffer >> 24;
|
||||||
ld->BitBuffer <<= 8;
|
ld->BitBuffer <<= 8;
|
||||||
ld->Remaining += 8;
|
ld->Remaining += 8;
|
||||||
}
|
}
|
||||||
ld->Remaining = 32;
|
ld->Remaining = 32;
|
||||||
ld->BitBuffer = 0;
|
ld->BitBuffer = 0;
|
||||||
|
@@ -89,37 +89,36 @@ static int reset()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writeData(void* _call)
|
static int writeData(void *_call)
|
||||||
{
|
{
|
||||||
WriterAVCallData_t* call = (WriterAVCallData_t*) _call;
|
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||||
|
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
|
|
||||||
mp3_printf(10, "\n");
|
mp3_printf(10, "\n");
|
||||||
|
|
||||||
if (call == NULL)
|
if (call == NULL) {
|
||||||
{
|
mp3_err("call data is NULL...\n");
|
||||||
mp3_err("call data is NULL...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mp3_printf(10, "AudioPts %lld\n", call->Pts);
|
mp3_printf(10, "AudioPts %lld\n", call->Pts);
|
||||||
|
|
||||||
if ((call->data == NULL) || (call->len <= 0))
|
if ((call->data == NULL) || (call->len <= 0)) {
|
||||||
{
|
mp3_err("parsing NULL Data. ignoring...\n");
|
||||||
mp3_err("parsing NULL Data. ignoring...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call->fd < 0)
|
if (call->fd < 0) {
|
||||||
{
|
mp3_err("file pointer < 0. ignoring ...\n");
|
||||||
mp3_err("file pointer < 0. ignoring ...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
iov[0].iov_base = PesHeader;
|
iov[0].iov_base = PesHeader;
|
||||||
iov[0].iov_len = InsertPesHeader (PesHeader, call->len , MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
|
iov[0].iov_len =
|
||||||
|
InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE,
|
||||||
|
call->Pts, 0);
|
||||||
iov[1].iov_base = call->data;
|
iov[1].iov_base = call->data;
|
||||||
iov[1].iov_len = call->len;
|
iov[1].iov_len = call->len;
|
||||||
|
|
||||||
|
@@ -90,59 +90,58 @@ static int reset()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writeData(void* _call)
|
static int writeData(void *_call)
|
||||||
{
|
{
|
||||||
WriterAVCallData_t* call = (WriterAVCallData_t*) _call;
|
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||||
|
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
int len = 0;
|
int len = 0;
|
||||||
unsigned int Position = 0;
|
unsigned int Position = 0;
|
||||||
|
|
||||||
mpeg2_printf(10, "\n");
|
mpeg2_printf(10, "\n");
|
||||||
|
|
||||||
if (call == NULL)
|
if (call == NULL) {
|
||||||
{
|
mpeg2_err("call data is NULL...\n");
|
||||||
mpeg2_err("call data is NULL...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mpeg2_printf(10, "VideoPts %lld\n", call->Pts);
|
mpeg2_printf(10, "VideoPts %lld\n", call->Pts);
|
||||||
|
|
||||||
if ((call->data == NULL) || (call->len <= 0))
|
if ((call->data == NULL) || (call->len <= 0)) {
|
||||||
{
|
mpeg2_err("parsing NULL Data. ignoring...\n");
|
||||||
mpeg2_err("parsing NULL Data. ignoring...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call->fd < 0)
|
if (call->fd < 0) {
|
||||||
{
|
mpeg2_err("file pointer < 0. ignoring ...\n");
|
||||||
mpeg2_err("file pointer < 0. ignoring ...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while(Position < call->len) {
|
while (Position < call->len) {
|
||||||
int PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ?
|
int PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ?
|
||||||
(call->len - Position) : MAX_PES_PACKET_SIZE;
|
(call->len - Position) : MAX_PES_PACKET_SIZE;
|
||||||
|
|
||||||
int Remaining = call->len - Position - PacketLength;
|
int Remaining = call->len - Position - PacketLength;
|
||||||
|
|
||||||
mpeg2_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", PacketLength, Remaining, Position);
|
mpeg2_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n",
|
||||||
|
PacketLength, Remaining, Position);
|
||||||
|
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
iov[0].iov_base = PesHeader;
|
iov[0].iov_base = PesHeader;
|
||||||
iov[0].iov_len = InsertPesHeader (PesHeader, PacketLength, 0xe0, call->Pts, 0);
|
iov[0].iov_len =
|
||||||
|
InsertPesHeader(PesHeader, PacketLength, 0xe0, call->Pts, 0);
|
||||||
iov[1].iov_base = call->data + Position;
|
iov[1].iov_base = call->data + Position;
|
||||||
iov[1].iov_len = PacketLength;
|
iov[1].iov_len = PacketLength;
|
||||||
|
|
||||||
ssize_t l = writev(call->fd, iov, 2);
|
ssize_t l = writev(call->fd, iov, 2);
|
||||||
if (l < 0) {
|
if (l < 0) {
|
||||||
len = l;
|
len = l;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
len += l;
|
len += l;
|
||||||
|
|
||||||
Position += PacketLength;
|
Position += PacketLength;
|
||||||
call->Pts = INVALID_PTS_VALUE;
|
call->Pts = INVALID_PTS_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpeg2_printf(10, "< len %d\n", len);
|
mpeg2_printf(10, "< len %d\n", len);
|
||||||
|
@@ -83,18 +83,18 @@ static unsigned int SubFrameLen = 0;
|
|||||||
static unsigned int SubFramesPerPES = 0;
|
static unsigned int SubFramesPerPES = 0;
|
||||||
|
|
||||||
// reference: search for TypeLpcmDVDAudio in player/frame_parser/frame_parser_audio_lpcm.cpp
|
// reference: search for TypeLpcmDVDAudio in player/frame_parser/frame_parser_audio_lpcm.cpp
|
||||||
static const unsigned char clpcm_prv[14] = { 0xA0, //sub_stream_id
|
static const unsigned char clpcm_prv[14] = { 0xA0, //sub_stream_id
|
||||||
0, 0, //resvd and UPC_EAN_ISRC stuff, unused
|
0, 0, //resvd and UPC_EAN_ISRC stuff, unused
|
||||||
0x0A, //private header length
|
0x0A, //private header length
|
||||||
0, 9, //first_access_unit_pointer
|
0, 9, //first_access_unit_pointer
|
||||||
0x00, //emph,rsvd,stereo,downmix
|
0x00, //emph,rsvd,stereo,downmix
|
||||||
0x0F, //quantisation word length 1,2
|
0x0F, //quantisation word length 1,2
|
||||||
0x0F, //audio sampling freqency 1,2
|
0x0F, //audio sampling freqency 1,2
|
||||||
0, //resvd, multi channel type
|
0, //resvd, multi channel type
|
||||||
0, //bit shift on channel GR2, assignment
|
0, //bit shift on channel GR2, assignment
|
||||||
0x80, //dynamic range control
|
0x80, //dynamic range control
|
||||||
0, 0 //resvd for copyright management
|
0, 0 //resvd for copyright management
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned char lpcm_prv[14];
|
static unsigned char lpcm_prv[14];
|
||||||
static unsigned char breakBuffer[8192];
|
static unsigned char breakBuffer[8192];
|
||||||
@@ -108,184 +108,199 @@ static unsigned int breakBufferFillSize = 0;
|
|||||||
/* MISC Functions */
|
/* MISC Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static int prepareClipPlay(int uNoOfChannels, int uSampleRate, int uBitsPerSample, int bLittleEndian __attribute__((unused)))
|
static int prepareClipPlay(int uNoOfChannels, int uSampleRate,
|
||||||
|
int uBitsPerSample, int bLittleEndian
|
||||||
|
__attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
printf("rate: %d ch: %d bits: %d (%d bps)\n",
|
printf("rate: %d ch: %d bits: %d (%d bps)\n",
|
||||||
uSampleRate/*Format->dwSamplesPerSec*/,
|
uSampleRate /*Format->dwSamplesPerSec */ ,
|
||||||
uNoOfChannels/*Format->wChannels*/,
|
uNoOfChannels /*Format->wChannels */ ,
|
||||||
uBitsPerSample/*Format->wBitsPerSample*/,
|
uBitsPerSample /*Format->wBitsPerSample */ ,
|
||||||
(uBitsPerSample/*Format->wBitsPerSample*/ / 8)
|
(uBitsPerSample /*Format->wBitsPerSample */ / 8)
|
||||||
);
|
);
|
||||||
|
|
||||||
SubFrameLen = 0;
|
SubFrameLen = 0;
|
||||||
SubFramesPerPES = 0;
|
SubFramesPerPES = 0;
|
||||||
breakBufferFillSize = 0;
|
breakBufferFillSize = 0;
|
||||||
|
|
||||||
memcpy(lpcm_prv, clpcm_prv, sizeof(lpcm_prv));
|
memcpy(lpcm_prv, clpcm_prv, sizeof(lpcm_prv));
|
||||||
|
|
||||||
//figure out size of subframe
|
//figure out size of subframe
|
||||||
//and set up sample rate
|
//and set up sample rate
|
||||||
switch(uSampleRate) {
|
switch (uSampleRate) {
|
||||||
case 48000: SubFrameLen = 40;
|
case 48000:
|
||||||
break;
|
SubFrameLen = 40;
|
||||||
case 96000: lpcm_prv[8] |= 0x10;
|
break;
|
||||||
SubFrameLen = 80;
|
case 96000:
|
||||||
break;
|
lpcm_prv[8] |= 0x10;
|
||||||
case 192000: lpcm_prv[8] |= 0x20;
|
SubFrameLen = 80;
|
||||||
SubFrameLen = 160;
|
break;
|
||||||
break;
|
case 192000:
|
||||||
case 44100: lpcm_prv[8] |= 0x80;
|
lpcm_prv[8] |= 0x20;
|
||||||
SubFrameLen = 40;
|
SubFrameLen = 160;
|
||||||
break;
|
break;
|
||||||
case 88200: lpcm_prv[8] |= 0x90;
|
case 44100:
|
||||||
SubFrameLen = 80;
|
lpcm_prv[8] |= 0x80;
|
||||||
break;
|
SubFrameLen = 40;
|
||||||
case 176400: lpcm_prv[8] |= 0xA0;
|
break;
|
||||||
SubFrameLen = 160;
|
case 88200:
|
||||||
break;
|
lpcm_prv[8] |= 0x90;
|
||||||
default: break;
|
SubFrameLen = 80;
|
||||||
}
|
break;
|
||||||
|
case 176400:
|
||||||
|
lpcm_prv[8] |= 0xA0;
|
||||||
|
SubFrameLen = 160;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
SubFrameLen *= uNoOfChannels;
|
SubFrameLen *= uNoOfChannels;
|
||||||
SubFrameLen *= (uBitsPerSample / 8);
|
SubFrameLen *= (uBitsPerSample / 8);
|
||||||
|
|
||||||
//rewrite PES size to have as many complete subframes per PES as we can
|
//rewrite PES size to have as many complete subframes per PES as we can
|
||||||
// FIXME: PES header size was hardcoded to 18 in previous code. Actual size returned by InsertPesHeader is 14.
|
// FIXME: PES header size was hardcoded to 18 in previous code. Actual size returned by InsertPesHeader is 14.
|
||||||
SubFramesPerPES = ((2048 - 18) - sizeof(lpcm_prv))/SubFrameLen;
|
SubFramesPerPES = ((2048 - 18) - sizeof(lpcm_prv)) / SubFrameLen;
|
||||||
SubFrameLen *= SubFramesPerPES;
|
SubFrameLen *= SubFramesPerPES;
|
||||||
|
|
||||||
//set number of channels
|
//set number of channels
|
||||||
lpcm_prv[10] = uNoOfChannels - 1;
|
lpcm_prv[10] = uNoOfChannels - 1;
|
||||||
|
|
||||||
switch(uBitsPerSample) {
|
switch (uBitsPerSample) {
|
||||||
case 24:
|
case 24:
|
||||||
lpcm_prv[7] |= 0x20;
|
lpcm_prv[7] |= 0x20;
|
||||||
case 16:
|
case 16:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("inappropriate bits per sample (%d) - must be 16 or 24\n",uBitsPerSample);
|
printf("inappropriate bits per sample (%d) - must be 16 or 24\n",
|
||||||
return 1;
|
uBitsPerSample);
|
||||||
}
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int reset()
|
static int reset()
|
||||||
{
|
{
|
||||||
initialHeader = 1;
|
initialHeader = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writeData(void* _call)
|
static int writeData(void *_call)
|
||||||
{
|
{
|
||||||
WriterAVCallData_t* call = (WriterAVCallData_t*) _call;
|
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||||
|
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
|
|
||||||
pcm_printf(10, "\n");
|
pcm_printf(10, "\n");
|
||||||
|
|
||||||
if (!call) {
|
if (!call) {
|
||||||
pcm_err("call data is NULL...\n");
|
pcm_err("call data is NULL...\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcm_printf(10, "AudioPts %lld\n", call->Pts);
|
||||||
|
|
||||||
|
if (!call->data || (call->len <= 0)) {
|
||||||
|
pcm_err("parsing NULL Data. ignoring...\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (call->fd < 0) {
|
||||||
|
pcm_err("file pointer < 0. ignoring ...\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcmPrivateData_t *pcmPrivateData =
|
||||||
|
(pcmPrivateData_t *) call->private_data;
|
||||||
|
|
||||||
|
if (initialHeader) {
|
||||||
|
initialHeader = 0;
|
||||||
|
prepareClipPlay(pcmPrivateData->uNoOfChannels,
|
||||||
|
pcmPrivateData->uSampleRate,
|
||||||
|
pcmPrivateData->uBitsPerSample,
|
||||||
|
pcmPrivateData->bLittleEndian);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *buffer = call->data;
|
||||||
|
unsigned int size = call->len;
|
||||||
|
|
||||||
|
unsigned int n;
|
||||||
|
unsigned char *injectBuffer = (unsigned char *) malloc(SubFrameLen);
|
||||||
|
unsigned int pos;
|
||||||
|
|
||||||
|
for (pos = 0; pos < size;) {
|
||||||
|
//printf("PCM %s - Position=%d\n", __FUNCTION__, pos);
|
||||||
|
if ((size - pos) < SubFrameLen) {
|
||||||
|
breakBufferFillSize = size - pos;
|
||||||
|
memcpy(breakBuffer, &buffer[pos],
|
||||||
|
sizeof(unsigned char) * breakBufferFillSize);
|
||||||
|
//printf("PCM %s - Unplayed=%d\n", __FUNCTION__, breakBufferFillSize);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//get first PES's worth
|
||||||
|
if (breakBufferFillSize > 0) {
|
||||||
|
memcpy(injectBuffer, breakBuffer,
|
||||||
|
sizeof(unsigned char) * breakBufferFillSize);
|
||||||
|
memcpy(&injectBuffer[breakBufferFillSize], &buffer[pos],
|
||||||
|
sizeof(unsigned char) * (SubFrameLen -
|
||||||
|
breakBufferFillSize));
|
||||||
|
pos += (SubFrameLen - breakBufferFillSize);
|
||||||
|
breakBufferFillSize = 0;
|
||||||
|
} else {
|
||||||
|
memcpy(injectBuffer, &buffer[pos],
|
||||||
|
sizeof(unsigned char) * SubFrameLen);
|
||||||
|
pos += SubFrameLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcm_printf(10, "AudioPts %lld\n", call->Pts);
|
struct iovec iov[3];
|
||||||
|
iov[0].iov_base = PesHeader;
|
||||||
|
iov[1].iov_base = lpcm_prv;
|
||||||
|
iov[1].iov_len = sizeof(lpcm_prv);
|
||||||
|
|
||||||
if (!call->data || (call->len <= 0)) {
|
iov[2].iov_base = injectBuffer;
|
||||||
pcm_err("parsing NULL Data. ignoring...\n");
|
iov[2].iov_len = SubFrameLen;
|
||||||
return 0;
|
|
||||||
|
//write the PCM data
|
||||||
|
if (pcmPrivateData->uBitsPerSample == 16) {
|
||||||
|
for (n = 0; n < SubFrameLen; n += 2) {
|
||||||
|
unsigned char tmp;
|
||||||
|
tmp = injectBuffer[n];
|
||||||
|
injectBuffer[n] = injectBuffer[n + 1];
|
||||||
|
injectBuffer[n + 1] = tmp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 10 11
|
||||||
|
// A1c A1b A1a-B1c B1b B1a-A2c A2b A2a-B2c B2b B2a
|
||||||
|
// to A1a A1b B1a B1b.A2a A2b B2a B2b-A1c B1c A2c B2c
|
||||||
|
for (n = 0; n < SubFrameLen; n += 12) {
|
||||||
|
unsigned char t, *p = &injectBuffer[n];
|
||||||
|
t = p[0];
|
||||||
|
p[0] = p[2];
|
||||||
|
p[2] = p[5];
|
||||||
|
p[5] = p[7];
|
||||||
|
p[7] = p[11];
|
||||||
|
p[11] = p[9];
|
||||||
|
p[9] = p[3];
|
||||||
|
p[3] = p[4];
|
||||||
|
p[4] = p[8];
|
||||||
|
p[8] = t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call->fd < 0) {
|
//increment err... subframe count?
|
||||||
pcm_err("file pointer < 0. ignoring ...\n");
|
lpcm_prv[1] = ((lpcm_prv[1] + SubFramesPerPES) & 0x1F);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pcmPrivateData_t* pcmPrivateData = (pcmPrivateData_t*)call->private_data;
|
iov[0].iov_len =
|
||||||
|
InsertPesHeader(PesHeader, iov[1].iov_len + iov[2].iov_len,
|
||||||
|
PCM_PES_START_CODE, call->Pts, 0);
|
||||||
|
int len = writev(call->fd, iov, 3);
|
||||||
|
if (len < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(injectBuffer);
|
||||||
|
|
||||||
if (initialHeader) {
|
return size;
|
||||||
initialHeader = 0;
|
|
||||||
prepareClipPlay(pcmPrivateData->uNoOfChannels, pcmPrivateData->uSampleRate,
|
|
||||||
pcmPrivateData->uBitsPerSample, pcmPrivateData->bLittleEndian);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char * buffer = call->data;
|
|
||||||
unsigned int size = call->len;
|
|
||||||
|
|
||||||
unsigned int n;
|
|
||||||
unsigned char * injectBuffer = (unsigned char *)malloc(SubFrameLen);
|
|
||||||
unsigned int pos;
|
|
||||||
|
|
||||||
for(pos = 0; pos < size; )
|
|
||||||
{
|
|
||||||
//printf("PCM %s - Position=%d\n", __FUNCTION__, pos);
|
|
||||||
if((size - pos) < SubFrameLen)
|
|
||||||
{
|
|
||||||
breakBufferFillSize = size - pos;
|
|
||||||
memcpy(breakBuffer, &buffer[pos], sizeof(unsigned char) * breakBufferFillSize);
|
|
||||||
//printf("PCM %s - Unplayed=%d\n", __FUNCTION__, breakBufferFillSize);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get first PES's worth
|
|
||||||
if(breakBufferFillSize > 0)
|
|
||||||
{
|
|
||||||
memcpy(injectBuffer, breakBuffer, sizeof(unsigned char)*breakBufferFillSize);
|
|
||||||
memcpy(&injectBuffer[breakBufferFillSize], &buffer[pos], sizeof(unsigned char)*(SubFrameLen - breakBufferFillSize));
|
|
||||||
pos += (SubFrameLen - breakBufferFillSize);
|
|
||||||
breakBufferFillSize = 0;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
memcpy(injectBuffer, &buffer[pos], sizeof(unsigned char)*SubFrameLen);
|
|
||||||
pos += SubFrameLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct iovec iov[3];
|
|
||||||
iov[0].iov_base = PesHeader;
|
|
||||||
iov[1].iov_base = lpcm_prv;
|
|
||||||
iov[1].iov_len = sizeof(lpcm_prv);
|
|
||||||
|
|
||||||
iov[2].iov_base = injectBuffer;
|
|
||||||
iov[2].iov_len = SubFrameLen;
|
|
||||||
|
|
||||||
//write the PCM data
|
|
||||||
if(pcmPrivateData->uBitsPerSample == 16) {
|
|
||||||
for(n=0; n<SubFrameLen; n+=2) {
|
|
||||||
unsigned char tmp;
|
|
||||||
tmp=injectBuffer[n];
|
|
||||||
injectBuffer[n]=injectBuffer[n+1];
|
|
||||||
injectBuffer[n+1]=tmp;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 0 1 2 3 4 5 6 7 8 9 10 11
|
|
||||||
// A1c A1b A1a-B1c B1b B1a-A2c A2b A2a-B2c B2b B2a
|
|
||||||
// to A1a A1b B1a B1b.A2a A2b B2a B2b-A1c B1c A2c B2c
|
|
||||||
for(n=0; n<SubFrameLen; n+=12) {
|
|
||||||
unsigned char t, *p = &injectBuffer[n];
|
|
||||||
t = p[0];
|
|
||||||
p[ 0] = p[ 2];
|
|
||||||
p[ 2] = p[ 5];
|
|
||||||
p[ 5] = p[ 7];
|
|
||||||
p[ 7] = p[11];
|
|
||||||
p[11] = p[ 9];
|
|
||||||
p[ 9] = p[ 3];
|
|
||||||
p[ 3] = p[ 4];
|
|
||||||
p[ 4] = p[ 8];
|
|
||||||
p[ 8] = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//increment err... subframe count?
|
|
||||||
lpcm_prv[1] = ((lpcm_prv[1]+SubFramesPerPES) & 0x1F);
|
|
||||||
|
|
||||||
iov[0].iov_len = InsertPesHeader (PesHeader, iov[1].iov_len + iov[2].iov_len, PCM_PES_START_CODE, call->Pts, 0);
|
|
||||||
int len = writev(call->fd, iov, 3);
|
|
||||||
if (len < 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(injectBuffer);
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
@@ -293,29 +308,29 @@ static int writeData(void* _call)
|
|||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static WriterCaps_t caps_pcm = {
|
static WriterCaps_t caps_pcm = {
|
||||||
"pcm",
|
"pcm",
|
||||||
eAudio,
|
eAudio,
|
||||||
"A_PCM",
|
"A_PCM",
|
||||||
AUDIO_ENCODING_LPCMA
|
AUDIO_ENCODING_LPCMA
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Writer_s WriterAudioPCM = {
|
struct Writer_s WriterAudioPCM = {
|
||||||
&reset,
|
&reset,
|
||||||
&writeData,
|
&writeData,
|
||||||
NULL,
|
NULL,
|
||||||
&caps_pcm
|
&caps_pcm
|
||||||
};
|
};
|
||||||
|
|
||||||
static WriterCaps_t caps_ipcm = {
|
static WriterCaps_t caps_ipcm = {
|
||||||
"ipcm",
|
"ipcm",
|
||||||
eAudio,
|
eAudio,
|
||||||
"A_IPCM",
|
"A_IPCM",
|
||||||
AUDIO_ENCODING_LPCMA
|
AUDIO_ENCODING_LPCMA
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Writer_s WriterAudioIPCM = {
|
struct Writer_s WriterAudioIPCM = {
|
||||||
&reset,
|
&reset,
|
||||||
&writeData,
|
&writeData,
|
||||||
NULL,
|
NULL,
|
||||||
&caps_ipcm
|
&caps_ipcm
|
||||||
};
|
};
|
||||||
|
@@ -69,84 +69,83 @@
|
|||||||
|
|
||||||
int InsertVideoPrivateDataHeader(unsigned char *data, int payload_size)
|
int InsertVideoPrivateDataHeader(unsigned char *data, int payload_size)
|
||||||
{
|
{
|
||||||
BitPacker_t ld2 = {data, 0, 32};
|
BitPacker_t ld2 = { data, 0, 32 };
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
PutBits (&ld2, PES_PRIVATE_DATA_FLAG, 8);
|
PutBits(&ld2, PES_PRIVATE_DATA_FLAG, 8);
|
||||||
PutBits (&ld2, payload_size & 0xff, 8);
|
PutBits(&ld2, payload_size & 0xff, 8);
|
||||||
PutBits (&ld2, (payload_size >> 8) & 0xff, 8);
|
PutBits(&ld2, (payload_size >> 8) & 0xff, 8);
|
||||||
PutBits (&ld2, (payload_size >> 16) & 0xff, 8);
|
PutBits(&ld2, (payload_size >> 16) & 0xff, 8);
|
||||||
|
|
||||||
for (i = 4; i < (PES_PRIVATE_DATA_LENGTH+1); i++)
|
for (i = 4; i < (PES_PRIVATE_DATA_LENGTH + 1); i++)
|
||||||
PutBits (&ld2, 0, 8);
|
PutBits(&ld2, 0, 8);
|
||||||
|
|
||||||
FlushBits (&ld2);
|
FlushBits(&ld2);
|
||||||
|
|
||||||
return PES_PRIVATE_DATA_LENGTH + 1;
|
return PES_PRIVATE_DATA_LENGTH + 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int InsertPesHeader (unsigned char *data, int size, unsigned char stream_id, unsigned long long int pts, int pic_start_code)
|
int InsertPesHeader(unsigned char *data, int size, unsigned char stream_id,
|
||||||
|
unsigned long long int pts, int pic_start_code)
|
||||||
{
|
{
|
||||||
BitPacker_t ld2 = {data, 0, 32};
|
BitPacker_t ld2 = { data, 0, 32 };
|
||||||
|
|
||||||
if (size > MAX_PES_PACKET_SIZE)
|
if (size > MAX_PES_PACKET_SIZE)
|
||||||
size = 0; // unbounded
|
size = 0; // unbounded
|
||||||
|
|
||||||
PutBits(&ld2,0x0 ,8);
|
PutBits(&ld2, 0x0, 8);
|
||||||
PutBits(&ld2,0x0 ,8);
|
PutBits(&ld2, 0x0, 8);
|
||||||
PutBits(&ld2,0x1 ,8); // Start Code
|
PutBits(&ld2, 0x1, 8); // Start Code
|
||||||
PutBits(&ld2,stream_id ,8); // Stream_id = Audio Stream
|
PutBits(&ld2, stream_id, 8); // Stream_id = Audio Stream
|
||||||
//4
|
//4
|
||||||
PutBits(&ld2,size + 3 + (pts != INVALID_PTS_VALUE ? 5:0) + (pic_start_code ? (5) : 0),16); // PES_packet_length
|
PutBits(&ld2, size + 3 + (pts != INVALID_PTS_VALUE ? 5 : 0) + (pic_start_code ? (5) : 0), 16); // PES_packet_length
|
||||||
//6 = 4+2
|
//6 = 4+2
|
||||||
PutBits(&ld2,0x2 ,2); // 10
|
PutBits(&ld2, 0x2, 2); // 10
|
||||||
PutBits(&ld2,0x0 ,2); // PES_Scrambling_control
|
PutBits(&ld2, 0x0, 2); // PES_Scrambling_control
|
||||||
PutBits(&ld2,0x0 ,1); // PES_Priority
|
PutBits(&ld2, 0x0, 1); // PES_Priority
|
||||||
PutBits(&ld2,0x0 ,1); // data_alignment_indicator
|
PutBits(&ld2, 0x0, 1); // data_alignment_indicator
|
||||||
PutBits(&ld2,0x0 ,1); // Copyright
|
PutBits(&ld2, 0x0, 1); // Copyright
|
||||||
PutBits(&ld2,0x0 ,1); // Original or Copy
|
PutBits(&ld2, 0x0, 1); // Original or Copy
|
||||||
//7 = 6+1
|
//7 = 6+1
|
||||||
|
|
||||||
if (pts!=INVALID_PTS_VALUE)
|
if (pts != INVALID_PTS_VALUE)
|
||||||
PutBits(&ld2,0x2 ,2);
|
PutBits(&ld2, 0x2, 2);
|
||||||
else
|
else
|
||||||
PutBits(&ld2,0x0 ,2); // PTS_DTS flag
|
PutBits(&ld2, 0x0, 2); // PTS_DTS flag
|
||||||
|
|
||||||
PutBits(&ld2,0x0 ,1); // ESCR_flag
|
PutBits(&ld2, 0x0, 1); // ESCR_flag
|
||||||
PutBits(&ld2,0x0 ,1); // ES_rate_flag
|
PutBits(&ld2, 0x0, 1); // ES_rate_flag
|
||||||
PutBits(&ld2,0x0 ,1); // DSM_trick_mode_flag
|
PutBits(&ld2, 0x0, 1); // DSM_trick_mode_flag
|
||||||
PutBits(&ld2,0x0 ,1); // additional_copy_ingo_flag
|
PutBits(&ld2, 0x0, 1); // additional_copy_ingo_flag
|
||||||
PutBits(&ld2,0x0 ,1); // PES_CRC_flag
|
PutBits(&ld2, 0x0, 1); // PES_CRC_flag
|
||||||
PutBits(&ld2,0x0 ,1); // PES_extension_flag
|
PutBits(&ld2, 0x0, 1); // PES_extension_flag
|
||||||
//8 = 7+1
|
//8 = 7+1
|
||||||
|
|
||||||
if (pts!=INVALID_PTS_VALUE)
|
if (pts != INVALID_PTS_VALUE)
|
||||||
PutBits(&ld2,0x5,8);
|
PutBits(&ld2, 0x5, 8);
|
||||||
else
|
else
|
||||||
PutBits(&ld2,0x0 ,8); // PES_header_data_length
|
PutBits(&ld2, 0x0, 8); // PES_header_data_length
|
||||||
//9 = 8+1
|
//9 = 8+1
|
||||||
|
|
||||||
if (pts!=INVALID_PTS_VALUE)
|
if (pts != INVALID_PTS_VALUE) {
|
||||||
{
|
PutBits(&ld2, 0x2, 4);
|
||||||
PutBits(&ld2,0x2,4);
|
PutBits(&ld2, (pts >> 30) & 0x7, 3);
|
||||||
PutBits(&ld2,(pts>>30) & 0x7,3);
|
PutBits(&ld2, 0x1, 1);
|
||||||
PutBits(&ld2,0x1,1);
|
PutBits(&ld2, (pts >> 15) & 0x7fff, 15);
|
||||||
PutBits(&ld2,(pts>>15) & 0x7fff,15);
|
PutBits(&ld2, 0x1, 1);
|
||||||
PutBits(&ld2,0x1,1);
|
PutBits(&ld2, pts & 0x7fff, 15);
|
||||||
PutBits(&ld2,pts & 0x7fff,15);
|
PutBits(&ld2, 0x1, 1);
|
||||||
PutBits(&ld2,0x1,1);
|
|
||||||
}
|
}
|
||||||
//14 = 9+5
|
//14 = 9+5
|
||||||
|
|
||||||
if (pic_start_code)
|
if (pic_start_code) {
|
||||||
{
|
PutBits(&ld2, 0x0, 8);
|
||||||
PutBits(&ld2,0x0 ,8);
|
PutBits(&ld2, 0x0, 8);
|
||||||
PutBits(&ld2,0x0 ,8);
|
PutBits(&ld2, 0x1, 8); // Start Code
|
||||||
PutBits(&ld2,0x1 ,8); // Start Code
|
PutBits(&ld2, pic_start_code & 0xff, 8); // 00, for picture start
|
||||||
PutBits(&ld2,pic_start_code & 0xff ,8); // 00, for picture start
|
PutBits(&ld2, (pic_start_code >> 8) & 0xff, 8); // For any extra information (like in mpeg4p2, the pic_start_code)
|
||||||
PutBits(&ld2,(pic_start_code >> 8 )&0xff,8); // For any extra information (like in mpeg4p2, the pic_start_code)
|
//14 + 4 = 18
|
||||||
//14 + 4 = 18
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FlushBits(&ld2);
|
FlushBits(&ld2);
|
||||||
|
@@ -85,20 +85,20 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x);
|
|||||||
/* Types */
|
/* Types */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static const unsigned char SequenceLayerStartCode[] = {0x00, 0x00, 0x01, VC1_SEQUENCE_LAYER_METADATA_START_CODE};
|
static const unsigned char SequenceLayerStartCode[] =
|
||||||
|
{ 0x00, 0x00, 0x01, VC1_SEQUENCE_LAYER_METADATA_START_CODE };
|
||||||
|
|
||||||
|
|
||||||
static const unsigned char Metadata[] =
|
static const unsigned char Metadata[] = {
|
||||||
{
|
0x00, 0x00, 0x00, 0xc5,
|
||||||
0x00, 0x00, 0x00, 0xc5,
|
0x04, 0x00, 0x00, 0x00,
|
||||||
0x04, 0x00, 0x00, 0x00,
|
0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile */
|
||||||
0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile*/
|
0x00, 0x00, 0x00, 0x00, /* Struct A */
|
||||||
0x00, 0x00, 0x00, 0x00, /* Struct A */
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x0c, 0x00, 0x00, 0x00,
|
||||||
0x0c, 0x00, 0x00, 0x00,
|
0x60, 0x00, 0x00, 0x00, /* Struct B */
|
||||||
0x60, 0x00, 0x00, 0x00, /* Struct B */
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00
|
||||||
0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
@@ -121,9 +121,9 @@ static int reset()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writeData(void* _call)
|
static int writeData(void *_call)
|
||||||
{
|
{
|
||||||
WriterAVCallData_t* call = (WriterAVCallData_t*) _call;
|
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
@@ -151,81 +151,94 @@ static int writeData(void* _call)
|
|||||||
|
|
||||||
if (initialHeader) {
|
if (initialHeader) {
|
||||||
|
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
unsigned char PesPayload[128];
|
unsigned char PesPayload[128];
|
||||||
unsigned char* PesPtr;
|
unsigned char *PesPtr;
|
||||||
unsigned int crazyFramerate = 0;
|
unsigned int crazyFramerate = 0;
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
|
|
||||||
vc1_printf(10, "Framerate: %u\n", call->FrameRate);
|
vc1_printf(10, "Framerate: %u\n", call->FrameRate);
|
||||||
vc1_printf(10, "biWidth: %d\n", call->Width);
|
vc1_printf(10, "biWidth: %d\n", call->Width);
|
||||||
vc1_printf(10, "biHeight: %d\n", call->Height);
|
vc1_printf(10, "biHeight: %d\n", call->Height);
|
||||||
|
|
||||||
crazyFramerate = ((10000000.0 / call->FrameRate) * 1000.0);
|
crazyFramerate = ((10000000.0 / call->FrameRate) * 1000.0);
|
||||||
vc1_printf(10, "crazyFramerate: %u\n", crazyFramerate);
|
vc1_printf(10, "crazyFramerate: %u\n", crazyFramerate);
|
||||||
|
|
||||||
memset(PesPayload, 0, sizeof(PesPayload));
|
memset(PesPayload, 0, sizeof(PesPayload));
|
||||||
|
|
||||||
PesPtr = PesPayload;
|
PesPtr = PesPayload;
|
||||||
|
|
||||||
memcpy (PesPtr, SequenceLayerStartCode, sizeof(SequenceLayerStartCode));
|
memcpy(PesPtr, SequenceLayerStartCode,
|
||||||
PesPtr += sizeof(SequenceLayerStartCode);
|
sizeof(SequenceLayerStartCode));
|
||||||
|
PesPtr += sizeof(SequenceLayerStartCode);
|
||||||
|
|
||||||
memcpy (PesPtr, Metadata, sizeof(Metadata));
|
memcpy(PesPtr, Metadata, sizeof(Metadata));
|
||||||
PesPtr += METADATA_STRUCT_C_START;
|
PesPtr += METADATA_STRUCT_C_START;
|
||||||
PesPtr += WMV3_PRIVATE_DATA_LENGTH;
|
PesPtr += WMV3_PRIVATE_DATA_LENGTH;
|
||||||
|
|
||||||
/* Metadata Header Struct A */
|
/* Metadata Header Struct A */
|
||||||
*PesPtr++ = (call->Height >> 0) & 0xff;
|
*PesPtr++ = (call->Height >> 0) & 0xff;
|
||||||
*PesPtr++ = (call->Height >> 8) & 0xff;
|
*PesPtr++ = (call->Height >> 8) & 0xff;
|
||||||
*PesPtr++ = (call->Height >> 16) & 0xff;
|
*PesPtr++ = (call->Height >> 16) & 0xff;
|
||||||
*PesPtr++ = call->Height >> 24;
|
*PesPtr++ = call->Height >> 24;
|
||||||
*PesPtr++ = (call->Width >> 0) & 0xff;
|
*PesPtr++ = (call->Width >> 0) & 0xff;
|
||||||
*PesPtr++ = (call->Width >> 8) & 0xff;
|
*PesPtr++ = (call->Width >> 8) & 0xff;
|
||||||
*PesPtr++ = (call->Width >> 16) & 0xff;
|
*PesPtr++ = (call->Width >> 16) & 0xff;
|
||||||
*PesPtr++ = call->Width >> 24;
|
*PesPtr++ = call->Width >> 24;
|
||||||
|
|
||||||
PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */
|
PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */
|
||||||
|
|
||||||
*PesPtr++ = (crazyFramerate >> 0) & 0xff;
|
*PesPtr++ = (crazyFramerate >> 0) & 0xff;
|
||||||
*PesPtr++ = (crazyFramerate >> 8) & 0xff;
|
*PesPtr++ = (crazyFramerate >> 8) & 0xff;
|
||||||
*PesPtr++ = (crazyFramerate >> 16) & 0xff;
|
*PesPtr++ = (crazyFramerate >> 16) & 0xff;
|
||||||
*PesPtr++ = crazyFramerate >> 24;
|
*PesPtr++ = crazyFramerate >> 24;
|
||||||
|
|
||||||
iov[0].iov_base = PesHeader;
|
iov[0].iov_base = PesHeader;
|
||||||
iov[1].iov_base = PesPayload;
|
iov[1].iov_base = PesPayload;
|
||||||
iov[1].iov_len = PesPtr - PesPayload;
|
iov[1].iov_len = PesPtr - PesPayload;
|
||||||
iov[0].iov_len = InsertPesHeader (PesHeader, iov[1].iov_len, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
|
iov[0].iov_len =
|
||||||
|
InsertPesHeader(PesHeader, iov[1].iov_len,
|
||||||
|
VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE,
|
||||||
|
0);
|
||||||
len = writev(call->fd, iov, 2);
|
len = writev(call->fd, iov, 2);
|
||||||
|
|
||||||
/* For VC1 the codec private data is a standard vc1 sequence header so we just copy it to the output */
|
/* For VC1 the codec private data is a standard vc1 sequence header so we just copy it to the output */
|
||||||
iov[0].iov_base = PesHeader;
|
iov[0].iov_base = PesHeader;
|
||||||
iov[1].iov_base = call->private_data;
|
iov[1].iov_base = call->private_data;
|
||||||
iov[1].iov_len = call->private_size;
|
iov[1].iov_len = call->private_size;
|
||||||
iov[0].iov_len = InsertPesHeader (PesHeader, iov[1].iov_len, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
|
iov[0].iov_len =
|
||||||
|
InsertPesHeader(PesHeader, iov[1].iov_len,
|
||||||
|
VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE,
|
||||||
|
0);
|
||||||
len = writev(call->fd, iov, 2);
|
len = writev(call->fd, iov, 2);
|
||||||
|
|
||||||
initialHeader = 0;
|
initialHeader = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(call->len > 0 && call->data) {
|
if (call->len > 0 && call->data) {
|
||||||
unsigned int Position = 0;
|
unsigned int Position = 0;
|
||||||
unsigned char insertSampleHeader = 1;
|
unsigned char insertSampleHeader = 1;
|
||||||
|
|
||||||
while(Position < call->len) {
|
while (Position < call->len) {
|
||||||
|
|
||||||
int PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ?
|
int PacketLength =
|
||||||
(call->len - Position) : MAX_PES_PACKET_SIZE;
|
(call->len - Position) <=
|
||||||
|
MAX_PES_PACKET_SIZE ? (call->len -
|
||||||
|
Position) : MAX_PES_PACKET_SIZE;
|
||||||
|
|
||||||
int Remaining = call->len - Position - PacketLength;
|
int Remaining = call->len - Position - PacketLength;
|
||||||
|
|
||||||
vc1_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", PacketLength, Remaining, Position);
|
vc1_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n",
|
||||||
|
PacketLength, Remaining, Position);
|
||||||
|
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
int HeaderLength = InsertPesHeader (PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, call->Pts, 0);
|
int HeaderLength =
|
||||||
|
InsertPesHeader(PesHeader, PacketLength,
|
||||||
|
VC1_VIDEO_PES_START_CODE, call->Pts, 0);
|
||||||
|
|
||||||
if(insertSampleHeader) {
|
if (insertSampleHeader) {
|
||||||
const unsigned char Vc1FrameStartCode[] = {0, 0, 1, VC1_FRAME_START_CODE};
|
const unsigned char Vc1FrameStartCode[] =
|
||||||
|
{ 0, 0, 1, VC1_FRAME_START_CODE };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vc1_printf(10, "Data Start: {00 00 01 0d} - ");
|
vc1_printf(10, "Data Start: {00 00 01 0d} - ");
|
||||||
@@ -234,13 +247,14 @@ static int writeData(void* _call)
|
|||||||
vc1_printf(10, "\n");
|
vc1_printf(10, "\n");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!FrameHeaderSeen && (call->len > 3) && (memcmp (call->data, Vc1FrameStartCode, 4) == 0))
|
if (!FrameHeaderSeen && (call->len > 3)
|
||||||
FrameHeaderSeen = 1;
|
&& (memcmp(call->data, Vc1FrameStartCode, 4) == 0))
|
||||||
if (!FrameHeaderSeen)
|
FrameHeaderSeen = 1;
|
||||||
{
|
if (!FrameHeaderSeen) {
|
||||||
memcpy (&PesHeader[HeaderLength], Vc1FrameStartCode, sizeof(Vc1FrameStartCode));
|
memcpy(&PesHeader[HeaderLength], Vc1FrameStartCode,
|
||||||
HeaderLength += sizeof(Vc1FrameStartCode);
|
sizeof(Vc1FrameStartCode));
|
||||||
}
|
HeaderLength += sizeof(Vc1FrameStartCode);
|
||||||
|
}
|
||||||
insertSampleHeader = 0;
|
insertSampleHeader = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -93,72 +93,71 @@ static int reset()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writeData(void* _call)
|
static int writeData(void *_call)
|
||||||
{
|
{
|
||||||
WriterAVCallData_t* call = (WriterAVCallData_t*) _call;
|
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
wma_printf(10, "\n");
|
wma_printf(10, "\n");
|
||||||
|
|
||||||
if (call == NULL)
|
if (call == NULL) {
|
||||||
{
|
wma_err("call data is NULL...\n");
|
||||||
wma_err("call data is NULL...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wma_printf(10, "AudioPts %lld\n", call->Pts);
|
wma_printf(10, "AudioPts %lld\n", call->Pts);
|
||||||
|
|
||||||
if ((call->data == NULL) || (call->len <= 0))
|
if ((call->data == NULL) || (call->len <= 0)) {
|
||||||
{
|
wma_err("parsing NULL Data. ignoring...\n");
|
||||||
wma_err("parsing NULL Data. ignoring...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call->fd < 0)
|
if (call->fd < 0) {
|
||||||
{
|
wma_err("file pointer < 0. ignoring ...\n");
|
||||||
wma_err("file pointer < 0. ignoring ...\n");
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initialHeader) {
|
if (initialHeader) {
|
||||||
|
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
|
|
||||||
if ((call->private_size <= 0) || (call->private_data == NULL))
|
if ((call->private_size <= 0) || (call->private_data == NULL)) {
|
||||||
{
|
wma_err("private NULL.\n");
|
||||||
wma_err("private NULL.\n");
|
return -1;
|
||||||
return -1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
iov[0].iov_base = PesHeader;
|
iov[0].iov_base = PesHeader;
|
||||||
iov[0].iov_len = InsertPesHeader (PesHeader, call->private_size, MPEG_AUDIO_PES_START_CODE, 0, 0);
|
iov[0].iov_len =
|
||||||
|
InsertPesHeader(PesHeader, call->private_size,
|
||||||
|
MPEG_AUDIO_PES_START_CODE, 0, 0);
|
||||||
iov[1].iov_base = call->private_data;
|
iov[1].iov_base = call->private_data;
|
||||||
iov[1].iov_len = call->private_size;
|
iov[1].iov_len = call->private_size;
|
||||||
|
|
||||||
len = writev(call->fd, iov, 2);
|
len = writev(call->fd, iov, 2);
|
||||||
|
|
||||||
initialHeader = 0;
|
initialHeader = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > -1 && call->len > 0 && call->data)
|
if (len > -1 && call->len > 0 && call->data) {
|
||||||
{
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
|
||||||
|
|
||||||
|
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
iov[0].iov_base = PesHeader;
|
iov[0].iov_base = PesHeader;
|
||||||
iov[0].iov_len = InsertPesHeader (PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
|
iov[0].iov_len =
|
||||||
|
InsertPesHeader(PesHeader, call->len,
|
||||||
|
MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
|
||||||
iov[1].iov_base = call->data;
|
iov[1].iov_base = call->data;
|
||||||
iov[1].iov_len = call->len;
|
iov[1].iov_len = call->len;
|
||||||
|
|
||||||
ssize_t l = writev(call->fd, iov, 2);
|
ssize_t l = writev(call->fd, iov, 2);
|
||||||
if (l > -1)
|
if (l > -1)
|
||||||
len += l;
|
len += l;
|
||||||
else
|
else
|
||||||
len = l;
|
len = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
wma_printf(10, "wma < %d\n", len);
|
wma_printf(10, "wma < %d\n", len);
|
||||||
|
@@ -81,25 +81,23 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x);
|
|||||||
/* Types */
|
/* Types */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
unsigned char privateData[WMV3_PRIVATE_DATA_LENGTH];
|
||||||
unsigned char privateData[WMV3_PRIVATE_DATA_LENGTH];
|
unsigned int width;
|
||||||
unsigned int width;
|
unsigned int height;
|
||||||
unsigned int height;
|
unsigned int framerate;
|
||||||
unsigned int framerate;
|
|
||||||
} awmv_t;
|
} awmv_t;
|
||||||
|
|
||||||
static const unsigned char Metadata[] =
|
static const unsigned char Metadata[] = {
|
||||||
{
|
0x00, 0x00, 0x00, 0xc5,
|
||||||
0x00, 0x00, 0x00, 0xc5,
|
0x04, 0x00, 0x00, 0x00,
|
||||||
0x04, 0x00, 0x00, 0x00,
|
0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile */
|
||||||
0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile*/
|
0x00, 0x00, 0x00, 0x00, /* Struct A */
|
||||||
0x00, 0x00, 0x00, 0x00, /* Struct A */
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x0c, 0x00, 0x00, 0x00,
|
||||||
0x0c, 0x00, 0x00, 0x00,
|
0x60, 0x00, 0x00, 0x00, /* Struct B */
|
||||||
0x60, 0x00, 0x00, 0x00, /* Struct B */
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00
|
||||||
0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
@@ -120,9 +118,9 @@ static int reset()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int writeData(void* _call)
|
static int writeData(void *_call)
|
||||||
{
|
{
|
||||||
WriterAVCallData_t* call = (WriterAVCallData_t*) _call;
|
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||||
|
|
||||||
awmv_t private_data;
|
awmv_t private_data;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
@@ -130,25 +128,27 @@ static int writeData(void* _call)
|
|||||||
wmv_printf(10, "\n");
|
wmv_printf(10, "\n");
|
||||||
|
|
||||||
if (call == NULL) {
|
if (call == NULL) {
|
||||||
wmv_err("call data is NULL...\n");
|
wmv_err("call data is NULL...\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((call->data == NULL) || (call->len <= 0)) {
|
if ((call->data == NULL) || (call->len <= 0)) {
|
||||||
wmv_err("parsing NULL Data. ignoring...\n");
|
wmv_err("parsing NULL Data. ignoring...\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call->fd < 0) {
|
if (call->fd < 0) {
|
||||||
wmv_err("file pointer < 0. ignoring ...\n");
|
wmv_err("file pointer < 0. ignoring ...\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
wmv_printf(10, "VideoPts %lld\n", call->Pts);
|
wmv_printf(10, "VideoPts %lld\n", call->Pts);
|
||||||
wmv_printf(10, "Got Private Size %d\n", call->private_size);
|
wmv_printf(10, "Got Private Size %d\n", call->private_size);
|
||||||
|
|
||||||
memcpy(private_data.privateData, call->private_data,
|
memcpy(private_data.privateData, call->private_data,
|
||||||
call->private_size>WMV3_PRIVATE_DATA_LENGTH?WMV3_PRIVATE_DATA_LENGTH:call->private_size);
|
call->private_size >
|
||||||
|
WMV3_PRIVATE_DATA_LENGTH ? WMV3_PRIVATE_DATA_LENGTH : call->
|
||||||
|
private_size);
|
||||||
|
|
||||||
private_data.width = call->Width;
|
private_data.width = call->Width;
|
||||||
private_data.height = call->Height;
|
private_data.height = call->Height;
|
||||||
@@ -156,97 +156,110 @@ static int writeData(void* _call)
|
|||||||
|
|
||||||
#define PES_MIN_HEADER_SIZE 9
|
#define PES_MIN_HEADER_SIZE 9
|
||||||
if (initialHeader) {
|
if (initialHeader) {
|
||||||
unsigned char PesPacket[PES_MIN_HEADER_SIZE+128];
|
unsigned char PesPacket[PES_MIN_HEADER_SIZE + 128];
|
||||||
unsigned char* PesPtr;
|
unsigned char *PesPtr;
|
||||||
unsigned int MetadataLength;
|
unsigned int MetadataLength;
|
||||||
unsigned int crazyFramerate = 0;
|
unsigned int crazyFramerate = 0;
|
||||||
|
|
||||||
wmv_printf(10, "Framerate: %u\n", private_data.framerate);
|
wmv_printf(10, "Framerate: %u\n", private_data.framerate);
|
||||||
wmv_printf(10, "biWidth: %d\n", private_data.width);
|
wmv_printf(10, "biWidth: %d\n", private_data.width);
|
||||||
wmv_printf(10, "biHeight: %d\n", private_data.height);
|
wmv_printf(10, "biHeight: %d\n", private_data.height);
|
||||||
|
|
||||||
crazyFramerate = ((10000000.0 / private_data.framerate) * 1000.0);
|
crazyFramerate = ((10000000.0 / private_data.framerate) * 1000.0);
|
||||||
wmv_printf(10, "crazyFramerate: %u\n", crazyFramerate);
|
wmv_printf(10, "crazyFramerate: %u\n", crazyFramerate);
|
||||||
|
|
||||||
PesPtr = &PesPacket[PES_MIN_HEADER_SIZE];
|
PesPtr = &PesPacket[PES_MIN_HEADER_SIZE];
|
||||||
|
|
||||||
memcpy (PesPtr, Metadata, sizeof(Metadata));
|
memcpy(PesPtr, Metadata, sizeof(Metadata));
|
||||||
PesPtr += METADATA_STRUCT_C_START;
|
PesPtr += METADATA_STRUCT_C_START;
|
||||||
|
|
||||||
memcpy (PesPtr, private_data.privateData, WMV3_PRIVATE_DATA_LENGTH);
|
memcpy(PesPtr, private_data.privateData, WMV3_PRIVATE_DATA_LENGTH);
|
||||||
PesPtr += WMV3_PRIVATE_DATA_LENGTH;
|
PesPtr += WMV3_PRIVATE_DATA_LENGTH;
|
||||||
|
|
||||||
/* Metadata Header Struct A */
|
/* Metadata Header Struct A */
|
||||||
*PesPtr++ = (private_data.height >> 0) & 0xff;
|
*PesPtr++ = (private_data.height >> 0) & 0xff;
|
||||||
*PesPtr++ = (private_data.height >> 8) & 0xff;
|
*PesPtr++ = (private_data.height >> 8) & 0xff;
|
||||||
*PesPtr++ = (private_data.height >> 16) & 0xff;
|
*PesPtr++ = (private_data.height >> 16) & 0xff;
|
||||||
*PesPtr++ = private_data.height >> 24;
|
*PesPtr++ = private_data.height >> 24;
|
||||||
*PesPtr++ = (private_data.width >> 0) & 0xff;
|
*PesPtr++ = (private_data.width >> 0) & 0xff;
|
||||||
*PesPtr++ = (private_data.width >> 8) & 0xff;
|
*PesPtr++ = (private_data.width >> 8) & 0xff;
|
||||||
*PesPtr++ = (private_data.width >> 16) & 0xff;
|
*PesPtr++ = (private_data.width >> 16) & 0xff;
|
||||||
*PesPtr++ = private_data.width >> 24;
|
*PesPtr++ = private_data.width >> 24;
|
||||||
|
|
||||||
PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */
|
PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */
|
||||||
|
|
||||||
*PesPtr++ = (crazyFramerate >> 0) & 0xff;
|
*PesPtr++ = (crazyFramerate >> 0) & 0xff;
|
||||||
*PesPtr++ = (crazyFramerate >> 8) & 0xff;
|
*PesPtr++ = (crazyFramerate >> 8) & 0xff;
|
||||||
*PesPtr++ = (crazyFramerate >> 16) & 0xff;
|
*PesPtr++ = (crazyFramerate >> 16) & 0xff;
|
||||||
*PesPtr++ = crazyFramerate >> 24;
|
*PesPtr++ = crazyFramerate >> 24;
|
||||||
|
|
||||||
MetadataLength = PesPtr - &PesPacket[PES_MIN_HEADER_SIZE];
|
MetadataLength = PesPtr - &PesPacket[PES_MIN_HEADER_SIZE];
|
||||||
|
|
||||||
int HeaderLength = InsertPesHeader (PesPacket, MetadataLength, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
|
int HeaderLength =
|
||||||
|
InsertPesHeader(PesPacket, MetadataLength,
|
||||||
|
VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE,
|
||||||
|
0);
|
||||||
|
|
||||||
len = write(call->fd,PesPacket, HeaderLength + MetadataLength);
|
len = write(call->fd, PesPacket, HeaderLength + MetadataLength);
|
||||||
|
|
||||||
initialHeader = 0;
|
initialHeader = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(call->len > 0 && call->data) {
|
if (call->len > 0 && call->data) {
|
||||||
unsigned int Position = 0;
|
unsigned int Position = 0;
|
||||||
unsigned char insertSampleHeader = 1;
|
unsigned char insertSampleHeader = 1;
|
||||||
while(Position < call->len) {
|
while (Position < call->len) {
|
||||||
|
|
||||||
int PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ?
|
int PacketLength =
|
||||||
(call->len - Position) : MAX_PES_PACKET_SIZE;
|
(call->len - Position) <=
|
||||||
|
MAX_PES_PACKET_SIZE ? (call->len -
|
||||||
|
Position) : MAX_PES_PACKET_SIZE;
|
||||||
|
|
||||||
int Remaining = call->len - Position - PacketLength;
|
int Remaining = call->len - Position - PacketLength;
|
||||||
|
|
||||||
wmv_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", PacketLength, Remaining, Position);
|
wmv_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n",
|
||||||
|
PacketLength, Remaining, Position);
|
||||||
|
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
memset (PesHeader, '0', PES_MAX_HEADER_SIZE);
|
memset(PesHeader, '0', PES_MAX_HEADER_SIZE);
|
||||||
int HeaderLength = InsertPesHeader (PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, call->Pts, 0);
|
int HeaderLength =
|
||||||
unsigned char* PacketStart;
|
InsertPesHeader(PesHeader, PacketLength,
|
||||||
|
VC1_VIDEO_PES_START_CODE, call->Pts, 0);
|
||||||
|
unsigned char *PacketStart;
|
||||||
|
|
||||||
if(insertSampleHeader) {
|
if (insertSampleHeader) {
|
||||||
unsigned int PesLength;
|
unsigned int PesLength;
|
||||||
unsigned int PrivateHeaderLength;
|
unsigned int PrivateHeaderLength;
|
||||||
|
|
||||||
PrivateHeaderLength = InsertVideoPrivateDataHeader (&PesHeader[HeaderLength],
|
PrivateHeaderLength =
|
||||||
call->len);
|
InsertVideoPrivateDataHeader(&PesHeader[HeaderLength],
|
||||||
/* Update PesLength */
|
call->len);
|
||||||
PesLength = PesHeader[PES_LENGTH_BYTE_0] +
|
/* Update PesLength */
|
||||||
(PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength;
|
PesLength = PesHeader[PES_LENGTH_BYTE_0] +
|
||||||
PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff;
|
(PesHeader[PES_LENGTH_BYTE_1] << 8) +
|
||||||
PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff;
|
PrivateHeaderLength;
|
||||||
PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength;
|
PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff;
|
||||||
PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT;
|
PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff;
|
||||||
|
PesHeader[PES_HEADER_DATA_LENGTH_BYTE] +=
|
||||||
|
PrivateHeaderLength;
|
||||||
|
PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT;
|
||||||
|
|
||||||
HeaderLength += PrivateHeaderLength;
|
HeaderLength += PrivateHeaderLength;
|
||||||
insertSampleHeader = 0;
|
insertSampleHeader = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketStart = malloc(call->len + HeaderLength);
|
PacketStart = malloc(call->len + HeaderLength);
|
||||||
memcpy (PacketStart, PesHeader, HeaderLength);
|
memcpy(PacketStart, PesHeader, HeaderLength);
|
||||||
memcpy (PacketStart + HeaderLength, call->data + Position, PacketLength);
|
memcpy(PacketStart + HeaderLength, call->data + Position,
|
||||||
|
PacketLength);
|
||||||
|
|
||||||
len = write(call->fd, PacketStart, PacketLength + HeaderLength);
|
len =
|
||||||
free(PacketStart);
|
write(call->fd, PacketStart, PacketLength + HeaderLength);
|
||||||
|
free(PacketStart);
|
||||||
|
|
||||||
Position += PacketLength;
|
Position += PacketLength;
|
||||||
call->Pts = INVALID_PTS_VALUE;
|
call->Pts = INVALID_PTS_VALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wmv_printf(10, "< %d\n", len);
|
wmv_printf(10, "< %d\n", len);
|
||||||
|
@@ -58,7 +58,7 @@ if (debug_level >= level) printf(x); } while (0)
|
|||||||
/* Varaibles */
|
/* Varaibles */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
static Writer_t * AvailableWriter[] = {
|
static Writer_t *AvailableWriter[] = {
|
||||||
&WriterAudioIPCM,
|
&WriterAudioIPCM,
|
||||||
&WriterAudioPCM,
|
&WriterAudioPCM,
|
||||||
&WriterAudioMP3,
|
&WriterAudioMP3,
|
||||||
@@ -93,35 +93,35 @@ static Writer_t * AvailableWriter[] = {
|
|||||||
/* Functions */
|
/* Functions */
|
||||||
/* ***************************** */
|
/* ***************************** */
|
||||||
|
|
||||||
Writer_t* getWriter(char* encoding)
|
Writer_t *getWriter(char *encoding)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; AvailableWriter[i] != NULL; i++)
|
for (i = 0; AvailableWriter[i] != NULL; i++) {
|
||||||
{
|
if (strcmp(AvailableWriter[i]->caps->textEncoding, encoding) == 0) {
|
||||||
if (strcmp(AvailableWriter[i]->caps->textEncoding, encoding) == 0)
|
writer_printf(50, "%s: found writer \"%s\" for \"%s\"\n",
|
||||||
{
|
__func__, AvailableWriter[i]->caps->name,
|
||||||
writer_printf(50, "%s: found writer \"%s\" for \"%s\"\n", __func__, AvailableWriter[i]->caps->name, encoding);
|
encoding);
|
||||||
return AvailableWriter[i];
|
return AvailableWriter[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writer_printf(1, "%s: no writer found for \"%s\"\n", __func__, encoding);
|
writer_printf(1, "%s: no writer found for \"%s\"\n", __func__,
|
||||||
|
encoding);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Writer_t* getDefaultVideoWriter()
|
Writer_t *getDefaultVideoWriter()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; AvailableWriter[i] != NULL; i++)
|
for (i = 0; AvailableWriter[i] != NULL; i++) {
|
||||||
{
|
if (strcmp(AvailableWriter[i]->caps->textEncoding, "V_MPEG2") == 0) {
|
||||||
if (strcmp(AvailableWriter[i]->caps->textEncoding, "V_MPEG2") == 0)
|
writer_printf(50, "%s: found writer \"%s\"\n", __func__,
|
||||||
{
|
AvailableWriter[i]->caps->name);
|
||||||
writer_printf(50, "%s: found writer \"%s\"\n", __func__, AvailableWriter[i]->caps->name);
|
return AvailableWriter[i];
|
||||||
return AvailableWriter[i];
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
writer_printf(1, "%s: no writer found\n", __func__);
|
writer_printf(1, "%s: no writer found\n", __func__);
|
||||||
@@ -129,17 +129,16 @@ Writer_t* getDefaultVideoWriter()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Writer_t* getDefaultAudioWriter()
|
Writer_t *getDefaultAudioWriter()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; AvailableWriter[i] != NULL; i++)
|
for (i = 0; AvailableWriter[i] != NULL; i++) {
|
||||||
{
|
if (strcmp(AvailableWriter[i]->caps->textEncoding, "A_MP3") == 0) {
|
||||||
if (strcmp(AvailableWriter[i]->caps->textEncoding, "A_MP3") == 0)
|
writer_printf(50, "%s: found writer \"%s\"\n", __func__,
|
||||||
{
|
AvailableWriter[i]->caps->name);
|
||||||
writer_printf(50, "%s: found writer \"%s\"\n", __func__, AvailableWriter[i]->caps->name);
|
return AvailableWriter[i];
|
||||||
return AvailableWriter[i];
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
writer_printf(1, "%s: no writer found\n", __func__);
|
writer_printf(1, "%s: no writer found\n", __func__);
|
||||||
@@ -147,18 +146,18 @@ Writer_t* getDefaultAudioWriter()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Writer_t* getDefaultFramebufferWriter()
|
Writer_t *getDefaultFramebufferWriter()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; AvailableWriter[i] != NULL; i++)
|
for (i = 0; AvailableWriter[i] != NULL; i++) {
|
||||||
{
|
writer_printf(10, "%s\n", AvailableWriter[i]->caps->textEncoding);
|
||||||
writer_printf(10, "%s\n", AvailableWriter[i]->caps->textEncoding);
|
if (strcmp(AvailableWriter[i]->caps->textEncoding, "framebuffer")
|
||||||
if (strcmp(AvailableWriter[i]->caps->textEncoding, "framebuffer") == 0)
|
== 0) {
|
||||||
{
|
writer_printf(50, "%s: found writer \"%s\"\n", __func__,
|
||||||
writer_printf(50, "%s: found writer \"%s\"\n", __func__, AvailableWriter[i]->caps->name);
|
AvailableWriter[i]->caps->name);
|
||||||
return AvailableWriter[i];
|
return AvailableWriter[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writer_printf(1, "%s: no writer found\n", __func__);
|
writer_printf(1, "%s: no writer found\n", __func__);
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -12,31 +12,31 @@
|
|||||||
#include <libavutil/avutil.h>
|
#include <libavutil/avutil.h>
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
|
|
||||||
static AVFormatContext* avContext = NULL;
|
static AVFormatContext *avContext = NULL;
|
||||||
|
|
||||||
void dump_metadata()
|
void dump_metadata()
|
||||||
{
|
{
|
||||||
AVDictionaryEntry *tag = NULL;
|
AVDictionaryEntry *tag = NULL;
|
||||||
while ((tag = av_dict_get(avContext->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
|
while ((tag =
|
||||||
printf("%s: %s\n", tag->key, tag->value);
|
av_dict_get(avContext->metadata, "", tag,
|
||||||
|
AV_DICT_IGNORE_SUFFIX)))
|
||||||
|
printf("%s: %s\n", tag->key, tag->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc,char* argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char file[255] = {""};
|
char file[255] = { "" };
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2) {
|
||||||
{
|
printf("give me a filename please\n");
|
||||||
printf("give me a filename please\n");
|
return -1;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strstr(argv[1], "://") == NULL)
|
if (strstr(argv[1], "://") == NULL) {
|
||||||
{
|
strcpy(file, "file://");
|
||||||
strcpy(file, "file://");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
strcat(file, argv[1]);
|
strcat(file, argv[1]);
|
||||||
@@ -44,35 +44,34 @@ int main(int argc,char* argv[])
|
|||||||
av_register_all();
|
av_register_all();
|
||||||
|
|
||||||
if ((err = avformat_open_input(&avContext, file, NULL, 0)) != 0) {
|
if ((err = avformat_open_input(&avContext, file, NULL, 0)) != 0) {
|
||||||
char error[512];
|
char error[512];
|
||||||
|
|
||||||
printf("avformat_open_input failed %d (%s)\n", err, file);
|
printf("avformat_open_input failed %d (%s)\n", err, file);
|
||||||
av_strerror(err, error, 512);
|
av_strerror(err, error, 512);
|
||||||
printf("Cause: %s\n", error);
|
printf("Cause: %s\n", error);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avformat_find_stream_info(avContext, NULL) < 0)
|
if (avformat_find_stream_info(avContext, NULL) < 0) {
|
||||||
{
|
printf("Error avformat_find_stream_info\n");
|
||||||
printf("Error avformat_find_stream_info\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n***\n");
|
printf("\n***\n");
|
||||||
dump_metadata();
|
dump_metadata();
|
||||||
|
|
||||||
printf("\nstream specific metadata:\n");
|
printf("\nstream specific metadata:\n");
|
||||||
for (i = 0; i < avContext->nb_streams; i++)
|
for (i = 0; i < avContext->nb_streams; i++) {
|
||||||
{
|
AVStream *stream = avContext->streams[i];
|
||||||
AVStream* stream = avContext->streams[i];
|
|
||||||
|
|
||||||
if (stream)
|
if (stream) {
|
||||||
{
|
AVDictionaryEntry *tag = NULL;
|
||||||
AVDictionaryEntry *tag = NULL;
|
if (stream->metadata != NULL)
|
||||||
if (stream->metadata != NULL)
|
while ((tag =
|
||||||
while ((tag = av_dict_get(stream->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
|
av_dict_get(stream->metadata, "", tag,
|
||||||
printf("%s: %s\n", tag->key, tag->value);
|
AV_DICT_IGNORE_SUFFIX)))
|
||||||
}
|
printf("%s: %s\n", tag->key, tag->value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user