libeplayer3-arm: insert original blank lines from exteplayer3.git, for better merge

Origin commit data
------------------
Branch: master
Commit: d444bee65a
Author: max_10 <max_10@gmx.de>
Date: 2018-04-10 (Tue, 10 Apr 2018)


------------------
No further description and justification available within origin commit message!

------------------
This commit was generated by Migit
This commit is contained in:
max_10
2018-04-10 11:31:57 +02:00
committed by TangoCash
parent 07d618980a
commit 02cab43744
79 changed files with 2070 additions and 117 deletions

View File

@@ -19,9 +19,9 @@ libeplayer3_arm_la_SOURCES = \
manager/subtitle.c \ manager/subtitle.c \
manager/chapter.c \ manager/chapter.c \
output/linuxdvb_mipsel.c \ output/linuxdvb_mipsel.c \
output/linuxdvb_buffering.c \
output/output_subtitle.c \ output/output_subtitle.c \
output/output.c \ output/output.c \
output/linuxdvb_buffering.c \
output/writer/common/pes.c \ output/writer/common/pes.c \
output/writer/common/misc.c \ output/writer/common/misc.c \
output/writer/mipsel/writer.c \ output/writer/mipsel/writer.c \

View File

@@ -95,15 +95,19 @@ static void update_finish_timeout()
int64_t currPts = -1; int64_t currPts = -1;
int32_t ret = g_context->playback->Command(g_context, PLAYBACK_PTS, &currPts); int32_t ret = g_context->playback->Command(g_context, PLAYBACK_PTS, &currPts);
finishTimeout += 1; finishTimeout += 1;
if (maxInjectedPts < 0 || maxInjectedPts == INVALID_PTS_VALUE) if (maxInjectedPts < 0 || maxInjectedPts == INVALID_PTS_VALUE)
{ {
maxInjectedPts = 0; maxInjectedPts = 0;
} }
//printf("ret[%d] playPts[%lld] currPts[%lld] maxInjectedPts[%lld]\n", ret, playPts, currPts, maxInjectedPts); //printf("ret[%d] playPts[%lld] currPts[%lld] maxInjectedPts[%lld]\n", ret, playPts, currPts, maxInjectedPts);
/* On some STBs PTS readed from decoder is invalid after seek or at start /* On some STBs PTS readed from decoder is invalid after seek or at start
* this is the reason for additional validation when we what to close immediately * this is the reason for additional validation when we what to close immediately
*/ */
if (!progressive_playback && 0 == ret && currPts >= maxInjectedPts && ((currPts - maxInjectedPts) / 90000) < 2) if (!progressive_playback && 0 == ret && currPts >= maxInjectedPts &&
((currPts - maxInjectedPts) / 90000) < 2)
{ {
/* close immediately /* close immediately
*/ */
@@ -129,6 +133,7 @@ static int32_t ffmpeg_read_wrapper_base(void *opaque, uint8_t *buf, int32_t buf_
{ {
break; break;
} }
int32_t partLen = ffmpeg_real_read_org(opaque, buf + len, buf_size - len); int32_t partLen = ffmpeg_real_read_org(opaque, buf + len, buf_size - len);
if (partLen > 0) if (partLen > 0)
{ {
@@ -141,7 +146,9 @@ static int32_t ffmpeg_read_wrapper_base(void *opaque, uint8_t *buf, int32_t buf_
len = 0; len = 0;
break; break;
} }
update_finish_timeout(); update_finish_timeout();
usleep(100000); usleep(100000);
continue; continue;
} }
@@ -163,25 +170,31 @@ static int32_t ffmpeg_read_wrapper(void *opaque, uint8_t *buf, int32_t buf_size)
return ffmpeg_real_read_org(opaque, buf, buf_size); return ffmpeg_real_read_org(opaque, buf, buf_size);
} }
} }
#if 0 #if 0
static int32_t ffmpeg_read_wrapper2(void *opaque, uint8_t *buf, int32_t buf_size) static int32_t ffmpeg_read_wrapper2(void *opaque, uint8_t *buf, int32_t buf_size)
{ {
return ffmpeg_read_wrapper_base(opaque, buf, buf_size, 1); return ffmpeg_read_wrapper_base(opaque, buf, buf_size, 1);
} }
#endif #endif
//for buffered io //for buffered io
void getfillerMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) void getfillerMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused)))
{ {
ffmpeg_printf(100, "::%d requesting mutex\n", line); ffmpeg_printf(100, "::%d requesting mutex\n", line);
pthread_mutex_lock(&fillermutex); pthread_mutex_lock(&fillermutex);
ffmpeg_printf(100, "::%d received mutex\n", line); ffmpeg_printf(100, "::%d received mutex\n", line);
} }
void releasefillerMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int line __attribute__((unused))) void releasefillerMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int line __attribute__((unused)))
{ {
pthread_mutex_unlock(&fillermutex); pthread_mutex_unlock(&fillermutex);
ffmpeg_printf(100, "::%d released mutex\n", line); ffmpeg_printf(100, "::%d released mutex\n", line);
} }
//for buffered io (end)encoding //for buffered io (end)encoding
#if 0 #if 0
static int32_t container_set_ffmpeg_buf_seek_time(int32_t *time) static int32_t container_set_ffmpeg_buf_seek_time(int32_t *time)
@@ -190,6 +203,7 @@ static int32_t container_set_ffmpeg_buf_seek_time(int32_t *time)
return cERR_CONTAINER_FFMPEG_NO_ERROR; return cERR_CONTAINER_FFMPEG_NO_ERROR;
} }
#endif #endif
static int32_t container_set_ffmpeg_buf_size(int32_t *size) static int32_t container_set_ffmpeg_buf_size(int32_t *size)
{ {
if (ffmpeg_buf == NULL) if (ffmpeg_buf == NULL)
@@ -203,6 +217,7 @@ static int32_t container_set_ffmpeg_buf_size(int32_t *size)
ffmpeg_buf_size = (*size) + FILLBUFDIFF; ffmpeg_buf_size = (*size) + FILLBUFDIFF;
} }
} }
ffmpeg_printf(10, "size=%d, buffer size=%d\n", (*size), ffmpeg_buf_size); ffmpeg_printf(10, "size=%d, buffer size=%d\n", (*size), ffmpeg_buf_size);
return cERR_CONTAINER_FFMPEG_NO_ERROR; return cERR_CONTAINER_FFMPEG_NO_ERROR;
} }
@@ -216,6 +231,7 @@ static int32_t container_get_ffmpeg_buf_size(int32_t *size)
static int32_t container_get_fillbufstatus(int32_t *size) static int32_t container_get_fillbufstatus(int32_t *size)
{ {
int32_t rwdiff = 0; int32_t rwdiff = 0;
if (ffmpeg_buf != NULL && ffmpeg_buf_read != NULL && ffmpeg_buf_write != NULL) if (ffmpeg_buf != NULL && ffmpeg_buf_read != NULL && ffmpeg_buf_write != NULL)
{ {
if (ffmpeg_buf_read < ffmpeg_buf_write) if (ffmpeg_buf_read < ffmpeg_buf_write)
@@ -225,10 +241,13 @@ static int32_t container_get_fillbufstatus(int32_t *size)
rwdiff = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read; rwdiff = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read;
rwdiff += ffmpeg_buf_write - ffmpeg_buf; rwdiff += ffmpeg_buf_write - ffmpeg_buf;
} }
*size = rwdiff; *size = rwdiff;
} }
return cERR_CONTAINER_FFMPEG_NO_ERROR; return cERR_CONTAINER_FFMPEG_NO_ERROR;
} }
#if 0 #if 0
static int32_t container_stop_buffer() static int32_t container_stop_buffer()
{ {
@@ -236,6 +255,7 @@ static int32_t container_stop_buffer()
return 0; return 0;
} }
#endif #endif
//flag 0: start direct //flag 0: start direct
//flag 1: from thread //flag 1: from thread
static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int32_t flag) static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int32_t flag)
@@ -243,11 +263,13 @@ static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int3
int32_t len = 0; int32_t len = 0;
int32_t rwdiff = ffmpeg_buf_size; int32_t rwdiff = ffmpeg_buf_size;
uint8_t buf[FILLBUFPAKET]; uint8_t buf[FILLBUFPAKET];
if (ffmpeg_read_org == NULL || ffmpeg_seek_org == NULL) if (ffmpeg_read_org == NULL || ffmpeg_seek_org == NULL)
{ {
ffmpeg_err("ffmpeg_read_org or ffmpeg_seek_org is NULL\n"); ffmpeg_err("ffmpeg_read_org or ffmpeg_seek_org is NULL\n");
return; return;
} }
while ((flag == 0 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF) || while ((flag == 0 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF) ||
(flag == 1 && hasfillerThreadStarted[id] == 1 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF)) (flag == 1 && hasfillerThreadStarted[id] == 1 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF))
{ {
@@ -255,11 +277,13 @@ static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int3
{ {
break; break;
} }
if (flag == 0 && ffmpeg_buf_stop == 1) if (flag == 0 && ffmpeg_buf_stop == 1)
{ {
ffmpeg_buf_stop = 0; ffmpeg_buf_stop = 0;
break; break;
} }
getfillerMutex(__FILE__, __FUNCTION__, __LINE__); getfillerMutex(__FILE__, __FUNCTION__, __LINE__);
//do a seek //do a seek
if (ffmpeg_do_seek != 0) if (ffmpeg_do_seek != 0)
@@ -270,42 +294,53 @@ static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int3
ffmpeg_buf_write = ffmpeg_buf; ffmpeg_buf_write = ffmpeg_buf;
ffmpeg_buf_read = ffmpeg_buf; ffmpeg_buf_read = ffmpeg_buf;
} }
ffmpeg_do_seek = 0; ffmpeg_do_seek = 0;
} }
if (ffmpeg_buf_read == ffmpeg_buf_write) if (ffmpeg_buf_read == ffmpeg_buf_write)
{ {
ffmpeg_buf_valid_size = 0; ffmpeg_buf_valid_size = 0;
rwdiff = ffmpeg_buf_size; rwdiff = ffmpeg_buf_size;
} }
if (ffmpeg_buf_read < ffmpeg_buf_write) if (ffmpeg_buf_read < ffmpeg_buf_write)
{ {
rwdiff = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_write; rwdiff = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_write;
rwdiff += ffmpeg_buf_read - ffmpeg_buf; rwdiff += ffmpeg_buf_read - ffmpeg_buf;
} }
if (ffmpeg_buf_read > ffmpeg_buf_write) if (ffmpeg_buf_read > ffmpeg_buf_write)
{ {
rwdiff = ffmpeg_buf_read - ffmpeg_buf_write; rwdiff = ffmpeg_buf_read - ffmpeg_buf_write;
} }
int32_t size = FILLBUFPAKET; int32_t size = FILLBUFPAKET;
if (rwdiff - FILLBUFDIFF < size) if (rwdiff - FILLBUFDIFF < size)
{ {
size = (rwdiff - FILLBUFDIFF); size = (rwdiff - FILLBUFDIFF);
} }
if (ffmpeg_buf_write + size > ffmpeg_buf + ffmpeg_buf_size) if (ffmpeg_buf_write + size > ffmpeg_buf + ffmpeg_buf_size)
{ {
size = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_write; size = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_write;
} }
if (ffmpeg_buf_write == ffmpeg_buf + ffmpeg_buf_size) if (ffmpeg_buf_write == ffmpeg_buf + ffmpeg_buf_size)
{ {
ffmpeg_buf_write = ffmpeg_buf; ffmpeg_buf_write = ffmpeg_buf;
} }
releasefillerMutex(__FILE__, __FUNCTION__, __LINE__); releasefillerMutex(__FILE__, __FUNCTION__, __LINE__);
if (size > 0) if (size > 0)
{ {
if (flag == 1 && hasfillerThreadStarted[id] == 2) break; if (flag == 1 && hasfillerThreadStarted[id] == 2) break;
len = ffmpeg_read_org(avContextTab[0]->pb->opaque, buf, size); len = ffmpeg_read_org(avContextTab[0]->pb->opaque, buf, size);
if (flag == 1 && hasfillerThreadStarted[id] == 2) break; if (flag == 1 && hasfillerThreadStarted[id] == 2) break;
ffmpeg_printf(20, "buffer-status (free buffer=%d)\n", rwdiff - FILLBUFDIFF - len); ffmpeg_printf(20, "buffer-status (free buffer=%d)\n", rwdiff - FILLBUFDIFF - len);
getfillerMutex(__FILE__, __FUNCTION__, __LINE__); getfillerMutex(__FILE__, __FUNCTION__, __LINE__);
if (len > 0) if (len > 0)
{ {
@@ -333,11 +368,13 @@ static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int3
{ {
int32_t buflen = 0; int32_t buflen = 0;
(*inpause) = 0; (*inpause) = 0;
getfillerMutex(__FILE__, __FUNCTION__, __LINE__); getfillerMutex(__FILE__, __FUNCTION__, __LINE__);
if (ffmpeg_buf_read < ffmpeg_buf_write) if (ffmpeg_buf_read < ffmpeg_buf_write)
{ {
buflen = ffmpeg_buf_write - ffmpeg_buf_read; buflen = ffmpeg_buf_write - ffmpeg_buf_read;
} }
if (ffmpeg_buf_read > ffmpeg_buf_write) if (ffmpeg_buf_read > ffmpeg_buf_write)
{ {
buflen = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read; buflen = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read;
@@ -355,13 +392,17 @@ static void ffmpeg_fillerTHREAD(Context_t *context)
{ {
int32_t inpause = 0; int32_t inpause = 0;
int32_t id = hasfillerThreadStartedID; int32_t id = hasfillerThreadStartedID;
ffmpeg_printf(10, "Running ID=%d!\n", id); ffmpeg_printf(10, "Running ID=%d!\n", id);
while (hasfillerThreadStarted[id] == 1) while (hasfillerThreadStarted[id] == 1)
{ {
ffmpeg_filler(context, id, &inpause, 1); ffmpeg_filler(context, id, &inpause, 1);
usleep(10000); usleep(10000);
} }
hasfillerThreadStarted[id] = 0; hasfillerThreadStarted[id] = 0;
ffmpeg_printf(10, "terminating ID=%d\n", id); ffmpeg_printf(10, "terminating ID=%d\n", id);
} }
@@ -370,7 +411,9 @@ static int32_t ffmpeg_start_fillerTHREAD(Context_t *context)
int32_t error; int32_t error;
int32_t ret = 0, i = 0; int32_t ret = 0, i = 0;
pthread_attr_t attr; pthread_attr_t attr;
ffmpeg_printf(10, "\n"); ffmpeg_printf(10, "\n");
if (context && context->playback && context->playback->isPlaying) if (context && context->playback && context->playback->isPlaying)
{ {
ffmpeg_printf(10, "is Playing\n"); ffmpeg_printf(10, "is Playing\n");
@@ -379,6 +422,7 @@ static int32_t ffmpeg_start_fillerTHREAD(Context_t *context)
{ {
ffmpeg_printf(10, "is NOT Playing\n"); ffmpeg_printf(10, "is NOT Playing\n");
} }
//get filler thread ID //get filler thread ID
//if the thread hangs for long time, we use a new id //if the thread hangs for long time, we use a new id
for (i = 0; i < 10; i++) for (i = 0; i < 10; i++)
@@ -389,15 +433,18 @@ static int32_t ffmpeg_start_fillerTHREAD(Context_t *context)
break; break;
} }
} }
if (hasfillerThreadStarted[hasfillerThreadStartedID] == 0) if (hasfillerThreadStarted[hasfillerThreadStartedID] == 0)
{ {
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
hasfillerThreadStarted[hasfillerThreadStartedID] = 1; hasfillerThreadStarted[hasfillerThreadStartedID] = 1;
if ((error = pthread_create(&fillerThread, &attr, (void *)&ffmpeg_fillerTHREAD, context)) != 0) if ((error = pthread_create(&fillerThread, &attr, (void *)&ffmpeg_fillerTHREAD, context)) != 0)
{ {
hasfillerThreadStarted[hasfillerThreadStartedID] = 0; hasfillerThreadStarted[hasfillerThreadStartedID] = 0;
ffmpeg_printf(10, "Error creating filler thread, error:%d:%s\n", error, strerror(error)); ffmpeg_printf(10, "Error creating filler thread, error:%d:%s\n", error, strerror(error));
ret = cERR_CONTAINER_FFMPEG_ERR; ret = cERR_CONTAINER_FFMPEG_ERR;
} }
else else
@@ -408,8 +455,10 @@ static int32_t ffmpeg_start_fillerTHREAD(Context_t *context)
else else
{ {
ffmpeg_printf(10, "All filler thread ID's in use!\n"); ffmpeg_printf(10, "All filler thread ID's in use!\n");
ret = cERR_CONTAINER_FFMPEG_ERR; ret = cERR_CONTAINER_FFMPEG_ERR;
} }
ffmpeg_printf(10, "exiting with value %d\n", ret); ffmpeg_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
@@ -418,9 +467,11 @@ static int32_t ffmpeg_read_real(void *opaque __attribute__((unused)), uint8_t *b
{ {
int32_t len = buf_size; int32_t len = buf_size;
int32_t rwdiff = 0; int32_t rwdiff = 0;
if (buf_size > 0) if (buf_size > 0)
{ {
getfillerMutex(__FILE__, __FUNCTION__, __LINE__); getfillerMutex(__FILE__, __FUNCTION__, __LINE__);
if (ffmpeg_buf_read < ffmpeg_buf_write) if (ffmpeg_buf_read < ffmpeg_buf_write)
rwdiff = ffmpeg_buf_write - ffmpeg_buf_read; rwdiff = ffmpeg_buf_write - ffmpeg_buf_read;
if (ffmpeg_buf_read > ffmpeg_buf_write) if (ffmpeg_buf_read > ffmpeg_buf_write)
@@ -429,18 +480,22 @@ static int32_t ffmpeg_read_real(void *opaque __attribute__((unused)), uint8_t *b
rwdiff += ffmpeg_buf_write - ffmpeg_buf; rwdiff += ffmpeg_buf_write - ffmpeg_buf;
} }
rwdiff--; rwdiff--;
if (len > rwdiff) if (len > rwdiff)
{ {
len = rwdiff; len = rwdiff;
} }
if (ffmpeg_buf_read + len > ffmpeg_buf + ffmpeg_buf_size) if (ffmpeg_buf_read + len > ffmpeg_buf + ffmpeg_buf_size)
{ {
len = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read; len = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read;
} }
if (len > 0) if (len > 0)
{ {
memcpy(buf, ffmpeg_buf_read, len); memcpy(buf, ffmpeg_buf_read, len);
ffmpeg_buf_read += len; ffmpeg_buf_read += len;
if (ffmpeg_buf_valid_size < FILLBUFDIFF) if (ffmpeg_buf_valid_size < FILLBUFDIFF)
{ {
if (ffmpeg_buf_valid_size + len > FILLBUFDIFF) if (ffmpeg_buf_valid_size + len > FILLBUFDIFF)
@@ -452,6 +507,7 @@ static int32_t ffmpeg_read_real(void *opaque __attribute__((unused)), uint8_t *b
ffmpeg_buf_valid_size += len; ffmpeg_buf_valid_size += len;
} }
} }
if (ffmpeg_buf_read == ffmpeg_buf + ffmpeg_buf_size) if (ffmpeg_buf_read == ffmpeg_buf + ffmpeg_buf_size)
{ {
ffmpeg_buf_read = ffmpeg_buf; ffmpeg_buf_read = ffmpeg_buf;
@@ -463,6 +519,7 @@ static int32_t ffmpeg_read_real(void *opaque __attribute__((unused)), uint8_t *b
} }
releasefillerMutex(__FILE__, __FUNCTION__, __LINE__); releasefillerMutex(__FILE__, __FUNCTION__, __LINE__);
} }
return len; return len;
} }
@@ -471,6 +528,7 @@ static int32_t ffmpeg_read(void *opaque, uint8_t *buf, int32_t buf_size)
int32_t sumlen = 0; int32_t sumlen = 0;
int32_t len = 0; int32_t len = 0;
int32_t count = 2000; int32_t count = 2000;
while (sumlen < buf_size && (--count) > 0 && 0 == PlaybackDieNow(0)) while (sumlen < buf_size && (--count) > 0 && 0 == PlaybackDieNow(0))
{ {
len = ffmpeg_read_real(opaque, buf, buf_size - sumlen); len = ffmpeg_read_real(opaque, buf, buf_size - sumlen);
@@ -481,6 +539,7 @@ static int32_t ffmpeg_read(void *opaque, uint8_t *buf, int32_t buf_size)
usleep(10000); usleep(10000);
} }
} }
if (count == 0) if (count == 0)
{ {
if (sumlen == 0) if (sumlen == 0)
@@ -492,6 +551,7 @@ static int32_t ffmpeg_read(void *opaque, uint8_t *buf, int32_t buf_size)
ffmpeg_err("Timeout, not all buffered data availabel (buf_size=%d sumlen=%d)!\n", buf_size, sumlen); ffmpeg_err("Timeout, not all buffered data availabel (buf_size=%d sumlen=%d)!\n", buf_size, sumlen);
} }
} }
return sumlen; return sumlen;
} }
@@ -500,10 +560,12 @@ static int64_t ffmpeg_seek(void *opaque __attribute__((unused)), int64_t offset,
int64_t diff; int64_t diff;
int32_t rwdiff = 0; int32_t rwdiff = 0;
whence &= ~AVSEEK_FORCE; whence &= ~AVSEEK_FORCE;
if (whence != SEEK_CUR && whence != SEEK_SET) if (whence != SEEK_CUR && whence != SEEK_SET)
{ {
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
if (whence == SEEK_CUR) if (whence == SEEK_CUR)
{ {
diff = offset; diff = offset;
@@ -512,20 +574,25 @@ static int64_t ffmpeg_seek(void *opaque __attribute__((unused)), int64_t offset,
{ {
diff = offset - avContextTab[0]->pb->pos; diff = offset - avContextTab[0]->pb->pos;
} }
if (diff == 0) if (diff == 0)
{ {
return avContextTab[0]->pb->pos; return avContextTab[0]->pb->pos;
} }
getfillerMutex(__FILE__, __FUNCTION__, __LINE__); getfillerMutex(__FILE__, __FUNCTION__, __LINE__);
if (ffmpeg_buf_read < ffmpeg_buf_write) if (ffmpeg_buf_read < ffmpeg_buf_write)
{ {
rwdiff = ffmpeg_buf_write - ffmpeg_buf_read; rwdiff = ffmpeg_buf_write - ffmpeg_buf_read;
} }
if (ffmpeg_buf_read > ffmpeg_buf_write) if (ffmpeg_buf_read > ffmpeg_buf_write)
{ {
rwdiff = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read; rwdiff = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read;
rwdiff += ffmpeg_buf_write - ffmpeg_buf; rwdiff += ffmpeg_buf_write - ffmpeg_buf;
} }
if (diff > 0 && diff < rwdiff) if (diff > 0 && diff < rwdiff)
{ {
/* can do the seek inside the buffer */ /* can do the seek inside the buffer */
@@ -557,29 +624,35 @@ static int64_t ffmpeg_seek(void *opaque __attribute__((unused)), int64_t offset,
{ {
releasefillerMutex(__FILE__, __FUNCTION__, __LINE__); releasefillerMutex(__FILE__, __FUNCTION__, __LINE__);
ffmpeg_printf(20, "real-seek diff=%lld\n", diff); ffmpeg_printf(20, "real-seek diff=%lld\n", diff);
ffmpeg_do_seek_ret = 0; ffmpeg_do_seek_ret = 0;
ffmpeg_do_seek = diff; ffmpeg_do_seek = diff;
while (ffmpeg_do_seek != 0) while (ffmpeg_do_seek != 0)
{ {
usleep(100000); usleep(100000);
} }
ffmpeg_do_seek = 0; ffmpeg_do_seek = 0;
if (ffmpeg_do_seek_ret < 0) if (ffmpeg_do_seek_ret < 0)
{ {
ffmpeg_err("seek not ok ret=%d\n", ffmpeg_do_seek_ret); ffmpeg_err("seek not ok ret=%d\n", ffmpeg_do_seek_ret);
return ffmpeg_do_seek_ret; return ffmpeg_do_seek_ret;
} }
//fill buffer //fill buffer
int32_t count = ffmpeg_buf_seek_time * 10; int32_t count = ffmpeg_buf_seek_time * 10;
int32_t size = 0; int32_t size = 0;
container_get_fillbufstatus(&size); container_get_fillbufstatus(&size);
while (size < ffmpeg_buf_size - FILLBUFDIFF && (--count) > 0) while (size < ffmpeg_buf_size - FILLBUFDIFF && (--count) > 0)
{ {
usleep(100000); usleep(100000);
container_get_fillbufstatus(&size); container_get_fillbufstatus(&size);
} }
return avContextTab[0]->pb->pos + diff; return avContextTab[0]->pb->pos + diff;
} }
releasefillerMutex(__FILE__, __FUNCTION__, __LINE__); releasefillerMutex(__FILE__, __FUNCTION__, __LINE__);
return avContextTab[0]->pb->pos + diff; return avContextTab[0]->pb->pos + diff;
} }

View File

@@ -56,8 +56,10 @@ static void printContainerCapabilities()
{ {
int32_t i = 0; int32_t i = 0;
int32_t j = 0; int32_t j = 0;
container_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); container_printf(10, "%s::%s\n", __FILE__, __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++)
@@ -73,7 +75,9 @@ static int32_t selectContainer(Context_t *context, char *extension)
int32_t i = 0; int32_t i = 0;
int32_t j = 0; int32_t j = 0;
int32_t ret = -1; int32_t ret = -1;
container_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); container_printf(10, "%s::%s\n", __FILE__, __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++)
@@ -81,26 +85,32 @@ static int32_t selectContainer(Context_t *context, char *extension)
if (!strcasecmp(AvailableContainer[i]->Capabilities[j], extension)) if (!strcasecmp(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", context->container->selectedContainer->Name);
ret = 0; ret = 0;
break; break;
} }
} }
if (ret == 0) if (ret == 0)
{ {
break; break;
} }
} }
if (ret != 0) if (ret != 0)
{ {
container_err("No Container found :-(\n"); container_err("No Container found :-(\n");
} }
return ret; return ret;
} }
static int Command(Context_t *context, ContainerCmd_t command, void *argument __attribute__((unused))) static int Command(Context_t *context, ContainerCmd_t command, void *argument __attribute__((unused)))
{ {
int ret = 0; int ret = 0;
container_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); container_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
switch (command) switch (command)
@@ -124,9 +134,11 @@ static int Command(Context_t *context, ContainerCmd_t command, void *argument __
container_err("%s::%s ContainerCmd %d not supported!\n", __FILE__, __FUNCTION__, command); container_err("%s::%s ContainerCmd %d not supported!\n", __FILE__, __FUNCTION__, command);
break; break;
} }
return ret; return ret;
} }
ContainerHandler_t ContainerHandler = ContainerHandler_t ContainerHandler =
{ {
"Output", "Output",

File diff suppressed because it is too large Load Diff

View File

@@ -5,6 +5,7 @@
#include "flv2mpeg4/flv2mpeg4.h" #include "flv2mpeg4/flv2mpeg4.h"
typedef struct typedef struct
{ {
flv2mpeg4_CTX *ctx; flv2mpeg4_CTX *ctx;
@@ -15,6 +16,7 @@ typedef struct
Track_t *track; Track_t *track;
} Flv2Mpeg4Context; } Flv2Mpeg4Context;
static int flv2mpeg4_context_write_packet_cb(void *usr_data, int keyframe, int pts, const uint8_t *buf, int size) static int flv2mpeg4_context_write_packet_cb(void *usr_data, int keyframe, int pts, const uint8_t *buf, int size)
{ {
Flv2Mpeg4Context *ctx = usr_data; Flv2Mpeg4Context *ctx = usr_data;
@@ -22,6 +24,7 @@ static int flv2mpeg4_context_write_packet_cb(void *usr_data, int keyframe, int p
{ {
return -1; return -1;
} }
AudioVideoOut_t avOut; AudioVideoOut_t avOut;
avOut.data = (char *)buf; avOut.data = (char *)buf;
avOut.len = size; avOut.len = size;
@@ -34,10 +37,12 @@ static int flv2mpeg4_context_write_packet_cb(void *usr_data, int keyframe, int p
avOut.width = ctx->track->width; avOut.width = ctx->track->width;
avOut.height = ctx->track->height; avOut.height = ctx->track->height;
avOut.type = "video"; avOut.type = "video";
if (Write(ctx->out_ctx->output->video->Write, ctx->out_ctx, &avOut, avOut.pts) < 0) if (Write(ctx->out_ctx->output->video->Write, ctx->out_ctx, &avOut, avOut.pts) < 0)
{ {
ffmpeg_err("writing data to video device failed\n"); ffmpeg_err("writing data to video device failed\n");
} }
return 0; return 0;
} }
@@ -48,10 +53,12 @@ static int flv2mpeg4_context_write_extradata_cb(void *usr_data, int width, int h
{ {
return -1; return -1;
} }
free(ctx->extradata); free(ctx->extradata);
ctx->extradata = malloc(extradatasize); ctx->extradata = malloc(extradatasize);
memcpy(ctx->extradata, extradata, extradatasize); memcpy(ctx->extradata, extradata, extradatasize);
ctx->extradatasize = extradatasize; ctx->extradatasize = extradatasize;
return 0; return 0;
} }
@@ -59,6 +66,7 @@ static void flv2mpeg4_context_reset(Flv2Mpeg4Context *context)
{ {
if (context == NULL || context->ctx == NULL) if (context == NULL || context->ctx == NULL)
return; return;
flv2mpeg4_set_frame(context->ctx, 0, 0); flv2mpeg4_set_frame(context->ctx, 0, 0);
} }
@@ -69,14 +77,19 @@ static int flv2mpeg4_write_packet(Context_t *out_ctx, Flv2Mpeg4Context *mpeg4p2_
mpeg4p2_ctx->ctx = flv2mpeg4_init_ctx(mpeg4p2_ctx, track->width, track->height, flv2mpeg4_context_write_packet_cb, flv2mpeg4_context_write_extradata_cb); mpeg4p2_ctx->ctx = flv2mpeg4_init_ctx(mpeg4p2_ctx, track->width, track->height, flv2mpeg4_context_write_packet_cb, flv2mpeg4_context_write_extradata_cb);
flv2mpeg4_prepare_extra_data(mpeg4p2_ctx->ctx); flv2mpeg4_prepare_extra_data(mpeg4p2_ctx->ctx);
} }
*pts_current = track->pts = calcPts(cAVIdx, track->stream, pkt->pts); *pts_current = track->pts = calcPts(cAVIdx, track->stream, pkt->pts);
if ((*pts_current > *pts_latest) && (*pts_current != INVALID_PTS_VALUE)) if ((*pts_current > *pts_latest) && (*pts_current != INVALID_PTS_VALUE))
{ {
*pts_latest = *pts_current; *pts_latest = *pts_current;
} }
track->dts = calcPts(cAVIdx, track->stream, pkt->dts); track->dts = calcPts(cAVIdx, track->stream, pkt->dts);
mpeg4p2_ctx->out_ctx = out_ctx; mpeg4p2_ctx->out_ctx = out_ctx;
mpeg4p2_ctx->track = track; mpeg4p2_ctx->track = track;
uint32_t time_ms = (uint32_t)(track->pts / 90); uint32_t time_ms = (uint32_t)(track->pts / 90);
return flv2mpeg4_process_flv_packet(mpeg4p2_ctx->ctx, 0, pkt->data, pkt->size, time_ms); return flv2mpeg4_process_flv_packet(mpeg4p2_ctx->ctx, 0, pkt->data, pkt->size, time_ms);
} }

View File

@@ -14,6 +14,7 @@ typedef struct
AVPacket *second_ip_frame; AVPacket *second_ip_frame;
} Mpeg4P2Context; } Mpeg4P2Context;
static void set_packet(AVPacket **pkt_dest, AVPacket *pkt_src) static void set_packet(AVPacket **pkt_dest, AVPacket *pkt_src)
{ {
if (pkt_dest == NULL) if (pkt_dest == NULL)
@@ -82,6 +83,7 @@ static void mpeg4p2_context_reset(Mpeg4P2Context *context)
av_free(context->second_ip_frame); av_free(context->second_ip_frame);
} }
context->second_ip_frame = NULL; context->second_ip_frame = NULL;
context->b_frames_count = 0; context->b_frames_count = 0;
context->first_ip_frame_written = 0; context->first_ip_frame_written = 0;
context->packet_duration = 0; context->packet_duration = 0;
@@ -95,6 +97,7 @@ static void mpeg4p2_write(Context_t *ctx, Track_t *track, int avContextIdx, int6
*pts_latest = *pts_current; *pts_latest = *pts_current;
} }
track->dts = calcPts(avContextIdx, track->stream, pkt->dts); track->dts = calcPts(avContextIdx, track->stream, pkt->dts);
AudioVideoOut_t avOut; AudioVideoOut_t avOut;
avOut.data = pkt->data; avOut.data = pkt->data;
avOut.len = pkt->size; avOut.len = pkt->size;
@@ -107,6 +110,7 @@ static void mpeg4p2_write(Context_t *ctx, Track_t *track, int avContextIdx, int6
avOut.width = track->width; avOut.width = track->width;
avOut.height = track->height; avOut.height = track->height;
avOut.type = "video"; avOut.type = "video";
if (Write(ctx->output->video->Write, ctx, &avOut, avOut.pts) < 0) if (Write(ctx->output->video->Write, ctx, &avOut, avOut.pts) < 0)
{ {
ffmpeg_err("writing data to video device failed\n"); ffmpeg_err("writing data to video device failed\n");
@@ -206,3 +210,4 @@ static int mpeg4p2_write_packet(Context_t *ctx, Mpeg4P2Context *mpeg4p2_ctx, Tra
} }
return 0; return 0;
} }

View File

@@ -121,9 +121,11 @@ int store_avcodec_context(AVCodecContext *avCodecCtx __attribute__((unused)), ui
{ {
return -1; return -1;
} }
memset(ptr, 0x00, sizeof(CodecCtxStoreItem_t)); memset(ptr, 0x00, sizeof(CodecCtxStoreItem_t));
ptr->next = g_codecCtxStoreListHead; ptr->next = g_codecCtxStoreListHead;
g_codecCtxStoreListHead = ptr; g_codecCtxStoreListHead = ptr;
return 0; return 0;
} }
#else #else
@@ -144,6 +146,7 @@ static AVCodecContext *wrapped_avcodec_get_context(uint32_t cAVIdx, AVStream *st
fprintf(stderr, "context3 alloc for stream %d failed\n", (int)stream->id); fprintf(stderr, "context3 alloc for stream %d failed\n", (int)stream->id);
return NULL; return NULL;
} }
if (avcodec_parameters_to_context(avCodecCtx, stream->codecpar) < 0) if (avcodec_parameters_to_context(avCodecCtx, stream->codecpar) < 0)
{ {
fprintf(stderr, "parameters to context for stream %d failed\n", (int)stream->id); fprintf(stderr, "parameters to context for stream %d failed\n", (int)stream->id);
@@ -151,8 +154,10 @@ static AVCodecContext *wrapped_avcodec_get_context(uint32_t cAVIdx, AVStream *st
return NULL; return NULL;
} }
av_codec_set_pkt_timebase(avCodecCtx, stream->time_base); av_codec_set_pkt_timebase(avCodecCtx, stream->time_base);
store_avcodec_context(avCodecCtx, cAVIdx, stream->id); store_avcodec_context(avCodecCtx, cAVIdx, stream->id);
} }
return avCodecCtx; return avCodecCtx;
#else #else
return stream->codec; return stream->codec;

View File

@@ -100,9 +100,11 @@ typedef struct GetBitContext
unsigned int name ## _index = (gb)->index; \ unsigned int name ## _index = (gb)->index; \
unsigned int av_unused name ## _cache unsigned int av_unused name ## _cache
#define OPEN_READER(name, gb) OPEN_READER_NOSIZE(name, gb) #define OPEN_READER(name, gb) OPEN_READER_NOSIZE(name, gb)
#define BITS_AVAILABLE(name, gb) 1 #define BITS_AVAILABLE(name, gb) 1
#define CLOSE_READER(name, gb) (gb)->index = name ## _index #define CLOSE_READER(name, gb) (gb)->index = name ## _index
# ifdef LONG_BITSTREAM_READER # ifdef LONG_BITSTREAM_READER
@@ -123,6 +125,7 @@ typedef struct GetBitContext
#endif #endif
#ifdef BITSTREAM_READER_LE #ifdef BITSTREAM_READER_LE
# define UPDATE_CACHE(name, gb) UPDATE_CACHE_LE(name, gb) # define UPDATE_CACHE(name, gb) UPDATE_CACHE_LE(name, gb)
@@ -139,6 +142,7 @@ typedef struct GetBitContext
#define SKIP_COUNTER(name, gb, num) name ## _index += (num) #define SKIP_COUNTER(name, gb, num) name ## _index += (num)
#define BITS_LEFT(name, gb) ((int)((gb)->size_in_bits - name ## _index)) #define BITS_LEFT(name, gb) ((int)((gb)->size_in_bits - name ## _index))
#define SKIP_BITS(name, gb, num) \ #define SKIP_BITS(name, gb, num) \
@@ -282,6 +286,7 @@ static inline unsigned int get_bits1(GetBitContext *s)
#endif #endif
index++; index++;
s->index = index; s->index = index;
return result; return result;
} }
@@ -349,6 +354,7 @@ static inline int get_sbits_long(GetBitContext *s, int n)
/* sign_extend(x, 0) is undefined */ /* sign_extend(x, 0) is undefined */
if (!n) if (!n)
return 0; return 0;
return sign_extend(get_bits_long(s, n), n); return sign_extend(get_bits_long(s, n), n);
} }
@@ -387,18 +393,22 @@ static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer,
{ {
int buffer_size; int buffer_size;
int ret = 0; int ret = 0;
if (bit_size >= INT_MAX - 7 || bit_size < 0 || !buffer) if (bit_size >= INT_MAX - 7 || bit_size < 0 || !buffer)
{ {
bit_size = 0; bit_size = 0;
buffer = NULL; buffer = NULL;
ret = AVERROR_INVALIDDATA; ret = AVERROR_INVALIDDATA;
} }
buffer_size = (bit_size + 7) >> 3; buffer_size = (bit_size + 7) >> 3;
s->buffer = buffer; s->buffer = buffer;
s->size_in_bits = bit_size; s->size_in_bits = bit_size;
s->size_in_bits_plus8 = bit_size + 8; s->size_in_bits_plus8 = bit_size + 8;
s->buffer_end = buffer + buffer_size; s->buffer_end = buffer + buffer_size;
s->index = 0; s->index = 0;
return ret; return ret;
} }
@@ -500,6 +510,7 @@ static inline const uint8_t *align_get_bits(GetBitContext *s)
SKIP_BITS(name, gb, n); \ SKIP_BITS(name, gb, n); \
} while (0) } while (0)
static inline int decode012(GetBitContext *gb) static inline int decode012(GetBitContext *gb)
{ {
int n; int n;
@@ -527,12 +538,14 @@ static inline int skip_1stop_8data_bits(GetBitContext *gb)
{ {
if (get_bits_left(gb) <= 0) if (get_bits_left(gb) <= 0)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
while (get_bits1(gb)) while (get_bits1(gb))
{ {
skip_bits(gb, 8); skip_bits(gb, 8);
if (get_bits_left(gb) <= 0) if (get_bits_left(gb) <= 0)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
return 0; return 0;
} }

View File

@@ -42,3 +42,4 @@ int latmenc_decode_extradata(LATMContext *ctx, uint8_t *buf, int size);
int latmenc_write_packet(LATMContext *ctx, uint8_t *data, int size, uint8_t *extradata, int extradata_size); int latmenc_write_packet(LATMContext *ctx, uint8_t *data, int size, uint8_t *extradata, int extradata_size);
#endif /* AVCODEC_LATMENC_H */ #endif /* AVCODEC_LATMENC_H */

View File

@@ -54,6 +54,7 @@ static inline void init_put_bits(PutBitContext *s, uint8_t *buffer,
buffer_size = 0; buffer_size = 0;
buffer = NULL; buffer = NULL;
} }
s->size_in_bits = 8 * buffer_size; s->size_in_bits = 8 * buffer_size;
s->buf = buffer; s->buf = buffer;
s->buf_end = s->buf + buffer_size; s->buf_end = s->buf + buffer_size;
@@ -73,6 +74,7 @@ static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer,
int buffer_size) int buffer_size)
{ {
av_assert0(8 * buffer_size > s->size_in_bits); av_assert0(8 * buffer_size > s->size_in_bits);
s->buf_end = buffer + buffer_size; s->buf_end = buffer + buffer_size;
s->buf_ptr = buffer + (s->buf_ptr - s->buf); s->buf_ptr = buffer + (s->buf_ptr - s->buf);
s->buf = buffer; s->buf = buffer;
@@ -154,9 +156,12 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value)
{ {
unsigned int bit_buf; unsigned int bit_buf;
int bit_left; int bit_left;
av_assert2(n <= 31 && value < (1U << n)); av_assert2(n <= 31 && value < (1U << n));
bit_buf = s->bit_buf; bit_buf = s->bit_buf;
bit_left = s->bit_left; bit_left = s->bit_left;
/* XXX: optimize */ /* XXX: optimize */
#ifdef BITSTREAM_WRITER_LE #ifdef BITSTREAM_WRITER_LE
bit_buf |= value << (32 - bit_left); bit_buf |= value << (32 - bit_left);
@@ -200,6 +205,7 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value)
bit_buf = value; bit_buf = value;
} }
#endif #endif
s->bit_buf = bit_buf; s->bit_buf = bit_buf;
s->bit_left = bit_left; s->bit_left = bit_left;
} }
@@ -207,6 +213,7 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value)
static inline void put_sbits(PutBitContext *pb, int n, int32_t value) static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
{ {
av_assert2(n >= 0 && n <= 31); av_assert2(n >= 0 && n <= 31);
put_bits(pb, n, av_mod_uintp2(value, n)); put_bits(pb, n, av_mod_uintp2(value, n));
} }

View File

@@ -31,6 +31,7 @@
#include <libavutil/avassert.h> #include <libavutil/avassert.h>
#include <ffmpeg/put_bits.h> #include <ffmpeg/put_bits.h>
void avpriv_align_put_bits(PutBitContext *s) void avpriv_align_put_bits(PutBitContext *s)
{ {
put_bits(s, s->bit_left & 7, 0); put_bits(s, s->bit_left & 7, 0);
@@ -52,9 +53,12 @@ void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
int words = length >> 4; int words = length >> 4;
int bits = length & 15; int bits = length & 15;
int i; int i;
if (length == 0) if (length == 0)
return; return;
av_assert0(length <= put_bits_left(pb)); av_assert0(length <= put_bits_left(pb));
if (words < 16 || put_bits_count(pb) & 7) if (words < 16 || put_bits_count(pb) & 7)
{ {
for (i = 0; i < words; i++) for (i = 0; i < words; i++)
@@ -68,5 +72,7 @@ void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
memcpy(put_bits_ptr(pb), src + i, 2 * words - i); memcpy(put_bits_ptr(pb), src + i, 2 * words - i);
skip_put_bytes(pb, 2 * words - i); skip_put_bytes(pb, 2 * words - i);
} }
put_bits(pb, bits, AV_RB16(src + 2 * words) >> (16 - bits)); put_bits(pb, bits, AV_RB16(src + 2 * words) >> (16 - bits));
} }

View File

@@ -38,9 +38,11 @@
#define latmenc_err(fmt, x...) #define latmenc_err(fmt, x...)
#endif #endif
int latmenc_decode_extradata(LATMContext *ctx, uint8_t *buf, int size) int latmenc_decode_extradata(LATMContext *ctx, uint8_t *buf, int size)
{ {
MPEG4AudioConfig m4ac; MPEG4AudioConfig m4ac;
if (size > MAX_EXTRADATA_SIZE) if (size > MAX_EXTRADATA_SIZE)
{ {
latmenc_err("Extradata is larger than currently supported.\n"); latmenc_err("Extradata is larger than currently supported.\n");
@@ -49,6 +51,7 @@ int latmenc_decode_extradata(LATMContext *ctx, uint8_t *buf, int size)
ctx->off = avpriv_mpeg4audio_get_config(&m4ac, buf, size * 8, 1); ctx->off = avpriv_mpeg4audio_get_config(&m4ac, buf, size * 8, 1);
if (ctx->off < 0) if (ctx->off < 0)
return ctx->off; return ctx->off;
if (ctx->object_type == AOT_ALS && (ctx->off & 7)) if (ctx->object_type == AOT_ALS && (ctx->off & 7))
{ {
// as long as avpriv_mpeg4audio_get_config works correctly this is impossible // as long as avpriv_mpeg4audio_get_config works correctly this is impossible
@@ -56,6 +59,7 @@ int latmenc_decode_extradata(LATMContext *ctx, uint8_t *buf, int size)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
/* FIXME: are any formats not allowed in LATM? */ /* FIXME: are any formats not allowed in LATM? */
if (m4ac.object_type > AOT_SBR && m4ac.object_type != AOT_ALS) if (m4ac.object_type > AOT_SBR && m4ac.object_type != AOT_ALS)
{ {
latmenc_err("Muxing MPEG-4 AOT %d in LATM is not supported\n", m4ac.object_type); latmenc_err("Muxing MPEG-4 AOT %d in LATM is not supported\n", m4ac.object_type);
@@ -63,14 +67,17 @@ int latmenc_decode_extradata(LATMContext *ctx, uint8_t *buf, int size)
} }
ctx->channel_conf = m4ac.chan_config; ctx->channel_conf = m4ac.chan_config;
ctx->object_type = m4ac.object_type; ctx->object_type = m4ac.object_type;
return 0; return 0;
} }
static void latmenc_write_frame_header(LATMContext *ctx, uint8_t *extradata, int extradata_size, PutBitContext *bs) static void latmenc_write_frame_header(LATMContext *ctx, uint8_t *extradata, int extradata_size, PutBitContext *bs)
{ {
int header_size; int header_size;
/* AudioMuxElement */ /* AudioMuxElement */
put_bits(bs, 1, !!ctx->counter); put_bits(bs, 1, !!ctx->counter);
if (!ctx->counter) if (!ctx->counter)
{ {
/* StreamMuxConfig */ /* StreamMuxConfig */
@@ -79,6 +86,7 @@ static void latmenc_write_frame_header(LATMContext *ctx, uint8_t *extradata, int
put_bits(bs, 6, 0); /* numSubFrames */ put_bits(bs, 6, 0); /* numSubFrames */
put_bits(bs, 4, 0); /* numProgram */ put_bits(bs, 4, 0); /* numProgram */
put_bits(bs, 3, 0); /* numLayer */ put_bits(bs, 3, 0); /* numLayer */
/* AudioSpecificConfig */ /* AudioSpecificConfig */
if (ctx->object_type == AOT_ALS) if (ctx->object_type == AOT_ALS)
{ {
@@ -90,6 +98,7 @@ static void latmenc_write_frame_header(LATMContext *ctx, uint8_t *extradata, int
// + 3 assumes not scalable and dependsOnCoreCoder == 0, // + 3 assumes not scalable and dependsOnCoreCoder == 0,
// see decode_ga_specific_config in libavcodec/aacdec.c // see decode_ga_specific_config in libavcodec/aacdec.c
avpriv_copy_bits(bs, extradata, ctx->off + 3); avpriv_copy_bits(bs, extradata, ctx->off + 3);
if (!ctx->channel_conf) if (!ctx->channel_conf)
{ {
GetBitContext gb; GetBitContext gb;
@@ -99,11 +108,14 @@ static void latmenc_write_frame_header(LATMContext *ctx, uint8_t *extradata, int
avpriv_copy_pce_data(bs, &gb); avpriv_copy_pce_data(bs, &gb);
} }
} }
put_bits(bs, 3, 0); /* frameLengthType */ put_bits(bs, 3, 0); /* frameLengthType */
put_bits(bs, 8, 0xff); /* latmBufferFullness */ put_bits(bs, 8, 0xff); /* latmBufferFullness */
put_bits(bs, 1, 0); /* otherDataPresent */ put_bits(bs, 1, 0); /* otherDataPresent */
put_bits(bs, 1, 0); /* crcCheckPresent */ put_bits(bs, 1, 0); /* crcCheckPresent */
} }
ctx->counter++; ctx->counter++;
ctx->counter %= ctx->mod; ctx->counter %= ctx->mod;
} }
@@ -112,15 +124,22 @@ int latmenc_write_packet(LATMContext *ctx, uint8_t *data, int size, uint8_t *ext
{ {
PutBitContext bs; PutBitContext bs;
int i, len; int i, len;
if (size > 0x1fff) if (size > 0x1fff)
goto too_large; goto too_large;
init_put_bits(&bs, ctx->buffer, size + 1024 + MAX_EXTRADATA_SIZE); init_put_bits(&bs, ctx->buffer, size + 1024 + MAX_EXTRADATA_SIZE);
latmenc_write_frame_header(ctx, extradata, extradata_size, &bs); latmenc_write_frame_header(ctx, extradata, extradata_size, &bs);
/* PayloadLengthInfo() */ /* PayloadLengthInfo() */
for (i = 0; i <= size - 255; i += 255) for (i = 0; i <= size - 255; i += 255)
put_bits(&bs, 8, 255); put_bits(&bs, 8, 255);
put_bits(&bs, 8, size - i); put_bits(&bs, 8, size - i);
/* The LATM payload is written unaligned */ /* The LATM payload is written unaligned */
/* PayloadMux() */ /* PayloadMux() */
if (size && (data[0] & 0xe1) == 0x81) if (size && (data[0] & 0xe1) == 0x81)
{ {
@@ -137,17 +156,23 @@ int latmenc_write_packet(LATMContext *ctx, uint8_t *data, int size, uint8_t *ext
} }
else else
avpriv_copy_bits(&bs, data, 8 * size); avpriv_copy_bits(&bs, data, 8 * size);
avpriv_align_put_bits(&bs); avpriv_align_put_bits(&bs);
flush_put_bits(&bs); flush_put_bits(&bs);
len = put_bits_count(&bs) >> 3; len = put_bits_count(&bs) >> 3;
if (len > 0x1fff) if (len > 0x1fff)
goto too_large; goto too_large;
memcpy(ctx->loas_header, "\x56\xe0\x00", 3); memcpy(ctx->loas_header, "\x56\xe0\x00", 3);
ctx->loas_header[1] |= (len >> 8) & 0x1f; ctx->loas_header[1] |= (len >> 8) & 0x1f;
ctx->loas_header[2] |= len & 0xff; ctx->loas_header[2] |= len & 0xff;
ctx->len = len; ctx->len = len;
return 0; return 0;
too_large: too_large:
latmenc_err("LATM packet size larger than maximum size 0x1fff\n"); latmenc_err("LATM packet size larger than maximum size 0x1fff\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }

View File

@@ -34,16 +34,21 @@ static int parse_config_ALS(GetBitContext *gb, MPEG4AudioConfig *c)
{ {
if (get_bits_left(gb) < 112) if (get_bits_left(gb) < 112)
return -1; return -1;
if (get_bits_long(gb, 32) != MKBETAG('A', 'L', 'S', '\0')) if (get_bits_long(gb, 32) != MKBETAG('A', 'L', 'S', '\0'))
return -1; return -1;
// override AudioSpecificConfig channel configuration and sample rate // override AudioSpecificConfig channel configuration and sample rate
// which are buggy in old ALS conformance files // which are buggy in old ALS conformance files
c->sample_rate = get_bits_long(gb, 32); c->sample_rate = get_bits_long(gb, 32);
// skip number of samples // skip number of samples
skip_bits_long(gb, 32); skip_bits_long(gb, 32);
// read number of channels // read number of channels
c->chan_config = 0; c->chan_config = 0;
c->channels = get_bits(gb, 16) + 1; c->channels = get_bits(gb, 16) + 1;
return 0; return 0;
} }
@@ -79,11 +84,14 @@ int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf,
{ {
GetBitContext gb; GetBitContext gb;
int specific_config_bitindex, ret; int specific_config_bitindex, ret;
if (bit_size <= 0) if (bit_size <= 0)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
ret = init_get_bits(&gb, buf, bit_size); ret = init_get_bits(&gb, buf, bit_size);
if (ret < 0) if (ret < 0)
return ret; return ret;
c->object_type = get_object_type(&gb); c->object_type = get_object_type(&gb);
c->sample_rate = get_sample_rate(&gb, &c->sampling_index); c->sample_rate = get_sample_rate(&gb, &c->sampling_index);
c->chan_config = get_bits(&gb, 4); c->chan_config = get_bits(&gb, 4);
@@ -110,15 +118,19 @@ int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf,
c->ext_sample_rate = 0; c->ext_sample_rate = 0;
} }
specific_config_bitindex = get_bits_count(&gb); specific_config_bitindex = get_bits_count(&gb);
if (c->object_type == AOT_ALS) if (c->object_type == AOT_ALS)
{ {
skip_bits(&gb, 5); skip_bits(&gb, 5);
if (show_bits_long(&gb, 24) != MKBETAG('\0', 'A', 'L', 'S')) if (show_bits_long(&gb, 24) != MKBETAG('\0', 'A', 'L', 'S'))
skip_bits_long(&gb, 24); skip_bits_long(&gb, 24);
specific_config_bitindex = get_bits_count(&gb); specific_config_bitindex = get_bits_count(&gb);
if (parse_config_ALS(&gb, c)) if (parse_config_ALS(&gb, c))
return -1; return -1;
} }
if (c->ext_object_type != AOT_SBR && sync_extension) if (c->ext_object_type != AOT_SBR && sync_extension)
{ {
while (get_bits_left(&gb) > 15) while (get_bits_left(&gb) > 15)
@@ -141,12 +153,14 @@ int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf,
get_bits1(&gb); // skip 1 bit get_bits1(&gb); // skip 1 bit
} }
} }
//PS requires SBR //PS requires SBR
if (!c->sbr) if (!c->sbr)
c->ps = 0; c->ps = 0;
//Limit implicit PS to the HE-AACv2 Profile //Limit implicit PS to the HE-AACv2 Profile
if ((c->ps == -1 && c->object_type != AOT_AAC_LC) || c->channels & ~0x01) if ((c->ps == -1 && c->object_type != AOT_AAC_LC) || c->channels & ~0x01)
c->ps = 0; c->ps = 0;
return specific_config_bitindex; return specific_config_bitindex;
} }
@@ -163,6 +177,7 @@ int avpriv_copy_pce_data(PutBitContext *pb, GetBitContext *gb)
{ {
int five_bit_ch, four_bit_ch, comment_size, bits; int five_bit_ch, four_bit_ch, comment_size, bits;
int offset = put_bits_count(pb); int offset = put_bits_count(pb);
copy_bits(pb, gb, 10); //Tag, Object Type, Frequency copy_bits(pb, gb, 10); //Tag, Object Type, Frequency
five_bit_ch = copy_bits(pb, gb, 4); //Front five_bit_ch = copy_bits(pb, gb, 4); //Front
five_bit_ch += copy_bits(pb, gb, 4); //Side five_bit_ch += copy_bits(pb, gb, 4); //Side
@@ -185,5 +200,6 @@ int avpriv_copy_pce_data(PutBitContext *pb, GetBitContext *gb)
comment_size = copy_bits(pb, gb, 8); comment_size = copy_bits(pb, gb, 8);
for (; comment_size > 0; comment_size--) for (; comment_size > 0; comment_size--)
copy_bits(pb, gb, 8); copy_bits(pb, gb, 8);
return put_bits_count(pb) - offset; return put_bits_count(pb) - offset;
} }

View File

@@ -56,6 +56,7 @@ static uint32 get_u24(BR *p)
uint32 a = get_u8(p); uint32 a = get_u8(p);
uint32 b = get_u8(p); uint32 b = get_u8(p);
uint32 c = get_u8(p); uint32 c = get_u8(p);
return (a << 16) | (b << 8) | c; return (a << 16) | (b << 8) | c;
} }
@@ -65,6 +66,7 @@ static uint32 get_u32(BR *p)
uint32 b = get_u8(p); uint32 b = get_u8(p);
uint32 c = get_u8(p); uint32 c = get_u8(p);
uint32 d = get_u8(p); uint32 d = get_u8(p);
return (a << 24) | (b << 16) | (c << 8) | d; return (a << 24) | (b << 16) | (c << 8) | d;
} }
@@ -82,10 +84,12 @@ static uint32 show_bits(BR *p, uint32 bits)
{ {
const uint8 *pp; const uint8 *pp;
uint32 tmp; uint32 tmp;
pp = p->buf + p->read; pp = p->buf + p->read;
tmp = (pp[0] << 24) | (pp[1] << 16) | (pp[2] << 8) | (pp[3]); tmp = (pp[0] << 24) | (pp[1] << 16) | (pp[2] << 8) | (pp[3]);
tmp <<= p->bitoffset; tmp <<= p->bitoffset;
tmp >>= 32 - bits; tmp >>= 32 - bits;
return tmp; return tmp;
} }
@@ -93,10 +97,12 @@ static int32 show_sbits(BR *p, uint32 bits)
{ {
const uint8 *pp; const uint8 *pp;
int32 tmp; int32 tmp;
pp = p->buf + p->read; pp = p->buf + p->read;
tmp = (pp[0] << 24) | (pp[1] << 16) | (pp[2] << 8) | (pp[3]); tmp = (pp[0] << 24) | (pp[1] << 16) | (pp[2] << 8) | (pp[3]);
tmp <<= p->bitoffset; tmp <<= p->bitoffset;
tmp >>= 32 - bits; tmp >>= 32 - bits;
return tmp; return tmp;
} }
@@ -150,14 +156,17 @@ static int __inline get_vlc(BR *br, const VLCtab *table, int bits, int max_depth
index = show_bits(br, bits); index = show_bits(br, bits);
code = table[index].code; code = table[index].code;
n = table[index].n; n = table[index].n;
if (max_depth > 1 && n < 0) if (max_depth > 1 && n < 0)
{ {
flash_bits(br, bits); flash_bits(br, bits);
nb_bits = -n; nb_bits = -n;
index = show_bits(br, nb_bits) + code; index = show_bits(br, nb_bits) + code;
code = table[index].code; code = table[index].code;
n = table[index].n; n = table[index].n;
} }
flash_bits(br, n); flash_bits(br, n);
return code; return code;
} }

View File

@@ -57,12 +57,14 @@ static void __inline init_bw(BW *p, uint8 *buf, uint32 size)
static void __inline forword_bits(BW *p, uint32 bits) static void __inline forword_bits(BW *p, uint32 bits)
{ {
p->bitoffset += bits; p->bitoffset += bits;
if (p->bitoffset >= 32) if (p->bitoffset >= 32)
{ {
p->buf[p->pos++] = (p->tmp >> 24) & 0xff; p->buf[p->pos++] = (p->tmp >> 24) & 0xff;
p->buf[p->pos++] = (p->tmp >> 16) & 0xff; p->buf[p->pos++] = (p->tmp >> 16) & 0xff;
p->buf[p->pos++] = (p->tmp >> 8) & 0xff; p->buf[p->pos++] = (p->tmp >> 8) & 0xff;
p->buf[p->pos++] = (p->tmp >> 0) & 0xff; p->buf[p->pos++] = (p->tmp >> 0) & 0xff;
p->tmp = 0; p->tmp = 0;
p->bitoffset -= 32; p->bitoffset -= 32;
} }
@@ -71,6 +73,7 @@ static void __inline forword_bits(BW *p, uint32 bits)
static void __inline put_bits(BW *p, uint32 bits, uint32 value) static void __inline put_bits(BW *p, uint32 bits, uint32 value)
{ {
uint32 shift = 32 - p->bitoffset - bits; uint32 shift = 32 - p->bitoffset - bits;
if (shift <= 32) if (shift <= 32)
{ {
p->tmp |= value << shift; p->tmp |= value << shift;
@@ -81,6 +84,7 @@ static void __inline put_bits(BW *p, uint32 bits, uint32 value)
shift = bits - (32 - p->bitoffset); shift = bits - (32 - p->bitoffset);
p->tmp |= value >> shift; p->tmp |= value >> shift;
forword_bits(p, bits - shift); forword_bits(p, bits - shift);
p->tmp |= value << (32 - shift); p->tmp |= value << (32 - shift);
forword_bits(p, shift); forword_bits(p, shift);
} }
@@ -98,6 +102,7 @@ static void __inline pad_to_boundary(BW *p)
static void __inline flash_bw(BW *p) static void __inline flash_bw(BW *p)
{ {
pad_to_boundary(p); pad_to_boundary(p);
switch (p->bitoffset) switch (p->bitoffset)
{ {
case 0: // nothing to do case 0: // nothing to do
@@ -118,6 +123,7 @@ static void __inline flash_bw(BW *p)
// fprintf(stderr, "flash_bw error!(%d)\n", p->bitoffset); // fprintf(stderr, "flash_bw error!(%d)\n", p->bitoffset);
break; break;
} }
p->tmp = 0; p->tmp = 0;
p->bitoffset = 0; p->bitoffset = 0;
} }
@@ -136,6 +142,7 @@ static void __inline put_vlcdec(BW *bw, VLCDEC *vlcdec)
static void __inline m4v_stuffing(BW *p) static void __inline m4v_stuffing(BW *p)
{ {
int length; int length;
put_bits(p, 1, 0); put_bits(p, 1, 0);
length = (- p->bitoffset) & 7; length = (- p->bitoffset) & 7;
if (length) put_bits(p, length, (1 << length) - 1); if (length) put_bits(p, length, (1 << length) - 1);

View File

@@ -25,6 +25,7 @@
#include "dcprediction.h" #include "dcprediction.h"
// M4V ADDED // M4V ADDED
static const uint8 mpeg4_y_dc_scale_table[32] = static const uint8 mpeg4_y_dc_scale_table[32] =
{ {
@@ -43,10 +44,12 @@ static int __inline get_pred(int *dc_cur, int stride, int scale)
{ {
/* B C /* B C
A X */ A X */
int A = dc_cur[-1]; int A = dc_cur[-1];
int B = dc_cur[-1 - stride]; int B = dc_cur[-1 - stride];
int C = dc_cur[-stride]; int C = dc_cur[-stride];
int pred; int pred;
if (abs(A - B) < abs(B - C)) if (abs(A - B) < abs(B - C))
{ {
pred = C; pred = C;
@@ -55,6 +58,7 @@ static int __inline get_pred(int *dc_cur, int stride, int scale)
{ {
pred = A; pred = A;
} }
return (pred + (scale >> 1)) / scale; return (pred + (scale >> 1)) / scale;
} }
@@ -68,6 +72,7 @@ static void __inline set_dc_to_dc_cur(int *dc_cur, int level, int scale)
else else
level = 2047; level = 2047;
} }
dc_cur[0] = level; dc_cur[0] = level;
} }
@@ -118,6 +123,7 @@ int dcpred_for_enc(M4V_DCPRED *p, int n, int level)
int *dc_cur = p->dc_cur[n]; int *dc_cur = p->dc_cur[n];
int scale = get_scale(p, n); int scale = get_scale(p, n);
int pred = get_pred(dc_cur, p->stride[n], scale); int pred = get_pred(dc_cur, p->stride[n], scale);
set_dc_to_dc_cur(dc_cur, level, scale); set_dc_to_dc_cur(dc_cur, level, scale);
return level - pred; return level - pred;
} }
@@ -127,6 +133,7 @@ int dcpred_for_dec(M4V_DCPRED *p, int n, int level)
int *dc_cur = p->dc_cur[n]; int *dc_cur = p->dc_cur[n];
int scale = get_scale(p, n); int scale = get_scale(p, n);
int pred = get_pred(dc_cur, p->stride[n], scale); int pred = get_pred(dc_cur, p->stride[n], scale);
level += pred; level += pred;
set_dc_to_dc_cur(dc_cur, level, scale); set_dc_to_dc_cur(dc_cur, level, scale);
return level; return level;
@@ -137,6 +144,7 @@ static void init_plane(M4V_DCPRED *pred, int n)
{ {
int x, len = pred->stride[n] * pred->height[n]; int x, len = pred->stride[n] * pred->height[n];
int *p = pred->_dc[n]; int *p = pred->_dc[n];
for (x = 0; x < len; x++) for (x = 0; x < len; x++)
{ {
p[x] = 1024; p[x] = 1024;
@@ -156,16 +164,20 @@ void alloc_dcpred(M4V_DCPRED *pred, int mb_width, int mb_height)
const int h2 = mb_height * 2 + 1; const int h2 = mb_height * 2 + 1;
const int w = mb_width + 1; const int w = mb_width + 1;
const int h = mb_height + 1; const int h = mb_height + 1;
pred->_dc[0] = pred->_dc[1] = pred->_dc[2] = pred->_dc[3] = (int *)malloc(sizeof(int) * w2 * h2); pred->_dc[0] = pred->_dc[1] = pred->_dc[2] = pred->_dc[3] = (int *)malloc(sizeof(int) * w2 * h2);
pred->_dc[4] = (int *)malloc(sizeof(int) * w * h); pred->_dc[4] = (int *)malloc(sizeof(int) * w * h);
pred->_dc[5] = (int *)malloc(sizeof(int) * w * h); pred->_dc[5] = (int *)malloc(sizeof(int) * w * h);
pred->dc[0] = pred->dc[1] = pred->dc[2] = pred->dc[3] = pred->_dc[0] + w2 + 1; pred->dc[0] = pred->dc[1] = pred->dc[2] = pred->dc[3] = pred->_dc[0] + w2 + 1;
pred->dc[4] = pred->_dc[4] + w + 1; pred->dc[4] = pred->_dc[4] + w + 1;
pred->dc[5] = pred->_dc[5] + w + 1; pred->dc[5] = pred->_dc[5] + w + 1;
pred->stride[0] = pred->stride[1] = pred->stride[2] = pred->stride[3] = w2; pred->stride[0] = pred->stride[1] = pred->stride[2] = pred->stride[3] = w2;
pred->height[0] = pred->height[1] = pred->height[2] = pred->height[3] = h2; pred->height[0] = pred->height[1] = pred->height[2] = pred->height[3] = h2;
pred->stride[4] = pred->stride[5] = w; pred->stride[4] = pred->stride[5] = w;
pred->height[4] = pred->height[5] = h; pred->height[4] = pred->height[5] = h;
pred->block_offset[0] = 0; pred->block_offset[0] = 0;
pred->block_offset[1] = 1; pred->block_offset[1] = 1;
pred->block_offset[2] = w2; pred->block_offset[2] = w2;

View File

@@ -40,6 +40,7 @@ typedef struct _M4V_DCPRED
int y_dc_scale; int y_dc_scale;
int c_dc_scale; int c_dc_scale;
} M4V_DCPRED; } M4V_DCPRED;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -65,6 +65,7 @@ typedef struct _PICTURE
int width; int width;
int height; int height;
#define FLV_I_TYPE 0 #define FLV_I_TYPE 0
#define FLV_P_TYPE 1 #define FLV_P_TYPE 1
@@ -156,4 +157,5 @@ static const int8 rl_inter_run[102] =
static const int rl_inter_n = 102; static const int rl_inter_n = 102;
static const int rl_inter_last = 58; static const int rl_inter_last = 58;
#endif // FLV_H #endif // FLV_H

View File

@@ -41,6 +41,7 @@ typedef struct _CONVCTX
M4V_VOL vol; M4V_VOL vol;
} CONVCTX; } CONVCTX;
typedef struct typedef struct
{ {
uint8 *out_buf; uint8 *out_buf;
@@ -64,6 +65,7 @@ static const uint8 ff_mpeg4_c_dc_scale_table[32] =
0, 8, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 0, 8, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25
}; };
static void copy_vol(PICTURE *flv_pic, M4V_VOL *vol) static void copy_vol(PICTURE *flv_pic, M4V_VOL *vol)
{ {
vol->width = flv_pic->width; vol->width = flv_pic->width;
@@ -74,9 +76,11 @@ static void copy_vol(PICTURE *flv_pic, M4V_VOL *vol)
static void copy_vop(PICTURE *flv_pic, M4V_VOP *vop, CONVCTX *c) static void copy_vop(PICTURE *flv_pic, M4V_VOP *vop, CONVCTX *c)
{ {
vop->qscale = flv_pic->qscale; vop->qscale = flv_pic->qscale;
vop->time = c->frame % 30; vop->time = c->frame % 30;
vop->icount = (c->icounter + 29) / 30; vop->icount = (c->icounter + 29) / 30;
vop->intra_dc_threshold = 99; vop->intra_dc_threshold = 99;
if (flv_pic->picture_type == FLV_I_TYPE) if (flv_pic->picture_type == FLV_I_TYPE)
{ {
vop->picture_type = M4V_I_TYPE; vop->picture_type = M4V_I_TYPE;
@@ -91,13 +95,16 @@ static void copy_vop(PICTURE *flv_pic, M4V_VOP *vop, CONVCTX *c)
static void copy_microblock(MICROBLOCK *flv_mb, M4V_MICROBLOCK *m4v_mb) static void copy_microblock(MICROBLOCK *flv_mb, M4V_MICROBLOCK *m4v_mb)
{ {
int i; int i;
m4v_mb->dquant = flv_mb->dquant; m4v_mb->dquant = flv_mb->dquant;
memcpy(m4v_mb->block, flv_mb->block, sizeof(m4v_mb->block)); // !!!!!!! memcpy(m4v_mb->block, flv_mb->block, sizeof(m4v_mb->block)); // !!!!!!!
m4v_mb->intra = flv_mb->intra; m4v_mb->intra = flv_mb->intra;
m4v_mb->skip = flv_mb->skip; m4v_mb->skip = flv_mb->skip;
m4v_mb->mv_type = flv_mb->mv_type; m4v_mb->mv_type = flv_mb->mv_type;
memcpy(m4v_mb->mv_x, flv_mb->mv_x, sizeof(m4v_mb->mv_x)); // !!!!!! memcpy(m4v_mb->mv_x, flv_mb->mv_x, sizeof(m4v_mb->mv_x)); // !!!!!!
memcpy(m4v_mb->mv_y, flv_mb->mv_y, sizeof(m4v_mb->mv_y)); // !!!!!! memcpy(m4v_mb->mv_y, flv_mb->mv_y, sizeof(m4v_mb->mv_y)); // !!!!!!
// dc rescale // dc rescale
if (m4v_mb->intra) if (m4v_mb->intra)
{ {
@@ -106,6 +113,7 @@ static void copy_microblock(MICROBLOCK *flv_mb, M4V_MICROBLOCK *m4v_mb)
m4v_mb->block[i].block[0] *= 8; m4v_mb->block[i].block[0] *= 8;
m4v_mb->block[i].block[0] /= ff_mpeg4_y_dc_scale_table[m4v_mb->qscale]; m4v_mb->block[i].block[0] /= ff_mpeg4_y_dc_scale_table[m4v_mb->qscale];
} }
for (i = 4; i < 6; i++) for (i = 4; i < 6; i++)
{ {
m4v_mb->block[i].block[0] *= 8; m4v_mb->block[i].block[0] *= 8;
@@ -126,7 +134,9 @@ static int write_pad_not_coded_frames(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BW *bw
vop.icount = (c->icounter + 29) / 30; vop.icount = (c->icounter + 29) / 30;
m4v_encode_vop_header(bw, &vop, VOL_TIME_BITS, 1); m4v_encode_vop_header(bw, &vop, VOL_TIME_BITS, 1);
m4v_stuffing(bw); m4v_stuffing(bw);
flash_bw(bw); flash_bw(bw);
// write frame // write frame
if (pub_ctx->write_packet_cb(pub_ctx->usr_data, if (pub_ctx->write_packet_cb(pub_ctx->usr_data,
0, 0,
@@ -136,10 +146,13 @@ static int write_pad_not_coded_frames(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BW *bw
{ {
return -1; return -1;
} }
clear_bw(bw); clear_bw(bw);
c->frame++; c->frame++;
c->icounter++; c->icounter++;
} }
return 0; return 0;
} }
@@ -151,9 +164,12 @@ static int write_m4v_picture_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, B
int x, y; int x, y;
int mb_width = (flvpic->width + 15) / 16; int mb_width = (flvpic->width + 15) / 16;
int mb_height = (flvpic->height + 15) / 16; int mb_height = (flvpic->height + 15) / 16;
memset(&vop, 0, sizeof(vop)); memset(&vop, 0, sizeof(vop));
copy_vop(flvpic, &vop, c); copy_vop(flvpic, &vop, c);
m4v_encode_vop_header(bw, &vop, VOL_TIME_BITS, 0); m4v_encode_vop_header(bw, &vop, VOL_TIME_BITS, 0);
// transcode flv to mpeg4 // transcode flv to mpeg4
for (y = 0; y < mb_height; y++) for (y = 0; y < mb_height; y++)
{ {
@@ -161,6 +177,7 @@ static int write_m4v_picture_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, B
{ {
memset(&mb, 0, sizeof(mb)); memset(&mb, 0, sizeof(mb));
memset(&m4v_mb, 0, sizeof(m4v_mb)); memset(&m4v_mb, 0, sizeof(m4v_mb));
if (vop.picture_type == M4V_I_TYPE) if (vop.picture_type == M4V_I_TYPE)
{ {
mb.intra = 1; mb.intra = 1;
@@ -180,8 +197,10 @@ static int write_m4v_picture_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, B
} }
} }
} }
m4v_stuffing(bw); m4v_stuffing(bw);
flash_bw(bw); flash_bw(bw);
// write frame // write frame
if (pub_ctx->write_packet_cb(pub_ctx->usr_data, if (pub_ctx->write_packet_cb(pub_ctx->usr_data,
vop.picture_type == M4V_I_TYPE, vop.picture_type == M4V_I_TYPE,
@@ -191,19 +210,25 @@ static int write_m4v_picture_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, B
{ {
return -1; return -1;
} }
c->frame++; c->frame++;
c->icounter++; c->icounter++;
return 0; return 0;
} }
static int write_m4v_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, BW *bw, uint32 time) static int write_m4v_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, BW *bw, uint32 time)
{ {
PICTURE picture; PICTURE picture;
memset(&picture, 0, sizeof(picture)); memset(&picture, 0, sizeof(picture));
init_dcpred(&c->vol.dcpred); init_dcpred(&c->vol.dcpred);
if (decode_picture_header(br, &picture) < 0) return -1; if (decode_picture_header(br, &picture) < 0) return -1;
if (c->width != picture.width || c->height != picture.height) return -1; //size changed.. if (c->width != picture.width || c->height != picture.height) return -1; //size changed..
copy_vol(&picture, &c->vol); copy_vol(&picture, &c->vol);
if (picture.picture_type == FLV_I_TYPE) if (picture.picture_type == FLV_I_TYPE)
{ {
c->icounter = 0; c->icounter = 0;
@@ -212,10 +237,12 @@ static int write_m4v_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, BW *bw, u
{ {
if (write_pad_not_coded_frames(pub_ctx, c, bw, time) < 0) return -1; if (write_pad_not_coded_frames(pub_ctx, c, bw, time) < 0) return -1;
} }
if (write_m4v_picture_frame(pub_ctx, c, br, bw, &picture, time) < 0) if (write_m4v_picture_frame(pub_ctx, c, br, bw, &picture, time) < 0)
{ {
return -1; return -1;
} }
return 0; return 0;
} }
@@ -235,16 +262,23 @@ int flv2mpeg4_prepare_extra_data(flv2mpeg4_CTX *ctx)
CTX *p = ctx->priv; CTX *p = ctx->priv;
BW bw; BW bw;
CONVCTX *c = &(p->conv); CONVCTX *c = &(p->conv);
M4V_VOP vop; M4V_VOP vop;
memset(&vop, 0, sizeof(vop)); memset(&vop, 0, sizeof(vop));
init_bw(&bw, p->out_buf, PACKETBUFFER_SIZE); init_bw(&bw, p->out_buf, PACKETBUFFER_SIZE);
c->vol.width = c->width; c->vol.width = c->width;
c->vol.height = c->height; c->vol.height = c->height;
c->vol.time_bits = VOL_TIME_BITS; // 0-31 c->vol.time_bits = VOL_TIME_BITS; // 0-31
m4v_encode_m4v_header(&bw, &c->vol, 0); m4v_encode_m4v_header(&bw, &c->vol, 0);
m4v_stuffing(&bw); m4v_stuffing(&bw);
flash_bw(&bw); flash_bw(&bw);
alloc_dcpred(&c->vol.dcpred, (c->width + 15) / 16, (c->height + 15) / 16); alloc_dcpred(&c->vol.dcpred, (c->width + 15) / 16, (c->height + 15) / 16);
return ctx->write_extradata_cb(ctx->usr_data, c->width, c->height, 200 * 1000, bw.buf, bw.pos); return ctx->write_extradata_cb(ctx->usr_data, c->width, c->height, 200 * 1000, bw.buf, bw.pos);
} }
@@ -265,20 +299,26 @@ flv2mpeg4_CTX *flv2mpeg4_init_ctx(void *priv_data, int width, int height, flv2mp
pub_ctx->priv = malloc(sizeof(CTX)); pub_ctx->priv = malloc(sizeof(CTX));
memset(pub_ctx->priv, 0x0, sizeof(CTX)); memset(pub_ctx->priv, 0x0, sizeof(CTX));
CTX *ctx = pub_ctx->priv; CTX *ctx = pub_ctx->priv;
ctx->conv.width = width; ctx->conv.width = width;
ctx->conv.height = height; ctx->conv.height = height;
ctx->out_buf = malloc(PACKETBUFFER_SIZE); ctx->out_buf = malloc(PACKETBUFFER_SIZE);
memset(ctx->out_buf, 0x0, PACKETBUFFER_SIZE); memset(ctx->out_buf, 0x0, PACKETBUFFER_SIZE);
memset(&(ctx->vol), 0x0, sizeof(ctx->vol)); memset(&(ctx->vol), 0x0, sizeof(ctx->vol));
return pub_ctx; return pub_ctx;
} }
void flv2mpeg4_release_ctx(flv2mpeg4_CTX **pub_ctx) void flv2mpeg4_release_ctx(flv2mpeg4_CTX **pub_ctx)
{ {
CTX *ctx = (*pub_ctx)->priv; CTX *ctx = (*pub_ctx)->priv;
free_dcpred(&ctx->conv.vol.dcpred); free_dcpred(&ctx->conv.vol.dcpred);
free(ctx->out_buf); free(ctx->out_buf);
free(ctx); free(ctx);
free(*pub_ctx); free(*pub_ctx);
*pub_ctx = NULL; *pub_ctx = NULL;
} }

View File

@@ -38,6 +38,7 @@ static const uint8 zig_zag_scan[64] =
58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
}; };
static const VLCtab vlc_table_intra_MCBPC[] = //: table_size=72 table_allocated=128 bits=6 static const VLCtab vlc_table_intra_MCBPC[] = //: table_size=72 table_allocated=128 bits=6
{ {
{64, -3}, {64, -3},
@@ -127,6 +128,7 @@ static const VLCtab vlc_table_rl_inter[] = //: table_size=554 table_allocated=10
{100, 3}, {101, 3}, {8, 1}, {7, 1} {100, 3}, {101, 3}, {8, 1}, {7, 1}
}; };
static const VLCtab vlc_table_mv[] = //mv_vlc: table_size=538 table_allocated=1024 bits=9 static const VLCtab vlc_table_mv[] = //mv_vlc: table_size=538 table_allocated=1024 bits=9
{ {
{512, -3}, {520, -2}, {524, -1}, {526, -1}, {528, -1}, {530, -1}, {532, -1}, {534, -1}, {536, -1}, {10, 9}, {512, -3}, {520, -2}, {524, -1}, {526, -1}, {528, -1}, {530, -1}, {532, -1}, {534, -1}, {536, -1}, {10, 9},
@@ -181,6 +183,7 @@ static int __inline decode_DC(BR *p)
return -1; return -1;
} }
if (level == 255) level = 128; if (level == 255) level = 128;
// printf("DC: %d\n", level); // printf("DC: %d\n", level);
return level; return level;
} }
@@ -188,6 +191,7 @@ static int __inline decode_DC(BR *p)
static int __inline decode_AC(BR *p, BLOCK *block, int escape_type, int i) static int __inline decode_AC(BR *p, BLOCK *block, int escape_type, int i)
{ {
int code, run, level, last, sign; int code, run, level, last, sign;
while (1) while (1)
{ {
code = get_vlc(p, vlc_table_rl_inter, 9, 2); code = get_vlc(p, vlc_table_rl_inter, 9, 2);
@@ -196,12 +200,14 @@ static int __inline decode_AC(BR *p, BLOCK *block, int escape_type, int i)
printf("invalid Huffman code in getblock()\n"); printf("invalid Huffman code in getblock()\n");
return -1; return -1;
} }
if (code == rl_inter_n) if (code == rl_inter_n)
{ {
//escape //escape
if (escape_type == 1) if (escape_type == 1)
{ {
int is11bit = get_bits(p, 1); int is11bit = get_bits(p, 1);
last = get_bits(p, 1); last = get_bits(p, 1);
run = get_bits(p, 6); run = get_bits(p, 6);
if (is11bit) if (is11bit)
@@ -227,9 +233,11 @@ static int __inline decode_AC(BR *p, BLOCK *block, int escape_type, int i)
run = rl_inter_run[code]; run = rl_inter_run[code];
level = rl_inter_level[code]; level = rl_inter_level[code];
last = code >= rl_inter_last; last = code >= rl_inter_last;
sign = get_bits(p, 1); sign = get_bits(p, 1);
if (sign) level = -level; if (sign) level = -level;
} }
i += run; i += run;
if (i >= 64) if (i >= 64)
{ {
@@ -240,6 +248,7 @@ static int __inline decode_AC(BR *p, BLOCK *block, int escape_type, int i)
if (last) break; if (last) break;
i++; i++;
} }
block->last_index = i; block->last_index = i;
return 0; return 0;
} }
@@ -252,12 +261,15 @@ static int __inline decode_intra_block(BR *p, BLOCK *block, int escape_type, int
printf("dc error.\n"); printf("dc error.\n");
return -1; return -1;
} }
block->block[0] = level; block->block[0] = level;
block->last_index = 0; block->last_index = 0;
if (!coded) if (!coded)
{ {
return 0; return 0;
} }
if (decode_AC(p, block, escape_type, 1) < 0) return -1; if (decode_AC(p, block, escape_type, 1) < 0) return -1;
return 0; return 0;
} }
@@ -265,10 +277,12 @@ static int __inline decode_intra_block(BR *p, BLOCK *block, int escape_type, int
static int __inline decode_inter_block(BR *p, BLOCK *block, int escape_type, int coded) static int __inline decode_inter_block(BR *p, BLOCK *block, int escape_type, int coded)
{ {
block->last_index = -1; block->last_index = -1;
if (!coded) if (!coded)
{ {
return 0; return 0;
} }
if (decode_AC(p, block, escape_type, 0) < 0) return -1; if (decode_AC(p, block, escape_type, 0) < 0) return -1;
return 0; return 0;
} }
@@ -298,6 +312,7 @@ static int __inline get_inter_MCBPC(BR *br)
if (cbpc < 0) return -1; if (cbpc < 0) return -1;
} }
while (cbpc == 20); while (cbpc == 20);
return cbpc; return cbpc;
} }
@@ -316,11 +331,14 @@ static int __inline decode_motion(BR *br, VLCDEC *vlcdec)
{ {
int tmp; int tmp;
int code = get_vlcdec(br, vlc_table_mv, 9, 2, vlcdec); int code = get_vlcdec(br, vlc_table_mv, 9, 2, vlcdec);
vlcdec->bits_ex = 0; vlcdec->bits_ex = 0;
if (code == 0) if (code == 0)
return 0; return 0;
if (code < 0) if (code < 0)
return -1; return -1;
tmp = get_bits(br, 1); tmp = get_bits(br, 1);
/* /*
vlcdec->value |= (tmp << vlcdec->bits); vlcdec->value |= (tmp << vlcdec->bits);
@@ -331,6 +349,7 @@ static int __inline decode_motion(BR *br, VLCDEC *vlcdec)
*/ */
vlcdec->bits_ex = 1; vlcdec->bits_ex = 1;
vlcdec->value_ex = tmp; vlcdec->value_ex = tmp;
return 0; return 0;
} }
@@ -338,23 +357,28 @@ static int __inline decode_intra_mb_internal(BR *p, MICROBLOCK *mb, int escape_t
{ {
int cbpy, cbp; int cbpy, cbp;
int i; int i;
cbpy = get_cbpy(p); cbpy = get_cbpy(p);
if (cbpy < 0) if (cbpy < 0)
{ {
printf("cbpy error\n"); printf("cbpy error\n");
return -1; return -1;
} }
cbp = (cbpc & 3) | (cbpy << 2); cbp = (cbpc & 3) | (cbpy << 2);
if (dquant) if (dquant)
{ {
mb->dquant = decode_dquant(p); mb->dquant = decode_dquant(p);
qscale += mb->dquant; qscale += mb->dquant;
} }
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
{ {
if (decode_intra_block(p, &mb->block[i], escape_type, cbp & 32) != 0) return -1; if (decode_intra_block(p, &mb->block[i], escape_type, cbp & 32) != 0) return -1;
cbp += cbp; cbp += cbp;
} }
return 0; return 0;
} }
@@ -362,19 +386,23 @@ static int __inline decode_inter_mb_internal(BR *p, MICROBLOCK *mb, int escape_t
{ {
int cbpy, cbp; int cbpy, cbp;
int i; int i;
cbpy = get_cbpy(p); cbpy = get_cbpy(p);
if (cbpy < 0) if (cbpy < 0)
{ {
printf("cbpy error\n"); printf("cbpy error\n");
return -1; return -1;
} }
cbpy ^= 0xF; cbpy ^= 0xF;
cbp = (cbpc & 3) | (cbpy << 2); cbp = (cbpc & 3) | (cbpy << 2);
if (dquant) if (dquant)
{ {
mb->dquant = decode_dquant(p); mb->dquant = decode_dquant(p);
qscale += mb->dquant; qscale += mb->dquant;
} }
if ((cbpc & 16) == 0) if ((cbpc & 16) == 0)
{ {
// 16x16 motion prediction // 16x16 motion prediction
@@ -392,11 +420,13 @@ static int __inline decode_inter_mb_internal(BR *p, MICROBLOCK *mb, int escape_t
} }
mb->mv_type = MV_TYPE_8X8; mb->mv_type = MV_TYPE_8X8;
} }
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
{ {
if (decode_inter_block(p, &mb->block[i], escape_type, cbp & 32) != 0) return -1; if (decode_inter_block(p, &mb->block[i], escape_type, cbp & 32) != 0) return -1;
cbp += cbp; cbp += cbp;
} }
return 0; return 0;
} }
@@ -410,18 +440,22 @@ int decode_I_mb(BR *p, MICROBLOCK *mb, int escape_type, int qscale)
printf("intra_MCBPC error\n"); printf("intra_MCBPC error\n");
return -1; return -1;
} }
dquant = cbpc & 4; dquant = cbpc & 4;
decode_intra_mb_internal(p, mb, escape_type, qscale, cbpc, dquant); decode_intra_mb_internal(p, mb, escape_type, qscale, cbpc, dquant);
if (show_bits(p, 16) == 0) if (show_bits(p, 16) == 0)
{ {
// printf("slice end???\n"); // printf("slice end???\n");
} }
return 0; return 0;
} }
int decode_P_mb(BR *p, MICROBLOCK *mb, int escape_type, int qscale) int decode_P_mb(BR *p, MICROBLOCK *mb, int escape_type, int qscale)
{ {
int cbpc = get_inter_MCBPC(p); int cbpc = get_inter_MCBPC(p);
if (cbpc == -1) if (cbpc == -1)
{ {
printf("inter_MCBPC error\n"); printf("inter_MCBPC error\n");
@@ -435,6 +469,7 @@ int decode_P_mb(BR *p, MICROBLOCK *mb, int escape_type, int qscale)
{ {
int dquant = cbpc & 8; int dquant = cbpc & 8;
mb->skip = 0; mb->skip = 0;
if ((cbpc & 4) != 0) if ((cbpc & 4) != 0)
{ {
mb->intra = 1; mb->intra = 1;
@@ -446,31 +481,38 @@ int decode_P_mb(BR *p, MICROBLOCK *mb, int escape_type, int qscale)
decode_inter_mb_internal(p, mb, escape_type, qscale, cbpc, dquant); decode_inter_mb_internal(p, mb, escape_type, qscale, cbpc, dquant);
} }
} }
if (show_bits(p, 16) == 0) if (show_bits(p, 16) == 0)
{ {
// printf("slice end???\n"); // printf("slice end???\n");
} }
return 0; return 0;
} }
int decode_picture_header(BR *p, PICTURE *picture) int decode_picture_header(BR *p, PICTURE *picture)
{ {
int tmp, width = 0, height = 0; int tmp, width = 0, height = 0;
if (get_bits(p, 17) != 1) if (get_bits(p, 17) != 1)
{ {
fprintf(stderr, "start code error\n"); fprintf(stderr, "start code error\n");
return -1; return -1;
} }
tmp = get_bits(p, 5); tmp = get_bits(p, 5);
if (tmp != 0 && tmp != 1) if (tmp != 0 && tmp != 1)
{ {
fprintf(stderr, "picture format error\n"); fprintf(stderr, "picture format error\n");
return -1; return -1;
} }
picture->escape_type = tmp; picture->escape_type = tmp;
picture->frame_number = get_bits(p, 8); picture->frame_number = get_bits(p, 8);
// printf("picture_format: %d\n", tmp); // printf("picture_format: %d\n", tmp);
// printf("picture_number: %d\n", get_bits(p, 8)); // printf("picture_number: %d\n", get_bits(p, 8));
tmp = get_bits(p, 3); tmp = get_bits(p, 3);
switch (tmp) switch (tmp)
{ {
@@ -501,21 +543,27 @@ int decode_picture_header(BR *p, PICTURE *picture)
fprintf(stderr, "size error\n"); fprintf(stderr, "size error\n");
return -1; return -1;
} }
picture->width = width; picture->width = width;
picture->height = height; picture->height = height;
// printf("width: %d height: %d\n", width, height); // printf("width: %d height: %d\n", width, height);
picture->picture_type = get_bits(p, 2); picture->picture_type = get_bits(p, 2);
// printf("picture_type: %d\n", tmp); // printf("picture_type: %d\n", tmp);
tmp = get_bits(p, 1); tmp = get_bits(p, 1);
// printf("deblocking flag: %d\n", tmp); // printf("deblocking flag: %d\n", tmp);
tmp = get_bits(p, 5); tmp = get_bits(p, 5);
picture->qscale = tmp; picture->qscale = tmp;
// printf("qscale: %d\n", tmp); // printf("qscale: %d\n", tmp);
// PEI // PEI
while (get_bits(p, 1) != 0) while (get_bits(p, 1) != 0)
{ {
flash_bits(p, 8); flash_bits(p, 8);
} }
// dump_marker(0, "dd header end"); // dump_marker(0, "dd header end");
return 0; return 0;
} }

View File

@@ -134,4 +134,6 @@ static const uint8 alternate_vertical_scan[64] =
38, 46, 54, 62, 39, 47, 55, 63, 38, 46, 54, 62, 39, 47, 55, 63,
}; };
#endif // M4V_H #endif // M4V_H

View File

@@ -63,6 +63,7 @@ static const uint32 vlce_inter_MCBPC_bits[28] =
static void __inline encode_DC(BW *p, int level, int n) static void __inline encode_DC(BW *p, int level, int n)
{ {
if (level < -255 || level > 255) printf("dc overflow\n"); if (level < -255 || level > 255) printf("dc overflow\n");
#if 1 #if 1
level += 256; level += 256;
if (n < 4) if (n < 4)
@@ -74,6 +75,7 @@ static void __inline encode_DC(BW *p, int level, int n)
put_bits(p, uni_DCtab_chrom_len[level], uni_DCtab_chrom_bits[level]); put_bits(p, uni_DCtab_chrom_len[level], uni_DCtab_chrom_bits[level]);
} }
#else #else
int size, v; int size, v;
/* find number of bits */ /* find number of bits */
size = 0; size = 0;
@@ -83,6 +85,7 @@ static void __inline encode_DC(BW *p, int level, int n)
v >>= 1; v >>= 1;
size++; size++;
} }
if (n < 4) if (n < 4)
{ {
/* luminance */ /* luminance */
@@ -93,6 +96,7 @@ static void __inline encode_DC(BW *p, int level, int n)
/* chrominance */ /* chrominance */
put_bits(p, DCtab_chrom[size][1], DCtab_chrom[size][0]); put_bits(p, DCtab_chrom[size][1], DCtab_chrom[size][0]);
} }
/* encode remaining bits */ /* encode remaining bits */
if (size > 0) if (size > 0)
{ {
@@ -102,7 +106,9 @@ static void __inline encode_DC(BW *p, int level, int n)
if (size > 8) if (size > 8)
put_bits(p, 1, 1); put_bits(p, 1, 1);
} }
#endif #endif
} }
static void __inline encode_escape_3(BW *p, int last, int run, int level) static void __inline encode_escape_3(BW *p, int last, int run, int level)
@@ -129,10 +135,13 @@ static void __inline encode_AC(BW *p, M4V_BLOCK *block, int intra)
int i = intra; int i = intra;
int last_index = block->last_index; int last_index = block->last_index;
int last_non_zero = i - 1; int last_non_zero = i - 1;
const uint8 *scan_table = zig_zag_scan; // !!! const uint8 *scan_table = zig_zag_scan; // !!!
#if 1 #if 1
const uint8 *len_tab; const uint8 *len_tab;
const uint32 *bits_tab; const uint32 *bits_tab;
if (intra) if (intra)
{ {
len_tab = uni_mpeg4_intra_rl_len; len_tab = uni_mpeg4_intra_rl_len;
@@ -143,6 +152,7 @@ static void __inline encode_AC(BW *p, M4V_BLOCK *block, int intra)
len_tab = uni_mpeg4_inter_rl_len; len_tab = uni_mpeg4_inter_rl_len;
bits_tab = uni_mpeg4_inter_rl_bits; bits_tab = uni_mpeg4_inter_rl_bits;
} }
for (; i < last_index; i++) for (; i < last_index; i++)
{ {
int level = block->block[scan_table[i]]; int level = block->block[scan_table[i]];
@@ -159,9 +169,11 @@ static void __inline encode_AC(BW *p, M4V_BLOCK *block, int intra)
{ {
encode_escape_3(p, 0, run, level); encode_escape_3(p, 0, run, level);
} }
last_non_zero = i; last_non_zero = i;
} }
} }
{ {
int level = block->block[scan_table[i]]; int level = block->block[scan_table[i]];
int run = i - last_non_zero - 1; int run = i - last_non_zero - 1;
@@ -179,6 +191,7 @@ static void __inline encode_AC(BW *p, M4V_BLOCK *block, int intra)
#else #else
const RL *rl; const RL *rl;
int last, sign, code; int last, sign, code;
if (intra) if (intra)
{ {
rl = &rl_intra; rl = &rl_intra;
@@ -187,6 +200,7 @@ static void __inline encode_AC(BW *p, M4V_BLOCK *block, int intra)
{ {
rl = &rl_inter; rl = &rl_inter;
} }
for (; i <= last_index; i++) for (; i <= last_index; i++)
{ {
const int slevel = block->block[scan_table[i]]; const int slevel = block->block[scan_table[i]];
@@ -202,6 +216,7 @@ static void __inline encode_AC(BW *p, M4V_BLOCK *block, int intra)
sign = 1; sign = 1;
level = -level; level = -level;
} }
code = get_rl_index(rl, last, run, level); code = get_rl_index(rl, last, run, level);
put_bits(p, rl->table_vlc[code][1], rl->table_vlc[code][0]); put_bits(p, rl->table_vlc[code][1], rl->table_vlc[code][0]);
if (code == rl->n) if (code == rl->n)
@@ -210,6 +225,7 @@ static void __inline encode_AC(BW *p, M4V_BLOCK *block, int intra)
level1 = level - rl->max_level[run][last]; level1 = level - rl->max_level[run][last];
if (level1 < 1) if (level1 < 1)
goto esc2; goto esc2;
code = get_rl_index(rl, last, run, level1); code = get_rl_index(rl, last, run, level1);
if (code == rl->n) if (code == rl->n)
{ {
@@ -255,7 +271,10 @@ esc3:
last_non_zero = i; last_non_zero = i;
} }
} }
#endif #endif
} }
static void __inline encode_intra_block(BW *bw, M4V_BLOCK *block, int n) static void __inline encode_intra_block(BW *bw, M4V_BLOCK *block, int n)
@@ -293,6 +312,7 @@ static void __inline encode_inter_8x8_MCBPC(BW *bw, int cbpc)
put_bits(bw, vlce_inter_MCBPC_bits[cbpc + 16], vlce_inter_MCBPC_code[cbpc + 16]); put_bits(bw, vlce_inter_MCBPC_bits[cbpc + 16], vlce_inter_MCBPC_code[cbpc + 16]);
} }
// same as H.263 // same as H.263
static void __inline encode_cbpy(BW *bw, int cbpy) static void __inline encode_cbpy(BW *bw, int cbpy)
{ {
@@ -320,6 +340,7 @@ static void __inline encode_motion(BW *bw, VLCDEC *mv_x, VLCDEC *mv_y)
{ {
put_bits(bw, mv_x->bits_ex - 1, mv_x->value_ex >> 1); put_bits(bw, mv_x->bits_ex - 1, mv_x->value_ex >> 1);
} }
} }
put_vlcdec(bw, mv_y); put_vlcdec(bw, mv_y);
if (mv_y->bits_ex) if (mv_y->bits_ex)
@@ -337,6 +358,7 @@ static void __inline encode_mb_inter_internal(BW *bw, M4V_MICROBLOCK *mb)
{ {
int cbp = 0, cbpc, cbpy; int cbp = 0, cbpc, cbpy;
int i; int i;
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
{ {
if (mb->block[i].last_index >= 0) if (mb->block[i].last_index >= 0)
@@ -344,10 +366,13 @@ static void __inline encode_mb_inter_internal(BW *bw, M4V_MICROBLOCK *mb)
cbp |= 1 << (5 - i); cbp |= 1 << (5 - i);
} }
} }
cbpc = cbp & 3; cbpc = cbp & 3;
cbpy = cbp >> 2; cbpy = cbp >> 2;
cbpy ^= 0xF; cbpy ^= 0xF;
if (mb->dquant) cbpc += 8; if (mb->dquant) cbpc += 8;
switch (mb->mv_type) switch (mb->mv_type)
{ {
case MV_TYPE_16X16: case MV_TYPE_16X16:
@@ -366,6 +391,7 @@ static void __inline encode_mb_inter_internal(BW *bw, M4V_MICROBLOCK *mb)
} }
break; break;
} }
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
{ {
encode_inter_block(bw, &mb->block[i]); encode_inter_block(bw, &mb->block[i]);
@@ -376,6 +402,7 @@ static void __inline encode_mb_intra_internal(BW *bw, M4V_MICROBLOCK *mb, int if
{ {
int cbp = 0, cbpc, cbpy; int cbp = 0, cbpc, cbpy;
int i; int i;
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
{ {
if (mb->block[i].last_index >= 1) if (mb->block[i].last_index >= 1)
@@ -383,6 +410,7 @@ static void __inline encode_mb_intra_internal(BW *bw, M4V_MICROBLOCK *mb, int if
cbp |= 1 << (5 - i); cbp |= 1 << (5 - i);
} }
} }
cbpc = cbp & 3; cbpc = cbp & 3;
if (iframe) if (iframe)
{ {
@@ -394,10 +422,15 @@ static void __inline encode_mb_intra_internal(BW *bw, M4V_MICROBLOCK *mb, int if
if (mb->dquant) cbpc += 8; if (mb->dquant) cbpc += 8;
encode_intra_P_MCBPC(bw, cbpc); encode_intra_P_MCBPC(bw, cbpc);
} }
put_bits(bw, 1, 0); // AC Prediction = no put_bits(bw, 1, 0); // AC Prediction = no
cbpy = cbp >> 2; cbpy = cbp >> 2;
encode_cbpy(bw, cbpy); encode_cbpy(bw, cbpy);
encode_dquant(bw, mb->dquant); encode_dquant(bw, mb->dquant);
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
{ {
encode_intra_block(bw, &mb->block[i], i); encode_intra_block(bw, &mb->block[i], i);
@@ -409,15 +442,20 @@ static int __inline encode_vo_header(BW *p)
{ {
put_bits(p, 16, 0); put_bits(p, 16, 0);
put_bits(p, 16, VOS_STARTCODE); put_bits(p, 16, VOS_STARTCODE);
put_bits(p, 8, 1); // *** profile_and_level_indidation put_bits(p, 8, 1); // *** profile_and_level_indidation
put_bits(p, 16, 0); put_bits(p, 16, 0);
put_bits(p, 16, VISUAL_OBJECT_STARTCODE); put_bits(p, 16, VISUAL_OBJECT_STARTCODE);
put_bits(p, 1, 1); put_bits(p, 1, 1);
put_bits(p, 4, 1); // vo_vel_id put_bits(p, 4, 1); // vo_vel_id
put_bits(p, 3, 1); // priority put_bits(p, 3, 1); // priority
put_bits(p, 4, 1); // visual_object_type = video object put_bits(p, 4, 1); // visual_object_type = video object
put_bits(p, 1, 0); // video signal type = no clue put_bits(p, 1, 0); // video signal type = no clue
m4v_stuffing(p); m4v_stuffing(p);
return 0; return 0;
} }
@@ -425,19 +463,28 @@ static int __inline encode_vol_header(BW *p, M4V_VOL *vol)
{ {
const int vo_number = 0; const int vo_number = 0;
const int vol_number = 0; const int vol_number = 0;
put_bits(p, 16, 0); put_bits(p, 16, 0);
put_bits(p, 16, 0x100 + vo_number); put_bits(p, 16, 0x100 + vo_number);
put_bits(p, 16, 0); put_bits(p, 16, 0);
put_bits(p, 16, 0x120 + vol_number); put_bits(p, 16, 0x120 + vol_number);
put_bits(p, 1, 0); // random_accessible_vol put_bits(p, 1, 0); // random_accessible_vol
put_bits(p, 8, 1); // video_object_type_indication = Simple Object Type put_bits(p, 8, 1); // video_object_type_indication = Simple Object Type
put_bits(p, 1, 0); //is_object_layer_identifier put_bits(p, 1, 0); //is_object_layer_identifier
put_bits(p, 4, 1); // *** aspect_ratio_info = 1(1:1) put_bits(p, 4, 1); // *** aspect_ratio_info = 1(1:1)
put_bits(p, 1, 0); //vol_control_parameters put_bits(p, 1, 0); //vol_control_parameters
put_bits(p, 2, 0); // shape_type put_bits(p, 2, 0); // shape_type
put_bits(p, 1, 1); // marker put_bits(p, 1, 1); // marker
if (vol->time_bits != 5) return -1; // for vop_time_increment_resolution = 30 if (vol->time_bits != 5) return -1; // for vop_time_increment_resolution = 30
put_bits(p, 16, 30); // *** vop_time_increment_resolution = 30 put_bits(p, 16, 30); // *** vop_time_increment_resolution = 30
put_bits(p, 1, 1); // marker put_bits(p, 1, 1); // marker
put_bits(p, 1, 0); // fixed vop rate = no put_bits(p, 1, 0); // fixed vop rate = no
put_bits(p, 1, 1); // marker put_bits(p, 1, 1); // marker
@@ -450,10 +497,12 @@ static int __inline encode_vol_header(BW *p, M4V_VOL *vol)
put_bits(p, 1, 0); // sprite = disable put_bits(p, 1, 0); // sprite = disable
put_bits(p, 1, 0); // not8bit = false put_bits(p, 1, 0); // not8bit = false
put_bits(p, 1, 0); // quant type = H.263 put_bits(p, 1, 0); // quant type = H.263
put_bits(p, 1, 1); // complexity estimaition disable = true put_bits(p, 1, 1); // complexity estimaition disable = true
put_bits(p, 1, 1); // resync marker disable = true put_bits(p, 1, 1); // resync marker disable = true
put_bits(p, 1, 0); // data pertitioning = false put_bits(p, 1, 0); // data pertitioning = false
put_bits(p, 1, 0); // scalability = false put_bits(p, 1, 0); // scalability = false
m4v_stuffing(p); m4v_stuffing(p);
return 0; return 0;
} }
@@ -461,14 +510,21 @@ static int __inline encode_vol_header(BW *p, M4V_VOL *vol)
static int __inline encode_vop_header(BW *p, M4V_VOP *vop, int time_bits, int vop_not_coded) static int __inline encode_vop_header(BW *p, M4V_VOP *vop, int time_bits, int vop_not_coded)
{ {
// static int time_old = 0; // static int time_old = 0;
int time_incr = vop->icount; int time_incr = vop->icount;
if (vop->time != 0) if (vop->time != 0)
time_incr = 0; time_incr = 0;
put_bits(p, 16, 0); put_bits(p, 16, 0);
put_bits(p, 16, VOP_STARTCODE); put_bits(p, 16, VOP_STARTCODE);
put_bits(p, 2, vop->picture_type); put_bits(p, 2, vop->picture_type);
// printf("not_code:%d vop_time: %d\n", vop_not_coded, vop->time); // printf("not_code:%d vop_time: %d\n", vop_not_coded, vop->time);
// printf("pic:%d icount:%d vop_time: %d\n", vop->picture_type, time_incr, vop->time); // printf("pic:%d icount:%d vop_time: %d\n", vop->picture_type, time_incr, vop->time);
/* if (time_old > vop->time) /* if (time_old > vop->time)
{ {
put_bits(p, 1, 1); put_bits(p, 1, 1);
@@ -476,54 +532,70 @@ static int __inline encode_vop_header(BW *p, M4V_VOP *vop, int time_bits, int vo
time_old = vop->time; time_old = vop->time;
*/ */
// !!!!! // !!!!!
while (time_incr--) while (time_incr--)
put_bits(p, 1, 1); put_bits(p, 1, 1);
put_bits(p, 1, 0); put_bits(p, 1, 0);
put_bits(p, 1, 1); // marker put_bits(p, 1, 1); // marker
put_bits(p, time_bits, vop->time); // time_increment put_bits(p, time_bits, vop->time); // time_increment
put_bits(p, 1, 1); // marker put_bits(p, 1, 1); // marker
if (vop_not_coded) if (vop_not_coded)
{ {
put_bits(p, 1, 0); // vop coded put_bits(p, 1, 0); // vop coded
return 0; return 0;
} }
put_bits(p, 1, 1); // vop coded put_bits(p, 1, 1); // vop coded
if (vop->picture_type == M4V_P_TYPE) if (vop->picture_type == M4V_P_TYPE)
{ {
put_bits(p, 1, vop->rounding_type); // rounding type put_bits(p, 1, vop->rounding_type); // rounding type
} }
put_bits(p, 3, 0); // intra dc VLC threashold put_bits(p, 3, 0); // intra dc VLC threashold
put_bits(p, 5, vop->qscale); // qscale put_bits(p, 5, vop->qscale); // qscale
if (vop->picture_type != M4V_I_TYPE) if (vop->picture_type != M4V_I_TYPE)
{ {
put_bits(p, 3, vop->f_code); put_bits(p, 3, vop->f_code);
} }
if (vop->picture_type == M4V_B_TYPE) if (vop->picture_type == M4V_B_TYPE)
{ {
put_bits(p, 3, vop->b_code); put_bits(p, 3, vop->b_code);
} }
return 0; return 0;
} }
static __inline int encode_gop_header(BW *bw, uint32 time_ms) static __inline int encode_gop_header(BW *bw, uint32 time_ms)
{ {
int sec, min, hour; int sec, min, hour;
sec = time_ms / 1000; sec = time_ms / 1000;
min = sec / 60; min = sec / 60;
sec %= 60; sec %= 60;
hour = min / 60; hour = min / 60;
min %= 60; min %= 60;
hour %= 24; hour %= 24;
put_bits(bw, 16, 0); put_bits(bw, 16, 0);
put_bits(bw, 16, GOP_STARTCODE); put_bits(bw, 16, GOP_STARTCODE);
put_bits(bw, 5, hour); put_bits(bw, 5, hour);
put_bits(bw, 6, min); put_bits(bw, 6, min);
put_bits(bw, 1, 1); put_bits(bw, 1, 1);
put_bits(bw, 6, sec); put_bits(bw, 6, sec);
put_bits(bw, 1, 0); // closed_gop == NO put_bits(bw, 1, 0); // closed_gop == NO
put_bits(bw, 1, 0); // broken link == NO put_bits(bw, 1, 0); // broken link == NO
printf("GOP %02d:%02d:%02d\n", hour, min, sec); printf("GOP %02d:%02d:%02d\n", hour, min, sec);
m4v_stuffing(bw); m4v_stuffing(bw);
return 0; return 0;
} }
@@ -532,6 +604,7 @@ static int __inline encode_user_header(BW *p)
{ {
put_bits(p, 16, 0); put_bits(p, 16, 0);
put_bits(p, 16, USERDATA_STARTCODE); put_bits(p, 16, USERDATA_STARTCODE);
put_bits(p, 8, 'v'); put_bits(p, 8, 'v');
put_bits(p, 8, 'i'); put_bits(p, 8, 'i');
put_bits(p, 8, 'x'); put_bits(p, 8, 'x');
@@ -540,6 +613,7 @@ static int __inline encode_user_header(BW *p)
put_bits(p, 8, 'n'); put_bits(p, 8, 'n');
put_bits(p, 8, 'e'); put_bits(p, 8, 'e');
put_bits(p, 8, 't'); put_bits(p, 8, 't');
m4v_stuffing(p); m4v_stuffing(p);
return 0; return 0;
} }
@@ -575,6 +649,7 @@ void m4v_encode_P_mb(BW *bw, M4V_MICROBLOCK *mb)
{ {
put_bits(bw, 1, 0); // coded put_bits(bw, 1, 0); // coded
} }
if (mb->intra) if (mb->intra)
{ {
encode_mb_intra_internal(bw, mb, 0); encode_mb_intra_internal(bw, mb, 0);
@@ -592,6 +667,7 @@ int m4v_encode_I_dcpred(M4V_MICROBLOCK *mb, M4V_DCPRED *dcpred, int mb_x, int mb
{ {
dcpred_set_qscale(dcpred, mb->qscale); dcpred_set_qscale(dcpred, mb->qscale);
dcpred_set_pos(dcpred, mb_x, mb_y); dcpred_set_pos(dcpred, mb_x, mb_y);
for (n = 0; n < 6; n ++) for (n = 0; n < 6; n ++)
{ {
int level = dcpred_for_enc(dcpred, n, mb->block[n].block[0]); int level = dcpred_for_enc(dcpred, n, mb->block[n].block[0]);

View File

@@ -29,6 +29,7 @@ static inline int HasADTSHeader(uint8_t *data, int size)
{ {
return 1; return 1;
} }
return 0; return 0;
} }

View File

@@ -35,6 +35,7 @@ typedef enum
CT_VP9 CT_VP9
} video_codec_type_t; } video_codec_type_t;
typedef enum typedef enum
{ {
STREAMTYPE_UNKNOWN = -1, STREAMTYPE_UNKNOWN = -1,
@@ -56,6 +57,8 @@ typedef enum
STREAMTYPE_SPARK = 21, STREAMTYPE_SPARK = 21,
} video_stream_type_t; } video_stream_type_t;
typedef enum typedef enum
{ {
AUDIOTYPE_UNKNOWN = -1, AUDIOTYPE_UNKNOWN = -1,
@@ -75,4 +78,8 @@ typedef enum
AUDIOTYPE_RAW = 0xf AUDIOTYPE_RAW = 0xf
} audio_stream_type_t; } audio_stream_type_t;
#endif /* H_DVB_BCM_H */ #endif /* H_DVB_BCM_H */

View File

@@ -6,6 +6,7 @@
static inline void Hexdump(unsigned char *Data, int length) 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++)
{ {
@@ -14,6 +15,7 @@ static inline void Hexdump(unsigned char *Data, int length)
printf("\n"); printf("\n");
} }
printf("\n"); printf("\n");
} }
#endif #endif

View File

@@ -94,6 +94,7 @@ typedef struct TrackDescription_s
int32_t aspect_ratio_num; int32_t aspect_ratio_num;
int32_t aspect_ratio_den; int32_t aspect_ratio_den;
int progressive; int progressive;
} TrackDescription_t; } TrackDescription_t;
struct Context_s; struct Context_s;
@@ -104,6 +105,7 @@ typedef struct Manager_s
char *Name; char *Name;
int (* Command)(Context_t *, ManagerCmd_t, void *); int (* Command)(Context_t *, ManagerCmd_t, void *);
char **Capabilities; char **Capabilities;
} Manager_t; } Manager_t;
typedef struct ManagerHandler_s typedef struct ManagerHandler_s

View File

@@ -56,14 +56,17 @@ 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;
} }
@@ -73,6 +76,7 @@ static inline char *dirname(char *name)
static char path[100]; static char path[100];
uint32_t i = 0; uint32_t i = 0;
int32_t pos = 0; int32_t pos = 0;
while ((name[i] != 0) && (i < sizeof(path))) while ((name[i] != 0) && (i < sizeof(path)))
{ {
if (name[i] == '/') if (name[i] == '/')
@@ -82,8 +86,10 @@ static inline char *dirname(char *name)
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;
} }

View File

@@ -74,6 +74,7 @@ typedef struct Output_s
int32_t (* Command)(Context_t *, OutputCmd_t, void *); int32_t (* Command)(Context_t *, OutputCmd_t, void *);
int32_t (* Write)(Context_t *, void *); int32_t (* Write)(Context_t *, void *);
char **Capabilities; char **Capabilities;
} Output_t; } Output_t;
extern Output_t LinuxDvbOutput; extern Output_t LinuxDvbOutput;

View File

@@ -12,8 +12,10 @@
#define PES_START_CODE_RESERVED_4 0xfd #define PES_START_CODE_RESERVED_4 0xfd
#define PES_VERSION_FAKE_START_CODE 0x31 #define PES_VERSION_FAKE_START_CODE 0x31
#define MAX_PES_PACKET_SIZE (65535) #define MAX_PES_PACKET_SIZE (65535)
/* start codes */ /* start codes */
#define PCM_PES_START_CODE 0xbd #define PCM_PES_START_CODE 0xbd
#define PRIVATE_STREAM_1_PES_START_CODE 0xbd #define PRIVATE_STREAM_1_PES_START_CODE 0xbd

View File

@@ -92,6 +92,7 @@ typedef enum
VIDEO_ENCODING_PRIVATE VIDEO_ENCODING_PRIVATE
} video_encoding_t; } video_encoding_t;
/* /*
* List of possible audio encodings - used to select frame parser and codec. * List of possible audio encodings - used to select frame parser and codec.
*/ */
@@ -198,6 +199,7 @@ typedef struct dvb_play_info_s
typedef dvb_play_info_t video_play_info_t; typedef dvb_play_info_t video_play_info_t;
typedef dvb_play_info_t audio_play_info_t; typedef dvb_play_info_t audio_play_info_t;
typedef enum typedef enum
{ {
#define DVB_OPTION_VALUE_DISABLE 0 #define DVB_OPTION_VALUE_DISABLE 0
@@ -283,6 +285,7 @@ typedef enum
// Legacy typo correction // Legacy typo correction
#define DVP_OPTION_H264_FORCE_PIC_ORDER_CNT_IGNORE_DPB_DISPLAY_FRAME_ORDERING DVB_OPTION_H264_FORCE_PIC_ORDER_CNT_IGNORE_DPB_DISPLAY_FRAME_ORDERING #define DVP_OPTION_H264_FORCE_PIC_ORDER_CNT_IGNORE_DPB_DISPLAY_FRAME_ORDERING DVB_OPTION_H264_FORCE_PIC_ORDER_CNT_IGNORE_DPB_DISPLAY_FRAME_ORDERING
typedef dvb_option_t video_option_t; typedef dvb_option_t video_option_t;
/* Decoder commands */ /* Decoder commands */
@@ -293,6 +296,7 @@ typedef dvb_option_t video_option_t;
#define VIDEO_CMD_SET_OPTION (4) #define VIDEO_CMD_SET_OPTION (4)
#define VIDEO_CMD_GET_OPTION (5) #define VIDEO_CMD_GET_OPTION (5)
/* Flags for VIDEO_CMD_FREEZE */ /* Flags for VIDEO_CMD_FREEZE */
#define VIDEO_CMD_FREEZE_TO_BLACK (1 << 0) #define VIDEO_CMD_FREEZE_TO_BLACK (1 << 0)

View File

@@ -26,6 +26,8 @@ typedef struct
ssize_t (* WriteV) (int, const struct iovec *, size_t); ssize_t (* WriteV) (int, const struct iovec *, size_t);
} WriterAVCallData_t; } WriterAVCallData_t;
typedef struct WriterCaps_s typedef struct WriterCaps_s
{ {
char *name; char *name;
@@ -88,6 +90,6 @@ Writer_t *getDefaultVideoWriter();
Writer_t *getDefaultAudioWriter(); Writer_t *getDefaultAudioWriter();
ssize_t write_with_retry(int fd, const void *buf, size_t size); ssize_t write_with_retry(int fd, const void *buf, size_t size);
ssize_t writev_with_retry(int fd, const struct iovec *iov, size_t ic); ssize_t writev_with_retry(int fd, const struct iovec *iov, size_t ic);
ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, size_t size);
ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, size_t size);
#endif #endif

View File

@@ -101,34 +101,42 @@ static void *TermThreadFun(void *arg __attribute__((unused)))
int cl = -1; int cl = -1;
int nfds = 1; int nfds = 1;
fd_set readfds; fd_set readfds;
unlink(socket_path); unlink(socket_path);
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
{ {
perror("TermThreadFun socket error"); perror("TermThreadFun socket error");
goto finish; goto finish;
} }
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX; addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1); strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
{ {
perror("TermThreadFun bind error"); perror("TermThreadFun bind error");
goto finish; goto finish;
} }
if (listen(fd, 1) == -1) if (listen(fd, 1) == -1)
{ {
perror("TermThreadFun listen error"); perror("TermThreadFun listen error");
goto finish; goto finish;
} }
FD_ZERO(&readfds); FD_ZERO(&readfds);
FD_SET(g_pfd[0], &readfds); FD_SET(g_pfd[0], &readfds);
FD_SET(fd, &readfds); FD_SET(fd, &readfds);
nfds = fd > g_pfd[0] ? fd + 1 : g_pfd[0] + 1; nfds = fd > g_pfd[0] ? fd + 1 : g_pfd[0] + 1;
while (select(nfds, &readfds, NULL, NULL, NULL) == -1 && errno == EINTR) while (select(nfds, &readfds, NULL, NULL, NULL) == -1 && errno == EINTR)
{ {
/* Restart if interrupted by signal */ /* Restart if interrupted by signal */
continue; continue;
} }
if (FD_ISSET(fd, &readfds)) if (FD_ISSET(fd, &readfds))
{ {
pthread_mutex_lock(&playbackStartMtx); pthread_mutex_lock(&playbackStartMtx);
@@ -139,10 +147,12 @@ static void *TermThreadFun(void *arg __attribute__((unused)))
kill(getpid(), SIGINT); kill(getpid(), SIGINT);
pthread_mutex_unlock(&playbackStartMtx); pthread_mutex_unlock(&playbackStartMtx);
} }
finish: finish:
close(cl); close(cl);
close(fd); close(fd);
pthread_exit(NULL); pthread_exit(NULL);
} }
static void map_inter_file_path(char *filename) static void map_inter_file_path(char *filename)
@@ -170,19 +180,24 @@ static int kbhit(void)
{ {
struct timeval tv; struct timeval tv;
fd_set readfds; fd_set readfds;
tv.tv_sec = 1; tv.tv_sec = 1;
tv.tv_usec = 0; tv.tv_usec = 0;
FD_ZERO(&readfds); FD_ZERO(&readfds);
FD_SET(0,&readfds); FD_SET(0, &readfds);
FD_SET(g_pfd[0], &readfds); FD_SET(g_pfd[0], &readfds);
if(-1 == select(g_pfd[0] + 1, &readfds, NULL, NULL, &tv))
if (-1 == select(g_pfd[0] + 1, &readfds, NULL, NULL, &tv))
{ {
return 0; return 0;
} }
if (FD_ISSET(0, &readfds)) if (FD_ISSET(0, &readfds))
{ {
return 1; return 1;
} }
return 0; return 0;
} }
@@ -194,6 +209,7 @@ static void SetBuffering()
{ {
printf("SetBuffering: failed to change the buffer of stderr\n"); printf("SetBuffering: failed to change the buffer of stderr\n");
} }
// make fgets not blocking // make fgets not blocking
int flags = fcntl(stdin->_fileno, F_GETFL, 0); int flags = fcntl(stdin->_fileno, F_GETFL, 0);
fcntl(stdin->_fileno, F_SETFL, flags | O_NONBLOCK); fcntl(stdin->_fileno, F_SETFL, flags | O_NONBLOCK);
@@ -203,6 +219,7 @@ static void SetNice(int prio)
{ {
#if 0 #if 0
setpriority(PRIO_PROCESS, 0, -8); setpriority(PRIO_PROCESS, 0, -8);
int prio = sched_get_priority_max(SCHED_RR) / 2; int prio = sched_get_priority_max(SCHED_RR) / 2;
struct sched_param param = struct sched_param param =
{ {
@@ -221,10 +238,12 @@ static void SetNice(int prio)
static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbackSwitchCmd, const char *argvBuff) static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbackSwitchCmd, const char *argvBuff)
{ {
int commandRetVal = 0; int commandRetVal = 0;
if (NULL == ptrManager || NULL == argvBuff || 2 != strnlen(argvBuff, 2)) if (NULL == ptrManager || NULL == argvBuff || 2 != strnlen(argvBuff, 2))
{ {
return -1; return -1;
} }
switch (argvBuff[1]) switch (argvBuff[1])
{ {
case 'l': case 'l':
@@ -340,6 +359,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac
{ {
ok = sscanf(argvBuff + 1, "%d", &id); ok = sscanf(argvBuff + 1, "%d", &id);
} }
if (id >= 0 || (1 == ok && id == -1)) if (id >= 0 || (1 == ok && id == -1))
{ {
commandRetVal = g_player->playback->Command(g_player, playbackSwitchCmd, (void *)&id); commandRetVal = g_player->playback->Command(g_player, playbackSwitchCmd, (void *)&id);
@@ -349,8 +369,10 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac
break; break;
} }
} }
return commandRetVal; return commandRetVal;
} }
#if 0 #if 0
static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbackSwitchCmd, const char *argvBuff) static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbackSwitchCmd, const char *argvBuff)
{ {
@@ -391,6 +413,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac
} }
case 'c': case 'c':
{ {
TrackDescription_t *track = NULL; TrackDescription_t *track = NULL;
ptrManager->Command(g_player, MANAGER_GET_TRACK_DESC, &track); ptrManager->Command(g_player, MANAGER_GET_TRACK_DESC, &track);
if (NULL != track) if (NULL != track)
@@ -461,6 +484,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac
{ {
ok = sscanf(argvBuff + 1, "%d", &id); ok = sscanf(argvBuff + 1, "%d", &id);
} }
if (id >= 0 || (1 == ok && id == -1)) if (id >= 0 || (1 == ok && id == -1))
{ {
commandRetVal = g_player->playback->Command(g_player, playbackSwitchCmd, (void *)&id); commandRetVal = g_player->playback->Command(g_player, playbackSwitchCmd, (void *)&id);
@@ -470,6 +494,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac
break; break;
} }
} }
return commandRetVal; return commandRetVal;
} }
#endif #endif
@@ -486,7 +511,7 @@ static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int
//int digit_optind = 0; //int digit_optind = 0;
//int aopt = 0, bopt = 0; //int aopt = 0, bopt = 0;
//char *copt = 0, *dopt = 0; //char *copt = 0, *dopt = 0;
while ((c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:P:t:9:0:1:4:f:b:")) != -1) while ((c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:P:t:9:0:1:4:f:b:")) != -1)
{ {
switch (c) switch (c)
{ {
@@ -604,9 +629,11 @@ static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int
ret = -1; ret = -1;
} }
} }
if (0 == ret && optind < argc) if (0 == ret && optind < argc)
{ {
ret = 0; ret = 0;
if (NULL == strstr(argv[optind], "://")) if (NULL == strstr(argv[optind], "://"))
{ {
strcpy(file, "file://"); strcpy(file, "file://");
@@ -629,16 +656,21 @@ int main(int argc, char *argv[])
int isTermThreadStarted = 0; int isTermThreadStarted = 0;
char file[IPTV_MAX_FILE_PATH]; char file[IPTV_MAX_FILE_PATH];
memset(file, '\0', sizeof(file)); memset(file, '\0', sizeof(file));
char audioFile[IPTV_MAX_FILE_PATH]; char audioFile[IPTV_MAX_FILE_PATH];
memset(audioFile, '\0', sizeof(audioFile)); memset(audioFile, '\0', sizeof(audioFile));
int audioTrackIdx = -1; int audioTrackIdx = -1;
int subtitleTrackIdx = -1; int subtitleTrackIdx = -1;
uint32_t linuxDvbBufferSizeMB = 0;
uint32_t linuxDvbBufferSizeMB = 0;
char argvBuff[256]; char argvBuff[256];
memset(argvBuff, '\0', sizeof(argvBuff)); memset(argvBuff, '\0', sizeof(argvBuff));
int commandRetVal = -1; int commandRetVal = -1;
/* inform client that we can handle additional commands */ /* inform client that we can handle additional commands */
fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 45); fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 45);
if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB)) if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB))
{ {
printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n"); printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n");
@@ -671,59 +703,76 @@ int main(int argc, char *argv[])
printf("[-f ffopt=ffval] any other ffmpeg option\n"); printf("[-f ffopt=ffval] any other ffmpeg option\n");
exit(1); exit(1);
} }
g_player = malloc(sizeof(Context_t)); g_player = malloc(sizeof(Context_t));
if (NULL == g_player) if (NULL == g_player)
{ {
printf("g_player allocate error\n"); printf("g_player allocate error\n");
exit(1); exit(1);
} }
pthread_mutex_init(&playbackStartMtx, NULL); pthread_mutex_init(&playbackStartMtx, NULL);
do do
{ {
int flags = 0; int flags = 0;
if (pipe(g_pfd) == -1) if (pipe(g_pfd) == -1)
break; break;
/* Make read and write ends of pipe nonblocking */ /* Make read and write ends of pipe nonblocking */
if ((flags = fcntl(g_pfd[0], F_GETFL)) == -1) if ((flags = fcntl(g_pfd[0], F_GETFL)) == -1)
break; break;
/* Make read end nonblocking */ /* Make read end nonblocking */
flags |= O_NONBLOCK; flags |= O_NONBLOCK;
if (fcntl(g_pfd[0], F_SETFL, flags) == -1) if (fcntl(g_pfd[0], F_SETFL, flags) == -1)
break; break;
if ((flags = fcntl(g_pfd[1], F_GETFL)) == -1) if ((flags = fcntl(g_pfd[1], F_GETFL)) == -1)
break; break;
/* Make write end nonblocking */ /* Make write end nonblocking */
flags |= O_NONBLOCK; flags |= O_NONBLOCK;
if (fcntl(g_pfd[1], F_SETFL, flags) == -1) if (fcntl(g_pfd[1], F_SETFL, flags) == -1)
break; break;
if (0 == pthread_create(&termThread, NULL, TermThreadFun, NULL)) if (0 == pthread_create(&termThread, NULL, TermThreadFun, NULL))
isTermThreadStarted = 1; isTermThreadStarted = 1;
} }
while (0); while (0);
g_player->playback = &PlaybackHandler; g_player->playback = &PlaybackHandler;
g_player->output = &OutputHandler; g_player->output = &OutputHandler;
g_player->container = &ContainerHandler; g_player->container = &ContainerHandler;
g_player->manager = &ManagerHandler; g_player->manager = &ManagerHandler;
// make sure to kill myself when parent dies // make sure to kill myself when parent dies
prctl(PR_SET_PDEATHSIG, SIGKILL); prctl(PR_SET_PDEATHSIG, SIGKILL);
SetBuffering(); SetBuffering();
//Registrating output devices //Registrating output devices
g_player->output->Command(g_player, OUTPUT_ADD, "audio"); g_player->output->Command(g_player, OUTPUT_ADD, "audio");
g_player->output->Command(g_player, OUTPUT_ADD, "video"); g_player->output->Command(g_player, OUTPUT_ADD, "video");
g_player->output->Command(g_player, OUTPUT_ADD, "subtitle"); g_player->output->Command(g_player, OUTPUT_ADD, "subtitle");
//Set LINUX DVB additional write buffer size
//Set LINUX DVB additional write buffer size
if (linuxDvbBufferSizeMB) if (linuxDvbBufferSizeMB)
g_player->output->Command(g_player, OUTPUT_SET_BUFFER_SIZE, &linuxDvbBufferSizeMB); g_player->output->Command(g_player, OUTPUT_SET_BUFFER_SIZE, &linuxDvbBufferSizeMB);
g_player->manager->video->Command(g_player, MANAGER_REGISTER_UPDATED_TRACK_INFO, UpdateVideoTrack); g_player->manager->video->Command(g_player, MANAGER_REGISTER_UPDATED_TRACK_INFO, UpdateVideoTrack);
if (strncmp(file, "rtmp", 4) && strncmp(file, "ffrtmp", 4)) if (strncmp(file, "rtmp", 4) && strncmp(file, "ffrtmp", 4))
{ {
g_player->playback->noprobe = 1; g_player->playback->noprobe = 1;
} }
PlayFiles_t playbackFiles = {file, NULL}; PlayFiles_t playbackFiles = {file, NULL};
if ('\0' != audioFile[0]) if ('\0' != audioFile[0])
{ {
playbackFiles.szSecondFile = audioFile; playbackFiles.szSecondFile = audioFile;
} }
commandRetVal = g_player->playback->Command(g_player, PLAYBACK_OPEN, &playbackFiles); commandRetVal = g_player->playback->Command(g_player, PLAYBACK_OPEN, &playbackFiles);
fprintf(stderr, "{\"PLAYBACK_OPEN\":{\"OutputName\":\"%s\", \"file\":\"%s\", \"sts\":%d}}\n", g_player->output->Name, file, commandRetVal); fprintf(stderr, "{\"PLAYBACK_OPEN\":{\"OutputName\":\"%s\", \"file\":\"%s\", \"sts\":%d}}\n", g_player->output->Name, file, commandRetVal);
if (commandRetVal < 0) if (commandRetVal < 0)
@@ -734,17 +783,21 @@ int main(int argc, char *argv[])
} }
return 10; return 10;
} }
{ {
pthread_mutex_lock(&playbackStartMtx); pthread_mutex_lock(&playbackStartMtx);
isPlaybackStarted = 1; isPlaybackStarted = 1;
pthread_mutex_unlock(&playbackStartMtx); pthread_mutex_unlock(&playbackStartMtx);
commandRetVal = g_player->output->Command(g_player, OUTPUT_OPEN, NULL); commandRetVal = g_player->output->Command(g_player, OUTPUT_OPEN, NULL);
fprintf(stderr, "{\"OUTPUT_OPEN\":{\"sts\":%d}}\n", commandRetVal); fprintf(stderr, "{\"OUTPUT_OPEN\":{\"sts\":%d}}\n", commandRetVal);
commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PLAY, NULL); commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PLAY, NULL);
fprintf(stderr, "{\"PLAYBACK_PLAY\":{\"sts\":%d}}\n", commandRetVal); fprintf(stderr, "{\"PLAYBACK_PLAY\":{\"sts\":%d}}\n", commandRetVal);
if (g_player->playback->isPlaying) if (g_player->playback->isPlaying)
{ {
PlaybackDieNowRegisterCallback(TerminateWakeUp); PlaybackDieNowRegisterCallback(TerminateWakeUp);
HandleTracks(g_player->manager->video, (PlaybackCmd_t) - 1, "vc"); HandleTracks(g_player->manager->video, (PlaybackCmd_t) - 1, "vc");
HandleTracks(g_player->manager->audio, (PlaybackCmd_t) - 1, "al"); HandleTracks(g_player->manager->audio, (PlaybackCmd_t) - 1, "al");
if (audioTrackIdx >= 0) if (audioTrackIdx >= 0)
@@ -754,6 +807,7 @@ int main(int argc, char *argv[])
commandRetVal = HandleTracks(g_player->manager->audio, PLAYBACK_SWITCH_AUDIO, cmd); commandRetVal = HandleTracks(g_player->manager->audio, PLAYBACK_SWITCH_AUDIO, cmd);
} }
HandleTracks(g_player->manager->audio, (PlaybackCmd_t) - 1, "ac"); HandleTracks(g_player->manager->audio, (PlaybackCmd_t) - 1, "ac");
HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t) - 1, "sl"); HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t) - 1, "sl");
if (subtitleTrackIdx >= 0) if (subtitleTrackIdx >= 0)
{ {
@@ -763,6 +817,7 @@ int main(int argc, char *argv[])
} }
HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t) - 1, "sc"); HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t) - 1, "sc");
} }
while (g_player->playback->isPlaying && 0 == PlaybackDieNow(0)) while (g_player->playback->isPlaying && 0 == PlaybackDieNow(0))
{ {
/* we made fgets non blocking */ /* we made fgets non blocking */
@@ -772,10 +827,12 @@ int main(int argc, char *argv[])
kbhit(); kbhit();
continue; continue;
} }
if (0 == argvBuff[0]) if (0 == argvBuff[0])
{ {
continue; continue;
} }
switch (argvBuff[0]) switch (argvBuff[0])
{ {
case 'v': case 'v':
@@ -815,6 +872,7 @@ int main(int argc, char *argv[])
{ {
int speed = 0; int speed = 0;
sscanf(argvBuff + 1, "%d", &speed); sscanf(argvBuff + 1, "%d", &speed);
commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SLOWMOTION, &speed); commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SLOWMOTION, &speed);
fprintf(stderr, "{\"PLAYBACK_SLOWMOTION\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal); fprintf(stderr, "{\"PLAYBACK_SLOWMOTION\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal);
break; break;
@@ -833,6 +891,7 @@ int main(int argc, char *argv[])
{ {
int speed = 0; int speed = 0;
sscanf(argvBuff + 1, "%d", &speed); sscanf(argvBuff + 1, "%d", &speed);
commandRetVal = g_player->playback->Command(g_player, PLAYBACK_FASTFORWARD, &speed); commandRetVal = g_player->playback->Command(g_player, PLAYBACK_FASTFORWARD, &speed);
fprintf(stderr, "{\"PLAYBACK_FASTFORWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal); fprintf(stderr, "{\"PLAYBACK_FASTFORWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal);
break; break;
@@ -841,6 +900,7 @@ int main(int argc, char *argv[])
{ {
int speed = 0; int speed = 0;
sscanf(argvBuff + 1, "%d", &speed); sscanf(argvBuff + 1, "%d", &speed);
commandRetVal = g_player->playback->Command(g_player, PLAYBACK_FASTBACKWARD, &speed); commandRetVal = g_player->playback->Command(g_player, PLAYBACK_FASTBACKWARD, &speed);
fprintf(stderr, "{\"PLAYBACK_FASTBACKWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal); fprintf(stderr, "{\"PLAYBACK_FASTBACKWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal);
break; break;
@@ -852,11 +912,13 @@ int main(int argc, char *argv[])
int32_t lengthInt = 0; int32_t lengthInt = 0;
int64_t sec = 0; int64_t sec = 0;
int8_t force = ('f' == argvBuff[1]) ? 1 : 0; // f - force, c - check int8_t force = ('f' == argvBuff[1]) ? 1 : 0; // f - force, c - check
sscanf(argvBuff + 2, "%d", &gotoPos); sscanf(argvBuff + 2, "%d", &gotoPos);
if (0 <= gotoPos || force) if (0 <= gotoPos || force)
{ {
commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void *)&length); commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void *)&length);
fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%lld, \"sts\":%d}}\n", length, commandRetVal); fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%lld, \"sts\":%d}}\n", length, commandRetVal);
lengthInt = (int32_t)length; lengthInt = (int32_t)length;
if (10 <= lengthInt || force) if (10 <= lengthInt || force)
{ {
@@ -865,6 +927,7 @@ int main(int argc, char *argv[])
{ {
sec = lengthInt - 10; sec = lengthInt - 10;
} }
commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SEEK_ABS, (void *)&sec); commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SEEK_ABS, (void *)&sec);
fprintf(stderr, "{\"PLAYBACK_SEEK_ABS\":{\"sec\":%lld, \"sts\":%d}}\n", sec, commandRetVal); fprintf(stderr, "{\"PLAYBACK_SEEK_ABS\":{\"sec\":%lld, \"sts\":%d}}\n", sec, commandRetVal);
} }
@@ -880,7 +943,9 @@ int main(int argc, char *argv[])
int64_t pts = 0; int64_t pts = 0;
int32_t CurrentSec = 0; int32_t CurrentSec = 0;
int8_t force = ('f' == argvBuff[1]) ? 1 : 0; // f - force, c - check int8_t force = ('f' == argvBuff[1]) ? 1 : 0; // f - force, c - check
sscanf(argvBuff + 2, "%d", &seek); sscanf(argvBuff + 2, "%d", &seek);
commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PTS, &pts); commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PTS, &pts);
CurrentSec = (int32_t)(pts / 90000); CurrentSec = (int32_t)(pts / 90000);
if (0 == commandRetVal) if (0 == commandRetVal)
@@ -891,6 +956,7 @@ int main(int argc, char *argv[])
{ {
commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void *)&length); commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void *)&length);
fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%lld, \"sts\":%d}}\n", length, commandRetVal); fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%lld, \"sts\":%d}}\n", length, commandRetVal);
lengthInt = (int32_t)length; lengthInt = (int32_t)length;
if (10 <= lengthInt || force) if (10 <= lengthInt || force)
{ {
@@ -959,6 +1025,7 @@ int main(int argc, char *argv[])
fprintf(stderr, " \"isVideo\":%s, \"isAudio\":%s, \"isSubtitle\":%s, \"isDvbSubtitle\":%s, \"isTeletext\":%s, \"mayWriteToFramebuffer\":%s, \"abortRequested\":%s }}\n", \ fprintf(stderr, " \"isVideo\":%s, \"isAudio\":%s, \"isSubtitle\":%s, \"isDvbSubtitle\":%s, \"isTeletext\":%s, \"mayWriteToFramebuffer\":%s, \"abortRequested\":%s }}\n", \
DUMP_BOOL(ptrP->isVideo), DUMP_BOOL(ptrP->isAudio), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(ptrP->abortRequested)); DUMP_BOOL(ptrP->isVideo), DUMP_BOOL(ptrP->isAudio), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(ptrP->abortRequested));
} }
break; break;
} }
case 'n': case 'n':
@@ -975,24 +1042,31 @@ int main(int argc, char *argv[])
} }
break; break;
} }
default: default:
{ {
break; break;
} }
} }
} }
g_player->output->Command(g_player, OUTPUT_CLOSE, NULL); g_player->output->Command(g_player, OUTPUT_CLOSE, NULL);
} }
if (NULL != g_player) if (NULL != g_player)
{ {
free(g_player); free(g_player);
} }
if (isTermThreadStarted && 1 == write(g_pfd[1], "x", 1)) if (isTermThreadStarted && 1 == write(g_pfd[1], "x", 1))
{ {
pthread_join(termThread, NULL); pthread_join(termThread, NULL);
} }
pthread_mutex_destroy(&playbackStartMtx); pthread_mutex_destroy(&playbackStartMtx);
close(g_pfd[0]); close(g_pfd[0]);
close(g_pfd[1]); close(g_pfd[1]);
exit(0); exit(0);
} }

View File

@@ -84,6 +84,7 @@ static int CurrentTrack = 0; //TRACK[0] as default.
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", __FILE__, __FUNCTION__, track.Name, track.Encoding, track.Id); audio_mgr_printf(10, "%s::%s name=\"%s\" encoding=\"%s\" id=%d\n", __FILE__, __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);
@@ -93,11 +94,13 @@ static int ManagerAdd(Context_t *context, Track_t track)
Tracks[i].Id = -1; Tracks[i].Id = -1;
} }
} }
if (Tracks == NULL) if (Tracks == NULL)
{ {
audio_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__); audio_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__);
return cERR_AUDIO_MGR_ERROR; return cERR_AUDIO_MGR_ERROR;
} }
int i = 0; int i = 0;
for (i = 0; i < TRACKWRAP; i++) for (i = 0; i < TRACKWRAP; i++)
{ {
@@ -107,6 +110,7 @@ static int ManagerAdd(Context_t *context, Track_t track)
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);
@@ -117,10 +121,12 @@ static int ManagerAdd(Context_t *context, Track_t track)
audio_mgr_err("%s:%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP); audio_mgr_err("%s:%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP);
return cERR_AUDIO_MGR_ERROR; 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", __FILE__, __FUNCTION__); audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
return cERR_AUDIO_MGR_NO_ERROR; return cERR_AUDIO_MGR_NO_ERROR;
} }
@@ -129,28 +135,36 @@ 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", __FILE__, __FUNCTION__); audio_mgr_printf(10, "%s::%s\n", __FILE__, __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", __FILE__, __FUNCTION__); audio_mgr_err("%s:%s malloc failed\n", __FILE__, __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", Tracks[i].Id, Tracks[i].Name); snprintf(tmp, len, "%d %s", 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", __FILE__, __FUNCTION__, tracklist, j, TrackCount); audio_mgr_printf(10, "%s::%s return %p (%d - %d)\n", __FILE__, __FUNCTION__, tracklist, j, TrackCount);
return tracklist; return tracklist;
} }
@@ -159,15 +173,18 @@ static TrackDescription_t *ManagerList(Context_t *context __attribute__((unused
{ {
int i = 0; int i = 0;
TrackDescription_t *tracklist = NULL; TrackDescription_t *tracklist = NULL;
audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
if (Tracks != NULL) if (Tracks != NULL)
{ {
tracklist = malloc(sizeof(TrackDescription_t) * ((TrackCount) + 1)); tracklist = malloc(sizeof(TrackDescription_t) * ((TrackCount) + 1));
if (tracklist == NULL) if (tracklist == NULL)
{ {
audio_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__); audio_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__);
return NULL; return NULL;
} }
int j = 0; int j = 0;
for (i = 0; i < TrackCount; ++i) for (i = 0; i < TrackCount; ++i)
{ {
@@ -175,14 +192,17 @@ static TrackDescription_t *ManagerList(Context_t *context __attribute__((unused
{ {
continue; continue;
} }
tracklist[j].Id = Tracks[i].Id; tracklist[j].Id = Tracks[i].Id;
tracklist[j].Name = strdup(Tracks[i].Name); tracklist[j].Name = strdup(Tracks[i].Name);
tracklist[j].Encoding = strdup(Tracks[i].Encoding); tracklist[j].Encoding = strdup(Tracks[i].Encoding);
++j; ++j;
} }
tracklist[j].Id = -1; tracklist[j].Id = -1;
} }
//audio_mgr_printf(10, "%s::%s return %p (%d - %d)\n", __FILE__, __FUNCTION__, tracklist, j, TrackCount); //audio_mgr_printf(10, "%s::%s return %p (%d - %d)\n", __FILE__, __FUNCTION__, tracklist, j, TrackCount);
return tracklist; return tracklist;
} }
#endif #endif
@@ -190,13 +210,16 @@ static TrackDescription_t *ManagerList(Context_t *context __attribute__((unused
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", __FILE__, __FUNCTION__); audio_mgr_printf(10, "%s::%s\n", __FILE__, __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;
} }
@@ -205,17 +228,22 @@ static int ManagerDel(Context_t *context)
audio_mgr_err("%s::%s nothing to delete!\n", __FILE__, __FUNCTION__); audio_mgr_err("%s::%s nothing to delete!\n", __FILE__, __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", __FILE__, __FUNCTION__); audio_mgr_printf(10, "%s::%s return no error\n", __FILE__, __FUNCTION__);
return cERR_AUDIO_MGR_NO_ERROR; return cERR_AUDIO_MGR_NO_ERROR;
} }
static int Command(Context_t *context, ManagerCmd_t command, void *argument) static int Command(Context_t *context, ManagerCmd_t command, void *argument)
{ {
int ret = cERR_AUDIO_MGR_NO_ERROR; int ret = cERR_AUDIO_MGR_NO_ERROR;
audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
switch (command) switch (command)
{ {
case MANAGER_ADD: case MANAGER_ADD:
@@ -244,6 +272,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
case MANAGER_GET: case MANAGER_GET:
{ {
audio_mgr_printf(20, "%s::%s MANAGER_GET\n", __FILE__, __FUNCTION__); audio_mgr_printf(20, "%s::%s MANAGER_GET\n", __FILE__, __FUNCTION__);
if ((TrackCount > 0) && (CurrentTrack >= 0)) if ((TrackCount > 0) && (CurrentTrack >= 0))
{ {
*((int *)argument) = (int)Tracks[CurrentTrack].Id; *((int *)argument) = (int)Tracks[CurrentTrack].Id;
@@ -277,9 +306,10 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
case MANAGER_GET_TRACK: case MANAGER_GET_TRACK:
{ {
audio_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", __FILE__, __FUNCTION__); audio_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", __FILE__, __FUNCTION__);
if ((TrackCount > 0) && (CurrentTrack >= 0)) if ((TrackCount > 0) && (CurrentTrack >= 0))
{ {
*((Track_t **)argument) = (Track_t *) & Tracks[CurrentTrack]; *((Track_t **)argument) = (Track_t *) &Tracks[CurrentTrack];
} }
else else
{ {
@@ -315,6 +345,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
{ {
int i; int i;
audio_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", __FILE__, __FUNCTION__, *((int *)argument)); audio_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", __FILE__, __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))
@@ -323,6 +354,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
break; break;
} }
} }
if (i == TrackCount) if (i == TrackCount)
{ {
audio_mgr_err("%s::%s track id %d unknown\n", __FILE__, __FUNCTION__, *((int *)argument)); audio_mgr_err("%s::%s track id %d unknown\n", __FILE__, __FUNCTION__, *((int *)argument));
@@ -349,10 +381,13 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
ret = cERR_AUDIO_MGR_ERROR; ret = cERR_AUDIO_MGR_ERROR;
break; break;
} }
audio_mgr_printf(10, "%s:%s: returning %d\n", __FILE__, __FUNCTION__, ret); audio_mgr_printf(10, "%s:%s: returning %d\n", __FILE__, __FUNCTION__, ret);
return ret; return ret;
} }
struct Manager_s AudioManager = struct Manager_s AudioManager =
{ {
"Audio", "Audio",

View File

@@ -181,8 +181,7 @@ static int ManagerDel(Context_t *context __attribute__((unused)))
TrackCount = 0; TrackCount = 0;
CurrentTrack = 0; CurrentTrack = 0;
chapter_mgr_printf(10, "%s::%s return no error\n", FILENAME, chapter_mgr_printf(10, "%s::%s return no error\n", FILENAME, __FUNCTION__);
__FUNCTION__);
return cERR_CHAPTER_MGR_NO_ERROR; return cERR_CHAPTER_MGR_NO_ERROR;
} }

View File

@@ -72,6 +72,7 @@ void copyTrack(Track_t *to, Track_t *from)
{ {
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);
@@ -80,6 +81,7 @@ void copyTrack(Track_t *to, Track_t *from)
{ {
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);
@@ -100,16 +102,19 @@ void freeTrack(Track_t *track)
free(track->Name); free(track->Name);
track->Name = NULL; track->Name = NULL;
} }
if (track->Encoding != NULL) if (track->Encoding != NULL)
{ {
free(track->Encoding); free(track->Encoding);
track->Encoding = NULL; track->Encoding = NULL;
} }
if (track->language != NULL) if (track->language != NULL)
{ {
free(track->language); free(track->language);
track->language = NULL; track->language = NULL;
} }
if (track->aacbuf != NULL) if (track->aacbuf != NULL)
{ {
free(track->aacbuf); free(track->aacbuf);

View File

@@ -33,12 +33,14 @@
#define TRACKWRAP 20 #define TRACKWRAP 20
//#define SAM_WITH_DEBUG
#ifdef SAM_WITH_DEBUG #ifdef SAM_WITH_DEBUG
#define SUBTITLE_MGR_DEBUG #define SUBTITLE_MGR_DEBUG
#else #else
#define SUBTITLE_MGR_SILENT #define SUBTITLE_MGR_SILENT
#endif #endif
#ifdef SUBTITLE_MGR_DEBUG #ifdef SUBTITLE_MGR_DEBUG
static short debug_level = 20; static short debug_level = 20;
@@ -256,7 +258,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
{ {
if ((TrackCount > 0) && (CurrentTrack >= 0)) if ((TrackCount > 0) && (CurrentTrack >= 0))
{ {
*((Track_t **)argument) = (Track_t *) & Tracks[CurrentTrack]; *((Track_t **)argument) = (Track_t *) &Tracks[CurrentTrack];
} }
else else
{ {

View File

@@ -84,6 +84,7 @@ static void (* updatedTrackInfoFnc)(void) = NULL;
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", __FILE__, __FUNCTION__); video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
if (Tracks == NULL) if (Tracks == NULL)
{ {
Tracks = malloc(sizeof(Track_t) * TRACKWRAP); Tracks = malloc(sizeof(Track_t) * TRACKWRAP);
@@ -93,11 +94,13 @@ static int ManagerAdd(Context_t *context, Track_t track)
Tracks[i].Id = -1; Tracks[i].Id = -1;
} }
} }
if (Tracks == NULL) if (Tracks == NULL)
{ {
video_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__); video_mgr_err("%s:%s malloc failed\n", __FILE__, __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++)
{ {
@@ -107,6 +110,7 @@ static int ManagerAdd(Context_t *context, Track_t track)
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);
@@ -117,10 +121,12 @@ static int ManagerAdd(Context_t *context, Track_t track)
video_mgr_err("%s:%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP); video_mgr_err("%s:%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP);
return cERR_VIDEO_MGR_ERROR; 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", __FILE__, __FUNCTION__); video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
return cERR_VIDEO_MGR_NO_ERROR; return cERR_VIDEO_MGR_NO_ERROR;
} }
@@ -129,15 +135,19 @@ 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", __FILE__, __FUNCTION__); video_mgr_printf(10, "%s::%s\n", __FILE__, __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", __FILE__, __FUNCTION__); video_mgr_err("%s:%s malloc failed\n", __FILE__, __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)
@@ -152,6 +162,7 @@ static char **ManagerList(Context_t *context __attribute__((unused)))
} }
tracklist[j] = NULL; tracklist[j] = NULL;
} }
video_mgr_printf(10, "%s::%s return %p (%d - %d)\n", __FILE__, __FUNCTION__, tracklist, j, TrackCount); video_mgr_printf(10, "%s::%s return %p (%d - %d)\n", __FILE__, __FUNCTION__, tracklist, j, TrackCount);
return tracklist; return tracklist;
} }
@@ -159,7 +170,9 @@ static char **ManagerList(Context_t *context __attribute__((unused)))
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", __FILE__, __FUNCTION__); video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
if (Tracks != NULL) if (Tracks != NULL)
{ {
for (i = 0; i < TrackCount; i++) for (i = 0; i < TrackCount; i++)
@@ -174,9 +187,11 @@ static int ManagerDel(Context_t *context)
video_mgr_err("%s::%s nothing to delete!\n", __FILE__, __FUNCTION__); video_mgr_err("%s::%s nothing to delete!\n", __FILE__, __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", __FILE__, __FUNCTION__); video_mgr_printf(10, "%s::%s return no error\n", __FILE__, __FUNCTION__);
return cERR_VIDEO_MGR_NO_ERROR; return cERR_VIDEO_MGR_NO_ERROR;
} }
@@ -184,7 +199,9 @@ static int ManagerDel(Context_t *context)
static int Command(Context_t *context, ManagerCmd_t command, void *argument) static int Command(Context_t *context, ManagerCmd_t command, void *argument)
{ {
int ret = cERR_VIDEO_MGR_NO_ERROR; int ret = cERR_VIDEO_MGR_NO_ERROR;
video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
switch (command) switch (command)
{ {
case MANAGER_ADD: case MANAGER_ADD:
@@ -240,9 +257,10 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
case MANAGER_GET_TRACK: case MANAGER_GET_TRACK:
{ {
video_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", __FILE__, __FUNCTION__); video_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", __FILE__, __FUNCTION__);
if ((TrackCount > 0) && (CurrentTrack >= 0)) if ((TrackCount > 0) && (CurrentTrack >= 0))
{ {
*((Track_t **)argument) = (Track_t *) & Tracks[CurrentTrack]; *((Track_t **)argument) = (Track_t *) &Tracks[CurrentTrack];
} }
else else
{ {
@@ -285,6 +303,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
break; break;
} }
} }
if (i == TrackCount) if (i == TrackCount)
{ {
video_mgr_err("%s::%s track id %d unknown\n", __FILE__, __FUNCTION__, *((int *)argument)); video_mgr_err("%s::%s track id %d unknown\n", __FILE__, __FUNCTION__, *((int *)argument));
@@ -322,10 +341,12 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
ret = cERR_VIDEO_MGR_ERROR; ret = cERR_VIDEO_MGR_ERROR;
break; break;
} }
video_mgr_printf(10, "%s:%s: returning %d\n", __FILE__, __FUNCTION__, ret); video_mgr_printf(10, "%s:%s: returning %d\n", __FILE__, __FUNCTION__, ret);
return ret; return ret;
} }
struct Manager_s VideoManager = struct Manager_s VideoManager =
{ {
"Video", "Video",

View File

@@ -41,13 +41,15 @@
/* ***************************** */ /* ***************************** */
/* Types */ /* Types */
/* ***************************** */ /* ***************************** */
typedef enum OutputType_e{ typedef enum OutputType_e
{
OUTPUT_UNK, OUTPUT_UNK,
OUTPUT_AUDIO, OUTPUT_AUDIO,
OUTPUT_VIDEO, OUTPUT_VIDEO,
} OutputType_t; } OutputType_t;
typedef struct BufferingNode_s { typedef struct BufferingNode_s
{
uint32_t dataSize; uint32_t dataSize;
OutputType_t dataType; OutputType_t dataType;
struct BufferingNode_s *next; struct BufferingNode_s *next;
@@ -56,8 +58,8 @@ typedef struct BufferingNode_s {
/* ***************************** */ /* ***************************** */
/* Makros/Constants */ /* Makros/Constants */
/* ***************************** */ /* ***************************** */
#define cERR_LINUX_DVB_BUFFERING_NO_ERROR 0 #define cERR_LINUX_DVB_BUFFERING_NO_ERROR 0
#define cERR_LINUX_DVB_BUFFERING_ERROR -1 #define cERR_LINUX_DVB_BUFFERING_ERROR -1
//#define SAM_WITH_DEBUG //#define SAM_WITH_DEBUG
#ifdef SAM_WITH_DEBUG #ifdef SAM_WITH_DEBUG
@@ -83,8 +85,9 @@ if (debug_level >= level) printf("[%s:%d:%s] " fmt, __FILE__, __LINE__, __FUNCTI
#endif #endif
/* ***************************** */ /* ***************************** */
/* Varaibles */ /* Variables */
/* ***************************** */ /* ***************************** */
static pthread_t bufferingThread; static pthread_t bufferingThread;
static pthread_mutex_t bufferingMtx; static pthread_mutex_t bufferingMtx;
static pthread_cond_t bufferingExitCond; static pthread_cond_t bufferingExitCond;
@@ -108,46 +111,54 @@ static int g_pfd[2] = {-1, -1};
/* ***************************** */ /* ***************************** */
/* MISC Functions */ /* MISC Functions */
/* ***************************** */ /* ***************************** */
static void WriteWakeUp() static void WriteWakeUp()
{ {
write(g_pfd[1], "x", 1); write(g_pfd[1], "x", 1);
} }
/* **************************** */ /* ***************************** */
/* Worker Thread */ /* Worker Thread */
/* **************************** */ /* ***************************** */
static void LinuxDvbBuffThread(Context_t *context)
static void LinuxDvbBuffThread(Context_t *context)
{ {
int flags = 0; int flags = 0;
static BufferingNode_t *nodePtr = NULL; static BufferingNode_t *nodePtr = NULL;
buff_printf(20, "ENTER\n"); buff_printf(20, "ENTER\n");
if (pipe(g_pfd) == -1) if (pipe(g_pfd) == -1)
{ {
buff_err("critical error\n"); buff_err("critical error\n");
} }
/* Make read and write ends of pipe nonblocking */ /* Make read and write ends of pipe nonblocking */
if ((flags = fcntl(g_pfd[0], F_GETFL)) == -1) if ((flags = fcntl(g_pfd[0], F_GETFL)) == -1)
{ {
buff_err("critical error\n"); buff_err("critical error\n");
} }
/* Make read end nonblocking */ /* Make read end nonblocking */
flags |= O_NONBLOCK; flags |= O_NONBLOCK;
if (fcntl(g_pfd[0], F_SETFL, flags) == -1) if (fcntl(g_pfd[0], F_SETFL, flags) == -1)
{ {
buff_err("critical error\n"); buff_err("critical error\n");
} }
if ((flags = fcntl(g_pfd[1], F_GETFL)) == -1) if ((flags = fcntl(g_pfd[1], F_GETFL)) == -1)
{ {
buff_err("critical error\n"); buff_err("critical error\n");
} }
/* Make write end nonblocking */ /* Make write end nonblocking */
flags |= O_NONBLOCK; flags |= O_NONBLOCK;
if (fcntl(g_pfd[1], F_SETFL, flags) == -1) if (fcntl(g_pfd[1], F_SETFL, flags) == -1)
{ {
buff_err("critical error\n"); buff_err("critical error\n");
} }
PlaybackDieNowRegisterCallback(WriteWakeUp); PlaybackDieNowRegisterCallback(WriteWakeUp);
while (0 == PlaybackDieNow(0)) while (0 == PlaybackDieNow(0))
{ {
pthread_mutex_lock(&bufferingMtx); pthread_mutex_lock(&bufferingMtx);
@@ -158,11 +169,11 @@ static void LinuxDvbBuffThread(Context_t *context)
/* signal that we free some space in queue */ /* signal that we free some space in queue */
pthread_cond_signal(&bufferingDataConsumedCond); pthread_cond_signal(&bufferingDataConsumedCond);
} }
if (!bufferingQueueHead) if (!bufferingQueueHead)
{ {
assert(bufferingQueueTail == NULL); assert(bufferingQueueTail == NULL);
/* Queue is empty we need to wait for data to be added */ /* Queue is empty we need to wait for data to be added */
pthread_cond_wait(&bufferingdDataAddedCond, &bufferingMtx); pthread_cond_wait(&bufferingdDataAddedCond, &bufferingMtx);
pthread_mutex_unlock(&bufferingMtx); pthread_mutex_unlock(&bufferingMtx);
@@ -176,7 +187,7 @@ static void LinuxDvbBuffThread(Context_t *context)
{ {
bufferingQueueTail = NULL; bufferingQueueTail = NULL;
} }
if (bufferingDataSize >= (nodePtr->dataSize + sizeof(BufferingNode_t))) if (bufferingDataSize >= (nodePtr->dataSize + sizeof(BufferingNode_t)))
{ {
bufferingDataSize -= (nodePtr->dataSize + sizeof(BufferingNode_t)); bufferingDataSize -= (nodePtr->dataSize + sizeof(BufferingNode_t));
@@ -188,12 +199,12 @@ static void LinuxDvbBuffThread(Context_t *context)
} }
} }
pthread_mutex_unlock(&bufferingMtx); pthread_mutex_unlock(&bufferingMtx);
/* We will write data without mutex /* We will write data without mutex
* this have some disadvantage because we can * this have some disadvantage because we can
* write some portion of data after LinuxDvbBuffFlush, * write some portion of data after LinuxDvbBuffFlush,
* for example after seek, this will be fixed later * for example after seek, this will be fixed later
*/ */
if (nodePtr && !context->playback->isSeeking) if (nodePtr && !context->playback->isSeeking)
{ {
/* Write data to valid output */ /* Write data to valid output */
@@ -205,11 +216,11 @@ static void LinuxDvbBuffThread(Context_t *context)
} }
} }
} }
pthread_mutex_lock(&bufferingMtx); pthread_mutex_lock(&bufferingMtx);
pthread_cond_signal(&bufferingExitCond); pthread_cond_signal(&bufferingExitCond);
pthread_mutex_unlock(&bufferingMtx); pthread_mutex_unlock(&bufferingMtx);
buff_printf(20, "EXIT\n"); buff_printf(20, "EXIT\n");
hasBufferingThreadStarted = false; hasBufferingThreadStarted = false;
close(g_pfd[0]); close(g_pfd[0]);
@@ -228,36 +239,36 @@ int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd)
{ {
int32_t error = 0; int32_t error = 0;
int32_t ret = cERR_LINUX_DVB_BUFFERING_NO_ERROR; int32_t ret = cERR_LINUX_DVB_BUFFERING_NO_ERROR;
buff_printf(10, "\n"); buff_printf(10, "\n");
if (!hasBufferingThreadStarted) if (!hasBufferingThreadStarted)
{ {
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((error = pthread_create(&bufferingThread, &attr, (void *)&LinuxDvbBuffThread, context)) != 0) if ((error = pthread_create(&bufferingThread, &attr, (void *)&LinuxDvbBuffThread, context)) != 0)
{ {
buff_printf(10, "Creating thread, error:%d:%s\n", error, strerror(error)); buff_printf(10, "Creating thread, error:%d:%s\n", error, strerror(error));
hasBufferingThreadStarted = false; hasBufferingThreadStarted = false;
ret = cERR_LINUX_DVB_BUFFERING_ERROR; ret = cERR_LINUX_DVB_BUFFERING_ERROR;
} }
else else
{ {
buff_printf(10, "Created thread\n"); buff_printf(10, "Created thread\n");
hasBufferingThreadStarted = true; hasBufferingThreadStarted = true;
/* init synchronization prymitives */ /* init synchronization prymitives */
pthread_mutex_init(&bufferingMtx, NULL); pthread_mutex_init(&bufferingMtx, NULL);
pthread_cond_init(&bufferingExitCond, NULL); pthread_cond_init(&bufferingExitCond, NULL);
pthread_cond_init(&bufferingDataConsumedCond, NULL); pthread_cond_init(&bufferingDataConsumedCond, NULL);
pthread_cond_init(&bufferingdDataAddedCond, NULL); pthread_cond_init(&bufferingdDataAddedCond, NULL);
} }
} }
if (!ret) if (!ret)
{ {
if (!strcmp("video", type) && -1 == videofd) if (!strcmp("video", type) && -1 == videofd)
@@ -281,21 +292,22 @@ int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd)
int32_t LinuxDvbBuffClose(Context_t *context __attribute__((unused))) int32_t LinuxDvbBuffClose(Context_t *context __attribute__((unused)))
{ {
int32_t ret = 0; int32_t ret = 0;
buff_printf(10, "\n"); buff_printf(10, "\n");
videofd = -1; videofd = -1;
audiofd = -1; audiofd = -1;
if (hasBufferingThreadStarted) if (hasBufferingThreadStarted)
{ {
struct timespec max_wait = {0, 0}; struct timespec max_wait = {0, 0};
/* WakeUp if we are waiting in the write */ /* WakeUp if we are waiting in the write */
WriteWakeUp(); WriteWakeUp();
pthread_mutex_lock(&bufferingMtx); pthread_mutex_lock(&bufferingMtx);
/* wake up if thread is waiting for data */ /* wake up if thread is waiting for data */
pthread_cond_signal(&bufferingdDataAddedCond); pthread_cond_signal(&bufferingdDataAddedCond);
/* wait for thread end */ /* wait for thread end */
clock_gettime(CLOCK_REALTIME, &max_wait); clock_gettime(CLOCK_REALTIME, &max_wait);
max_wait.tv_sec += 1; max_wait.tv_sec += 1;
@@ -305,9 +317,9 @@ int32_t LinuxDvbBuffClose(Context_t *context __attribute__((unused)))
if (!hasBufferingThreadStarted) if (!hasBufferingThreadStarted)
{ {
/* destroy synchronization prymitives? /* destroy synchronization prymitives?
* for a moment, we'll exit linux process, * for a moment, we'll exit linux process,
* so the system will do this for us * so the system will do this for us
*/ */
/* /*
pthread_mutex_destroy(&bufferingMtx); pthread_mutex_destroy(&bufferingMtx);
pthread_cond_destroy(&bufferingDataConsumedCond); pthread_cond_destroy(&bufferingDataConsumedCond);
@@ -315,7 +327,7 @@ int32_t LinuxDvbBuffClose(Context_t *context __attribute__((unused)))
*/ */
} }
} }
ret = hasBufferingThreadStarted ? cERR_LINUX_DVB_BUFFERING_ERROR : cERR_LINUX_DVB_BUFFERING_NO_ERROR; ret = hasBufferingThreadStarted ? cERR_LINUX_DVB_BUFFERING_ERROR : cERR_LINUX_DVB_BUFFERING_NO_ERROR;
buff_printf(10, "exiting with value %d\n", ret); buff_printf(10, "exiting with value %d\n", ret);
@@ -326,46 +338,50 @@ int32_t LinuxDvbBuffFlush(Context_t *context __attribute__((unused)))
{ {
static BufferingNode_t *nodePtr = NULL; static BufferingNode_t *nodePtr = NULL;
buff_printf(40, "ENTER bufferingQueueHead[%p]\n", bufferingQueueHead); buff_printf(40, "ENTER bufferingQueueHead[%p]\n", bufferingQueueHead);
/* signal if we are waiting for write to DVB decoders */ /* signal if we are waiting for write to DVB decoders */
WriteWakeUp(); WriteWakeUp();
pthread_mutex_lock(&bufferingMtx); pthread_mutex_lock(&bufferingMtx);
while (bufferingQueueHead) while (bufferingQueueHead)
{ {
nodePtr = bufferingQueueHead; nodePtr = bufferingQueueHead;
bufferingQueueHead = nodePtr->next; bufferingQueueHead = nodePtr->next;
bufferingDataSize -= (nodePtr->dataSize + sizeof(BufferingNode_t)); bufferingDataSize -= (nodePtr->dataSize + sizeof(BufferingNode_t));
free(nodePtr); free(nodePtr);
} }
bufferingQueueHead = NULL; bufferingQueueHead = NULL;
bufferingQueueTail = NULL; bufferingQueueTail = NULL;
buff_printf(40, "bufferingDataSize [%u]\n", bufferingDataSize); buff_printf(40, "bufferingDataSize [%u]\n", bufferingDataSize);
assert(bufferingDataSize == 0); assert(bufferingDataSize == 0);
bufferingDataSize = 0; bufferingDataSize = 0;
/* signal that queue is empty */ /* signal that queue is empty */
pthread_cond_signal(&bufferingDataConsumedCond); pthread_cond_signal(&bufferingDataConsumedCond);
pthread_mutex_unlock(&bufferingMtx); pthread_mutex_unlock(&bufferingMtx);
buff_printf(40, "EXIT\n"); buff_printf(40, "EXIT\n");
return 0; return 0;
} }
int32_t LinuxDvbBuffResume(Context_t *context __attribute__((unused))) int32_t LinuxDvbBuffResume(Context_t *context __attribute__((unused)))
{ {
/* signal if we are waiting for write to DVB decoders */ /* signal if we are waiting for write to DVB decoders
*
*/
WriteWakeUp(); WriteWakeUp();
return 0; return 0;
} }
ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic) ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic)
{ {
OutputType_t dataType = OUTPUT_UNK; OutputType_t dataType = OUTPUT_UNK;
BufferingNode_t *nodePtr = NULL; BufferingNode_t *nodePtr = NULL;
uint8_t *dataPtr = NULL; uint8_t *dataPtr = NULL;
uint32_t chunkSize = 0; uint32_t chunkSize = 0;
uint32_t i = 0; uint32_t i = 0;
buff_printf(60, "ENTER\n"); buff_printf(60, "ENTER\n");
if (fd == videofd) if (fd == videofd)
{ {
@@ -382,13 +398,13 @@ ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic)
buff_err("Unknown output type\n"); buff_err("Unknown output type\n");
return cERR_LINUX_DVB_BUFFERING_ERROR; return cERR_LINUX_DVB_BUFFERING_ERROR;
} }
for (i=0; i<ic; ++i) for (i = 0; i < ic; ++i)
{ {
chunkSize += iov[i].iov_len; chunkSize += iov[i].iov_len;
} }
chunkSize += sizeof(BufferingNode_t); chunkSize += sizeof(BufferingNode_t);
/* Allocate memory for queue node + data */ /* Allocate memory for queue node + data */
nodePtr = malloc(chunkSize); nodePtr = malloc(chunkSize);
if (!nodePtr) if (!nodePtr)
@@ -396,10 +412,10 @@ ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic)
buff_err("OUT OF MEM\n"); buff_err("OUT OF MEM\n");
return cERR_LINUX_DVB_BUFFERING_ERROR; return cERR_LINUX_DVB_BUFFERING_ERROR;
} }
/* Copy data to new buffer */ /* Copy data to new buffer */
dataPtr = (uint8_t *)nodePtr + sizeof(BufferingNode_t); dataPtr = (uint8_t *)nodePtr + sizeof(BufferingNode_t);
for (i=0; i<ic; ++i) for (i = 0; i < ic; ++i)
{ {
memcpy(dataPtr, iov[i].iov_base, iov[i].iov_len); memcpy(dataPtr, iov[i].iov_base, iov[i].iov_len);
dataPtr += iov[i].iov_len; dataPtr += iov[i].iov_len;
@@ -426,13 +442,13 @@ ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic)
bufferingQueueTail->next = nodePtr; bufferingQueueTail->next = nodePtr;
bufferingQueueTail = nodePtr; bufferingQueueTail = nodePtr;
} }
bufferingDataSize += chunkSize; bufferingDataSize += chunkSize;
chunkSize -= sizeof(BufferingNode_t); chunkSize -= sizeof(BufferingNode_t);
nodePtr->dataSize = chunkSize; nodePtr->dataSize = chunkSize;
nodePtr->dataType = dataType; nodePtr->dataType = dataType;
nodePtr->next = NULL; nodePtr->next = NULL;
/* signal that we added some data to queue */ /* signal that we added some data to queue */
pthread_cond_signal(&bufferingdDataAddedCond); pthread_cond_signal(&bufferingdDataAddedCond);
break; break;

View File

@@ -50,9 +50,7 @@
/* Makros/Constants */ /* Makros/Constants */
/* ***************************** */ /* ***************************** */
// SULGE DEBUG
//#define SAM_WITH_DEBUG //#define SAM_WITH_DEBUG
#ifdef SAM_WITH_DEBUG #ifdef SAM_WITH_DEBUG
#define LINUXDVB_DEBUG #define LINUXDVB_DEBUG
static unsigned short debug_level = 20; static unsigned short debug_level = 20;
@@ -64,15 +62,15 @@ static const char FILENAME[] = __FILE__;
#ifdef LINUXDVB_DEBUG #ifdef LINUXDVB_DEBUG
#define linuxdvb_printf(level, fmt, x...) do { \ #define linuxdvb_printf(level, fmt, x...) do { \
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x ); } while (0) if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
#else #else
#define linuxdvb_printf(level, fmt, x...) #define linuxdvb_printf(x...)
#endif #endif
#ifndef LINUXDVB_SILENT #ifndef LINUXDVB_SILENT
#define linuxdvb_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) #define linuxdvb_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
#else #else
#define linuxdvb_err(fmt, x...) #define linuxdvb_err(x...)
#endif #endif
#define cERR_LINUXDVB_NO_ERROR 0 #define cERR_LINUXDVB_NO_ERROR 0
@@ -108,10 +106,11 @@ int32_t LinuxDvbBuffResume(Context_t *context);
ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic); ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic);
int32_t WriteSetBufferingSize(const uint32_t bufferSize); int32_t WriteSetBufferingSize(const uint32_t bufferSize);
int LinuxDvbStop(Context_t *context, char *type); int LinuxDvbStop(Context_t *context, char *type);
/* ***************************** */ /* ***************************** */
/* Functions */ /* MISC Functions */
/* ***************************** */ /* ***************************** */
void getLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) void getLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused)))
@@ -137,53 +136,67 @@ int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type)
{ {
uint8_t video = !strcmp("video", type); uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type); uint8_t audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
if (video && videofd < 0) if (video && videofd < 0)
{ {
videofd = open(VIDEODEV, O_RDWR | O_CLOEXEC); videofd = open(VIDEODEV, O_RDWR | O_CLOEXEC);
if (videofd < 0) if (videofd < 0)
{ {
linuxdvb_err("failed to open %s - errno %d, %s\n", VIDEODEV, errno, strerror(errno)); linuxdvb_err("failed to open %s - errno %d, %s\n", VIDEODEV, errno, strerror(errno));
linuxdvb_err("%s\n",);
return cERR_LINUXDVB_ERROR; return cERR_LINUXDVB_ERROR;
} }
if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
{ {
linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
} }
if (ioctl(videofd, VIDEO_SELECT_SOURCE, (void *)VIDEO_SOURCE_MEMORY) == -1) if (ioctl(videofd, VIDEO_SELECT_SOURCE, (void *)VIDEO_SOURCE_MEMORY) == -1)
{ {
linuxdvb_err("VIDEO_SELECT_SOURCE: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("VIDEO_SELECT_SOURCE: ERROR %d, %s\n", errno, strerror(errno));
} }
if (ioctl(videofd, VIDEO_FREEZE) == -1) if (ioctl(videofd, VIDEO_FREEZE) == -1)
{ {
linuxdvb_err("VIDEO_FREEZE: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("VIDEO_FREEZE: ERROR %d, %s\n", errno, strerror(errno));
} }
if (isBufferedOutput) if (isBufferedOutput)
LinuxDvbBuffOpen(context, type, videofd); LinuxDvbBuffOpen(context, type, videofd);
} }
if (audio && audiofd < 0) if (audio && audiofd < 0)
{ {
audiofd = open(AUDIODEV, O_RDWR | O_CLOEXEC); audiofd = open(AUDIODEV, O_RDWR | O_CLOEXEC);
if (audiofd < 0) if (audiofd < 0)
{ {
linuxdvb_err("failed to open %s - errno %d, %s\n", AUDIODEV, errno, strerror(errno)); linuxdvb_err("failed to open %s - errno %d, %s\n", AUDIODEV, errno, strerror(errno));
return cERR_LINUXDVB_ERROR; return cERR_LINUXDVB_ERROR;
} }
if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1)
{ {
linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
} }
if (ioctl(audiofd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY) == -1) if (ioctl(audiofd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY) == -1)
{ {
linuxdvb_err("AUDIO_SELECT_SOURCE: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("AUDIO_SELECT_SOURCE: ERROR %d, %s\n", errno, strerror(errno));
} }
if (ioctl(audiofd, AUDIO_PAUSE) == -1) if (ioctl(audiofd, AUDIO_PAUSE) == -1)
{ {
linuxdvb_err("AUDIO_PAUSE: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("AUDIO_PAUSE: ERROR %d, %s\n", errno, strerror(errno));
} }
if (isBufferedOutput) if (isBufferedOutput)
LinuxDvbBuffOpen(context, type, audiofd); LinuxDvbBuffOpen(context, type, audiofd);
} }
return cERR_LINUXDVB_NO_ERROR; return cERR_LINUXDVB_NO_ERROR;
} }
@@ -191,15 +204,20 @@ int LinuxDvbClose(Context_t *context, char *type)
{ {
uint8_t video = !strcmp("video", type); uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type); uint8_t audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
/* closing stand alone is not allowed, so prevent /* closing stand alone is not allowed, so prevent
* user from closing and don't call stop. stop will * user from closing and don't call stop. stop will
* set default values for us (speed and so on). * set default values for us (speed and so on).
*/ */
LinuxDvbStop(context, type); LinuxDvbStop(context, type);
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (isBufferedOutput) if (isBufferedOutput)
LinuxDvbBuffClose(context); LinuxDvbBuffClose(context);
if (video && videofd != -1) if (video && videofd != -1)
{ {
close(videofd); close(videofd);
@@ -210,6 +228,7 @@ int LinuxDvbClose(Context_t *context, char *type)
close(audiofd); close(audiofd);
audiofd = -1; audiofd = -1;
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
return cERR_LINUXDVB_NO_ERROR; return cERR_LINUXDVB_NO_ERROR;
} }
@@ -218,14 +237,19 @@ int LinuxDvbPlay(Context_t *context, char *type)
{ {
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
Writer_t *writer; Writer_t *writer;
uint8_t video = !strcmp("video", type); uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type); uint8_t audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
if (video && videofd != -1) if (video && videofd != -1)
{ {
char *Encoding = NULL; char *Encoding = NULL;
context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
linuxdvb_printf(10, "V %s\n", Encoding); linuxdvb_printf(10, "V %s\n", Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (writer == NULL) if (writer == NULL)
{ {
@@ -242,15 +266,18 @@ int LinuxDvbPlay(Context_t *context, char *type)
} }
} }
free(Encoding); free(Encoding);
if (0 != ioctl(videofd, VIDEO_PLAY)) if (0 != ioctl(videofd, VIDEO_PLAY))
{ {
linuxdvb_err("VIDEO_PLAY: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("VIDEO_PLAY: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
if (ioctl(videofd, VIDEO_CONTINUE) == -1) if (ioctl(videofd, VIDEO_CONTINUE) == -1)
{ {
linuxdvb_err("VIDEO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("VIDEO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno));
} }
if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
{ {
linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
@@ -260,8 +287,11 @@ int LinuxDvbPlay(Context_t *context, char *type)
{ {
char *Encoding = NULL; char *Encoding = NULL;
context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding);
linuxdvb_printf(20, "0 A %s\n", Encoding); linuxdvb_printf(20, "0 A %s\n", Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
@@ -276,11 +306,13 @@ int LinuxDvbPlay(Context_t *context, char *type)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
if (ioctl(audiofd, AUDIO_PLAY) < 0) if (ioctl(audiofd, AUDIO_PLAY) < 0)
{ {
linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
if (ioctl(audiofd, AUDIO_CONTINUE) < 0) if (ioctl(audiofd, AUDIO_CONTINUE) < 0)
{ {
linuxdvb_err("AUDIO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("AUDIO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno));
@@ -288,6 +320,7 @@ int LinuxDvbPlay(Context_t *context, char *type)
} }
free(Encoding); free(Encoding);
} }
ret = cERR_LINUXDVB_NO_ERROR; ret = cERR_LINUXDVB_NO_ERROR;
return ret; return ret;
//return 0; //return 0;
@@ -298,19 +331,24 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type)
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
unsigned char video = !strcmp("video", type); unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type); unsigned char audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (video && videofd != -1) if (video && videofd != -1)
{ {
if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
{ {
linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
} }
if (ioctl(videofd, VIDEO_STOP) == -1) if (ioctl(videofd, VIDEO_STOP) == -1)
{ {
linuxdvb_err("VIDEO_STOP: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("VIDEO_STOP: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
ioctl(videofd, VIDEO_SLOWMOTION, 0); ioctl(videofd, VIDEO_SLOWMOTION, 0);
ioctl(videofd, VIDEO_FAST_FORWARD, 0); ioctl(videofd, VIDEO_FAST_FORWARD, 0);
ioctl(videofd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX); ioctl(videofd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
@@ -321,6 +359,7 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type)
{ {
linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
} }
if (ioctl(audiofd, AUDIO_STOP) == -1) if (ioctl(audiofd, AUDIO_STOP) == -1)
{ {
linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno));
@@ -328,7 +367,9 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type)
} }
ioctl(audiofd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX); ioctl(audiofd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX);
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
return ret; return ret;
} }
@@ -337,8 +378,11 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type)
int32_t ret = cERR_LINUXDVB_NO_ERROR; int32_t ret = cERR_LINUXDVB_NO_ERROR;
uint8_t video = !strcmp("video", type); uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type); uint8_t audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (video && videofd != -1) if (video && videofd != -1)
{ {
if (ioctl(videofd, VIDEO_FREEZE, NULL) == -1) if (ioctl(videofd, VIDEO_FREEZE, NULL) == -1)
@@ -347,6 +391,7 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
if (audio && audiofd != -1) if (audio && audiofd != -1)
{ {
if (ioctl(audiofd, AUDIO_PAUSE, NULL) == -1) if (ioctl(audiofd, AUDIO_PAUSE, NULL) == -1)
@@ -355,7 +400,9 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
return ret; return ret;
} }
@@ -364,19 +411,23 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type)
int32_t ret = cERR_LINUXDVB_NO_ERROR; int32_t ret = cERR_LINUXDVB_NO_ERROR;
uint8_t video = !strcmp("video", type); uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type); uint8_t audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
if (video && videofd != -1) if (video && videofd != -1)
{ {
if (context->playback->isForwarding == 0) if (context->playback->isForwarding == 0)
{ {
ioctl(videofd, VIDEO_FAST_FORWARD, 0); ioctl(videofd, VIDEO_FAST_FORWARD, 0);
} }
if (ioctl(videofd, VIDEO_CONTINUE, NULL) == -1) if (ioctl(videofd, VIDEO_CONTINUE, NULL) == -1)
{ {
linuxdvb_err("VIDEO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("VIDEO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
if (audio && audiofd != -1) if (audio && audiofd != -1)
{ {
if (ioctl(audiofd, AUDIO_CONTINUE, NULL) == -1) if (ioctl(audiofd, AUDIO_CONTINUE, NULL) == -1)
@@ -385,16 +436,21 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
if (isBufferedOutput) if (isBufferedOutput)
LinuxDvbBuffResume(context); LinuxDvbBuffResume(context);
linuxdvb_printf(10, "exiting\n"); linuxdvb_printf(10, "exiting\n");
return ret; return ret;
} }
int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag) int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag)
{ {
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
linuxdvb_printf(10, "\n"); linuxdvb_printf(10, "\n");
if (audiofd != -1) if (audiofd != -1)
{ {
if (*flag == '1') if (*flag == '1')
@@ -414,7 +470,9 @@ int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag)
} }
} }
} }
linuxdvb_printf(10, "exiting\n"); linuxdvb_printf(10, "exiting\n");
return ret; return ret;
} }
@@ -428,8 +486,11 @@ int LinuxDvbFastForward(Context_t *context, char *type)
int32_t ret = cERR_LINUXDVB_NO_ERROR; int32_t ret = cERR_LINUXDVB_NO_ERROR;
uint8_t video = !strcmp("video", type); uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type); uint8_t audio = !strcmp("audio", type);
if (audio) {} if (audio) {}
linuxdvb_printf(10, "v%d a%d speed %d\n", video, audio, context->playback->Speed); linuxdvb_printf(10, "v%d a%d speed %d\n", video, audio, context->playback->Speed);
if (video && videofd != -1) if (video && videofd != -1)
{ {
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
@@ -441,6 +502,7 @@ int LinuxDvbFastForward(Context_t *context, char *type)
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
} }
linuxdvb_printf(10, "exiting with value %d\n", ret); linuxdvb_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
@@ -448,12 +510,16 @@ int LinuxDvbFastForward(Context_t *context, char *type)
int LinuxDvbSlowMotion(Context_t *context, char *type) int LinuxDvbSlowMotion(Context_t *context, char *type)
{ {
int32_t ret = cERR_LINUXDVB_NO_ERROR; int32_t ret = cERR_LINUXDVB_NO_ERROR;
uint8_t video = !strcmp("video", type); uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type); uint8_t audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
if ((video && videofd != -1) || (audio && audiofd != -1)) if ((video && videofd != -1) || (audio && audiofd != -1))
{ {
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (video && videofd != -1) if (video && videofd != -1)
{ {
if (ioctl(videofd, VIDEO_SLOWMOTION, context->playback->SlowMotion) == -1) if (ioctl(videofd, VIDEO_SLOWMOTION, context->playback->SlowMotion) == -1)
@@ -462,9 +528,12 @@ int LinuxDvbSlowMotion(Context_t *context, char *type)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
} }
linuxdvb_printf(10, "exiting with value %d\n", ret); linuxdvb_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
@@ -480,13 +549,16 @@ int LinuxDvbAVSync(Context_t *context __attribute__((unused)), char *type __attr
if (audiofd != -1) if (audiofd != -1)
{ {
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (ioctl(audiofd, AUDIO_SET_AV_SYNC, 0) == -1) //context->playback->AVSync) == -1) if (ioctl(audiofd, AUDIO_SET_AV_SYNC, 0) == -1) //context->playback->AVSync) == -1)
{ {
linuxdvb_err("AUDIO_SET_AV_SYNC: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("AUDIO_SET_AV_SYNC: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
} }
return ret; return ret;
} }
@@ -495,10 +567,13 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type)
int32_t ret = cERR_LINUXDVB_NO_ERROR; int32_t ret = cERR_LINUXDVB_NO_ERROR;
uint8_t video = !strcmp("video", type); uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type); uint8_t audio = !strcmp("audio", type);
linuxdvb_printf(10, "LinuxDvbClear v%d a%d\n", video, audio); linuxdvb_printf(10, "LinuxDvbClear v%d a%d\n", video, audio);
if ((video && videofd != -1) || (audio && audiofd != -1)) if ((video && videofd != -1) || (audio && audiofd != -1))
{ {
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (video && videofd != -1) if (video && videofd != -1)
{ {
if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
@@ -515,16 +590,21 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
} }
linuxdvb_printf(10, "exiting\n"); linuxdvb_printf(10, "exiting\n");
return ret; return ret;
} }
int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long int *pts) int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long int *pts)
{ {
int32_t ret = cERR_LINUXDVB_ERROR; int32_t ret = cERR_LINUXDVB_ERROR;
linuxdvb_printf(50, "\n"); linuxdvb_printf(50, "\n");
// GET_PTS is immutable call, so it can be done in parallel to other requests // GET_PTS is immutable call, so it can be done in parallel to other requests
if (videofd > -1 && !ioctl(videofd, VIDEO_GET_PTS, (void *)&sCURRENT_PTS)) if (videofd > -1 && !ioctl(videofd, VIDEO_GET_PTS, (void *)&sCURRENT_PTS))
{ {
@@ -534,6 +614,7 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i
{ {
linuxdvb_err("VIDEO_GET_PTS: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("VIDEO_GET_PTS: ERROR %d, %s\n", errno, strerror(errno));
} }
if (ret != cERR_LINUXDVB_NO_ERROR) if (ret != cERR_LINUXDVB_NO_ERROR)
{ {
if (audiofd > -1 && !ioctl(audiofd, AUDIO_GET_PTS, (void *)&sCURRENT_PTS)) if (audiofd > -1 && !ioctl(audiofd, AUDIO_GET_PTS, (void *)&sCURRENT_PTS))
@@ -545,10 +626,12 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i
linuxdvb_err("AUDIO_GET_PTS: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("AUDIO_GET_PTS: ERROR %d, %s\n", errno, strerror(errno));
} }
} }
if (ret != cERR_LINUXDVB_NO_ERROR) if (ret != cERR_LINUXDVB_NO_ERROR)
{ {
sCURRENT_PTS = 0; sCURRENT_PTS = 0;
} }
*((unsigned long long int *)pts) = (unsigned long long int)sCURRENT_PTS; *((unsigned long long int *)pts) = (unsigned long long int)sCURRENT_PTS;
return ret; return ret;
} }
@@ -563,26 +646,34 @@ int LinuxDvbSwitch(Context_t *context, char *type)
uint8_t audio = !strcmp("audio", type); uint8_t audio = !strcmp("audio", type);
uint8_t video = !strcmp("video", type); uint8_t video = !strcmp("video", type);
Writer_t *writer; Writer_t *writer;
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
if ((video && videofd != -1) || (audio && audiofd != -1)) if ((video && videofd != -1) || (audio && audiofd != -1))
{ {
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (audio && audiofd != -1) if (audio && audiofd != -1)
{ {
char *Encoding = NULL; char *Encoding = NULL;
if (context && context->manager && context->manager->audio) if (context && context->manager && context->manager->audio)
{ {
context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding);
linuxdvb_printf(10, "A %s\n", Encoding); linuxdvb_printf(10, "A %s\n", Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (ioctl(audiofd, AUDIO_STOP, NULL) == -1) if (ioctl(audiofd, AUDIO_STOP, NULL) == -1)
{ {
linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno));
} }
if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1)
{ {
linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
} }
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
@@ -595,6 +686,7 @@ int LinuxDvbSwitch(Context_t *context, char *type)
linuxdvb_err("AUDIO_SET_BYPASS_MODE: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("AUDIO_SET_BYPASS_MODE: ERROR %d, %s\n", errno, strerror(errno));
} }
} }
if (ioctl(audiofd, AUDIO_PLAY) == -1) if (ioctl(audiofd, AUDIO_PLAY) == -1)
{ {
linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno));
@@ -606,22 +698,28 @@ int LinuxDvbSwitch(Context_t *context, char *type)
linuxdvb_printf(20, "no context for Audio\n"); linuxdvb_printf(20, "no context for Audio\n");
} }
} }
if (video && videofd != -1) if (video && videofd != -1)
{ {
char *Encoding = NULL; char *Encoding = NULL;
if (context && context->manager && context->manager->video) if (context && context->manager && context->manager->video)
{ {
context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
if (ioctl(videofd, VIDEO_STOP, NULL) == -1) if (ioctl(videofd, VIDEO_STOP, NULL) == -1)
{ {
linuxdvb_err("VIDEO_STOP: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("VIDEO_STOP: ERROR %d, %s\n", errno, strerror(errno));
} }
if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
{ {
linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
} }
linuxdvb_printf(10, "V %s\n", Encoding); linuxdvb_printf(10, "V %s\n", Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
@@ -634,6 +732,7 @@ int LinuxDvbSwitch(Context_t *context, char *type)
linuxdvb_err("VIDEO_SET_STREAMTYPE: ERROR %d, %s\n", errno, strerror(errno)); linuxdvb_err("VIDEO_SET_STREAMTYPE: ERROR %d, %s\n", errno, strerror(errno));
} }
} }
if (ioctl(videofd, VIDEO_PLAY) == -1) if (ioctl(videofd, VIDEO_PLAY) == -1)
{ {
/* konfetti: fixme: think on this, I think we should /* konfetti: fixme: think on this, I think we should
@@ -648,42 +747,54 @@ int LinuxDvbSwitch(Context_t *context, char *type)
linuxdvb_printf(20, "no context for Video\n"); linuxdvb_printf(20, "no context for Video\n");
} }
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
} }
linuxdvb_printf(10, "exiting\n"); linuxdvb_printf(10, "exiting\n");
return cERR_LINUXDVB_NO_ERROR; return cERR_LINUXDVB_NO_ERROR;
} }
static int Write(Context_t *context, void *_out) static int Write(Context_t *context, void *_out)
{ {
AudioVideoOut_t *out = (AudioVideoOut_t *) _out; AudioVideoOut_t *out = (AudioVideoOut_t *) _out;
int32_t ret = cERR_LINUXDVB_NO_ERROR; int32_t ret = cERR_LINUXDVB_NO_ERROR;
int32_t res = 0; int32_t res = 0;
uint8_t video = 0; uint8_t video = 0;
uint8_t audio = 0; uint8_t audio = 0;
Writer_t *writer = NULL; Writer_t *writer = NULL;
WriterAVCallData_t call; WriterAVCallData_t call;
if (out == NULL) if (out == NULL)
{ {
linuxdvb_err("null pointer passed\n"); linuxdvb_err("null pointer passed\n");
return cERR_LINUXDVB_ERROR; return cERR_LINUXDVB_ERROR;
} }
video = !strcmp("video", out->type); video = !strcmp("video", out->type);
audio = !strcmp("audio", out->type); audio = !strcmp("audio", out->type);
linuxdvb_printf(20, "DataLength=%u PrivateLength=%u Pts=%llu FrameRate=%f\n", linuxdvb_printf(20, "DataLength=%u PrivateLength=%u Pts=%llu FrameRate=%f\n",
out->len, out->extralen, out->pts, out->frameRate); out->len, out->extralen, out->pts, out->frameRate);
linuxdvb_printf(20, "v%d a%d\n", video, audio); linuxdvb_printf(20, "v%d a%d\n", video, audio);
if (video) if (video)
{ {
char *Encoding = NULL; char *Encoding = NULL;
context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
linuxdvb_printf(20, "Encoding = %s\n", Encoding); linuxdvb_printf(20, "Encoding = %s\n", Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_printf(20, "searching default writer ... %s\n", Encoding); linuxdvb_printf(20, "searching default writer ... %s\n", Encoding);
writer = getDefaultVideoWriter(); writer = getDefaultVideoWriter();
} }
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_err("unknown video codec and no default writer %s\n", Encoding); linuxdvb_err("unknown video codec and no default writer %s\n", Encoding);
@@ -734,6 +845,7 @@ static int Write(Context_t *context, void *_out)
} }
} }
} }
call.fd = videofd; call.fd = videofd;
call.data = out->data; call.data = out->data;
call.len = out->len; call.len = out->len;
@@ -747,11 +859,13 @@ static int Write(Context_t *context, void *_out)
call.Height = out->height; call.Height = out->height;
call.InfoFlags = out->infoFlags; call.InfoFlags = out->infoFlags;
call.Version = 0; call.Version = 0;
call.WriteV = isBufferedOutput ? BufferingWriteV : writev_with_retry; call.WriteV = isBufferedOutput ? BufferingWriteV : writev_with_retry;
if (writer->writeData) if (writer->writeData)
{ {
res = writer->writeData(&call); res = writer->writeData(&call);
} }
if (res < 0) if (res < 0)
{ {
linuxdvb_err("failed to write data %d - %d\n", res, errno); linuxdvb_err("failed to write data %d - %d\n", res, errno);
@@ -759,19 +873,24 @@ static int Write(Context_t *context, void *_out)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
free(Encoding); free(Encoding);
} }
else if (audio) else if (audio)
{ {
char *Encoding = NULL; char *Encoding = NULL;
context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding);
linuxdvb_printf(20, "%s::%s Encoding = %s\n", FILENAME, __FUNCTION__, Encoding); linuxdvb_printf(20, "%s::%s Encoding = %s\n", FILENAME, __FUNCTION__, Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_printf(20, "searching default writer ... %s\n", Encoding); linuxdvb_printf(20, "searching default writer ... %s\n", Encoding);
writer = getDefaultAudioWriter(); writer = getDefaultAudioWriter();
} }
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_err("unknown audio codec %s and no default writer\n", Encoding); linuxdvb_err("unknown audio codec %s and no default writer\n", Encoding);
@@ -790,11 +909,13 @@ static int Write(Context_t *context, void *_out)
call.FrameScale = out->timeScale; call.FrameScale = out->timeScale;
call.InfoFlags = out->infoFlags; call.InfoFlags = out->infoFlags;
call.Version = 0; call.Version = 0;
call.WriteV = isBufferedOutput ? BufferingWriteV : writev_with_retry; call.WriteV = isBufferedOutput ? BufferingWriteV : writev_with_retry;
if (writer->writeData) if (writer->writeData)
{ {
res = writer->writeData(&call); res = writer->writeData(&call);
} }
if (res < 0) if (res < 0)
{ {
linuxdvb_err("failed to write data %d - %d\n", res, errno); linuxdvb_err("failed to write data %d - %d\n", res, errno);
@@ -802,8 +923,10 @@ static int Write(Context_t *context, void *_out)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
free(Encoding); free(Encoding);
} }
return ret; return ret;
} }
@@ -812,8 +935,11 @@ static int reset(Context_t *context)
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
Writer_t *writer; Writer_t *writer;
char *Encoding = NULL; char *Encoding = NULL;
context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_err("unknown video codec %s\n", Encoding); linuxdvb_err("unknown video codec %s\n", Encoding);
@@ -823,9 +949,13 @@ static int reset(Context_t *context)
{ {
writer->reset(); writer->reset();
} }
free(Encoding); free(Encoding);
context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_err("unknown video codec %s\n", Encoding); linuxdvb_err("unknown video codec %s\n", Encoding);
@@ -835,16 +965,21 @@ static int reset(Context_t *context)
{ {
writer->reset(); writer->reset();
} }
free(Encoding); free(Encoding);
if (isBufferedOutput) if (isBufferedOutput)
LinuxDvbBuffFlush(context); LinuxDvbBuffFlush(context);
return ret; return ret;
} }
static int Command(Context_t *context, OutputCmd_t command, void *argument) static int Command(Context_t *context, OutputCmd_t command, void *argument)
{ {
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
linuxdvb_printf(50, "Command %d\n", command); linuxdvb_printf(50, "Command %d\n", command);
switch (command) switch (command)
{ {
case OUTPUT_OPEN: case OUTPUT_OPEN:
@@ -946,7 +1081,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
if (!isBufferedOutput) if (!isBufferedOutput)
{ {
uint32_t bufferSize = *((uint32_t*)argument); uint32_t bufferSize = *((uint32_t *)argument);
ret = cERR_LINUXDVB_NO_ERROR; ret = cERR_LINUXDVB_NO_ERROR;
if (bufferSize > 0) if (bufferSize > 0)
{ {
@@ -961,7 +1096,9 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
break; break;
} }
linuxdvb_printf(50, "exiting with value %d\n", ret); linuxdvb_printf(50, "exiting with value %d\n", ret);
return ret; return ret;
} }

View File

@@ -70,6 +70,7 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x);
#define linuxdvb_err(x...) #define linuxdvb_err(x...)
#endif #endif
#define cERR_LINUXDVB_NO_ERROR 0 #define cERR_LINUXDVB_NO_ERROR 0
#define cERR_LINUXDVB_ERROR -1 #define cERR_LINUXDVB_ERROR -1
@@ -99,84 +100,103 @@ pthread_mutex_t LinuxDVBmutex;
int LinuxDvbStop(Context_t *context, char *type); int LinuxDvbStop(Context_t *context, char *type);
/* ***************************** */ /* ***************************** */
/* Functions */ /* MISC Functions */
/* ***************************** */ /* ***************************** */
void getLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) void getLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused)))
{ {
linuxdvb_printf(250, "requesting mutex\n"); linuxdvb_printf(250, "requesting mutex\n");
pthread_mutex_lock(&LinuxDVBmutex); pthread_mutex_lock(&LinuxDVBmutex);
linuxdvb_printf(250, "received mutex\n"); linuxdvb_printf(250, "received mutex\n");
} }
void releaseLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) void releaseLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused)))
{ {
pthread_mutex_unlock(&LinuxDVBmutex); pthread_mutex_unlock(&LinuxDVBmutex);
linuxdvb_printf(250, "released mutex\n"); linuxdvb_printf(250, "released mutex\n");
} }
int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type) int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type)
{ {
unsigned char video = !strcmp("video", type); unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type); unsigned char audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
if (video && videofd < 0) if (video && videofd < 0)
{ {
videofd = open(VIDEODEV, O_RDWR); videofd = open(VIDEODEV, O_RDWR);
if (videofd < 0) if (videofd < 0)
{ {
linuxdvb_err("failed to open %s - errno %d\n", VIDEODEV, errno); linuxdvb_err("failed to open %s - errno %d\n", VIDEODEV, errno);
linuxdvb_err("%s\n", strerror(errno)); linuxdvb_err("%s\n", strerror(errno));
return cERR_LINUXDVB_ERROR; return cERR_LINUXDVB_ERROR;
} }
if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno)); linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
} }
if (ioctl(videofd, VIDEO_SELECT_SOURCE, (void *)VIDEO_SOURCE_MEMORY) == -1) if (ioctl(videofd, VIDEO_SELECT_SOURCE, (void *)VIDEO_SOURCE_MEMORY) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_SELECT_SOURCE: %s\n", strerror(errno)); linuxdvb_err("VIDEO_SELECT_SOURCE: %s\n", strerror(errno));
} }
if (ioctl(videofd, VIDEO_SET_STREAMTYPE, (void *)STREAM_TYPE_PROGRAM) == -1) if (ioctl(videofd, VIDEO_SET_STREAMTYPE, (void *)STREAM_TYPE_PROGRAM) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno)); linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno));
} }
if (ioctl(videofd, VIDEO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1) if (ioctl(videofd, VIDEO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno)); linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno));
} }
} }
if (audio && audiofd < 0) if (audio && audiofd < 0)
{ {
audiofd = open(AUDIODEV, O_RDWR); audiofd = open(AUDIODEV, O_RDWR);
if (audiofd < 0) if (audiofd < 0)
{ {
linuxdvb_err("failed to open %s - errno %d\n", AUDIODEV, errno); linuxdvb_err("failed to open %s - errno %d\n", AUDIODEV, errno);
linuxdvb_err("%s\n", strerror(errno)); linuxdvb_err("%s\n", strerror(errno));
if (videofd < 0) if (videofd < 0)
close(videofd); close(videofd);
return cERR_LINUXDVB_ERROR; return cERR_LINUXDVB_ERROR;
} }
if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno)); linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno));
} }
if (ioctl(audiofd, AUDIO_SELECT_SOURCE, (void *)AUDIO_SOURCE_MEMORY) == -1) if (ioctl(audiofd, AUDIO_SELECT_SOURCE, (void *)AUDIO_SOURCE_MEMORY) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_SELECT_SOURCE: %s\n", strerror(errno)); linuxdvb_err("AUDIO_SELECT_SOURCE: %s\n", strerror(errno));
} }
if (ioctl(audiofd, AUDIO_SET_STREAMTYPE, (void *)STREAM_TYPE_PROGRAM) == -1) if (ioctl(audiofd, AUDIO_SET_STREAMTYPE, (void *)STREAM_TYPE_PROGRAM) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_SET_STREAMTYPE: %s\n", strerror(errno)); linuxdvb_err("AUDIO_SET_STREAMTYPE: %s\n", strerror(errno));
} }
} }
return cERR_LINUXDVB_NO_ERROR; return cERR_LINUXDVB_NO_ERROR;
} }
@@ -184,13 +204,17 @@ int LinuxDvbClose(Context_t *context, char *type)
{ {
unsigned char video = !strcmp("video", type); unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type); unsigned char audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
/* closing stand alone is not allowed, so prevent /* closing stand alone is not allowed, so prevent
* user from closing and dont call stop. stop will * user from closing and dont call stop. stop will
* set default values for us (speed and so on). * set default values for us (speed and so on).
*/ */
LinuxDvbStop(context, type); LinuxDvbStop(context, type);
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (video && videofd != -1) if (video && videofd != -1)
{ {
close(videofd); close(videofd);
@@ -201,6 +225,7 @@ int LinuxDvbClose(Context_t *context, char *type)
close(audiofd); close(audiofd);
audiofd = -1; audiofd = -1;
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
return cERR_LINUXDVB_NO_ERROR; return cERR_LINUXDVB_NO_ERROR;
} }
@@ -209,15 +234,21 @@ int LinuxDvbPlay(Context_t *context, char *type)
{ {
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
Writer_t *writer; Writer_t *writer;
unsigned char video = !strcmp("video", type); unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type); unsigned char audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
if (video && videofd != -1) if (video && videofd != -1)
{ {
char *Encoding = NULL; char *Encoding = NULL;
context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
linuxdvb_printf(10, "V %s\n", Encoding); linuxdvb_printf(10, "V %s\n", Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
@@ -238,6 +269,7 @@ int LinuxDvbPlay(Context_t *context, char *type)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
if (ioctl(videofd, VIDEO_PLAY, NULL) == -1) if (ioctl(videofd, VIDEO_PLAY, NULL) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
@@ -250,8 +282,11 @@ int LinuxDvbPlay(Context_t *context, char *type)
{ {
char *Encoding = NULL; char *Encoding = NULL;
context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding);
linuxdvb_printf(20, "0 A %s\n", Encoding); linuxdvb_printf(20, "0 A %s\n", Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
@@ -272,6 +307,7 @@ int LinuxDvbPlay(Context_t *context, char *type)
ret = -1; ret = -1;
} }
} }
if (ioctl(audiofd, AUDIO_PLAY, NULL) == -1) if (ioctl(audiofd, AUDIO_PLAY, NULL) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
@@ -280,6 +316,7 @@ int LinuxDvbPlay(Context_t *context, char *type)
} }
free(Encoding); free(Encoding);
} }
return ret; return ret;
} }
@@ -288,8 +325,11 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type)
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
unsigned char video = !strcmp("video", type); unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type); unsigned char audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (video && videofd != -1) if (video && videofd != -1)
{ {
if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
@@ -297,6 +337,7 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type)
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno)); linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
} }
/* set back to normal speed (end trickmodes) */ /* set back to normal speed (end trickmodes) */
if (ioctl(videofd, VIDEO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1) if (ioctl(videofd, VIDEO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1)
{ {
@@ -317,6 +358,7 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type)
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno)); linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno));
} }
/* set back to normal speed (end trickmodes) */ /* set back to normal speed (end trickmodes) */
if (ioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1) if (ioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1)
{ {
@@ -330,7 +372,9 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
return ret; return ret;
} }
@@ -339,8 +383,11 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type)
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
unsigned char video = !strcmp("video", type); unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type); unsigned char audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (video && videofd != -1) if (video && videofd != -1)
{ {
if (ioctl(videofd, VIDEO_FREEZE, NULL) == -1) if (ioctl(videofd, VIDEO_FREEZE, NULL) == -1)
@@ -359,7 +406,9 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
return ret; return ret;
} }
@@ -368,7 +417,9 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type)
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
unsigned char video = !strcmp("video", type); unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type); unsigned char audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
if (video && videofd != -1) if (video && videofd != -1)
{ {
if (ioctl(videofd, VIDEO_CONTINUE, NULL) == -1) if (ioctl(videofd, VIDEO_CONTINUE, NULL) == -1)
@@ -387,7 +438,10 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
linuxdvb_printf(10, "exiting\n"); linuxdvb_printf(10, "exiting\n");
return ret; return ret;
} }
@@ -395,20 +449,26 @@ int LinuxDvbReverseDiscontinuity(Context_t *context __attribute__((unused)), int
{ {
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
int dis_type = VIDEO_DISCONTINUITY_CONTINUOUS_REVERSE | *surplus; int dis_type = VIDEO_DISCONTINUITY_CONTINUOUS_REVERSE | *surplus;
linuxdvb_printf(50, "\n"); linuxdvb_printf(50, "\n");
if (ioctl(videofd, VIDEO_DISCONTINUITY, (void *) dis_type) == -1) if (ioctl(videofd, VIDEO_DISCONTINUITY, (void *) dis_type) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_DISCONTINUITY: %s\n", strerror(errno)); linuxdvb_err("VIDEO_DISCONTINUITY: %s\n", strerror(errno));
} }
linuxdvb_printf(50, "exiting\n"); linuxdvb_printf(50, "exiting\n");
return ret; return ret;
} }
int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag) int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag)
{ {
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
linuxdvb_printf(10, "\n"); linuxdvb_printf(10, "\n");
if (audiofd != -1) if (audiofd != -1)
{ {
if (*flag == '1') if (*flag == '1')
@@ -436,18 +496,24 @@ int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag)
} }
} }
} }
linuxdvb_printf(10, "exiting\n"); linuxdvb_printf(10, "exiting\n");
return ret; return ret;
} }
int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type) int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type)
{ {
unsigned char video = !strcmp("video", type); unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type); unsigned char audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
if ((video && videofd != -1) || (audio && audiofd != -1)) if ((video && videofd != -1) || (audio && audiofd != -1))
{ {
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (video && videofd != -1) if (video && videofd != -1)
{ {
if (ioctl(videofd, VIDEO_FLUSH, NULL) == -1) if (ioctl(videofd, VIDEO_FLUSH, NULL) == -1)
@@ -456,6 +522,7 @@ int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type)
linuxdvb_err("VIDEO_FLUSH: %s\n", strerror(errno)); linuxdvb_err("VIDEO_FLUSH: %s\n", strerror(errno));
} }
} }
if (audio && audiofd != -1) if (audio && audiofd != -1)
{ {
if (ioctl(audiofd, AUDIO_FLUSH, NULL) == -1) if (ioctl(audiofd, AUDIO_FLUSH, NULL) == -1)
@@ -464,9 +531,12 @@ int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type)
linuxdvb_err("AUDIO_FLUSH: %s\n", strerror(errno)); linuxdvb_err("AUDIO_FLUSH: %s\n", strerror(errno));
} }
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
} }
linuxdvb_printf(10, "exiting\n"); linuxdvb_printf(10, "exiting\n");
return cERR_LINUXDVB_NO_ERROR; return cERR_LINUXDVB_NO_ERROR;
} }
@@ -474,22 +544,31 @@ int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type)
int LinuxDvbFastForward(Context_t *context, char *type) int LinuxDvbFastForward(Context_t *context, char *type)
{ {
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
unsigned char video = !strcmp("video", type); unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type); unsigned char audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d speed %d\n", video, audio, context->playback->Speed); linuxdvb_printf(10, "v%d a%d speed %d\n", video, audio, context->playback->Speed);
if (video && videofd != -1) if (video && videofd != -1)
{ {
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
/* konfetti comment: speed is a value given in skipped frames */ /* konfetti comment: speed is a value given in skipped frames */
if (ioctl(videofd, VIDEO_FAST_FORWARD, context->playback->Speed) == -1) if (ioctl(videofd, VIDEO_FAST_FORWARD, context->playback->Speed) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_FAST_FORWARD: %s\n", strerror(errno)); linuxdvb_err("VIDEO_FAST_FORWARD: %s\n", strerror(errno));
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
} }
linuxdvb_printf(10, "exiting with value %d\n", ret); linuxdvb_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
#else #else
@@ -508,38 +587,54 @@ int LinuxDvbFastForward(Context_t *context, char *type)
int speedIndex; int speedIndex;
unsigned char video = !strcmp("video", type); unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type); unsigned char audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
if (video && videofd != -1) if (video && videofd != -1)
{ {
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int));
linuxdvb_printf(1, "speedIndex %d\n", speedIndex); linuxdvb_printf(1, "speedIndex %d\n", speedIndex);
if (ioctl(videofd, VIDEO_SET_SPEED, SpeedList[speedIndex]) == -1) if (ioctl(videofd, VIDEO_SET_SPEED, SpeedList[speedIndex]) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno)); linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno));
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
} }
if (audio && audiofd != -1) if (audio && audiofd != -1)
{ {
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int));
linuxdvb_printf(1, "speedIndex %d\n", speedIndex); linuxdvb_printf(1, "speedIndex %d\n", speedIndex);
if (ioctl(audiofd, AUDIO_SET_SPEED, SpeedList[speedIndex]) == -1) if (ioctl(audiofd, AUDIO_SET_SPEED, SpeedList[speedIndex]) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno)); linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno));
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
} }
linuxdvb_printf(10, "exiting with value %d\n", ret); linuxdvb_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
#endif #endif
int LinuxDvbReverse(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) int LinuxDvbReverse(Context_t *context __attribute__((unused)), char *type __attribute__((unused)))
{ {
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
@@ -549,12 +644,16 @@ int LinuxDvbReverse(Context_t *context __attribute__((unused)), char *type __att
int LinuxDvbSlowMotion(Context_t *context, char *type) int LinuxDvbSlowMotion(Context_t *context, char *type)
{ {
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
unsigned char video = !strcmp("video", type); unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type); unsigned char audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
if ((video && videofd != -1) || (audio && audiofd != -1)) if ((video && videofd != -1) || (audio && audiofd != -1))
{ {
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (video && videofd != -1) if (video && videofd != -1)
{ {
if (ioctl(videofd, VIDEO_SLOWMOTION, context->playback->SlowMotion) == -1) if (ioctl(videofd, VIDEO_SLOWMOTION, context->playback->SlowMotion) == -1)
@@ -564,9 +663,12 @@ int LinuxDvbSlowMotion(Context_t *context, char *type)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
} }
linuxdvb_printf(10, "exiting with value %d\n", ret); linuxdvb_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
@@ -582,14 +684,17 @@ int LinuxDvbAVSync(Context_t *context, char *type __attribute__((unused)))
if (audiofd != -1) if (audiofd != -1)
{ {
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (ioctl(audiofd, AUDIO_SET_AV_SYNC, context->playback->AVSync) == -1) if (ioctl(audiofd, AUDIO_SET_AV_SYNC, context->playback->AVSync) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_SET_AV_SYNC: %s\n", strerror(errno)); linuxdvb_err("AUDIO_SET_AV_SYNC: %s\n", strerror(errno));
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
} }
return ret; return ret;
} }
@@ -598,10 +703,13 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type)
int32_t ret = cERR_LINUXDVB_NO_ERROR; int32_t ret = cERR_LINUXDVB_NO_ERROR;
uint8_t video = !strcmp("video", type); uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type); uint8_t audio = !strcmp("audio", type);
linuxdvb_printf(10, ">>>>>>>>>>LinuxDvbClear v%d a%d\n", video, audio); linuxdvb_printf(10, ">>>>>>>>>>LinuxDvbClear v%d a%d\n", video, audio);
if ((video && videofd != -1) || (audio && audiofd != -1)) if ((video && videofd != -1) || (audio && audiofd != -1))
{ {
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (video && videofd != -1) if (video && videofd != -1)
{ {
if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
@@ -620,18 +728,24 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
} }
linuxdvb_printf(10, "exiting\n"); linuxdvb_printf(10, "exiting\n");
return ret; return ret;
} }
int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long int *pts) int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long int *pts)
{ {
int ret = cERR_LINUXDVB_ERROR; int ret = cERR_LINUXDVB_ERROR;
linuxdvb_printf(50, "\n"); linuxdvb_printf(50, "\n");
// pts is a non writting requests and can be done in parallel to other requests // pts is a non writting requests and can be done in parallel to other requests
//getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__); //getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
if (videofd > -1 && !ioctl(videofd, VIDEO_GET_PTS, (void *)&sCURRENT_PTS)) if (videofd > -1 && !ioctl(videofd, VIDEO_GET_PTS, (void *)&sCURRENT_PTS))
{ {
ret = cERR_LINUXDVB_NO_ERROR; ret = cERR_LINUXDVB_NO_ERROR;
@@ -640,6 +754,7 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i
{ {
linuxdvb_err("VIDEO_GET_PTS: %d (%s)\n", errno, strerror(errno)); linuxdvb_err("VIDEO_GET_PTS: %d (%s)\n", errno, strerror(errno));
} }
if (ret != cERR_LINUXDVB_NO_ERROR) if (ret != cERR_LINUXDVB_NO_ERROR)
{ {
if (audiofd > -1 && !ioctl(audiofd, AUDIO_GET_PTS, (void *)&sCURRENT_PTS)) if (audiofd > -1 && !ioctl(audiofd, AUDIO_GET_PTS, (void *)&sCURRENT_PTS))
@@ -651,12 +766,16 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i
linuxdvb_err("AUDIO_GET_PTS: %d (%s)\n", errno, strerror(errno)); linuxdvb_err("AUDIO_GET_PTS: %d (%s)\n", errno, strerror(errno));
} }
} }
if (ret != cERR_LINUXDVB_NO_ERROR) if (ret != cERR_LINUXDVB_NO_ERROR)
{ {
sCURRENT_PTS = 0; sCURRENT_PTS = 0;
} }
*((unsigned long long int *)pts) = (unsigned long long int)sCURRENT_PTS; *((unsigned long long int *)pts) = (unsigned long long int)sCURRENT_PTS;
//releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__); //releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
return ret; return ret;
} }
@@ -664,8 +783,11 @@ int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned l
{ {
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
dvb_play_info_t playInfo; dvb_play_info_t playInfo;
linuxdvb_printf(50, "\n"); linuxdvb_printf(50, "\n");
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (videofd != -1) if (videofd != -1)
{ {
if (ioctl(videofd, VIDEO_GET_PLAY_INFO, (void *)&playInfo) == -1) if (ioctl(videofd, VIDEO_GET_PLAY_INFO, (void *)&playInfo) == -1)
@@ -690,9 +812,12 @@ int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned l
{ {
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
if (ret == cERR_LINUXDVB_NO_ERROR) if (ret == cERR_LINUXDVB_NO_ERROR)
*((unsigned long long int *)frameCount) = playInfo.frame_count; *((unsigned long long int *)frameCount) = playInfo.frame_count;
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
return ret; return ret;
} }
@@ -701,28 +826,38 @@ int LinuxDvbSwitch(Context_t *context, char *type)
unsigned char audio = !strcmp("audio", type); unsigned char audio = !strcmp("audio", type);
unsigned char video = !strcmp("video", type); unsigned char video = !strcmp("video", type);
Writer_t *writer; Writer_t *writer;
linuxdvb_printf(10, "v%d a%d\n", video, audio); linuxdvb_printf(10, "v%d a%d\n", video, audio);
if ((video && videofd != -1) || (audio && audiofd != -1)) if ((video && videofd != -1) || (audio && audiofd != -1))
{ {
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (audio && audiofd != -1) if (audio && audiofd != -1)
{ {
char *Encoding = NULL; char *Encoding = NULL;
if (context && context->manager && context->manager->audio) if (context && context->manager && context->manager->audio)
{ {
context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding);
linuxdvb_printf(10, "A %s\n", Encoding); linuxdvb_printf(10, "A %s\n", Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (ioctl(audiofd, AUDIO_STOP, NULL) == -1) if (ioctl(audiofd, AUDIO_STOP, NULL) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno)); linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno));
} }
if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno)); linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno));
} }
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
@@ -741,6 +876,7 @@ int LinuxDvbSwitch(Context_t *context, char *type)
linuxdvb_err("AUDIO_SET_ENCODING: %s\n", strerror(errno)); linuxdvb_err("AUDIO_SET_ENCODING: %s\n", strerror(errno));
} }
} }
if (ioctl(audiofd, AUDIO_PLAY, NULL) == -1) if (ioctl(audiofd, AUDIO_PLAY, NULL) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
@@ -753,24 +889,30 @@ int LinuxDvbSwitch(Context_t *context, char *type)
linuxdvb_printf(20, "no context for Audio\n"); linuxdvb_printf(20, "no context for Audio\n");
} }
} }
if (video && videofd != -1) if (video && videofd != -1)
{ {
char *Encoding = NULL; char *Encoding = NULL;
if (context && context->manager && context->manager->video) if (context && context->manager && context->manager->video)
{ {
context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
if (ioctl(videofd, VIDEO_STOP, NULL) == -1) if (ioctl(videofd, VIDEO_STOP, NULL) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno)); linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno));
} }
if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
{ {
linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno)); linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
} }
linuxdvb_printf(10, "V %s\n", Encoding); linuxdvb_printf(10, "V %s\n", Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
@@ -789,6 +931,7 @@ int LinuxDvbSwitch(Context_t *context, char *type)
linuxdvb_err("VIDEO_SET_ENCODING: %s\n", strerror(errno)); linuxdvb_err("VIDEO_SET_ENCODING: %s\n", strerror(errno));
} }
} }
if (ioctl(videofd, VIDEO_PLAY, NULL) == -1) if (ioctl(videofd, VIDEO_PLAY, NULL) == -1)
{ {
/* konfetti: fixme: think on this, I think we should /* konfetti: fixme: think on this, I think we should
@@ -804,9 +947,13 @@ int LinuxDvbSwitch(Context_t *context, char *type)
linuxdvb_printf(20, "no context for Video\n"); linuxdvb_printf(20, "no context for Video\n");
} }
} }
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
} }
linuxdvb_printf(10, "exiting\n"); linuxdvb_printf(10, "exiting\n");
return cERR_LINUXDVB_NO_ERROR; return cERR_LINUXDVB_NO_ERROR;
} }
@@ -820,27 +967,35 @@ static int Write(void *_context, void *_out)
unsigned char audio = 0; unsigned char audio = 0;
Writer_t *writer; Writer_t *writer;
WriterAVCallData_t call; WriterAVCallData_t call;
if (out == NULL) if (out == NULL)
{ {
linuxdvb_err("null pointer passed\n"); linuxdvb_err("null pointer passed\n");
return cERR_LINUXDVB_ERROR; return cERR_LINUXDVB_ERROR;
} }
video = !strcmp("video", out->type); video = !strcmp("video", out->type);
audio = !strcmp("audio", out->type); audio = !strcmp("audio", out->type);
linuxdvb_printf(20, "DataLength=%u PrivateLength=%u Pts=%llu FrameRate=%f\n", linuxdvb_printf(20, "DataLength=%u PrivateLength=%u Pts=%llu FrameRate=%f\n",
out->len, out->extralen, out->pts, out->frameRate); out->len, out->extralen, out->pts, out->frameRate);
linuxdvb_printf(20, "v%d a%d\n", video, audio); linuxdvb_printf(20, "v%d a%d\n", video, audio);
if (video) if (video)
{ {
char *Encoding = NULL; char *Encoding = NULL;
context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
linuxdvb_printf(20, "Encoding = %s\n", Encoding); linuxdvb_printf(20, "Encoding = %s\n", Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_printf(20, "searching default writer ... %s\n", Encoding); linuxdvb_printf(20, "searching default writer ... %s\n", Encoding);
writer = getDefaultVideoWriter(); writer = getDefaultVideoWriter();
} }
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_err("unknown video codec and no default writer %s\n", Encoding); linuxdvb_err("unknown video codec and no default writer %s\n", Encoding);
@@ -891,6 +1046,7 @@ static int Write(void *_context, void *_out)
} }
} }
} }
call.fd = videofd; call.fd = videofd;
call.data = out->data; call.data = out->data;
call.len = out->len; call.len = out->len;
@@ -904,10 +1060,12 @@ static int Write(void *_context, void *_out)
call.Height = out->height; call.Height = out->height;
call.InfoFlags = out->infoFlags; call.InfoFlags = out->infoFlags;
call.Version = 0; // is unsingned char call.Version = 0; // is unsingned char
if (writer->writeData) if (writer->writeData)
{ {
res = writer->writeData(&call); res = writer->writeData(&call);
} }
if (res < 0) if (res < 0)
{ {
linuxdvb_err("failed to write data %d - %d\n", res, errno); linuxdvb_err("failed to write data %d - %d\n", res, errno);
@@ -915,19 +1073,24 @@ static int Write(void *_context, void *_out)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
free(Encoding); free(Encoding);
} }
else if (audio) else if (audio)
{ {
char *Encoding = NULL; char *Encoding = NULL;
context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding);
linuxdvb_printf(20, "%s::%s Encoding = %s\n", FILENAME, __FUNCTION__, Encoding); linuxdvb_printf(20, "%s::%s Encoding = %s\n", FILENAME, __FUNCTION__, Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_printf(20, "searching default writer ... %s\n", Encoding); linuxdvb_printf(20, "searching default writer ... %s\n", Encoding);
writer = getDefaultAudioWriter(); writer = getDefaultAudioWriter();
} }
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_err("unknown audio codec %s and no default writer\n", Encoding); linuxdvb_err("unknown audio codec %s and no default writer\n", Encoding);
@@ -946,10 +1109,12 @@ static int Write(void *_context, void *_out)
call.FrameScale = out->timeScale; call.FrameScale = out->timeScale;
call.InfoFlags = out->infoFlags; call.InfoFlags = out->infoFlags;
call.Version = 0; /* -1; unsigned char cannot be negative */ call.Version = 0; /* -1; unsigned char cannot be negative */
if (writer->writeData) if (writer->writeData)
{ {
res = writer->writeData(&call); res = writer->writeData(&call);
} }
if (res < 0) if (res < 0)
{ {
linuxdvb_err("failed to write data %d - %d\n", res, errno); linuxdvb_err("failed to write data %d - %d\n", res, errno);
@@ -957,8 +1122,10 @@ static int Write(void *_context, void *_out)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
} }
} }
free(Encoding); free(Encoding);
} }
return ret; return ret;
} }
@@ -967,8 +1134,11 @@ static int reset(Context_t *context)
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
Writer_t *writer; Writer_t *writer;
char *Encoding = NULL; char *Encoding = NULL;
context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_err("unknown video codec %s\n", Encoding); linuxdvb_err("unknown video codec %s\n", Encoding);
@@ -978,9 +1148,13 @@ static int reset(Context_t *context)
{ {
writer->reset(); writer->reset();
} }
free(Encoding); free(Encoding);
context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding);
writer = getWriter(Encoding); writer = getWriter(Encoding);
if (writer == NULL) if (writer == NULL)
{ {
linuxdvb_err("unknown video codec %s\n", Encoding); linuxdvb_err("unknown video codec %s\n", Encoding);
@@ -990,7 +1164,9 @@ static int reset(Context_t *context)
{ {
writer->reset(); writer->reset();
} }
free(Encoding); free(Encoding);
return ret; return ret;
} }
@@ -998,7 +1174,9 @@ 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_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
linuxdvb_printf(50, "Command %d\n", command); linuxdvb_printf(50, "Command %d\n", command);
switch (command) switch (command)
{ {
case OUTPUT_OPEN: case OUTPUT_OPEN:
@@ -1110,7 +1288,9 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
ret = cERR_LINUXDVB_ERROR; ret = cERR_LINUXDVB_ERROR;
break; break;
} }
linuxdvb_printf(50, "exiting with value %d\n", ret); linuxdvb_printf(50, "exiting with value %d\n", ret);
return ret; return ret;
} }

View File

@@ -77,14 +77,16 @@ static Output_t *AvailableOutput[] =
/* ***************************** */ /* ***************************** */
/* ***************************** */ /* ***************************** */
/* Functions */ /* MISC Functions */
/* ***************************** */ /* ***************************** */
static void printOutputCapabilities() static void printOutputCapabilities()
{ {
int i, j; int i, j;
output_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); output_printf(10, "%s::%s\n", __FILE__, __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);
@@ -103,7 +105,9 @@ static void printOutputCapabilities()
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", __FILE__, __FUNCTION__); output_printf(10, "%s::%s\n", __FILE__, __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++)
@@ -133,6 +137,7 @@ static void OutputAdd(Context_t *context, char *port)
static void OutputDel(Context_t *context, char *port) static void OutputDel(Context_t *context, char *port)
{ {
output_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); output_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
if (!strcmp("audio", port)) if (!strcmp("audio", port))
{ {
context->output->audio = NULL; context->output->audio = NULL;
@@ -150,7 +155,9 @@ static void OutputDel(Context_t *context, char *port)
static int Command(Context_t *context, OutputCmd_t command, void *argument) static int Command(Context_t *context, OutputCmd_t command, void *argument)
{ {
int ret = cERR_OUTPUT_NO_ERROR; int ret = cERR_OUTPUT_NO_ERROR;
output_printf(10, "%s::%s Command %d\n", __FILE__, __FUNCTION__, command); output_printf(10, "%s::%s Command %d\n", __FILE__, __FUNCTION__, command);
switch (command) switch (command)
{ {
case OUTPUT_OPEN: case OUTPUT_OPEN:
@@ -562,7 +569,9 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
ret = cERR_OUTPUT_INTERNAL_ERROR; ret = cERR_OUTPUT_INTERNAL_ERROR;
break; break;
} }
output_printf(10, "%s::%s exiting with value %d\n", __FILE__, __FUNCTION__, ret); output_printf(10, "%s::%s exiting with value %d\n", __FILE__, __FUNCTION__, ret);
return ret; return ret;
} }

View File

@@ -82,6 +82,7 @@ Number, Style, Name,, MarginL, MarginR, MarginV, Effect,, Text
/* Types */ /* Types */
/* ***************************** */ /* ***************************** */
/* ***************************** */ /* ***************************** */
/* Variables */ /* Variables */
/* ***************************** */ /* ***************************** */
@@ -94,19 +95,22 @@ static int isSubtitleOpened = 0;
/* ***************************** */ /* ***************************** */
/* ***************************** */ /* ***************************** */
/* Functions */ /* MISC Functions */
/* ***************************** */ /* ***************************** */
static void getMutex(int line __attribute__((unused))) static void getMutex(int line __attribute__((unused)))
{ {
subtitle_printf(100, "%d requesting mutex\n", line); subtitle_printf(100, "%d requesting mutex\n", line);
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
subtitle_printf(100, "%d received mutex\n", line); subtitle_printf(100, "%d received mutex\n", line);
} }
static void releaseMutex(int line __attribute__((unused))) static void releaseMutex(int line __attribute__((unused)))
{ {
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
subtitle_printf(100, "%d released mutex\n", line); subtitle_printf(100, "%d released mutex\n", line);
} }
@@ -176,6 +180,7 @@ static char *json_string_escape(char *str)
*ptr1++ = *ptr2; *ptr1++ = *ptr2;
break; break;
} }
++ptr2; ++ptr2;
} }
*ptr1 = '\0'; *ptr1 = '\0';
@@ -193,25 +198,32 @@ static int Write(Context_t *context, void *data)
char *Encoding = NULL; char *Encoding = NULL;
SubtitleOut_t *out = NULL; SubtitleOut_t *out = NULL;
int32_t curtrackid = -1; int32_t curtrackid = -1;
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;
context->manager->subtitle->Command(context, MANAGER_GET, &curtrackid); context->manager->subtitle->Command(context, MANAGER_GET, &curtrackid);
if (curtrackid != (int32_t)out->trackId) if (curtrackid != (int32_t)out->trackId)
{ {
Flush(); Flush();
} }
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");
return cERR_SUBTITLE_ERROR; return cERR_SUBTITLE_ERROR;
} }
subtitle_printf(20, "Encoding:%s Text:%s Len:%d\n", Encoding, (const char *) out->data, out->len); subtitle_printf(20, "Encoding:%s Text:%s Len:%d\n", Encoding, (const char *) out->data, out->len);
if (!strncmp("S_TEXT/SUBRIP", Encoding, 13)) if (!strncmp("S_TEXT/SUBRIP", Encoding, 13))
{ {
fprintf(stderr, "{\"s_a\":{\"id\":%d,\"s\":%lld,\"e\":%lld,\"t\":\"%s\"}}\n", out->trackId, out->pts / 90, out->pts / 90 + out->durationMS, json_string_escape((char *)out->data)); fprintf(stderr, "{\"s_a\":{\"id\":%d,\"s\":%lld,\"e\":%lld,\"t\":\"%s\"}}\n", out->trackId, out->pts / 90, out->pts / 90 + out->durationMS, json_string_escape((char *)out->data));
@@ -225,6 +237,7 @@ static int Write(Context_t *context, void *data)
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, "<\n"); subtitle_printf(10, "<\n");
return cERR_SUBTITLE_NO_ERROR; return cERR_SUBTITLE_NO_ERROR;
} }
@@ -232,15 +245,21 @@ static int Write(Context_t *context, void *data)
static int32_t subtitle_Open(Context_t *context __attribute__((unused))) static int32_t subtitle_Open(Context_t *context __attribute__((unused)))
{ {
//uint32_t i = 0 ; //uint32_t i = 0 ;
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__);
isSubtitleOpened = 1; isSubtitleOpened = 1;
releaseMutex(__LINE__); releaseMutex(__LINE__);
subtitle_printf(10, "<\n"); subtitle_printf(10, "<\n");
return cERR_SUBTITLE_NO_ERROR; return cERR_SUBTITLE_NO_ERROR;
} }
@@ -248,18 +267,26 @@ static int32_t subtitle_Open(Context_t *context __attribute__((unused)))
static int32_t subtitle_Close(Context_t *context __attribute__((unused))) static int32_t subtitle_Close(Context_t *context __attribute__((unused)))
{ {
//uint32_t i = 0 ; //uint32_t i = 0 ;
subtitle_printf(10, "\n"); subtitle_printf(10, "\n");
getMutex(__LINE__); getMutex(__LINE__);
isSubtitleOpened = 0; isSubtitleOpened = 0;
releaseMutex(__LINE__); releaseMutex(__LINE__);
subtitle_printf(10, "<\n"); subtitle_printf(10, "<\n");
return cERR_SUBTITLE_NO_ERROR; return cERR_SUBTITLE_NO_ERROR;
} }
static int Command(Context_t *context, OutputCmd_t command, void *argument __attribute__((unused))) static int Command(Context_t *context, OutputCmd_t command, void *argument __attribute__((unused)))
{ {
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:
@@ -312,10 +339,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument __att
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);
return ret; return ret;
} }
static char *SubtitleCapabilitis[] = { "subtitle", NULL }; static char *SubtitleCapabilitis[] = { "subtitle", NULL };
Output_t SubtitleOutput = Output_t SubtitleOutput =

View File

@@ -69,12 +69,15 @@ void PutBits(BitPacker_t *ld, unsigned int code, unsigned int length)
{ {
unsigned int bit_buf; unsigned int bit_buf;
unsigned int bit_left; unsigned int bit_left;
bit_buf = ld->BitBuffer; bit_buf = ld->BitBuffer;
bit_left = ld->Remaining; bit_left = ld->Remaining;
#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", code, length, bit_buf, bit_left);
#endif /* DEBUG_PUTBITS */ #endif /* DEBUG_PUTBITS */
if (length < bit_left) if (length < bit_left)
{ {
/* fits into current buffer */ /* fits into current buffer */
@@ -96,10 +99,12 @@ void PutBits(BitPacker_t *ld, unsigned int code, unsigned int length)
bit_left = 32 - length; bit_left = 32 - length;
bit_buf = code; 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;
ld->Remaining = bit_left; ld->Remaining = bit_left;

View File

@@ -57,6 +57,7 @@
/* Types */ /* Types */
/* ***************************** */ /* ***************************** */
/* ***************************** */ /* ***************************** */
/* Varaibles */ /* Varaibles */
/* ***************************** */ /* ***************************** */
@@ -73,25 +74,32 @@ int32_t InsertVideoPrivateDataHeader(uint8_t *data, int32_t payload_size)
{ {
BitPacker_t ld2 = {data, 0, 32}; BitPacker_t ld2 = {data, 0, 32};
int32_t i = 0; int32_t i = 0;
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;
} }
int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t pts, int32_t pic_start_code) int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t pts, int32_t pic_start_code)
{ {
BitPacker_t ld2 = {data, 0, 32}; BitPacker_t ld2 = {data, 0, 32};
if (size > (MAX_PES_PACKET_SIZE - 13)) if (size > (MAX_PES_PACKET_SIZE - 13))
{ {
size = -1; // unbounded size = -1; // 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
@@ -113,6 +121,7 @@ int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t
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);
@@ -121,6 +130,7 @@ int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t
{ {
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
@@ -128,6 +138,7 @@ int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t
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);
@@ -137,6 +148,7 @@ int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t
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);
@@ -148,6 +160,7 @@ int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t
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);
@@ -157,6 +170,8 @@ int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t
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);
return (ld2.Ptr - data); return (ld2.Ptr - data);
} }

View File

@@ -143,7 +143,7 @@ LATMContext *pLATMCtx = NULL;
/* ***************************** */ /* ***************************** */
/* ***************************** */ /* ***************************** */
/* Functions */ /* MISC Functions */
/* ***************************** */ /* ***************************** */
static int reset() static int reset()
@@ -159,16 +159,19 @@ static int reset()
static int _writeData(WriterAVCallData_t *call, int type) static int _writeData(WriterAVCallData_t *call, int type)
{ {
aac_printf(10, "\n _writeData type[%d]\n", type); aac_printf(10, "\n _writeData type[%d]\n", type);
if (call == NULL) if (call == NULL)
{ {
aac_err("call data is NULL...\n"); aac_err("call data is NULL...\n");
return 0; return 0;
} }
if ((call->data == NULL) || (call->len < 8)) if ((call->data == NULL) || (call->len < 8))
{ {
aac_err("parsing Data with missing AAC header. ignoring...\n"); aac_err("parsing Data with missing AAC header. ignoring...\n");
return 0; return 0;
} }
/* simple validation */ /* simple validation */
if (0 == type) // check ADTS header if (0 == type) // check ADTS header
{ {
@@ -195,9 +198,13 @@ static int _writeData(WriterAVCallData_t *call, int type)
return 0; return 0;
} }
} }
unsigned char PesHeader[PES_MAX_HEADER_SIZE]; unsigned char PesHeader[PES_MAX_HEADER_SIZE];
aac_printf(10, "AudioPts %lld\n", call->Pts); aac_printf(10, "AudioPts %lld\n", call->Pts);
unsigned int HeaderLength = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); unsigned int HeaderLength = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
struct iovec iov[2]; struct iovec iov[2];
iov[0].iov_base = PesHeader; iov[0].iov_base = PesHeader;
iov[0].iov_len = HeaderLength; iov[0].iov_len = HeaderLength;
@@ -209,31 +216,37 @@ static int _writeData(WriterAVCallData_t *call, int type)
static int writeDataADTS(WriterAVCallData_t *call) static int writeDataADTS(WriterAVCallData_t *call)
{ {
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;
} }
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 && 0 == strncmp("ADTS", (const char *)call->private_data, call->private_size)) || if ((call->private_data && 0 == strncmp("ADTS", (const char *)call->private_data, call->private_size)) ||
HasADTSHeader(call->data, call->len)) HasADTSHeader(call->data, call->len))
{ {
//printf("%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx\n", call->data[0], call->data[1], call->data[2], call->data[3], call->data[4], call->data[5], call->data[6], call->data[7]); //printf("%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx\n", call->data[0], call->data[1], call->data[2], call->data[3], call->data[4], call->data[5], call->data[6], call->data[7]);
return _writeData(call, 0); return _writeData(call, 0);
} }
uint32_t PacketLength = call->len + AAC_HEADER_LENGTH; uint32_t PacketLength = call->len + AAC_HEADER_LENGTH;
uint8_t PesHeader[PES_MAX_HEADER_SIZE + AAC_HEADER_LENGTH]; uint8_t PesHeader[PES_MAX_HEADER_SIZE + AAC_HEADER_LENGTH];
uint32_t headerSize = InsertPesHeader(PesHeader, PacketLength, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); uint32_t headerSize = InsertPesHeader(PesHeader, PacketLength, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
uint8_t *pExtraData = &PesHeader[headerSize]; uint8_t *pExtraData = &PesHeader[headerSize];
aac_printf(10, "AudioPts %lld\n", call->Pts); aac_printf(10, "AudioPts %lld\n", call->Pts);
if (call->private_data == NULL) if (call->private_data == NULL)
{ {
@@ -244,6 +257,7 @@ static int writeDataADTS(WriterAVCallData_t *call)
{ {
memcpy(pExtraData, call->private_data, AAC_HEADER_LENGTH); memcpy(pExtraData, call->private_data, AAC_HEADER_LENGTH);
} }
pExtraData[3] &= 0xC0; pExtraData[3] &= 0xC0;
/* frame size over last 2 bits */ /* frame size over last 2 bits */
pExtraData[3] |= (PacketLength & 0x1800) >> 11; pExtraData[3] |= (PacketLength & 0x1800) >> 11;
@@ -256,33 +270,41 @@ static int writeDataADTS(WriterAVCallData_t *call)
/* buffer fullness(0x7FF for VBR) continued over 6 first bits + 2 zeros for /* buffer fullness(0x7FF for VBR) continued over 6 first bits + 2 zeros for
* number of raw data blocks */ * number of raw data blocks */
pExtraData[6] = 0xFC; pExtraData[6] = 0xFC;
//PesHeader[6] = 0x81; //PesHeader[6] = 0x81;
struct iovec iov[2]; struct iovec iov[2];
iov[0].iov_base = PesHeader; iov[0].iov_base = PesHeader;
iov[0].iov_len = headerSize + AAC_HEADER_LENGTH; iov[0].iov_len = headerSize + AAC_HEADER_LENGTH;
iov[1].iov_base = call->data; iov[1].iov_base = call->data;
iov[1].iov_len = call->len; iov[1].iov_len = call->len;
return call->WriteV(call->fd, iov, 2); return call->WriteV(call->fd, iov, 2);
} }
static int writeDataLATM(WriterAVCallData_t *call) static int writeDataLATM(WriterAVCallData_t *call)
{ {
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;
} }
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->private_data && 0 == strncmp("LATM", (const char *)call->private_data, call->private_size)) if (call->private_data && 0 == strncmp("LATM", (const char *)call->private_data, call->private_size))
{ {
return _writeData(call, 1); return _writeData(call, 1);
} }
aac_printf(10, "AudioPts %lld\n", call->Pts); aac_printf(10, "AudioPts %lld\n", call->Pts);
if (!pLATMCtx) if (!pLATMCtx)
{ {
pLATMCtx = malloc(sizeof(LATMContext)); pLATMCtx = malloc(sizeof(LATMContext));
@@ -290,11 +312,13 @@ static int writeDataLATM(WriterAVCallData_t *call)
pLATMCtx->mod = 14; pLATMCtx->mod = 14;
pLATMCtx->counter = 0; pLATMCtx->counter = 0;
} }
if (!pLATMCtx) if (!pLATMCtx)
{ {
aac_err("parsing NULL pLATMCtx. ignoring...\n"); aac_err("parsing NULL pLATMCtx. ignoring...\n");
return 0; return 0;
} }
unsigned char PesHeader[PES_MAX_HEADER_SIZE]; unsigned char PesHeader[PES_MAX_HEADER_SIZE];
int ret = latmenc_decode_extradata(pLATMCtx, call->private_data, call->private_size); int ret = latmenc_decode_extradata(pLATMCtx, call->private_data, call->private_size);
if (ret) if (ret)
@@ -310,14 +334,19 @@ static int writeDataLATM(WriterAVCallData_t *call)
aac_err("latm_write_packet failed. ignoring...\n"); aac_err("latm_write_packet failed. ignoring...\n");
return 0; return 0;
} }
unsigned int HeaderLength = InsertPesHeader(PesHeader, pLATMCtx->len + 3, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); unsigned int HeaderLength = InsertPesHeader(PesHeader, pLATMCtx->len + 3, MPEG_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;
iov[0].iov_len = HeaderLength; iov[0].iov_len = HeaderLength;
iov[1].iov_base = pLATMCtx->loas_header; iov[1].iov_base = pLATMCtx->loas_header;
iov[1].iov_len = 3; iov[1].iov_len = 3;
iov[2].iov_base = pLATMCtx->buffer; iov[2].iov_base = pLATMCtx->buffer;
iov[2].iov_len = pLATMCtx->len; iov[2].iov_len = pLATMCtx->len;
return call->WriteV(call->fd, iov, 3); return call->WriteV(call->fd, iov, 3);
} }

View File

@@ -98,34 +98,45 @@ static int reset()
static int writeData(WriterAVCallData_t *call) static int writeData(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[3]; struct iovec iov[3];
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); //+ sizeof(AC3_SYNC_HEADER) iov[0].iov_len = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); //+ sizeof(AC3_SYNC_HEADER)
//PesHeader[6] = 0x81; //PesHeader[6] = 0x81;
//PesHeader[7] = 0x80; //PesHeader[7] = 0x80;
//PesHeader[8] = 0x09; //PesHeader[8] = 0x09;
//iov[1].iov_base = AC3_SYNC_HEADER; //iov[1].iov_base = AC3_SYNC_HEADER;
//iov[1].iov_len = sizeof(AC3_SYNC_HEADER); //iov[1].iov_len = sizeof(AC3_SYNC_HEADER);
iov[1].iov_base = call->data; iov[1].iov_base = call->data;
iov[1].iov_len = call->len; iov[1].iov_len = call->len;
ac3_printf(40, "PES HEADER LEN %d\n", iov[0].iov_len); ac3_printf(40, "PES HEADER LEN %d\n", iov[0].iov_len);
return call->WriteV(call->fd, iov, 2); return call->WriteV(call->fd, iov, 2);
} }

View File

@@ -99,23 +99,29 @@ static int reset()
static int writeData(WriterAVCallData_t *call) static int writeData(WriterAVCallData_t *call)
{ {
unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4 + 9]; unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4 + 9];
amr_printf(10, "\n"); amr_printf(10, "\n");
if (call == NULL) if (call == NULL)
{ {
amr_err("call data is NULL...\n"); amr_err("call data is NULL...\n");
return 0; return 0;
} }
amr_printf(10, "AudioPts %lld\n", call->Pts); amr_printf(10, "AudioPts %lld\n", call->Pts);
if ((call->data == NULL) || (call->len <= 0)) if ((call->data == NULL) || (call->len <= 0))
{ {
amr_err("parsing NULL Data. ignoring...\n"); amr_err("parsing NULL Data. ignoring...\n");
return 0; return 0;
} }
if (call->fd < 0) if (call->fd < 0)
{ {
amr_err("file pointer < 0. ignoring ...\n"); amr_err("file pointer < 0. ignoring ...\n");
return 0; return 0;
} }
uint8_t hasCodecData = 1; uint8_t hasCodecData = 1;
if (NULL != call->private_data && call->private_size >= 17) if (NULL != call->private_data && call->private_size >= 17)
{ {
@@ -128,11 +134,13 @@ static int writeData(WriterAVCallData_t *call)
payload_len += 9; payload_len += 9;
} }
payload_len += 4; payload_len += 4;
uint32_t headerSize = InsertPesHeader(PesHeader, payload_len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); uint32_t headerSize = InsertPesHeader(PesHeader, payload_len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
PesHeader[headerSize++] = (payload_len >> 24) & 0xff; PesHeader[headerSize++] = (payload_len >> 24) & 0xff;
PesHeader[headerSize++] = (payload_len >> 16) & 0xff; PesHeader[headerSize++] = (payload_len >> 16) & 0xff;
PesHeader[headerSize++] = (payload_len >> 8) & 0xff; PesHeader[headerSize++] = (payload_len >> 8) & 0xff;
PesHeader[headerSize++] = payload_len & 0xff; PesHeader[headerSize++] = payload_len & 0xff;
if (hasCodecData) if (hasCodecData)
{ {
uint8_t tmp[] = {0x45, 0x4d, 0x50, 0x20, 0x00, 0x00, 0x80, 0x00, 0x01}; uint8_t tmp[] = {0x45, 0x4d, 0x50, 0x20, 0x00, 0x00, 0x80, 0x00, 0x01};
@@ -140,12 +148,15 @@ static int writeData(WriterAVCallData_t *call)
//memcpy(&PesHeader[headerSize], call->private_data + 8, 9); //memcpy(&PesHeader[headerSize], call->private_data + 8, 9);
//memset(&PesHeader[headerSize], 0, 9); //memset(&PesHeader[headerSize], 0, 9);
} }
struct iovec iov[2]; struct iovec iov[2];
iov[0].iov_base = PesHeader; iov[0].iov_base = PesHeader;
iov[0].iov_len = headerSize; iov[0].iov_len = headerSize;
iov[1].iov_base = call->data; iov[1].iov_base = call->data;
iov[1].iov_len = call->len; iov[1].iov_len = call->len;
int len = call->WriteV(call->fd, iov, 2); int len = call->WriteV(call->fd, iov, 2);
amr_printf(10, "amr_Write-< len=%d\n", len); amr_printf(10, "amr_Write-< len=%d\n", len);
return len; return len;
} }

View File

@@ -118,25 +118,32 @@ static int writeData(WriterAVCallData_t *call)
unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4]; unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4];
// unsigned char Version = 5; // unsigned char Version = 5;
// unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE; // unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE;
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);
struct iovec iov[8]; struct iovec iov[8];
int ic = 0; int ic = 0;
if (initialHeader) if (initialHeader)
{ {
initialHeader = 0; initialHeader = 0;
@@ -151,11 +158,14 @@ static int writeData(WriterAVCallData_t *call)
data[2] = B_GET_BITS(height, 9, 2); data[2] = B_GET_BITS(height, 9, 2);
data[3] = B_SET_BITS("height [1.0]", B_GET_BITS(height, 1, 0), 7, 6) | data[3] = B_SET_BITS("height [1.0]", B_GET_BITS(height, 1, 0), 7, 6) |
B_SET_BITS("'100000'", 0x20, 5, 0); B_SET_BITS("'100000'", 0x20, 5, 0);
iov[ic].iov_base = brcm_divx311_sequence_header; iov[ic].iov_base = brcm_divx311_sequence_header;
iov[ic++].iov_len = sizeof(brcm_divx311_sequence_header); iov[ic++].iov_len = sizeof(brcm_divx311_sequence_header);
} }
iov[ic].iov_base = PesHeader; iov[ic].iov_base = PesHeader;
uint32_t headerSize = 0; uint32_t headerSize = 0;
if (memcmp(call->data, "\x00\x00\x01\xb6", 4)) if (memcmp(call->data, "\x00\x00\x01\xb6", 4))
{ {
headerSize = InsertPesHeader(PesHeader, call->len + 4, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); headerSize = InsertPesHeader(PesHeader, call->len + 4, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
@@ -167,10 +177,14 @@ static int writeData(WriterAVCallData_t *call)
headerSize = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); headerSize = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
} }
iov[ic++].iov_len = headerSize; iov[ic++].iov_len = headerSize;
iov[ic].iov_base = call->data; iov[ic].iov_base = call->data;
iov[ic++].iov_len = call->len; iov[ic++].iov_len = call->len;
int len = call->WriteV(call->fd, iov, ic);
int len = call->WriteV(call->fd, iov, ic);
divx_printf(10, "xvid_Write < len=%d\n", len); divx_printf(10, "xvid_Write < len=%d\n", len);
return len; return len;
} }

View File

@@ -103,25 +103,32 @@ static int32_t reset()
static int writeData(WriterAVCallData_t *call) static int writeData(WriterAVCallData_t *call)
{ {
uint8_t PesHeader[PES_AUDIO_HEADER_SIZE]; uint8_t 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;
} }
uint8_t *Data = call->data; uint8_t *Data = call->data;
int32_t Size = call->len; int32_t Size = call->len;
#ifdef CHECK_FOR_DTS_HD #ifdef CHECK_FOR_DTS_HD
int32_t pos = 0; int32_t pos = 0;
while ((pos + 4) <= Size) while ((pos + 4) <= Size)
@@ -135,6 +142,7 @@ static int writeData(WriterAVCallData_t *call)
++pos; ++pos;
} }
#endif #endif
// #define DO_BYTESWAP // #define DO_BYTESWAP
#ifdef DO_BYTESWAP #ifdef DO_BYTESWAP
/* 16-bit byte swap all data before injecting it */ /* 16-bit byte swap all data before injecting it */
@@ -145,11 +153,13 @@ static int writeData(WriterAVCallData_t *call)
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, Size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); iov[0].iov_len = InsertPesHeader(PesHeader, Size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
iov[1].iov_base = Data; iov[1].iov_base = Data;
iov[1].iov_len = Size; iov[1].iov_len = Size;
int32_t len = call->WriteV(call->fd, iov, 2); int32_t len = call->WriteV(call->fd, iov, 2);
dts_printf(10, "< len %d\n", len); dts_printf(10, "< len %d\n", len);
return len; return len;

View File

@@ -95,37 +95,46 @@ static int writeData(WriterAVCallData_t *call)
{ {
uint8_t PesHeader[PES_MAX_HEADER_SIZE]; uint8_t PesHeader[PES_MAX_HEADER_SIZE];
int32_t len = 0; int32_t 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;
} }
int32_t HeaderLength = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); int32_t HeaderLength = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
int32_t PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], call->len); int32_t PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], call->len);
int32_t PesLength = PesHeader[PES_LENGTH_BYTE_0] + (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength; int32_t 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;
iov[0].iov_len = HeaderLength; iov[0].iov_len = HeaderLength;
iov[1].iov_base = call->data; iov[1].iov_base = call->data;
iov[1].iov_len = call->len; iov[1].iov_len = call->len;
len = call->WriteV(call->fd, iov, 2); len = call->WriteV(call->fd, iov, 2);
h263_printf(10, "< len %d\n", len); h263_printf(10, "< len %d\n", len);
return len; return len;
} }

View File

@@ -103,34 +103,45 @@ static int sps_pps_in_stream = 0;
static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize, uint8_t *pData, uint32_t dataSize) static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize, uint8_t *pData, uint32_t dataSize)
{ {
uint8_t *aExtraData = *ppExtraData; uint8_t *aExtraData = *ppExtraData;
if (aExtraData[0] != 1 || !pData) if (aExtraData[0] != 1 || !pData)
{ {
// Not AVCC or nothing to update with. // Not AVCC or nothing to update with.
return -1; return -1;
} }
int32_t nalsize = (aExtraData[4] & 3) + 1; int32_t nalsize = (aExtraData[4] & 3) + 1;
uint8_t sps[256]; uint8_t sps[256];
uint8_t spsIdx = 0; uint8_t spsIdx = 0;
uint8_t numSps = 0; uint8_t numSps = 0;
uint8_t pps[256]; uint8_t pps[256];
uint8_t ppsIdx = 0; uint8_t ppsIdx = 0;
uint8_t numPps = 0; uint8_t numPps = 0;
if (nalsize != 4) if (nalsize != 4)
{ {
return -1; return -1;
} }
// Find SPS and PPS NALUs in AVCC data // Find SPS and PPS NALUs in AVCC data
uint8_t *d = pData; uint8_t *d = pData;
while (d + 4 < pData + dataSize) while (d + 4 < pData + dataSize)
{ {
uint32_t nalLen = ReadUint32(d); uint32_t nalLen = ReadUint32(d);
uint8_t nalType = d[4] & 0x1f; uint8_t nalType = d[4] & 0x1f;
if (nalType == 7) if (nalType == 7)
{ {
/* SPS */ /* SPS */
// 16 bits size // 16 bits size
sps[spsIdx++] = (uint8_t)(0xFF & (nalLen >> 8)); sps[spsIdx++] = (uint8_t)(0xFF & (nalLen >> 8));
sps[spsIdx++] = (uint8_t)(0xFF & nalLen); sps[spsIdx++] = (uint8_t)(0xFF & nalLen);
if (spsIdx + nalLen >= sizeof(sps)) if (spsIdx + nalLen >= sizeof(sps))
{ {
h264_err("SPS no free space to copy...\n"); h264_err("SPS no free space to copy...\n");
@@ -138,15 +149,19 @@ static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize,
} }
memcpy(&(sps[spsIdx]), d + 4, nalLen); memcpy(&(sps[spsIdx]), d + 4, nalLen);
spsIdx += nalLen; spsIdx += nalLen;
numSps += 1; numSps += 1;
h264_printf(10, "SPS len[%u]...\n", nalLen); h264_printf(10, "SPS len[%u]...\n", nalLen);
} }
else if (nalType == 8) else if (nalType == 8)
{ {
/* PPS */ /* PPS */
// 16 bits size // 16 bits size
pps[ppsIdx++] = (uint8_t)(0xFF & (nalLen >> 8)); pps[ppsIdx++] = (uint8_t)(0xFF & (nalLen >> 8));
pps[ppsIdx++] = (uint8_t)(0xFF & nalLen); pps[ppsIdx++] = (uint8_t)(0xFF & nalLen);
if (ppsIdx + nalLen >= sizeof(sps)) if (ppsIdx + nalLen >= sizeof(sps))
{ {
h264_err("PPS not free space to copy...\n"); h264_err("PPS not free space to copy...\n");
@@ -154,7 +169,9 @@ static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize,
} }
memcpy(&(pps[ppsIdx]), d + 4, nalLen); memcpy(&(pps[ppsIdx]), d + 4, nalLen);
ppsIdx += nalLen; ppsIdx += nalLen;
numPps += 1; numPps += 1;
h264_printf(10, "PPS len[%u]...\n", nalLen); h264_printf(10, "PPS len[%u]...\n", nalLen);
} }
d += 4 + nalLen; d += 4 + nalLen;
@@ -167,18 +184,21 @@ static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize,
aExtraData[idx++] = sps[4]; // profile compat aExtraData[idx++] = sps[4]; // profile compat
aExtraData[idx++] = sps[5]; // level aExtraData[idx++] = sps[5]; // level
aExtraData[idx++] = 0xff; // nal size - 1 aExtraData[idx++] = 0xff; // nal size - 1
aExtraData[idx++] = 0xe0 | numSps; aExtraData[idx++] = 0xe0 | numSps;
if (numSps) if (numSps)
{ {
memcpy(&(aExtraData[idx]), sps, spsIdx); memcpy(&(aExtraData[idx]), sps, spsIdx);
idx += spsIdx; idx += spsIdx;
} }
aExtraData[idx++] = numPps; aExtraData[idx++] = numPps;
if (numPps) if (numPps)
{ {
memcpy(&(aExtraData[idx]), pps, ppsIdx); memcpy(&(aExtraData[idx]), pps, ppsIdx);
idx += ppsIdx; idx += ppsIdx;
} }
h264_printf(10, "aExtraData len[%u]...\n", idx); h264_printf(10, "aExtraData len[%u]...\n", idx);
*pExtraDataSize = idx; *pExtraDataSize = idx;
return 0; return 0;
@@ -192,6 +212,7 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne
{ {
unsigned char tmp[2048]; unsigned char tmp[2048];
unsigned int tmp_len = 0; unsigned int tmp_len = 0;
unsigned int cd_pos = 0; unsigned int cd_pos = 0;
h264_printf(10, "H264 have codec data..!\n"); h264_printf(10, "H264 have codec data..!\n");
if (cd_len > 7 && data[0] == 1) if (cd_len > 7 && data[0] == 1)
@@ -238,9 +259,11 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne
tmp_len += 4; tmp_len += 4;
memcpy(tmp + tmp_len, data + cd_pos, len); memcpy(tmp + tmp_len, data + cd_pos, len);
tmp_len += len; tmp_len += len;
CodecData = malloc(tmp_len); CodecData = malloc(tmp_len);
memcpy(CodecData, tmp, tmp_len); memcpy(CodecData, tmp, tmp_len);
CodecDataLen = tmp_len; CodecDataLen = tmp_len;
*NalLength = (data[4] & 0x03) + 1; *NalLength = (data[4] & 0x03) + 1;
ret = 0; ret = 0;
} }
@@ -297,28 +320,34 @@ static int writeData(WriterAVCallData_t *call)
int ic = 0; int ic = 0;
struct iovec iov[IOVEC_SIZE]; struct iovec iov[IOVEC_SIZE];
h264_printf(20, "\n"); h264_printf(20, "\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;
/* avoid compiler warnings */ /* avoid compiler warnings */
if (TimeDelta) {} if (TimeDelta) {}
if (TimeScale) {} if (TimeScale) {}
VideoPts = call->Pts; VideoPts = call->Pts;
h264_printf(20, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale); h264_printf(20, "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;
} }
/* AnnexA */ /* AnnexA */
if (!avc3 && ((1 < call->private_size && 0 == call->private_data[0]) || if (!avc3 && ((1 < call->private_size && 0 == call->private_data[0]) ||
((call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) || ((call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) ||
@@ -329,6 +358,7 @@ static int writeData(WriterAVCallData_t *call)
uint32_t PacketLength = 0; uint32_t PacketLength = 0;
uint32_t FakeStartCode = (call->Version << 8) | PES_VERSION_FAKE_START_CODE; uint32_t FakeStartCode = (call->Version << 8) | PES_VERSION_FAKE_START_CODE;
iov[ic++].iov_base = PesHeader; iov[ic++].iov_base = PesHeader;
while (InsertPrivData && i < 36 && (call->len - i) > 5) while (InsertPrivData && i < 36 && (call->len - i) > 5)
{ {
if ((call->data[i] == 0x00 && call->data[i + 1] == 0x00 && call->data[i + 2] == 0x00 && call->data[i + 3] == 0x01 && (call->data[i + 4] == 0x67 || call->data[i + 4] == 0x68))) if ((call->data[i] == 0x00 && call->data[i + 1] == 0x00 && call->data[i + 2] == 0x00 && call->data[i + 3] == 0x01 && (call->data[i + 4] == 0x67 || call->data[i + 4] == 0x68)))
@@ -338,6 +368,7 @@ static int writeData(WriterAVCallData_t *call)
} }
i += 1; i += 1;
} }
if (InsertPrivData && call->private_size > 0 /*&& initialHeader*/) // some rtsp streams can update codec data at runtime if (InsertPrivData && call->private_size > 0 /*&& initialHeader*/) // some rtsp streams can update codec data at runtime
{ {
initialHeader = 0; initialHeader = 0;
@@ -345,10 +376,13 @@ static int writeData(WriterAVCallData_t *call)
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;
iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode); iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode);
return call->WriteV(call->fd, iov, ic); return call->WriteV(call->fd, iov, ic);
} }
else if (!call->private_data || call->private_size < 7 || 1 != call->private_data[0]) else if (!call->private_data || call->private_size < 7 || 1 != call->private_data[0])
@@ -356,9 +390,12 @@ static int writeData(WriterAVCallData_t *call)
h264_err("No valid private data available! [%d]\n", (int)call->private_size); h264_err("No valid private data available! [%d]\n", (int)call->private_size);
return 0; return 0;
} }
uint32_t PacketLength = 0; uint32_t PacketLength = 0;
ic = 0; ic = 0;
iov[ic++].iov_base = PesHeader; iov[ic++].iov_base = PesHeader;
//if (initialHeader) //if (initialHeader)
{ {
if (CodecData) if (CodecData)
@@ -366,19 +403,23 @@ static int writeData(WriterAVCallData_t *call)
free(CodecData); free(CodecData);
CodecData = NULL; CodecData = NULL;
} }
uint8_t *private_data = call->private_data; uint8_t *private_data = call->private_data;
uint32_t private_size = call->private_size; uint32_t private_size = call->private_size;
if (PreparCodecData(private_data, private_size, &NalLengthBytes)) if (PreparCodecData(private_data, private_size, &NalLengthBytes))
{ {
UpdateExtraData(&private_data, &private_size, call->data, call->len); UpdateExtraData(&private_data, &private_size, call->data, call->len);
PreparCodecData(private_data, private_size, &NalLengthBytes); PreparCodecData(private_data, private_size, &NalLengthBytes);
} }
if (private_data != call->private_data) if (private_data != call->private_data)
{ {
avc3 = 1; avc3 = 1;
free(private_data); free(private_data);
private_data = NULL; private_data = NULL;
} }
if (CodecData != NULL) if (CodecData != NULL)
{ {
iov[ic].iov_base = CodecData; iov[ic].iov_base = CodecData;
@@ -387,6 +428,7 @@ static int writeData(WriterAVCallData_t *call)
initialHeader = 0; initialHeader = 0;
} }
} }
if (CodecData != NULL) if (CodecData != NULL)
{ {
uint32_t pos = 0; uint32_t pos = 0;
@@ -397,6 +439,7 @@ static int writeData(WriterAVCallData_t *call)
h264_err(">> Drop data due to ic overflow\n"); h264_err(">> Drop data due to ic overflow\n");
break; break;
} }
uint32_t pack_len = 0; uint32_t pack_len = 0;
uint32_t i = 0; uint32_t i = 0;
for (i = 0; i < NalLengthBytes; i++, pos++) for (i = 0; i < NalLengthBytes; i++, pos++)
@@ -404,21 +447,28 @@ static int writeData(WriterAVCallData_t *call)
pack_len <<= 8; pack_len <<= 8;
pack_len += call->data[pos]; pack_len += call->data[pos];
} }
if ((pos + pack_len) > call->len) if ((pos + pack_len) > call->len)
{ {
pack_len = call->len - pos; pack_len = call->len - pos;
} }
iov[ic].iov_base = Head; iov[ic].iov_base = Head;
iov[ic++].iov_len = sizeof(Head); iov[ic++].iov_len = sizeof(Head);
PacketLength += sizeof(Head); PacketLength += sizeof(Head);
iov[ic].iov_base = call->data + pos; iov[ic].iov_base = call->data + pos;
iov[ic++].iov_len = pack_len; iov[ic++].iov_len = pack_len;
PacketLength += pack_len; PacketLength += pack_len;
pos += pack_len; pos += pack_len;
} }
while ((pos + NalLengthBytes) < call->len); while ((pos + NalLengthBytes) < call->len);
h264_printf(10, "<<<< PacketLength [%d]\n", PacketLength); h264_printf(10, "<<<< PacketLength [%d]\n", PacketLength);
iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, 0); iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, 0);
len = call->WriteV(call->fd, iov, ic); len = call->WriteV(call->fd, iov, ic);
PacketLength += iov[0].iov_len; PacketLength += iov[0].iov_len;
if (PacketLength != len) if (PacketLength != len)
@@ -426,6 +476,7 @@ static int writeData(WriterAVCallData_t *call)
h264_err("<<<< not all data have been written [%d/%d]\n", len, PacketLength); h264_err("<<<< not all data have been written [%d/%d]\n", len, PacketLength);
} }
} }
h264_printf(10, "< len %d\n", len); h264_printf(10, "< len %d\n", len);
return len; return len;
} }

View File

@@ -105,7 +105,9 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne
{ {
unsigned char tmp[2048]; unsigned char tmp[2048];
unsigned int tmp_len = 0; unsigned int tmp_len = 0;
h264_printf(10, "H265 have codec data..!"); h264_printf(10, "H265 have codec data..!");
if (cd_len > 3 && (data[0] || data[1] || data[2] > 1)) if (cd_len > 3 && (data[0] || data[1] || data[2] > 1))
{ {
if (cd_len > 22) if (cd_len > 22)
@@ -115,6 +117,7 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne
{ {
h264_printf(10, "Unsupported extra data version %d, decoding may fail", (int)data[0]); h264_printf(10, "Unsupported extra data version %d, decoding may fail", (int)data[0]);
} }
*NalLength = (data[21] & 3) + 1; *NalLength = (data[21] & 3) + 1;
int num_param_sets = data[22]; int num_param_sets = data[22];
uint32_t pos = 23; uint32_t pos = 23;
@@ -150,6 +153,7 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne
pos += nal_size; pos += nal_size;
} }
} }
CodecData = malloc(tmp_len); CodecData = malloc(tmp_len);
memcpy(CodecData, tmp, tmp_len); memcpy(CodecData, tmp, tmp_len);
CodecDataLen = tmp_len; CodecDataLen = tmp_len;
@@ -160,6 +164,7 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne
{ {
*NalLength = 0; *NalLength = 0;
} }
return ret; return ret;
} }
@@ -179,33 +184,40 @@ static int writeData(WriterAVCallData_t *call)
int ic = 0; int ic = 0;
struct iovec iov[IOVEC_SIZE]; struct iovec iov[IOVEC_SIZE];
h264_printf(20, "\n"); h264_printf(20, "\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;
/* avoid compiler warnings */ /* avoid compiler warnings */
if (TimeDelta) {} if (TimeDelta) {}
if (TimeScale) {} if (TimeScale) {}
VideoPts = call->Pts; VideoPts = call->Pts;
h264_printf(20, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale); h264_printf(20, "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->InfoFlags & 0x1) // TS container if (call->InfoFlags & 0x1) // TS container
{ {
h264_printf(10, "H265 simple inject method!\n"); h264_printf(10, "H265 simple inject method!\n");
uint32_t PacketLength = 0; uint32_t PacketLength = 0;
uint32_t FakeStartCode = (call->Version << 8) | PES_VERSION_FAKE_START_CODE; uint32_t FakeStartCode = (call->Version << 8) | PES_VERSION_FAKE_START_CODE;
iov[ic++].iov_base = PesHeader; iov[ic++].iov_base = PesHeader;
initialHeader = 0; initialHeader = 0;
if (initialHeader) if (initialHeader)
@@ -215,17 +227,24 @@ static int writeData(WriterAVCallData_t *call)
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 = ""; iov[ic].iov_base = "";
iov[ic++].iov_len = 1; iov[ic++].iov_len = 1;
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;
iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode); iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode);
return call->WriteV(call->fd, iov, ic); return call->WriteV(call->fd, iov, ic);
} }
uint32_t PacketLength = 0; uint32_t PacketLength = 0;
ic = 0; ic = 0;
iov[ic++].iov_base = PesHeader; iov[ic++].iov_base = PesHeader;
if (initialHeader) if (initialHeader)
{ {
if (CodecData) if (CodecData)
@@ -233,9 +252,12 @@ static int writeData(WriterAVCallData_t *call)
free(CodecData); free(CodecData);
CodecData = NULL; CodecData = NULL;
} }
uint8_t *private_data = call->private_data; uint8_t *private_data = call->private_data;
uint32_t private_size = call->private_size; uint32_t private_size = call->private_size;
PreparCodecData(private_data, private_size, &NalLengthBytes); PreparCodecData(private_data, private_size, &NalLengthBytes);
if (CodecData != NULL) if (CodecData != NULL)
{ {
iov[ic].iov_base = CodecData; iov[ic].iov_base = CodecData;
@@ -244,6 +266,7 @@ static int writeData(WriterAVCallData_t *call)
initialHeader = 0; initialHeader = 0;
} }
} }
if (CodecData != NULL) if (CodecData != NULL)
{ {
uint32_t pos = 0; uint32_t pos = 0;
@@ -254,6 +277,7 @@ static int writeData(WriterAVCallData_t *call)
h264_err(">> Drop data due to ic overflow\n"); h264_err(">> Drop data due to ic overflow\n");
break; break;
} }
uint32_t pack_len = 0; uint32_t pack_len = 0;
uint32_t i = 0; uint32_t i = 0;
for (i = 0; i < NalLengthBytes; i++, pos++) for (i = 0; i < NalLengthBytes; i++, pos++)
@@ -261,21 +285,28 @@ static int writeData(WriterAVCallData_t *call)
pack_len <<= 8; pack_len <<= 8;
pack_len += call->data[pos]; pack_len += call->data[pos];
} }
if ((pos + pack_len) > call->len) if ((pos + pack_len) > call->len)
{ {
pack_len = call->len - pos; pack_len = call->len - pos;
} }
iov[ic].iov_base = Head; iov[ic].iov_base = Head;
iov[ic++].iov_len = sizeof(Head); iov[ic++].iov_len = sizeof(Head);
PacketLength += sizeof(Head); PacketLength += sizeof(Head);
iov[ic].iov_base = call->data + pos; iov[ic].iov_base = call->data + pos;
iov[ic++].iov_len = pack_len; iov[ic++].iov_len = pack_len;
PacketLength += pack_len; PacketLength += pack_len;
pos += pack_len; pos += pack_len;
} }
while ((pos + NalLengthBytes) < call->len); while ((pos + NalLengthBytes) < call->len);
h264_printf(10, "<<<< PacketLength [%d]\n", PacketLength); h264_printf(10, "<<<< PacketLength [%d]\n", PacketLength);
iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, 0); iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, 0);
len = call->WriteV(call->fd, iov, ic); len = call->WriteV(call->fd, iov, ic);
PacketLength += iov[0].iov_len; PacketLength += iov[0].iov_len;
if (PacketLength != len) if (PacketLength != len)
@@ -283,6 +314,7 @@ static int writeData(WriterAVCallData_t *call)
h264_err("<<<< not all data have been written [%d/%d]\n", len, PacketLength); h264_err("<<<< not all data have been written [%d/%d]\n", len, PacketLength);
} }
} }
h264_printf(10, "< len %d\n", len); h264_printf(10, "< len %d\n", len);
return len; return len;
} }

View File

@@ -59,7 +59,6 @@
/* ***************************** */ /* ***************************** */
//#define SAM_WITH_DEBUG //#define SAM_WITH_DEBUG
#ifdef SAM_WITH_DEBUG #ifdef SAM_WITH_DEBUG
#define LPCM_DEBUG #define LPCM_DEBUG
#else #else
@@ -135,23 +134,29 @@ static int32_t reset()
static int writeData(WriterAVCallData_t *call) static int writeData(WriterAVCallData_t *call)
{ {
lpcm_printf(10, "\n"); lpcm_printf(10, "\n");
if (!call) if (!call)
{ {
lpcm_err("call data is NULL...\n"); lpcm_err("call data is NULL...\n");
return 0; return 0;
} }
lpcm_printf(10, "AudioPts %lld\n", call->Pts); lpcm_printf(10, "AudioPts %lld\n", call->Pts);
if (!call->data || (call->len <= 0)) if (!call->data || (call->len <= 0))
{ {
lpcm_err("parsing NULL Data. ignoring...\n"); lpcm_err("parsing NULL Data. ignoring...\n");
return 0; return 0;
} }
if (call->fd < 0) if (call->fd < 0)
{ {
lpcm_err("file pointer < 0. ignoring ...\n"); lpcm_err("file pointer < 0. ignoring ...\n");
return 0; return 0;
} }
pcmPrivateData_t *pcmPrivateData = (pcmPrivateData_t *)call->private_data; pcmPrivateData_t *pcmPrivateData = (pcmPrivateData_t *)call->private_data;
int32_t i_rate = (int32_t)pcmPrivateData->sample_rate; int32_t i_rate = (int32_t)pcmPrivateData->sample_rate;
int32_t i_channels = (int32_t)pcmPrivateData->channels; int32_t i_channels = (int32_t)pcmPrivateData->channels;
int32_t i_nb_samples = call->len / (i_channels * 2); int32_t i_nb_samples = call->len / (i_channels * 2);
@@ -161,6 +166,7 @@ static int writeData(WriterAVCallData_t *call)
lpcm_err("Error DVD LPCM supports a maximum of eight channels i_channels[%d]\n", i_channels); lpcm_err("Error DVD LPCM supports a maximum of eight channels i_channels[%d]\n", i_channels);
return 0; return 0;
} }
if (pcmPrivateData->bResampling || NULL == p_buffer) if (pcmPrivateData->bResampling || NULL == p_buffer)
{ {
lpcm_printf(1, "i_rate: [%d]\n", i_rate); lpcm_printf(1, "i_rate: [%d]\n", i_rate);
@@ -183,6 +189,7 @@ static int writeData(WriterAVCallData_t *call)
lpcm_err("Error DVD LPCM sample_rate not supported [%d]\n", i_rate); lpcm_err("Error DVD LPCM sample_rate not supported [%d]\n", i_rate);
return 0; return 0;
} }
/* In DVD LCPM, a frame is always 150 PTS ticks. */ /* In DVD LCPM, a frame is always 150 PTS ticks. */
i_frame_samples = i_rate * 150 / 90000; i_frame_samples = i_rate * 150 / 90000;
i_frame_size = i_frame_samples * i_channels * 2 + LLPCM_VOB_HEADER_LEN; i_frame_size = i_frame_samples * i_channels * 2 + LLPCM_VOB_HEADER_LEN;
@@ -191,6 +198,7 @@ static int writeData(WriterAVCallData_t *call)
free(p_buffer); free(p_buffer);
} }
p_buffer = malloc(i_frame_samples * i_channels * 16); p_buffer = malloc(i_frame_samples * i_channels * 16);
if (NULL != p_frame_buffer) if (NULL != p_frame_buffer)
{ {
free(p_frame_buffer); free(p_frame_buffer);
@@ -200,9 +208,11 @@ static int writeData(WriterAVCallData_t *call)
i_frame_num = 0; i_frame_num = 0;
i_bitspersample = 16; i_bitspersample = 16;
} }
const int i_num_frames = (i_buffer_used + i_nb_samples) / i_frame_samples; const int i_num_frames = (i_buffer_used + i_nb_samples) / i_frame_samples;
const int i_leftover_samples = (i_buffer_used + i_nb_samples) % i_frame_samples; const int i_leftover_samples = (i_buffer_used + i_nb_samples) % i_frame_samples;
const int i_start_offset = -i_buffer_used; const int i_start_offset = -i_buffer_used;
int32_t i_bytes_consumed = 0; int32_t i_bytes_consumed = 0;
int32_t i = 0; int32_t i = 0;
for (i = 0; i < i_num_frames; ++i) for (i = 0; i < i_num_frames; ++i)
@@ -214,9 +224,11 @@ static int writeData(WriterAVCallData_t *call)
frame[3] = (i_frame_num + i) & 0x1f; /* no emphasis, no mute */ frame[3] = (i_frame_num + i) & 0x1f; /* no emphasis, no mute */
frame[4] = (i_freq_code << 4) | (i_channels - 1); frame[4] = (i_freq_code << 4) | (i_channels - 1);
frame[5] = 0x80; /* neutral dynamic range */ frame[5] = 0x80; /* neutral dynamic range */
const int i_consume_samples = i_frame_samples - i_buffer_used; const int i_consume_samples = i_frame_samples - i_buffer_used;
const int i_kept_bytes = i_buffer_used * i_channels * 2; const int i_kept_bytes = i_buffer_used * i_channels * 2;
const int i_consume_bytes = i_consume_samples * i_channels * 2; const int i_consume_bytes = i_consume_samples * i_channels * 2;
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
memcpy(frame + 6, p_buffer, i_kept_bytes); memcpy(frame + 6, p_buffer, i_kept_bytes);
memcpy(frame + 6 + i_kept_bytes, call->data + i_bytes_consumed, i_consume_bytes); memcpy(frame + 6 + i_kept_bytes, call->data + i_bytes_consumed, i_consume_bytes);
@@ -224,15 +236,20 @@ static int writeData(WriterAVCallData_t *call)
swab(p_buffer, frame + 6, i_kept_bytes); swab(p_buffer, frame + 6, i_kept_bytes);
swab(call->data + i_bytes_consumed, frame + 6 + i_kept_bytes, i_consume_bytes); swab(call->data + i_bytes_consumed, frame + 6 + i_kept_bytes, i_consume_bytes);
#endif #endif
i_frame_num++; i_frame_num++;
i_buffer_used = 0; i_buffer_used = 0;
i_bytes_consumed += i_consume_bytes; i_bytes_consumed += i_consume_bytes;
/* We need to find i_length by means of next_pts due to possible roundoff errors. */ /* We need to find i_length by means of next_pts due to possible roundoff errors. */
uint64_t this_pts = call->Pts + (i * i_frame_samples + i_start_offset) * 90000 / i_rate; uint64_t this_pts = call->Pts + (i * i_frame_samples + i_start_offset) * 90000 / i_rate;
uint32_t pes_header_size = 0; uint32_t pes_header_size = 0;
pes_header_size = InsertPesHeader(PesHeader, i_frame_size + 1, MPEG_AUDIO_PES_START_CODE, this_pts, 0); pes_header_size = InsertPesHeader(PesHeader, i_frame_size + 1, MPEG_AUDIO_PES_START_CODE, this_pts, 0);
PesHeader[pes_header_size] = 0xa0; PesHeader[pes_header_size] = 0xa0;
pes_header_size += 1; pes_header_size += 1;
struct iovec iov[2]; struct iovec iov[2];
iov[0].iov_base = PesHeader; iov[0].iov_base = PesHeader;
iov[0].iov_len = pes_header_size; iov[0].iov_len = pes_header_size;
@@ -240,8 +257,10 @@ static int writeData(WriterAVCallData_t *call)
iov[1].iov_len = i_frame_size; iov[1].iov_len = i_frame_size;
i_ret_size += call->WriteV(call->fd, iov, 2); i_ret_size += call->WriteV(call->fd, iov, 2);
} }
memcpy(p_buffer, call->data + i_bytes_consumed, i_leftover_samples * i_channels * 2); memcpy(p_buffer, call->data + i_bytes_consumed, i_leftover_samples * i_channels * 2);
i_buffer_used = i_leftover_samples; i_buffer_used = i_leftover_samples;
return i_ret_size; return i_ret_size;
} }

View File

@@ -94,24 +94,31 @@ static int reset()
static int writeData(WriterAVCallData_t *call) static int writeData(WriterAVCallData_t *call)
{ {
unsigned char PesHeader[PES_MAX_HEADER_SIZE + 22]; unsigned char PesHeader[PES_MAX_HEADER_SIZE + 22];
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;
} }
call->private_size = 0; call->private_size = 0;
uint32_t headerSize = InsertPesHeader(PesHeader, call->len + call->private_size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); uint32_t headerSize = InsertPesHeader(PesHeader, call->len + call->private_size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
if (call->private_size > 0) if (call->private_size > 0)
{ {
@@ -123,7 +130,9 @@ static int writeData(WriterAVCallData_t *call)
iov[0].iov_len = headerSize; iov[0].iov_len = headerSize;
iov[1].iov_base = call->data; iov[1].iov_base = call->data;
iov[1].iov_len = call->len; iov[1].iov_len = call->len;
int len = call->WriteV(call->fd, iov, 2); int len = call->WriteV(call->fd, iov, 2);
mp3_printf(10, "mp3_Write-< len=%d\n", len); mp3_printf(10, "mp3_Write-< len=%d\n", len);
return len; return len;
} }

View File

@@ -95,36 +95,47 @@ static int reset()
static int writeData(WriterAVCallData_t *call) static int writeData(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 = call->WriteV(call->fd, iov, 2); ssize_t l = call->WriteV(call->fd, iov, 2);
if (l < 0) if (l < 0)
{ {
@@ -132,9 +143,11 @@ static int writeData(WriterAVCallData_t *call)
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);
return len; return len;
} }

View File

@@ -103,32 +103,40 @@ static int reset()
static int writeData(WriterAVCallData_t *call) static int writeData(WriterAVCallData_t *call)
{ {
unsigned char PesHeader[PES_MAX_HEADER_SIZE]; unsigned char PesHeader[PES_MAX_HEADER_SIZE];
mpeg4_printf(10, "\n"); mpeg4_printf(10, "\n");
if (call == NULL) if (call == NULL)
{ {
mpeg4_err("call data is NULL...\n"); mpeg4_err("call data is NULL...\n");
return 0; return 0;
} }
if ((call->data == NULL) || (call->len <= 0)) if ((call->data == NULL) || (call->len <= 0))
{ {
mpeg4_err("parsing NULL Data. ignoring...\n"); mpeg4_err("parsing NULL Data. ignoring...\n");
return 0; return 0;
} }
if (call->fd < 0) if (call->fd < 0)
{ {
mpeg4_err("file pointer < 0. ignoring ...\n"); mpeg4_err("file pointer < 0. ignoring ...\n");
return 0; return 0;
} }
mpeg4_printf(10, "VideoPts %lld\n", call->Pts); mpeg4_printf(10, "VideoPts %lld\n", call->Pts);
unsigned int PacketLength = call->len; unsigned int PacketLength = call->len;
if (initialHeader && call->private_size && call->private_data != NULL) if (initialHeader && call->private_size && call->private_data != NULL)
{ {
PacketLength += call->private_size; PacketLength += call->private_size;
} }
struct iovec iov[3]; struct iovec iov[3];
int ic = 0; int ic = 0;
iov[ic].iov_base = PesHeader; iov[ic].iov_base = PesHeader;
iov[ic++].iov_len = InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); iov[ic++].iov_len = InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
if (initialHeader && call->private_size && call->private_data != NULL) if (initialHeader && call->private_size && call->private_data != NULL)
{ {
initialHeader = 0; initialHeader = 0;
@@ -137,8 +145,11 @@ static int writeData(WriterAVCallData_t *call)
} }
iov[ic].iov_base = call->data; iov[ic].iov_base = call->data;
iov[ic++].iov_len = call->len; iov[ic++].iov_len = call->len;
int len = call->WriteV(call->fd, iov, ic); int len = call->WriteV(call->fd, iov, ic);
mpeg4_printf(10, "xvid_Write < len=%d\n", len); mpeg4_printf(10, "xvid_Write < len=%d\n", len);
return len; return len;
} }

View File

@@ -56,8 +56,6 @@
/* Makros/Constants */ /* Makros/Constants */
/* ***************************** */ /* ***************************** */
//#define SAM_WITH_DEBUG
#ifdef SAM_WITH_DEBUG #ifdef SAM_WITH_DEBUG
#define PCM_DEBUG #define PCM_DEBUG
#else #else
@@ -113,26 +111,32 @@ static int32_t reset()
static int writeData(WriterAVCallData_t *call) static int writeData(WriterAVCallData_t *call)
{ {
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); pcm_printf(10, "AudioPts %lld\n", call->Pts);
if (!call->data || (call->len <= 0)) if (!call->data || (call->len <= 0))
{ {
pcm_err("parsing NULL Data. ignoring...\n"); pcm_err("parsing NULL Data. ignoring...\n");
return 0; return 0;
} }
if (call->fd < 0) if (call->fd < 0)
{ {
pcm_err("file pointer < 0. ignoring ...\n"); pcm_err("file pointer < 0. ignoring ...\n");
return 0; return 0;
} }
static uint8_t PesHeader[PES_MAX_HEADER_SIZE + 22]; static uint8_t PesHeader[PES_MAX_HEADER_SIZE + 22];
pcmPrivateData_t *pcmPrivateData = (pcmPrivateData_t *)call->private_data; pcmPrivateData_t *pcmPrivateData = (pcmPrivateData_t *)call->private_data;
uint8_t *buffer = call->data; uint8_t *buffer = call->data;
uint32_t size = call->len; uint32_t size = call->len;
if (pcmPrivateData->bResampling || NULL == fixed_buffer) if (pcmPrivateData->bResampling || NULL == fixed_buffer)
{ {
if (0) if (0)
@@ -143,14 +147,18 @@ static int writeData(WriterAVCallData_t *call)
printf("ioctl %d", ioctl(call->fd, AUDIO_PLAY)); printf("ioctl %d", ioctl(call->fd, AUDIO_PLAY));
printf("ioctl %d", ioctl(call->fd, AUDIO_CONTINUE)); printf("ioctl %d", ioctl(call->fd, AUDIO_CONTINUE));
} }
int32_t format = 0x01; int32_t format = 0x01;
int32_t width = 0; int32_t width = 0;
int32_t depth = 0; int32_t depth = 0;
int32_t rate = (uint64_t)pcmPrivateData->sample_rate; int32_t rate = (uint64_t)pcmPrivateData->sample_rate;
int32_t channels = (uint8_t) pcmPrivateData->channels; int32_t channels = (uint8_t) pcmPrivateData->channels;
int32_t block_align = 0; int32_t block_align = 0;
int32_t byterate = 0; int32_t byterate = 0;
uint32_t codecID = (uint32_t)pcmPrivateData->ffmpeg_codec_id; uint32_t codecID = (uint32_t)pcmPrivateData->ffmpeg_codec_id;
//uint8_t dataPrecision = 0; //uint8_t dataPrecision = 0;
uint8_t LE = 0; uint8_t LE = 0;
switch (codecID) switch (codecID)
@@ -183,7 +191,9 @@ static int writeData(WriterAVCallData_t *call)
default: default:
break; break;
} }
uint8_t *data = codec_data; uint8_t *data = codec_data;
byterate = channels * rate * width / 8; byterate = channels * rate * width / 8;
block_align = channels * width / 8; block_align = channels * width / 8;
memset(data, 0, sizeof(codec_data)); memset(data, 0, sizeof(codec_data));
@@ -209,10 +219,12 @@ static int writeData(WriterAVCallData_t *call)
/* word size */ /* word size */
*(data++) = depth & 0xff; *(data++) = depth & 0xff;
*(data++) = (depth >> 8) & 0xff; *(data++) = (depth >> 8) & 0xff;
uint32_t nfixed_buffersize = rate * 30 / 1000; uint32_t nfixed_buffersize = rate * 30 / 1000;
nfixed_buffersize *= channels * depth / 8; nfixed_buffersize *= channels * depth / 8;
fixed_buffertimestamp = call->Pts; fixed_buffertimestamp = call->Pts;
fixed_bufferduration = 90000 * nfixed_buffersize / byterate; fixed_bufferduration = 90000 * nfixed_buffersize / byterate;
if (fixed_buffersize != nfixed_buffersize || NULL == fixed_buffer) if (fixed_buffersize != nfixed_buffersize || NULL == fixed_buffer)
{ {
fixed_buffersize = nfixed_buffersize; fixed_buffersize = nfixed_buffersize;
@@ -227,6 +239,7 @@ static int writeData(WriterAVCallData_t *call)
if (LE) {} if (LE) {}
//printf("PCM fixed_buffersize [%u] [%s]\n", fixed_buffersize, LE ? "LE":"BE"); //printf("PCM fixed_buffersize [%u] [%s]\n", fixed_buffersize, LE ? "LE":"BE");
} }
while (size > 0) while (size > 0)
{ {
uint32_t cpSize = (fixed_buffersize - fixed_bufferfilled); uint32_t cpSize = (fixed_buffersize - fixed_bufferfilled);
@@ -236,10 +249,12 @@ static int writeData(WriterAVCallData_t *call)
fixed_bufferfilled += size; fixed_bufferfilled += size;
return size; return size;
} }
memcpy(fixed_buffer + fixed_bufferfilled, buffer, cpSize); memcpy(fixed_buffer + fixed_bufferfilled, buffer, cpSize);
fixed_bufferfilled = 0; fixed_bufferfilled = 0;
buffer += cpSize; buffer += cpSize;
size -= cpSize; size -= cpSize;
uint32_t addHeaderSize = 0; uint32_t addHeaderSize = 0;
if (IsDreambox()) if (IsDreambox())
{ {
@@ -253,13 +268,17 @@ static int writeData(WriterAVCallData_t *call)
PesHeader[headerSize++] = 0x4D; // M PesHeader[headerSize++] = 0x4D; // M
PesHeader[headerSize++] = 0x41; // A PesHeader[headerSize++] = 0x41; // A
} }
PesHeader[headerSize++] = (fixed_buffersize >> 24) & 0xff; PesHeader[headerSize++] = (fixed_buffersize >> 24) & 0xff;
PesHeader[headerSize++] = (fixed_buffersize >> 16) & 0xff; PesHeader[headerSize++] = (fixed_buffersize >> 16) & 0xff;
PesHeader[headerSize++] = (fixed_buffersize >> 8) & 0xff; PesHeader[headerSize++] = (fixed_buffersize >> 8) & 0xff;
PesHeader[headerSize++] = fixed_buffersize & 0xff; PesHeader[headerSize++] = fixed_buffersize & 0xff;
memcpy(PesHeader + headerSize, codec_data, sizeof(codec_data)); memcpy(PesHeader + headerSize, codec_data, sizeof(codec_data));
headerSize += sizeof(codec_data); headerSize += sizeof(codec_data);
PesHeader[6] |= 1; PesHeader[6] |= 1;
struct iovec iov[2]; struct iovec iov[2];
iov[0].iov_base = PesHeader; iov[0].iov_base = PesHeader;
iov[0].iov_len = headerSize; iov[0].iov_len = headerSize;
@@ -267,10 +286,13 @@ static int writeData(WriterAVCallData_t *call)
iov[1].iov_len = fixed_buffersize; iov[1].iov_len = fixed_buffersize;
call->WriteV(call->fd, iov, 2); call->WriteV(call->fd, iov, 2);
fixed_buffertimestamp += fixed_bufferduration; fixed_buffertimestamp += fixed_bufferduration;
int g_fd_dump = open("/hdd/lpcm/ffmpeg.pes", O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR);
int g_fd_dump = open("/hdd/lpcm/ffmpeg.pes", O_CREAT |
O_RDWR | O_APPEND, S_IRUSR | S_IWUSR);
call->WriteV(g_fd_dump, iov, 2); call->WriteV(g_fd_dump, iov, 2);
close(g_fd_dump); close(g_fd_dump);
} }
return size; return size;
} }

View File

@@ -79,6 +79,7 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x);
#define vc1_err(fmt, x...) #define vc1_err(fmt, x...)
#endif #endif
/* ***************************** */ /* ***************************** */
/* Types */ /* Types */
/* ***************************** */ /* ***************************** */
@@ -110,28 +111,35 @@ static int reset()
static int writeData(WriterAVCallData_t *call) static int writeData(WriterAVCallData_t *call)
{ {
//int len = 0; //int len = 0;
vc1_printf(10, "\n"); vc1_printf(10, "\n");
if (call == NULL) if (call == NULL)
{ {
vc1_err("call data is NULL...\n"); vc1_err("call data is NULL...\n");
return 0; return 0;
} }
if ((call->data == NULL) || (call->len <= 0)) if ((call->data == NULL) || (call->len <= 0))
{ {
vc1_err("parsing NULL Data. ignoring...\n"); vc1_err("parsing NULL Data. ignoring...\n");
return 0; return 0;
} }
if (call->fd < 0) if (call->fd < 0)
{ {
vc1_err("file pointer < 0. ignoring ...\n"); vc1_err("file pointer < 0. ignoring ...\n");
return 0; return 0;
} }
vc1_printf(10, "VideoPts %lld\n", call->Pts); vc1_printf(10, "VideoPts %lld\n", call->Pts);
vc1_printf(10, "Got Private Size %d\n", call->private_size); vc1_printf(10, "Got Private Size %d\n", call->private_size);
unsigned char PesHeader[PES_MAX_HEADER_SIZE + sizeof(Vc1FrameStartCode)]; unsigned char PesHeader[PES_MAX_HEADER_SIZE + sizeof(Vc1FrameStartCode)];
int32_t ic = 0; int32_t ic = 0;
struct iovec iov[5]; struct iovec iov[5];
unsigned int PacketLength = 0; unsigned int PacketLength = 0;
iov[ic++].iov_base = PesHeader; iov[ic++].iov_base = PesHeader;
if (initialHeader) if (initialHeader)
{ {
@@ -152,6 +160,7 @@ static int writeData(WriterAVCallData_t *call)
PacketLength += videocodecdata.length; PacketLength += videocodecdata.length;
} }
} }
uint8_t needFrameStartCode = 0; uint8_t needFrameStartCode = 0;
if (sizeof(Vc1FrameStartCode) >= call->len || if (sizeof(Vc1FrameStartCode) >= call->len ||
memcmp(call->data, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)) != 0) memcmp(call->data, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)) != 0)
@@ -159,22 +168,28 @@ static int writeData(WriterAVCallData_t *call)
needFrameStartCode = 1; needFrameStartCode = 1;
PacketLength += sizeof(Vc1FrameStartCode); PacketLength += sizeof(Vc1FrameStartCode);
} }
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;
iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
/* some mipsel receiver(s) like et4x00 needs to have Copy(0)/Original(1) flag set to Original */ /* some mipsel receiver(s) like et4x00 needs to have Copy(0)/Original(1) flag set to Original */
PesHeader[6] |= 1; PesHeader[6] |= 1;
if (needFrameStartCode) if (needFrameStartCode)
{ {
memcpy(PesHeader + iov[0].iov_len, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)); memcpy(PesHeader + iov[0].iov_len, Vc1FrameStartCode, sizeof(Vc1FrameStartCode));
iov[0].iov_len += sizeof(Vc1FrameStartCode); iov[0].iov_len += sizeof(Vc1FrameStartCode);
} }
if (videocodecdata.data) if (videocodecdata.data)
{ {
free(videocodecdata.data); free(videocodecdata.data);
videocodecdata.data = NULL; videocodecdata.data = NULL;
} }
return call->WriteV(call->fd, iov, ic); return call->WriteV(call->fd, iov, ic);
} }

View File

@@ -54,7 +54,6 @@
/* ***************************** */ /* ***************************** */
//#define SAM_WITH_DEBUG //#define SAM_WITH_DEBUG
#ifdef SAM_WITH_DEBUG #ifdef SAM_WITH_DEBUG
#define VP_DEBUG #define VP_DEBUG
#else #else
@@ -77,6 +76,7 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x);
#define vp_err(fmt, x...) #define vp_err(fmt, x...)
#endif #endif
/* ***************************** */ /* ***************************** */
/* Types */ /* Types */
/* ***************************** */ /* ***************************** */
@@ -101,25 +101,31 @@ static int reset()
static int writeData(WriterAVCallData_t *call, int is_vp6) static int writeData(WriterAVCallData_t *call, int is_vp6)
{ {
vp_printf(10, "\n"); vp_printf(10, "\n");
if (call == NULL) if (call == NULL)
{ {
vp_err("call data is NULL...\n"); vp_err("call data is NULL...\n");
return 0; return 0;
} }
if ((call->data == NULL) || (call->len <= 0)) if ((call->data == NULL) || (call->len <= 0))
{ {
vp_err("parsing NULL Data. ignoring...\n"); vp_err("parsing NULL Data. ignoring...\n");
return 0; return 0;
} }
if (call->fd < 0) if (call->fd < 0)
{ {
vp_err("file pointer < 0. ignoring ...\n"); vp_err("file pointer < 0. ignoring ...\n");
return 0; return 0;
} }
vp_printf(10, "VideoPts %lld\n", call->Pts); vp_printf(10, "VideoPts %lld\n", call->Pts);
vp_printf(10, "Got Private Size %d\n", call->private_size); vp_printf(10, "Got Private Size %d\n", call->private_size);
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;
uint32_t pes_header_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); uint32_t pes_header_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
uint32_t len = call->len + 4 + 6; uint32_t len = call->len + 4 + 6;
@@ -138,6 +144,7 @@ static int writeData(WriterAVCallData_t *call, int is_vp6)
iov[0].iov_len = pes_header_len; iov[0].iov_len = pes_header_len;
iov[1].iov_base = call->data; iov[1].iov_base = call->data;
iov[1].iov_len = call->len; iov[1].iov_len = call->len;
return call->WriteV(call->fd, iov, 2); return call->WriteV(call->fd, iov, 2);
} }

View File

@@ -53,8 +53,6 @@
/* Makros/Constants */ /* Makros/Constants */
/* ***************************** */ /* ***************************** */
//#define SAM_WITH_DEBUG
#ifdef SAM_WITH_DEBUG #ifdef SAM_WITH_DEBUG
#define WMA_DEBUG #define WMA_DEBUG
#else #else
@@ -106,28 +104,36 @@ static int reset()
static int writeData(WriterAVCallData_t *call) static int writeData(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;
} }
uint32_t packetLength = 4 + call->private_size + call->len; uint32_t packetLength = 4 + call->private_size + call->len;
if (IsDreambox()) if (IsDreambox())
{ {
packetLength += 4; packetLength += 4;
} }
if ((packetLength + PES_MAX_HEADER_SIZE) > MaxPesHeader) if ((packetLength + PES_MAX_HEADER_SIZE) > MaxPesHeader)
{ {
if (PesHeader) if (PesHeader)
@@ -137,6 +143,7 @@ static int writeData(WriterAVCallData_t *call)
MaxPesHeader = packetLength + PES_MAX_HEADER_SIZE; MaxPesHeader = packetLength + PES_MAX_HEADER_SIZE;
PesHeader = malloc(MaxPesHeader); PesHeader = malloc(MaxPesHeader);
} }
uint32_t headerSize = InsertPesHeader(PesHeader, packetLength, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); uint32_t headerSize = InsertPesHeader(PesHeader, packetLength, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
if (IsDreambox()) if (IsDreambox())
{ {
@@ -145,14 +152,18 @@ static int writeData(WriterAVCallData_t *call)
PesHeader[headerSize++] = 0x4D; // M PesHeader[headerSize++] = 0x4D; // M
PesHeader[headerSize++] = 0x41; // A PesHeader[headerSize++] = 0x41; // A
} }
size_t payload_len = call->len; size_t payload_len = call->len;
PesHeader[headerSize++] = (payload_len >> 24) & 0xff; PesHeader[headerSize++] = (payload_len >> 24) & 0xff;
PesHeader[headerSize++] = (payload_len >> 16) & 0xff; PesHeader[headerSize++] = (payload_len >> 16) & 0xff;
PesHeader[headerSize++] = (payload_len >> 8) & 0xff; PesHeader[headerSize++] = (payload_len >> 8) & 0xff;
PesHeader[headerSize++] = payload_len & 0xff; PesHeader[headerSize++] = payload_len & 0xff;
memcpy(PesHeader + headerSize, call->private_data, call->private_size); memcpy(PesHeader + headerSize, call->private_data, call->private_size);
headerSize += call->private_size; headerSize += call->private_size;
PesHeader[6] |= 1; PesHeader[6] |= 1;
struct iovec iov[2]; struct iovec iov[2];
iov[0].iov_base = PesHeader; iov[0].iov_base = PesHeader;
iov[0].iov_len = headerSize; iov[0].iov_len = headerSize;

View File

@@ -108,27 +108,33 @@ static int reset()
static int writeData(WriterAVCallData_t *call) static int writeData(WriterAVCallData_t *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);
unsigned char PesHeader[PES_MAX_HEADER_SIZE + sizeof(Vc1FrameStartCode)]; unsigned char PesHeader[PES_MAX_HEADER_SIZE + sizeof(Vc1FrameStartCode)];
int32_t ic = 0; int32_t ic = 0;
struct iovec iov[5]; struct iovec iov[5];
unsigned int PacketLength = 0; unsigned int PacketLength = 0;
iov[ic++].iov_base = PesHeader; iov[ic++].iov_base = PesHeader;
if (initialHeader) if (initialHeader)
{ {
@@ -138,8 +144,10 @@ static int writeData(WriterAVCallData_t *call)
free(videocodecdata.data); free(videocodecdata.data);
videocodecdata.data = NULL; videocodecdata.data = NULL;
} }
unsigned int codec_size = call->private_size; unsigned int codec_size = call->private_size;
if (codec_size > 4) codec_size = 4; if (codec_size > 4) codec_size = 4;
videocodecdata.length = 33; videocodecdata.length = 33;
uint8_t *data = videocodecdata.data = malloc(videocodecdata.length); uint8_t *data = videocodecdata.data = malloc(videocodecdata.length);
memset(videocodecdata.data, 0, videocodecdata.length); memset(videocodecdata.data, 0, videocodecdata.length);
@@ -158,6 +166,7 @@ static int writeData(WriterAVCallData_t *call)
PacketLength += videocodecdata.length; PacketLength += videocodecdata.length;
} }
} }
uint8_t needFrameStartCode = 0; uint8_t needFrameStartCode = 0;
if (sizeof(Vc1FrameStartCode) >= call->len || if (sizeof(Vc1FrameStartCode) >= call->len ||
memcmp(call->data, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)) != 0) memcmp(call->data, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)) != 0)
@@ -165,22 +174,28 @@ static int writeData(WriterAVCallData_t *call)
needFrameStartCode = 1; needFrameStartCode = 1;
PacketLength += sizeof(Vc1FrameStartCode); PacketLength += sizeof(Vc1FrameStartCode);
} }
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;
iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
/* some mipsel receiver(s) like et4x00 needs to have Copy(0)/Original(1) flag set to Original */ /* some mipsel receiver(s) like et4x00 needs to have Copy(0)/Original(1) flag set to Original */
PesHeader[6] |= 1; PesHeader[6] |= 1;
if (needFrameStartCode) if (needFrameStartCode)
{ {
memcpy(PesHeader + iov[0].iov_len, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)); memcpy(PesHeader + iov[0].iov_len, Vc1FrameStartCode, sizeof(Vc1FrameStartCode));
iov[0].iov_len += sizeof(Vc1FrameStartCode); iov[0].iov_len += sizeof(Vc1FrameStartCode);
} }
if (videocodecdata.data) if (videocodecdata.data)
{ {
free(videocodecdata.data); free(videocodecdata.data);
videocodecdata.data = NULL; videocodecdata.data = NULL;
} }
return call->WriteV(call->fd, iov, ic); return call->WriteV(call->fd, iov, ic);
} }

View File

@@ -111,7 +111,7 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf,
{ {
fd_set rfds; fd_set rfds;
fd_set wfds; fd_set wfds;
ssize_t ret; ssize_t ret;
int retval = -1; int retval = -1;
int maxFd = pipefd > fd ? pipefd : fd; int maxFd = pipefd > fd ? pipefd : fd;
@@ -125,36 +125,36 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf,
FD_SET(pipefd, &rfds); FD_SET(pipefd, &rfds);
FD_SET(fd, &wfds); FD_SET(fd, &wfds);
/* When we PAUSE LINUX DVB outputs buffers then audio/video buffers /* When we PAUSE LINUX DVB outputs buffers then audio/video buffers
* will be filled to full unfortunately, in such case after resume * will be filled to full unfortunately, in such case after resume
* select never return with fd set - bug in DVB drivers? * select never return with fd set - bug in DVB drivers?
* So, there will be to workarounds: * So, there will be to workarounds:
* 1. write to pipe pipe at resume to exit select immediately * 1. write to pipe pipe at resume to exit select immediately
* 2. even if fd is not set exit from select after 0,1s * 2. even if fd is not set exit from select after 0,1s
* (it seems that second workaround is not needed) * (it seems that second workaround is not needed)
*/ */
//tv.tv_sec = 0; //tv.tv_sec = 0;
//tv.tv_usec = 100000; // 100ms //tv.tv_usec = 100000; // 100ms
retval = select(maxFd + 1, &rfds, &wfds, NULL, NULL); //&tv); retval = select(maxFd + 1, &rfds, &wfds, NULL, NULL); //&tv);
if (retval < 0) if (retval < 0)
{ {
break; break;
} }
//if (retval == 0) //if (retval == 0)
//{ //{
// //printf("RETURN FROM SELECT DUE TO TIMEOUT TIMEOUT\n"); // //printf("RETURN FROM SELECT DUE TO TIMEOUT TIMEOUT\n");
// continue; // continue;
//} //}
if(FD_ISSET(pipefd, &rfds)) if(FD_ISSET(pipefd, &rfds))
{ {
FlusPipe(pipefd); FlusPipe(pipefd);
//printf("RETURN FROM SELECT DUE TO pipefd SET\n"); //printf("RETURN FROM SELECT DUE TO pipefd SET\n");
continue; continue;
} }
if(FD_ISSET(fd, &wfds)) if(FD_ISSET(fd, &wfds))
{ {
ret = write(fd, buf, size); ret = write(fd, buf, size);
@@ -173,7 +173,7 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf,
{ {
break; break;
} }
return ret; return ret;
} }
else if (ret == 0) else if (ret == 0)
@@ -186,7 +186,7 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf,
FlusPipe(pipefd); FlusPipe(pipefd);
continue; continue;
} }
size -= ret; size -= ret;
buf += ret; buf += ret;
} }
@@ -219,12 +219,15 @@ ssize_t write_with_retry(int fd, const void *buf, size_t size)
break; break;
} }
} }
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
} }
size -= ret; size -= ret;
buf += ret; buf += ret;
if (size > 0) if (size > 0)
{ {
if (usleep(1000)) if (usleep(1000))
@@ -255,6 +258,7 @@ ssize_t writev_with_retry(int fd, const struct iovec *iov, size_t ic)
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)
@@ -263,13 +267,16 @@ Writer_t *getWriter(char *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)
@@ -278,13 +285,16 @@ Writer_t *getDefaultVideoWriter()
return AvailableWriter[i]; return AvailableWriter[i];
} }
} }
writer_printf(1, "%s: no writer found\n", __func__); writer_printf(1, "%s: no writer found\n", __func__);
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)
@@ -293,6 +303,8 @@ Writer_t *getDefaultAudioWriter()
return AvailableWriter[i]; return AvailableWriter[i];
} }
} }
writer_printf(1, "%s: no writer found\n", __func__); writer_printf(1, "%s: no writer found\n", __func__);
return NULL; return NULL;
} }

View File

@@ -43,6 +43,7 @@
#include <libavutil/intreadwrite.h> #include <libavutil/intreadwrite.h>
#include "ffmpeg/latmenc.h" #include "ffmpeg/latmenc.h"
#include "common.h" #include "common.h"
#include "output.h" #include "output.h"
#include "debug.h" #include "debug.h"
@@ -157,17 +158,21 @@ static int reset()
static int _writeData(void *_call, int type) static int _writeData(void *_call, int type)
{ {
WriterAVCallData_t *call = (WriterAVCallData_t *) _call; WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
aac_printf(10, "\n _writeData type[%d]\n", type); aac_printf(10, "\n _writeData type[%d]\n", type);
if (call == NULL) if (call == NULL)
{ {
aac_err("call data is NULL...\n"); aac_err("call data is NULL...\n");
return 0; return 0;
} }
if ((call->data == NULL) || (call->len < 8)) if ((call->data == NULL) || (call->len < 8))
{ {
aac_err("parsing Data with missing AAC header. ignoring...\n"); aac_err("parsing Data with missing AAC header. ignoring...\n");
return 0; return 0;
} }
/* simple validation */ /* simple validation */
if (0 == type) // check ADTS header if (0 == type) // check ADTS header
{ {
@@ -194,9 +199,13 @@ static int _writeData(void *_call, int type)
return 0; return 0;
} }
} }
unsigned char PesHeader[PES_MAX_HEADER_SIZE]; unsigned char PesHeader[PES_MAX_HEADER_SIZE];
aac_printf(10, "AudioPts %lld\n", call->Pts); aac_printf(10, "AudioPts %lld\n", call->Pts);
unsigned int HeaderLength = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); unsigned int HeaderLength = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
struct iovec iov[2]; struct iovec iov[2];
iov[0].iov_base = PesHeader; iov[0].iov_base = PesHeader;
iov[0].iov_len = HeaderLength; iov[0].iov_len = HeaderLength;
@@ -208,31 +217,38 @@ static int _writeData(void *_call, int type)
static int writeDataADTS(void *_call) static int writeDataADTS(void *_call)
{ {
WriterAVCallData_t *call = (WriterAVCallData_t *) _call; WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
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;
} }
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 && 0 == strncmp("ADTS", call->private_data, call->private_size)) || if ((call->private_data && 0 == strncmp("ADTS", call->private_data, call->private_size)) ||
HasADTSHeader(call->data, call->len)) HasADTSHeader(call->data, call->len))
{ {
return _writeData(_call, 0); return _writeData(_call, 0);
} }
uint32_t PacketLength = call->len + AAC_HEADER_LENGTH; uint32_t PacketLength = call->len + AAC_HEADER_LENGTH;
uint8_t PesHeader[PES_MAX_HEADER_SIZE + AAC_HEADER_LENGTH]; uint8_t PesHeader[PES_MAX_HEADER_SIZE + AAC_HEADER_LENGTH];
uint32_t headerSize = InsertPesHeader(PesHeader, PacketLength, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); uint32_t headerSize = InsertPesHeader(PesHeader, PacketLength, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
uint8_t *pExtraData = &PesHeader[headerSize]; uint8_t *pExtraData = &PesHeader[headerSize];
aac_printf(10, "AudioPts %lld\n", call->Pts); aac_printf(10, "AudioPts %lld\n", call->Pts);
if (call->private_data == NULL) if (call->private_data == NULL)
{ {
@@ -243,6 +259,7 @@ static int writeDataADTS(void *_call)
{ {
memcpy(pExtraData, call->private_data, AAC_HEADER_LENGTH); memcpy(pExtraData, call->private_data, AAC_HEADER_LENGTH);
} }
pExtraData[3] &= 0xC0; pExtraData[3] &= 0xC0;
/* frame size over last 2 bits */ /* frame size over last 2 bits */
pExtraData[3] |= (PacketLength & 0x1800) >> 11; pExtraData[3] |= (PacketLength & 0x1800) >> 11;
@@ -255,33 +272,41 @@ static int writeDataADTS(void *_call)
/* buffer fullness(0x7FF for VBR) continued over 6 first bits + 2 zeros for /* buffer fullness(0x7FF for VBR) continued over 6 first bits + 2 zeros for
* number of raw data blocks */ * number of raw data blocks */
pExtraData[6] = 0xFC; pExtraData[6] = 0xFC;
struct iovec iov[2]; struct iovec iov[2];
iov[0].iov_base = PesHeader; iov[0].iov_base = PesHeader;
iov[0].iov_len = headerSize + AAC_HEADER_LENGTH; iov[0].iov_len = headerSize + AAC_HEADER_LENGTH;
iov[1].iov_base = call->data; iov[1].iov_base = call->data;
iov[1].iov_len = call->len; iov[1].iov_len = call->len;
return writev(call->fd, iov, 2); return writev(call->fd, iov, 2);
} }
static int writeDataLATM(void *_call) static int writeDataLATM(void *_call)
{ {
WriterAVCallData_t *call = (WriterAVCallData_t *) _call; WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
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;
} }
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->private_data && 0 == strncmp("LATM", call->private_data, call->private_size)) if (call->private_data && 0 == strncmp("LATM", call->private_data, call->private_size))
{ {
return _writeData(_call, 1); return _writeData(_call, 1);
} }
aac_printf(10, "AudioPts %lld\n", call->Pts); aac_printf(10, "AudioPts %lld\n", call->Pts);
if (!pLATMCtx) if (!pLATMCtx)
{ {
pLATMCtx = malloc(sizeof(LATMContext)); pLATMCtx = malloc(sizeof(LATMContext));
@@ -289,11 +314,13 @@ static int writeDataLATM(void *_call)
pLATMCtx->mod = 14; pLATMCtx->mod = 14;
pLATMCtx->counter = 0; pLATMCtx->counter = 0;
} }
if (!pLATMCtx) if (!pLATMCtx)
{ {
aac_err("parsing NULL pLATMCtx. ignoring...\n"); aac_err("parsing NULL pLATMCtx. ignoring...\n");
return 0; return 0;
} }
unsigned char PesHeader[PES_MAX_HEADER_SIZE]; unsigned char PesHeader[PES_MAX_HEADER_SIZE];
int ret = latmenc_decode_extradata(pLATMCtx, call->private_data, call->private_size); int ret = latmenc_decode_extradata(pLATMCtx, call->private_data, call->private_size);
if (ret) if (ret)
@@ -309,14 +336,19 @@ static int writeDataLATM(void *_call)
aac_err("latm_write_packet failed. ignoring...\n"); aac_err("latm_write_packet failed. ignoring...\n");
return 0; return 0;
} }
unsigned int HeaderLength = InsertPesHeader(PesHeader, pLATMCtx->len + 3, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); unsigned int HeaderLength = InsertPesHeader(PesHeader, pLATMCtx->len + 3, MPEG_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;
iov[0].iov_len = HeaderLength; iov[0].iov_len = HeaderLength;
iov[1].iov_base = pLATMCtx->loas_header; iov[1].iov_base = pLATMCtx->loas_header;
iov[1].iov_len = 3; iov[1].iov_len = 3;
iov[2].iov_base = pLATMCtx->buffer; iov[2].iov_base = pLATMCtx->buffer;
iov[2].iov_len = pLATMCtx->len; iov[2].iov_len = pLATMCtx->len;
return writev(call->fd, iov, 3); return writev(call->fd, iov, 3);
} }

View File

@@ -98,29 +98,38 @@ static int reset()
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;
return writev(call->fd, iov, 2); return writev(call->fd, iov, 2);
} }

View File

@@ -101,6 +101,7 @@ static uint8_t updateCodecData(uint8_t *data, int32_t size)
{ {
static uint8_t *oldData = NULL; static uint8_t *oldData = NULL;
static int32_t oldSize = 0; static int32_t oldSize = 0;
uint8_t update = 0; uint8_t update = 0;
if (data != NULL && size > 0) if (data != NULL && size > 0)
{ {
@@ -121,6 +122,7 @@ static uint8_t updateCodecData(uint8_t *data, int32_t size)
} }
} }
} }
if (update) if (update)
{ {
if (oldData != NULL) if (oldData != NULL)
@@ -131,43 +133,56 @@ static uint8_t updateCodecData(uint8_t *data, int32_t size)
memcpy(oldData, data, size); memcpy(oldData, data, size);
oldSize = size; oldSize = size;
} }
return update; return update;
} }
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];
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, "VideoPts %lld\n", call->Pts); divx_printf(10, "VideoPts %lld\n", call->Pts);
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, 0); iov[ic++].iov_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
if (updateCodecData(call->private_data, call->private_size)) if (updateCodecData(call->private_data, call->private_size))
{ {
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;
} }
iov[ic].iov_base = call->data; iov[ic].iov_base = call->data;
iov[ic++].iov_len = call->len; iov[ic++].iov_len = call->len;
int len = writev(call->fd, iov, ic); int len = writev(call->fd, iov, ic);
divx_printf(10, "xvid_Write < len=%d\n", len); divx_printf(10, "xvid_Write < len=%d\n", len);
return len; return len;
} }

View File

@@ -101,6 +101,7 @@ static uint8_t updateCodecData(uint8_t *data, int32_t size)
{ {
static uint8_t *oldData = NULL; static uint8_t *oldData = NULL;
static int32_t oldSize = 0; static int32_t oldSize = 0;
uint8_t update = 0; uint8_t update = 0;
if (data != NULL && size > 0) if (data != NULL && size > 0)
{ {
@@ -121,6 +122,7 @@ static uint8_t updateCodecData(uint8_t *data, int32_t size)
} }
} }
} }
if (update) if (update)
{ {
if (oldData != NULL) if (oldData != NULL)
@@ -131,12 +133,14 @@ static uint8_t updateCodecData(uint8_t *data, int32_t size)
memcpy(oldData, data, size); memcpy(oldData, data, size);
oldSize = size; oldSize = size;
} }
return update; return update;
} }
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;
@@ -144,26 +148,34 @@ static int writeData(void *_call)
unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE; unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE;
unsigned int usecPerFrame = 41708; /* Hellmaster1024: default value */ unsigned int usecPerFrame = 41708; /* Hellmaster1024: default value */
BitPacker_t ld = {FakeHeaders, 0, 32}; 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);
usecPerFrame = 1000000000 / call->FrameRate; usecPerFrame = 1000000000 / call->FrameRate;
divx_printf(10, "Microsecends per frame = %d\n", usecPerFrame); divx_printf(10, "Microsecends per frame = %d\n", usecPerFrame);
memset(FakeHeaders, 0, sizeof(FakeHeaders)); memset(FakeHeaders, 0, sizeof(FakeHeaders));
/* Create info record for frame parser */ /* Create info record for frame parser */
/* divx4 & 5 /* divx4 & 5
VOS VOS
@@ -177,23 +189,30 @@ static int writeData(void *_call)
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;
if (initialHeader) if (initialHeader)
{ {
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;
int len = writev(call->fd, iov, ic); int len = writev(call->fd, iov, ic);
divx_printf(10, "xvid_Write < len=%d\n", len); divx_printf(10, "xvid_Write < len=%d\n", len);
return len; return len;
} }

View File

@@ -102,26 +102,34 @@ static int reset()
static int32_t writeData(void *_call) static int32_t writeData(void *_call)
{ {
WriterAVCallData_t *call = (WriterAVCallData_t *) _call; WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
uint8_t PesHeader[PES_AUDIO_HEADER_SIZE]; uint8_t 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;
} }
uint8_t *Data = call->data; uint8_t *Data = call->data;
int32_t Size = call->len; int32_t Size = call->len;
#ifdef CHECK_FOR_DTS_HD #ifdef CHECK_FOR_DTS_HD
int32_t pos = 0; int32_t pos = 0;
while ((pos + 4) <= Size) while ((pos + 4) <= Size)
@@ -135,6 +143,7 @@ static int32_t writeData(void *_call)
++pos; ++pos;
} }
#endif #endif
// #define DO_BYTESWAP // #define DO_BYTESWAP
#ifdef DO_BYTESWAP #ifdef DO_BYTESWAP
/* 16-bit byte swap all data before injecting it */ /* 16-bit byte swap all data before injecting it */
@@ -145,11 +154,13 @@ static int32_t writeData(void *_call)
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, Size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); iov[0].iov_len = InsertPesHeader(PesHeader, Size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
iov[1].iov_base = Data; iov[1].iov_base = Data;
iov[1].iov_len = Size; iov[1].iov_len = Size;
int32_t len = writev(call->fd, iov, 2); int32_t len = writev(call->fd, iov, 2);
dts_printf(10, "< len %d\n", len); dts_printf(10, "< len %d\n", len);
return len; return len;

View File

@@ -97,39 +97,52 @@ static int reset()
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;
iov[0].iov_len = HeaderLength; iov[0].iov_len = HeaderLength;
iov[1].iov_base = call->data; iov[1].iov_base = call->data;
iov[1].iov_len = call->len; iov[1].iov_len = call->len;
len = writev(call->fd, iov, 2); len = writev(call->fd, iov, 2);
h263_printf(10, "< len %d\n", len); h263_printf(10, "< len %d\n", len);
return len; return len;
} }

View File

@@ -113,34 +113,45 @@ static int avc3 = 0;
static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize, uint8_t *pData, uint32_t dataSize) static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize, uint8_t *pData, uint32_t dataSize)
{ {
uint8_t *aExtraData = *ppExtraData; uint8_t *aExtraData = *ppExtraData;
if (aExtraData[0] != 1 || !pData) if (aExtraData[0] != 1 || !pData)
{ {
// Not AVCC or nothing to update with. // Not AVCC or nothing to update with.
return -1; return -1;
} }
int32_t nalsize = (aExtraData[4] & 3) + 1; int32_t nalsize = (aExtraData[4] & 3) + 1;
uint8_t sps[256]; uint8_t sps[256];
uint8_t spsIdx = 0; uint8_t spsIdx = 0;
uint8_t numSps = 0; uint8_t numSps = 0;
uint8_t pps[256]; uint8_t pps[256];
uint8_t ppsIdx = 0; uint8_t ppsIdx = 0;
uint8_t numPps = 0; uint8_t numPps = 0;
if (nalsize != 4) if (nalsize != 4)
{ {
return -1; return -1;
} }
// Find SPS and PPS NALUs in AVCC data // Find SPS and PPS NALUs in AVCC data
uint8_t *d = pData; uint8_t *d = pData;
while (d + 4 < pData + dataSize) while (d + 4 < pData + dataSize)
{ {
uint32_t nalLen = ReadUint32(d); uint32_t nalLen = ReadUint32(d);
uint8_t nalType = d[4] & 0x1f; uint8_t nalType = d[4] & 0x1f;
if (nalType == 7) if (nalType == 7)
{ {
/* SPS */ /* SPS */
// 16 bits size // 16 bits size
sps[spsIdx++] = (uint8_t)(0xFF & (nalLen >> 8)); sps[spsIdx++] = (uint8_t)(0xFF & (nalLen >> 8));
sps[spsIdx++] = (uint8_t)(0xFF & nalLen); sps[spsIdx++] = (uint8_t)(0xFF & nalLen);
if (spsIdx + nalLen >= sizeof(sps)) if (spsIdx + nalLen >= sizeof(sps))
{ {
h264_err("SPS no free space to copy...\n"); h264_err("SPS no free space to copy...\n");
@@ -148,15 +159,19 @@ static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize,
} }
memcpy(&(sps[spsIdx]), d + 4, nalLen); memcpy(&(sps[spsIdx]), d + 4, nalLen);
spsIdx += nalLen; spsIdx += nalLen;
numSps += 1; numSps += 1;
h264_printf(10, "SPS len[%u]...\n", nalLen); h264_printf(10, "SPS len[%u]...\n", nalLen);
} }
else if (nalType == 8) else if (nalType == 8)
{ {
/* PPS */ /* PPS */
// 16 bits size // 16 bits size
pps[ppsIdx++] = (uint8_t)(0xFF & (nalLen >> 8)); pps[ppsIdx++] = (uint8_t)(0xFF & (nalLen >> 8));
pps[ppsIdx++] = (uint8_t)(0xFF & nalLen); pps[ppsIdx++] = (uint8_t)(0xFF & nalLen);
if (ppsIdx + nalLen >= sizeof(sps)) if (ppsIdx + nalLen >= sizeof(sps))
{ {
h264_err("PPS not free space to copy...\n"); h264_err("PPS not free space to copy...\n");
@@ -164,7 +179,9 @@ static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize,
} }
memcpy(&(pps[ppsIdx]), d + 4, nalLen); memcpy(&(pps[ppsIdx]), d + 4, nalLen);
ppsIdx += nalLen; ppsIdx += nalLen;
numPps += 1; numPps += 1;
h264_printf(10, "PPS len[%u]...\n", nalLen); h264_printf(10, "PPS len[%u]...\n", nalLen);
} }
d += 4 + nalLen; d += 4 + nalLen;
@@ -177,18 +194,21 @@ static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize,
aExtraData[idx++] = sps[4]; // profile compat aExtraData[idx++] = sps[4]; // profile compat
aExtraData[idx++] = sps[5]; // level aExtraData[idx++] = sps[5]; // level
aExtraData[idx++] = 0xff; // nal size - 1 aExtraData[idx++] = 0xff; // nal size - 1
aExtraData[idx++] = 0xe0 | numSps; aExtraData[idx++] = 0xe0 | numSps;
if (numSps) if (numSps)
{ {
memcpy(&(aExtraData[idx]), sps, spsIdx); memcpy(&(aExtraData[idx]), sps, spsIdx);
idx += spsIdx; idx += spsIdx;
} }
aExtraData[idx++] = numPps; aExtraData[idx++] = numPps;
if (numPps) if (numPps)
{ {
memcpy(&(aExtraData[idx]), pps, ppsIdx); memcpy(&(aExtraData[idx]), pps, ppsIdx);
idx += ppsIdx; idx += ppsIdx;
} }
h264_printf(10, "aExtraData len[%u]...\n", idx); h264_printf(10, "aExtraData len[%u]...\n", idx);
*pExtraDataSize = idx; *pExtraDataSize = idx;
return 0; return 0;
@@ -204,6 +224,7 @@ static int32_t reset()
static int32_t writeData(void *_call) static int32_t writeData(void *_call)
{ {
WriterAVCallData_t *call = (WriterAVCallData_t *) _call; WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
uint8_t PesHeader[PES_MAX_HEADER_SIZE]; uint8_t PesHeader[PES_MAX_HEADER_SIZE];
uint64_t VideoPts; uint64_t VideoPts;
uint32_t TimeDelta; uint32_t TimeDelta;
@@ -212,25 +233,31 @@ static int32_t writeData(void *_call)
int32_t ic = 0; int32_t 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;
} }
/* AnnexA */ /* AnnexA */
if (!avc3 && ((1 < call->private_size && 0 == call->private_data[0]) || if (!avc3 && ((1 < call->private_size && 0 == call->private_data[0]) ||
(call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) || (call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) ||
@@ -238,6 +265,7 @@ static int32_t writeData(void *_call)
{ {
uint32_t PacketLength = 0; uint32_t PacketLength = 0;
uint32_t FakeStartCode = /*(call->Version << 8) | */PES_VERSION_FAKE_START_CODE; uint32_t FakeStartCode = /*(call->Version << 8) | */PES_VERSION_FAKE_START_CODE;
iov[ic++].iov_base = PesHeader; iov[ic++].iov_base = PesHeader;
initialHeader = 0; initialHeader = 0;
if (initialHeader) if (initialHeader)
@@ -247,16 +275,20 @@ static int32_t writeData(void *_call)
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 = ""; iov[ic].iov_base = "";
iov[ic++].iov_len = 1; iov[ic++].iov_len = 1;
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 = "\0"; iov[ic].iov_base = "\0";
iov[ic++].iov_len = 1; iov[ic++].iov_len = 1;
iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode); iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode);
int ret = writev(call->fd, iov, ic); int ret = writev(call->fd, iov, ic);
return ret; return ret;
@@ -266,6 +298,7 @@ static int32_t writeData(void *_call)
h264_err("No valid private data available!\n"); h264_err("No valid private data available!\n");
return 0; return 0;
} }
if (initialHeader) if (initialHeader)
{ {
uint8_t *private_data = call->private_data; uint8_t *private_data = call->private_data;
@@ -276,8 +309,11 @@ static int32_t writeData(void *_call)
unsigned int ParamOffset; unsigned int ParamOffset;
unsigned int InitialHeaderLength = 0; unsigned int InitialHeaderLength = 0;
unsigned int ParametersLength; unsigned int ParametersLength;
ParametersLength = 0; ParametersLength = 0;
unsigned char HeaderData[19]; unsigned char HeaderData[19];
if (private_size <= sizeof(avcC_t)) if (private_size <= sizeof(avcC_t))
{ {
UpdateExtraData(&private_data, &private_size, call->data, call->len); UpdateExtraData(&private_data, &private_size, call->data, call->len);
@@ -287,6 +323,7 @@ static int32_t writeData(void *_call)
avcCHeader = (avcC_t *)private_data; avcCHeader = (avcC_t *)private_data;
} }
} }
HeaderData[ParametersLength++] = 0x00; // Start code HeaderData[ParametersLength++] = 0x00; // Start code
HeaderData[ParametersLength++] = 0x00; HeaderData[ParametersLength++] = 0x00;
HeaderData[ParametersLength++] = 0x01; HeaderData[ParametersLength++] = 0x01;
@@ -294,14 +331,17 @@ static int32_t writeData(void *_call)
// Container message version - changes when/if we vary the format of the message // Container message version - changes when/if we vary the format of the message
HeaderData[ParametersLength++] = CONTAINER_PARAMETERS_VERSION; HeaderData[ParametersLength++] = CONTAINER_PARAMETERS_VERSION;
HeaderData[ParametersLength++] = 0xff; // Field separator 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;
@@ -309,7 +349,9 @@ static int32_t writeData(void *_call)
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);
@@ -320,8 +362,10 @@ static int32_t writeData(void *_call)
{ {
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", avcCHeader->Version);
h264_printf(20, " profile: %d\n", avcCHeader->Profile); h264_printf(20, " profile: %d\n", avcCHeader->Profile);
@@ -329,13 +373,16 @@ static int32_t writeData(void *_call)
h264_printf(20, " level: %d\n", avcCHeader->Level); h264_printf(20, " level: %d\n", avcCHeader->Level);
h264_printf(20, " nal length bytes: %d\n", NalLengthBytes); h264_printf(20, " nal length bytes: %d\n", NalLengthBytes);
h264_printf(20, " number of sequence param sets: %d\n", ParamSets); 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_base = (char *)Head;
iov[ic++].iov_len = sizeof(Head); iov[ic++].iov_len = sizeof(Head);
InitialHeaderLength += sizeof(Head); InitialHeaderLength += sizeof(Head);
@@ -344,13 +391,18 @@ static int32_t writeData(void *_call)
InitialHeaderLength += PsLength; InitialHeaderLength += PsLength;
ParamOffset += PsLength + 2; ParamOffset += PsLength + 2;
} }
ParamSets = avcCHeader->Params[ParamOffset]; ParamSets = avcCHeader->Params[ParamOffset];
h264_printf(20, " number of picture param sets: %d\n", ParamSets); h264_printf(20, " number of picture param sets: %d\n", ParamSets);
ParamOffset++; ParamOffset++;
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, " pps %d has length %d\n", i, PsLength); 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);
@@ -359,27 +411,34 @@ static int32_t writeData(void *_call)
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); 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 (private_data != call->private_data) if (private_data != call->private_data)
{ {
free(private_data); free(private_data);
} }
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;
@@ -398,11 +457,14 @@ static int32_t writeData(void *_call)
NalLength = (NalData[0] << 24) | (NalData[1] << 16) | (NalData[2] << 8) | (NalData[3]); NalLength = (NalData[0] << 24) | (NalData[1] << 16) | (NalData[2] << 8) | (NalData[3]);
break; 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, "nal length past end of buffer - size %u frame offset %u left %u\n",
NalLength, NalStart, SampleSize - NalStart); NalLength, NalStart, SampleSize - NalStart);
NalStart = SampleSize; NalStart = SampleSize;
} }
else else
@@ -410,30 +472,37 @@ static int32_t writeData(void *_call)
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 = InsertPesHeader(PesHeader, NalLength, MPEG_VIDEO_PES_START_CODE, VideoPts, 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;
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;
} }

View File

@@ -97,30 +97,39 @@ static int reset()
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;
int len = writev(call->fd, iov, 2); int len = writev(call->fd, iov, 2);
mp3_printf(10, "mp3_Write-< len=%d\n", len); mp3_printf(10, "mp3_Write-< len=%d\n", len);
return len; return len;
} }

View File

@@ -97,37 +97,49 @@ static int reset()
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)
{ {
int32_t PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ? int32_t PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ?
(call->len - Position) : MAX_PES_PACKET_SIZE; (call->len - Position) : MAX_PES_PACKET_SIZE;
int32_t Remaining = call->len - Position - PacketLength; int32_t 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)
{ {
@@ -135,9 +147,11 @@ static int writeData(void *_call)
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);
return len; return len;
} }

View File

@@ -124,10 +124,13 @@ static int32_t prepareClipPlay(int32_t uNoOfChannels, int32_t uSampleRate, int32
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)
@@ -158,14 +161,18 @@ static int32_t prepareClipPlay(int32_t uNoOfChannels, int32_t uSampleRate, int32
default: default:
break; 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:
@@ -176,6 +183,7 @@ static int32_t prepareClipPlay(int32_t uNoOfChannels, int32_t uSampleRate, int32
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", uBitsPerSample);
return 1; return 1;
} }
return 0; return 0;
} }
@@ -188,25 +196,33 @@ static int32_t reset()
static int32_t writeData(void *_call) static int32_t 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); pcm_printf(10, "AudioPts %lld\n", call->Pts);
if (!call->data || (call->len <= 0)) if (!call->data || (call->len <= 0))
{ {
pcm_err("parsing NULL Data. ignoring...\n"); pcm_err("parsing NULL Data. ignoring...\n");
return 0; return 0;
} }
if (call->fd < 0) if (call->fd < 0)
{ {
pcm_err("file pointer < 0. ignoring ...\n"); pcm_err("file pointer < 0. ignoring ...\n");
return 0; return 0;
} }
pcmPrivateData_t *pcmPrivateData = (pcmPrivateData_t *)call->private_data; pcmPrivateData_t *pcmPrivateData = (pcmPrivateData_t *)call->private_data;
if (initialHeader) if (initialHeader)
{ {
uint32_t codecID = (uint32_t)pcmPrivateData->ffmpeg_codec_id; uint32_t codecID = (uint32_t)pcmPrivateData->ffmpeg_codec_id;
@@ -240,11 +256,14 @@ static int32_t writeData(void *_call)
initialHeader = 0; initialHeader = 0;
prepareClipPlay(pcmPrivateData->channels, pcmPrivateData->sample_rate, pcmPrivateData->bits_per_coded_sample, LE); prepareClipPlay(pcmPrivateData->channels, pcmPrivateData->sample_rate, pcmPrivateData->bits_per_coded_sample, LE);
} }
uint8_t *buffer = call->data; uint8_t *buffer = call->data;
uint32_t size = call->len; uint32_t size = call->len;
uint32_t n; uint32_t n;
uint8_t *injectBuffer = malloc(SubFrameLen); uint8_t *injectBuffer = malloc(SubFrameLen);
uint32_t pos; uint32_t pos;
for (pos = 0; pos < size;) for (pos = 0; pos < size;)
{ {
//printf("PCM %s - Position=%d\n", __FUNCTION__, pos); //printf("PCM %s - Position=%d\n", __FUNCTION__, pos);
@@ -255,6 +274,7 @@ static int32_t writeData(void *_call)
//printf("PCM %s - Unplayed=%d\n", __FUNCTION__, breakBufferFillSize); //printf("PCM %s - Unplayed=%d\n", __FUNCTION__, breakBufferFillSize);
break; break;
} }
//get first PES's worth //get first PES's worth
if (breakBufferFillSize > 0) if (breakBufferFillSize > 0)
{ {
@@ -268,12 +288,15 @@ static int32_t writeData(void *_call)
memcpy(injectBuffer, &buffer[pos], sizeof(uint8_t)*SubFrameLen); memcpy(injectBuffer, &buffer[pos], sizeof(uint8_t)*SubFrameLen);
pos += SubFrameLen; pos += SubFrameLen;
} }
struct iovec iov[3]; struct iovec iov[3];
iov[0].iov_base = PesHeader; iov[0].iov_base = PesHeader;
iov[1].iov_base = lpcm_prv; iov[1].iov_base = lpcm_prv;
iov[1].iov_len = sizeof(lpcm_prv); iov[1].iov_len = sizeof(lpcm_prv);
iov[2].iov_base = injectBuffer; iov[2].iov_base = injectBuffer;
iov[2].iov_len = SubFrameLen; iov[2].iov_len = SubFrameLen;
//write the PCM data //write the PCM data
if (16 == pcmPrivateData->bits_per_coded_sample) if (16 == pcmPrivateData->bits_per_coded_sample)
{ {
@@ -305,8 +328,10 @@ static int32_t writeData(void *_call)
p[ 8] = t; p[ 8] = t;
} }
} }
//increment err... subframe count? //increment err... subframe count?
lpcm_prv[1] = ((lpcm_prv[1] + SubFramesPerPES) & 0x1F); 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); iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len + iov[2].iov_len, PCM_PES_START_CODE, call->Pts, 0);
int32_t len = writev(call->fd, iov, 3); int32_t len = writev(call->fd, iov, 3);
if (len < 0) if (len < 0)
@@ -315,6 +340,7 @@ static int32_t writeData(void *_call)
} }
} }
free(injectBuffer); free(injectBuffer);
return size; return size;
} }

View File

@@ -70,23 +70,30 @@ 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 - 13)) if (size > (MAX_PES_PACKET_SIZE - 13))
{ {
size = -1; // unbounded size = -1; // 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
@@ -108,6 +115,7 @@ int InsertPesHeader(unsigned char *data, int size, unsigned char stream_id, unsi
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);
@@ -116,6 +124,7 @@ int InsertPesHeader(unsigned char *data, int size, unsigned char stream_id, unsi
{ {
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
@@ -123,11 +132,13 @@ int InsertPesHeader(unsigned char *data, int size, unsigned char stream_id, unsi
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);
@@ -139,6 +150,7 @@ int InsertPesHeader(unsigned char *data, int size, unsigned char stream_id, unsi
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);
@@ -148,6 +160,8 @@ int InsertPesHeader(unsigned char *data, int size, unsigned char stream_id, unsi
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);
return (ld2.Ptr - data); return (ld2.Ptr - data);
} }

View File

@@ -127,25 +127,31 @@ static int reset()
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;
vc1_printf(10, "\n"); vc1_printf(10, "\n");
if (call == NULL) if (call == NULL)
{ {
vc1_err("call data is NULL...\n"); vc1_err("call data is NULL...\n");
return 0; return 0;
} }
if ((call->data == NULL) || (call->len <= 0)) if ((call->data == NULL) || (call->len <= 0))
{ {
vc1_err("parsing NULL Data. ignoring...\n"); vc1_err("parsing NULL Data. ignoring...\n");
return 0; return 0;
} }
if (call->fd < 0) if (call->fd < 0)
{ {
vc1_err("file pointer < 0. ignoring ...\n"); vc1_err("file pointer < 0. ignoring ...\n");
return 0; return 0;
} }
vc1_printf(10, "VideoPts %lld\n", call->Pts); vc1_printf(10, "VideoPts %lld\n", call->Pts);
vc1_printf(10, "Got Private Size %d\n", call->private_size); vc1_printf(10, "Got Private Size %d\n", call->private_size);
if (initialHeader) if (initialHeader)
{ {
unsigned char PesHeader[PES_MAX_HEADER_SIZE]; unsigned char PesHeader[PES_MAX_HEADER_SIZE];
@@ -153,18 +159,25 @@ static int writeData(void *_call)
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, sizeof(SequenceLayerStartCode));
PesPtr += 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;
@@ -174,43 +187,56 @@ static int writeData(void *_call)
*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)
{ {
uint32_t Position = 0; uint32_t Position = 0;
uint8_t insertSampleHeader = 1; uint8_t insertSampleHeader = 1;
while (Position < call->len) while (Position < call->len)
{ {
int32_t PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ? int32_t PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ?
(call->len - Position) : MAX_PES_PACKET_SIZE; (call->len - Position) : MAX_PES_PACKET_SIZE;
int32_t Remaining = call->len - Position - PacketLength; int32_t 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);
uint8_t PesHeader[PES_MAX_HEADER_SIZE]; uint8_t PesHeader[PES_MAX_HEADER_SIZE];
int32_t HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, call->Pts, 0); int32_t HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, call->Pts, 0);
if (insertSampleHeader) if (insertSampleHeader)
{ {
const uint8_t Vc1FrameStartCode[] = {0, 0, 1, VC1_FRAME_START_CODE}; const uint8_t Vc1FrameStartCode[] = {0, 0, 1, VC1_FRAME_START_CODE};
if (!FrameHeaderSeen && (call->len > 3) && (memcmp(call->data, Vc1FrameStartCode, 4) == 0)) if (!FrameHeaderSeen && (call->len > 3) && (memcmp(call->data, Vc1FrameStartCode, 4) == 0))
{ {
FrameHeaderSeen = 1; FrameHeaderSeen = 1;
} }
if (!FrameHeaderSeen) if (!FrameHeaderSeen)
{ {
memcpy(&PesHeader[HeaderLength], Vc1FrameStartCode, sizeof(Vc1FrameStartCode)); memcpy(&PesHeader[HeaderLength], Vc1FrameStartCode, sizeof(Vc1FrameStartCode));
@@ -218,11 +244,13 @@ static int writeData(void *_call)
} }
insertSampleHeader = 0; insertSampleHeader = 0;
} }
struct iovec iov[2]; struct iovec iov[2];
iov[0].iov_base = PesHeader; iov[0].iov_base = PesHeader;
iov[0].iov_len = HeaderLength; iov[0].iov_len = HeaderLength;
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)
{ {
@@ -230,10 +258,12 @@ static int writeData(void *_call)
break; break;
} }
len += l; len += l;
Position += PacketLength; Position += PacketLength;
call->Pts = INVALID_PTS_VALUE; call->Pts = INVALID_PTS_VALUE;
} }
} }
vc1_printf(10, "< %d\n", len); vc1_printf(10, "< %d\n", len);
return len; return len;
} }

View File

@@ -50,8 +50,6 @@
/* Makros/Constants */ /* Makros/Constants */
/* ***************************** */ /* ***************************** */
//#define SAM_WITH_DEBUG
#ifdef SAM_WITH_DEBUG #ifdef SAM_WITH_DEBUG
#define VORBIS_DEBUG #define VORBIS_DEBUG
#else #else
@@ -98,30 +96,42 @@ static int reset()
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];
vorbis_printf(10, "\n"); vorbis_printf(10, "\n");
if (call == NULL) if (call == NULL)
{ {
vorbis_err("call data is NULL...\n"); vorbis_err("call data is NULL...\n");
return 0; return 0;
} }
vorbis_printf(10, "AudioPts %lld\n", call->Pts); vorbis_printf(10, "AudioPts %lld\n", call->Pts);
if ((call->data == NULL) || (call->len <= 0)) if ((call->data == NULL) || (call->len <= 0))
{ {
vorbis_err("parsing NULL Data. ignoring...\n"); vorbis_err("parsing NULL Data. ignoring...\n");
return 0; return 0;
} }
if (call->fd < 0) if (call->fd < 0)
{ {
vorbis_err("file pointer < 0. ignoring ...\n"); vorbis_err("file pointer < 0. ignoring ...\n");
return 0; return 0;
} }
int HeaderLength = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); int HeaderLength = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
unsigned char *PacketStart = malloc(call->len + HeaderLength); unsigned char *PacketStart = malloc(call->len + HeaderLength);
memcpy(PacketStart, PesHeader, HeaderLength); memcpy(PacketStart, PesHeader, HeaderLength);
memcpy(PacketStart + HeaderLength, call->data, call->len); memcpy(PacketStart + HeaderLength, call->data, call->len);
int len = write(call->fd, PacketStart, call->len + HeaderLength); int len = write(call->fd, PacketStart, call->len + HeaderLength);
free(PacketStart); free(PacketStart);
vorbis_printf(10, "vorbis_Write-< len=%d\n", len); vorbis_printf(10, "vorbis_Write-< len=%d\n", len);
return len; return len;
} }

View File

@@ -51,8 +51,6 @@
/* Makros/Constants */ /* Makros/Constants */
/* ***************************** */ /* ***************************** */
//#define SAM_WITH_DEBUG
#ifdef SAM_WITH_DEBUG #ifdef SAM_WITH_DEBUG
#define WMA_DEBUG #define WMA_DEBUG
#else #else
@@ -102,32 +100,41 @@ static int reset()
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);
@@ -136,6 +143,7 @@ static int writeData(void *_call)
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];
@@ -144,10 +152,13 @@ static int writeData(void *_call)
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);
len = (l > -1) ? len + l : l; len = (l > -1) ? len + l : l;
} }
wma_printf(10, "wma < %d\n", len); wma_printf(10, "wma < %d\n", len);
return len; return len;
} }

View File

@@ -128,31 +128,40 @@ static int reset()
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;
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;
private_data.framerate = call->FrameRate; private_data.framerate = call->FrameRate;
#define PES_MIN_HEADER_SIZE 9 #define PES_MIN_HEADER_SIZE 9
if (initialHeader) if (initialHeader)
{ {
@@ -160,16 +169,22 @@ static int writeData(void *_call)
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;
@@ -179,16 +194,23 @@ static int writeData(void *_call)
*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;
@@ -197,12 +219,16 @@ static int writeData(void *_call)
{ {
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 = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, call->Pts, 0);
unsigned char *PacketStart; unsigned char *PacketStart;
if (insertSampleHeader) if (insertSampleHeader)
{ {
unsigned int PesLength; unsigned int PesLength;
@@ -215,18 +241,23 @@ static int writeData(void *_call)
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;
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 = write(call->fd, PacketStart, PacketLength + HeaderLength);
free(PacketStart); 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);
return len; return len;
} }

View File

@@ -100,6 +100,7 @@ static Writer_t *AvailableWriter[] =
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)
@@ -108,13 +109,16 @@ Writer_t *getWriter(char *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)
@@ -123,13 +127,16 @@ Writer_t *getDefaultVideoWriter()
return AvailableWriter[i]; return AvailableWriter[i];
} }
} }
writer_printf(1, "%s: no writer found\n", __func__); writer_printf(1, "%s: no writer found\n", __func__);
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)
@@ -138,6 +145,8 @@ Writer_t *getDefaultAudioWriter()
return AvailableWriter[i]; return AvailableWriter[i];
} }
} }
writer_printf(1, "%s: no writer found\n", __func__); writer_printf(1, "%s: no writer found\n", __func__);
return NULL; return NULL;
} }

View File

@@ -114,7 +114,7 @@ bool PlaybackDieNowRegisterCallback(PlaybackDieNowCallback callback)
ret = true; ret = true;
break; break;
} }
if (playbackDieNowCallbacks[i] == NULL) if (playbackDieNowCallbacks[i] == NULL)
{ {
playbackDieNowCallbacks[i] = callback; playbackDieNowCallbacks[i] = callback;
@@ -135,6 +135,7 @@ static void SupervisorThread(Context_t *context)
{ {
hasThreadStarted = 1; hasThreadStarted = 1;
playback_printf(10, ">\n"); playback_printf(10, ">\n");
while (context && context->playback && context->playback->isPlaying && !context->playback->abortRequested) while (context && context->playback && context->playback->isPlaying && !context->playback->abortRequested)
{ {
usleep(100000); usleep(100000);
@@ -158,19 +159,26 @@ static int PlaybackOpen(Context_t *context, PlayFiles_t *pFiles)
{ {
PlaybackStop(context); PlaybackStop(context);
} }
char *uri = pFiles->szFirstFile; char *uri = pFiles->szFirstFile;
playback_printf(10, "URI=%s\n", uri); playback_printf(10, "URI=%s\n", uri);
if (context->playback->isPlaying) if (context->playback->isPlaying)
{ {
// shouldn't happen // shouldn't happen
playback_err("playback already running\n"); playback_err("playback already running\n");
return cERR_PLAYBACK_ERROR; return cERR_PLAYBACK_ERROR;
} }
char *extension = NULL; char *extension = NULL;
context->playback->uri = strdup(uri); context->playback->uri = strdup(uri);
context->playback->isFile = 0; context->playback->isFile = 0;
context->playback->isHttp = 0; context->playback->isHttp = 0;
context->playback->noprobe = 0; context->playback->noprobe = 0;
if (!strncmp("file://", uri, 7) || !strncmp("myts://", uri, 7)) if (!strncmp("file://", uri, 7) || !strncmp("myts://", uri, 7))
{ {
context->playback->isFile = 1; context->playback->isFile = 1;
@@ -183,6 +191,7 @@ static int PlaybackOpen(Context_t *context, PlayFiles_t *pFiles)
{ {
context->playback->noprobe = 0; context->playback->noprobe = 0;
} }
extension = getExtension(context->playback->uri + 7); extension = getExtension(context->playback->uri + 7);
if (!extension) if (!extension)
{ {
@@ -207,6 +216,7 @@ static int PlaybackOpen(Context_t *context, PlayFiles_t *pFiles)
free(context->playback->uri); free(context->playback->uri);
context->playback->uri = tUri; context->playback->uri = tUri;
} }
if (strstr(uri, ":10000") || strstr(uri, ":31339/id=")) if (strstr(uri, ":10000") || strstr(uri, ":31339/id="))
{ {
context->playback->noprobe = 1; context->playback->noprobe = 1;
@@ -217,6 +227,7 @@ static int PlaybackOpen(Context_t *context, PlayFiles_t *pFiles)
playback_err("Unknown stream (%s)\n", uri); playback_err("Unknown stream (%s)\n", uri);
return cERR_PLAYBACK_ERROR; return cERR_PLAYBACK_ERROR;
} }
pFiles->szFirstFile = context->playback->uri; pFiles->szFirstFile = context->playback->uri;
if ((context->container->Command(context, CONTAINER_ADD, extension) < 0) || if ((context->container->Command(context, CONTAINER_ADD, extension) < 0) ||
(!context->container->selectedContainer) || (!context->container->selectedContainer) ||
@@ -225,20 +236,26 @@ static int PlaybackOpen(Context_t *context, PlayFiles_t *pFiles)
playback_err("CONTAINER_ADD failed\n"); playback_err("CONTAINER_ADD failed\n");
return cERR_PLAYBACK_ERROR; return cERR_PLAYBACK_ERROR;
} }
playback_printf(10, "exiting with value 0\n"); playback_printf(10, "exiting with value 0\n");
return cERR_PLAYBACK_NO_ERROR; return cERR_PLAYBACK_NO_ERROR;
} }
static int PlaybackClose(Context_t *context) static int PlaybackClose(Context_t *context)
{ {
int ret = cERR_PLAYBACK_NO_ERROR; int ret = cERR_PLAYBACK_NO_ERROR;
playback_printf(10, "\n"); playback_printf(10, "\n");
if (context->container->Command(context, CONTAINER_DEL, NULL) < 0) if (context->container->Command(context, CONTAINER_DEL, NULL) < 0)
{ {
playback_err("container delete failed\n"); playback_err("container delete failed\n");
} }
context->manager->audio->Command(context, MANAGER_DEL, NULL); context->manager->audio->Command(context, MANAGER_DEL, NULL);
context->manager->video->Command(context, MANAGER_DEL, NULL); context->manager->video->Command(context, MANAGER_DEL, NULL);
context->playback->isPaused = 0; context->playback->isPaused = 0;
context->playback->isPlaying = 0; context->playback->isPlaying = 0;
context->playback->isForwarding = 0; context->playback->isForwarding = 0;
@@ -250,8 +267,10 @@ static int PlaybackClose(Context_t *context)
free(context->playback->uri); free(context->playback->uri);
context->playback->uri = NULL; context->playback->uri = NULL;
} }
PlaybackDieNow(2); PlaybackDieNow(2);
playback_printf(10, "exiting with value %d\n", ret); playback_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
@@ -259,13 +278,17 @@ static int PlaybackPlay(Context_t *context)
{ {
pthread_attr_t attr; pthread_attr_t attr;
int ret = cERR_PLAYBACK_NO_ERROR; int ret = cERR_PLAYBACK_NO_ERROR;
playback_printf(10, "\n"); playback_printf(10, "\n");
if (!context->playback->isPlaying) if (!context->playback->isPlaying)
{ {
context->playback->AVSync = 1; context->playback->AVSync = 1;
context->output->Command(context, OUTPUT_AVSYNC, NULL); context->output->Command(context, OUTPUT_AVSYNC, NULL);
context->playback->isCreationPhase = 1; // allows the created thread to go into wait mode context->playback->isCreationPhase = 1; // allows the created thread to go into wait mode
ret = context->output->Command(context, OUTPUT_PLAY, NULL); ret = context->output->Command(context, OUTPUT_PLAY, NULL);
if (ret != 0) if (ret != 0)
{ {
playback_err("OUTPUT_PLAY failed!\n"); playback_err("OUTPUT_PLAY failed!\n");
@@ -287,6 +310,7 @@ static int PlaybackPlay(Context_t *context)
context->playback->BackWard = 0; context->playback->BackWard = 0;
context->playback->SlowMotion = 0; context->playback->SlowMotion = 0;
context->playback->Speed = 1; context->playback->Speed = 1;
if (hasThreadStarted == 0) if (hasThreadStarted == 0)
{ {
int error; int error;
@@ -302,13 +326,17 @@ static int PlaybackPlay(Context_t *context)
playback_printf(10, "Created thread\n"); playback_printf(10, "Created thread\n");
} }
} }
playback_printf(10, "clearing isCreationPhase!\n"); playback_printf(10, "clearing isCreationPhase!\n");
context->playback->isCreationPhase = 0; // allow thread to go into next state context->playback->isCreationPhase = 0; // allow thread to go into next state
ret = context->container->selectedContainer->Command(context, CONTAINER_PLAY, NULL); ret = context->container->selectedContainer->Command(context, CONTAINER_PLAY, NULL);
if (ret != 0) if (ret != 0)
{ {
playback_err("CONTAINER_PLAY failed!\n"); playback_err("CONTAINER_PLAY failed!\n");
} }
} }
} }
else else
@@ -316,19 +344,25 @@ static int PlaybackPlay(Context_t *context)
playback_err("playback already running\n"); playback_err("playback already running\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
playback_printf(10, "exiting with value %d\n", ret); playback_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
static int PlaybackPause(Context_t *context) static int PlaybackPause(Context_t *context)
{ {
int ret = cERR_PLAYBACK_NO_ERROR; int ret = cERR_PLAYBACK_NO_ERROR;
playback_printf(10, "\n"); playback_printf(10, "\n");
if (context->playback->isPlaying && !context->playback->isPaused) if (context->playback->isPlaying && !context->playback->isPaused)
{ {
if (context->playback->SlowMotion) if (context->playback->SlowMotion)
context->output->Command(context, OUTPUT_CLEAR, NULL); context->output->Command(context, OUTPUT_CLEAR, NULL);
context->output->Command(context, OUTPUT_PAUSE, NULL); context->output->Command(context, OUTPUT_PAUSE, NULL);
context->playback->isPaused = 1; context->playback->isPaused = 1;
//context->playback->isPlaying = 1; //context->playback->isPlaying = 1;
context->playback->isForwarding = 0; context->playback->isForwarding = 0;
@@ -341,6 +375,7 @@ static int PlaybackPause(Context_t *context)
playback_err("playback not playing or already in pause mode\n"); playback_err("playback not playing or already in pause mode\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
playback_printf(10, "exiting with value %d\n", ret); playback_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
@@ -348,15 +383,19 @@ static int PlaybackPause(Context_t *context)
static int32_t PlaybackContinue(Context_t *context) static int32_t PlaybackContinue(Context_t *context)
{ {
int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t ret = cERR_PLAYBACK_NO_ERROR;
playback_printf(10, "\n"); playback_printf(10, "\n");
if (context->playback->isPlaying && if (context->playback->isPlaying &&
(context->playback->isPaused || context->playback->isForwarding || (context->playback->isPaused || context->playback->isForwarding ||
context->playback->BackWard || context->playback->SlowMotion)) context->playback->BackWard || context->playback->SlowMotion))
{ {
if (context->playback->SlowMotion || context->playback->isForwarding || context->playback->BackWard) if (context->playback->SlowMotion || context->playback->isForwarding || context->playback->BackWard)
context->output->Command(context, OUTPUT_CLEAR, NULL); context->output->Command(context, OUTPUT_CLEAR, NULL);
if (context->playback->BackWard) if (context->playback->BackWard)
context->output->Command(context, OUTPUT_AUDIOMUTE, "0"); context->output->Command(context, OUTPUT_AUDIOMUTE, "0");
context->playback->isPaused = 0; context->playback->isPaused = 0;
//context->playback->isPlaying = 1; //context->playback->isPlaying = 1;
context->playback->isForwarding = 0; context->playback->isForwarding = 0;
@@ -370,6 +409,7 @@ static int32_t PlaybackContinue(Context_t *context)
playback_err("continue not possible\n"); playback_err("continue not possible\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
playback_printf(10, "exiting with value %d\n", ret); playback_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
@@ -378,34 +418,43 @@ static int32_t PlaybackStop(Context_t *context)
{ {
int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t ret = cERR_PLAYBACK_NO_ERROR;
int wait_time = 20; int wait_time = 20;
playback_printf(10, "\n"); playback_printf(10, "\n");
PlaybackDieNow(1); PlaybackDieNow(1);
if (context && context->playback && context->playback->isPlaying) if (context && context->playback && context->playback->isPlaying)
{ {
context->playback->isPaused = 0; context->playback->isPaused = 0;
context->playback->isPlaying = 0; context->playback->isPlaying = 0;
context->playback->isForwarding = 0; context->playback->isForwarding = 0;
context->playback->BackWard = 0; context->playback->BackWard = 0;
context->playback->SlowMotion = 0; context->playback->SlowMotion = 0;
context->playback->Speed = 0; context->playback->Speed = 0;
context->output->Command(context, OUTPUT_STOP, NULL); context->output->Command(context, OUTPUT_STOP, NULL);
context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL); context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL);
} }
else else
{ {
playback_err("stop not possible\n"); playback_err("stop not possible\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
while ((hasThreadStarted == 1) && (--wait_time) > 0) while ((hasThreadStarted == 1) && (--wait_time) > 0)
{ {
playback_printf(10, "Waiting for supervisor thread to terminate itself, will try another %d times\n", wait_time); playback_printf(10, "Waiting for supervisor thread to terminate itself, will try another %d times\n", wait_time);
usleep(100000); usleep(100000);
} }
if (wait_time == 0) if (wait_time == 0)
{ {
playback_err("Timeout waiting for thread!\n"); playback_err("Timeout waiting for thread!\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
playback_printf(10, "exiting with value %d\n", ret); playback_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
@@ -413,16 +462,22 @@ static int32_t PlaybackStop(Context_t *context)
static int32_t PlaybackTerminate(Context_t *context) static int32_t PlaybackTerminate(Context_t *context)
{ {
int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t ret = cERR_PLAYBACK_NO_ERROR;
int wait_time = 20; int wait_time = 20;
playback_printf(20, "\n"); playback_printf(20, "\n");
PlaybackDieNow(1); PlaybackDieNow(1);
if (context && context->playback && context->playback->isPlaying) if (context && context->playback && context->playback->isPlaying)
{ {
//First Flush and than delete container, else e2 cant read length of file anymore //First Flush and than delete container, else e2 cant read length of file anymore
if (context->output->Command(context, OUTPUT_FLUSH, NULL) < 0) if (context->output->Command(context, OUTPUT_FLUSH, NULL) < 0)
{ {
playback_err("failed to flush output.\n"); playback_err("failed to flush output.\n");
} }
context->playback->isPaused = 0; context->playback->isPaused = 0;
context->playback->isPlaying = 0; context->playback->isPlaying = 0;
context->playback->isForwarding = 0; context->playback->isForwarding = 0;
@@ -435,21 +490,25 @@ static int32_t PlaybackTerminate(Context_t *context)
else else
{ {
playback_err("%p %p %d\n", context, context->playback, context->playback->isPlaying); playback_err("%p %p %d\n", context, context->playback, context->playback->isPlaying);
/* fixme: konfetti: we should return an error here but this seems to be a condition which /* fixme: konfetti: we should return an error here but this seems to be a condition which
* can happen and is not a real error, which leads to a dead neutrino. should investigate * can happen and is not a real error, which leads to a dead neutrino. should investigate
* here later. * here later.
*/ */
} }
while ((hasThreadStarted == 1) && (--wait_time) > 0) while ((hasThreadStarted == 1) && (--wait_time) > 0)
{ {
playback_printf(10, "Waiting for supervisor thread to terminate itself, will try another %d times\n", wait_time); playback_printf(10, "Waiting for supervisor thread to terminate itself, will try another %d times\n", wait_time);
usleep(100000); usleep(100000);
} }
if (wait_time == 0) if (wait_time == 0)
{ {
playback_err("Timeout waiting for thread!\n"); playback_err("Timeout waiting for thread!\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
playback_printf(20, "exiting with value %d\n", ret); playback_printf(20, "exiting with value %d\n", ret);
return ret; return ret;
} }
@@ -457,7 +516,9 @@ static int32_t PlaybackTerminate(Context_t *context)
static int PlaybackFastForward(Context_t *context, int *speed) static int PlaybackFastForward(Context_t *context, int *speed)
{ {
int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t ret = cERR_PLAYBACK_NO_ERROR;
playback_printf(10, "speed %d\n", *speed); playback_printf(10, "speed %d\n", *speed);
/* Audio only forwarding not supported */ /* Audio only forwarding not supported */
if (context->playback->isVideo && !context->playback->isHttp && !context->playback->BackWard && (!context->playback->isPaused || context->playback->isPlaying)) if (context->playback->isVideo && !context->playback->isHttp && !context->playback->BackWard && (!context->playback->isPaused || context->playback->isPlaying))
{ {
@@ -477,14 +538,18 @@ static int PlaybackFastForward(Context_t *context, int *speed)
playback_err("fast forward not possible\n"); playback_err("fast forward not possible\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
playback_printf(10, "exiting with value %d\n", ret); playback_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
static int PlaybackFastBackward(Context_t *context, int *speed) static int PlaybackFastBackward(Context_t *context, int *speed)
{ {
int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t ret = cERR_PLAYBACK_NO_ERROR;
playback_printf(10, "speed = %d\n", *speed); playback_printf(10, "speed = %d\n", *speed);
/* Audio only reverse play not supported */ /* Audio only reverse play not supported */
if (context->playback->isVideo && !context->playback->isForwarding && if (context->playback->isVideo && !context->playback->isForwarding &&
(!context->playback->isPaused || context->playback->isPlaying)) (!context->playback->isPaused || context->playback->isPlaying))
@@ -508,6 +573,7 @@ static int PlaybackFastBackward(Context_t *context, int *speed)
context->output->Command(context, OUTPUT_AUDIOMUTE, "1"); context->output->Command(context, OUTPUT_AUDIOMUTE, "1");
playback_printf(1, "S %d B %d\n", context->playback->Speed, context->playback->BackWard); playback_printf(1, "S %d B %d\n", context->playback->Speed, context->playback->BackWard);
} }
context->output->Command(context, OUTPUT_CLEAR, NULL); context->output->Command(context, OUTPUT_CLEAR, NULL);
} }
else else
@@ -515,15 +581,19 @@ static int PlaybackFastBackward(Context_t *context, int *speed)
playback_err("fast backward not possible\n"); playback_err("fast backward not possible\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
context->playback->isSeeking = 0; context->playback->isSeeking = 0;
playback_printf(10, "exiting with value %d\n", ret); playback_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
static int32_t PlaybackSlowMotion(Context_t *context, int *speed) static int32_t PlaybackSlowMotion(Context_t *context, int *speed)
{ {
int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t ret = cERR_PLAYBACK_NO_ERROR;
playback_printf(10, "\n"); playback_printf(10, "\n");
//Audio only forwarding not supported //Audio only forwarding not supported
if (context->playback->isVideo && !context->playback->isHttp && context->playback->isPlaying) if (context->playback->isVideo && !context->playback->isHttp && context->playback->isPlaying)
{ {
@@ -549,14 +619,18 @@ static int32_t PlaybackSlowMotion(Context_t *context, int *speed)
playback_err("slowmotion not possible\n"); playback_err("slowmotion not possible\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
playback_printf(10, "exiting with value %d\n", ret); playback_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
static int32_t PlaybackSeek(Context_t *context, int64_t *pos, uint8_t absolute) static int32_t PlaybackSeek(Context_t *context, int64_t *pos, uint8_t absolute)
{ {
int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t ret = cERR_PLAYBACK_NO_ERROR;
playback_printf(10, "pos: %lldd\n", *pos); playback_printf(10, "pos: %lldd\n", *pos);
if (context->playback->isPlaying && !context->playback->isForwarding && !context->playback->BackWard && !context->playback->SlowMotion && !context->playback->isPaused) if (context->playback->isPlaying && !context->playback->isForwarding && !context->playback->BackWard && !context->playback->SlowMotion && !context->playback->isPaused)
{ {
context->playback->isSeeking = 1; context->playback->isSeeking = 1;
@@ -576,15 +650,20 @@ static int32_t PlaybackSeek(Context_t *context, int64_t *pos, uint8_t absolute)
playback_err("not possible\n"); playback_err("not possible\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
playback_printf(10, "exiting with value %d\n", ret); playback_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
static int32_t PlaybackPts(Context_t *context, int64_t *pts) static int32_t PlaybackPts(Context_t *context, int64_t *pts)
{ {
int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t ret = cERR_PLAYBACK_NO_ERROR;
playback_printf(20, "\n"); playback_printf(20, "\n");
*pts = 0; *pts = 0;
if (context->playback->isPlaying) if (context->playback->isPlaying)
{ {
ret = context->output->Command(context, OUTPUT_PTS, pts); ret = context->output->Command(context, OUTPUT_PTS, pts);
@@ -594,15 +673,20 @@ static int32_t PlaybackPts(Context_t *context, int64_t *pts)
playback_err("not possible\n"); playback_err("not possible\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
playback_printf(20, "exiting with value %d\n", ret); playback_printf(20, "exiting with value %d\n", ret);
return ret; return ret;
} }
static int32_t PlaybackGetFrameCount(Context_t *context, uint64_t *frameCount) static int32_t PlaybackGetFrameCount(Context_t *context, uint64_t *frameCount)
{ {
int ret = cERR_PLAYBACK_NO_ERROR; int ret = cERR_PLAYBACK_NO_ERROR;
playback_printf(20, "\n"); playback_printf(20, "\n");
*frameCount = 0; *frameCount = 0;
if (context->playback->isPlaying) if (context->playback->isPlaying)
{ {
ret = context->output->Command(context, OUTPUT_GET_FRAME_COUNT, frameCount); ret = context->output->Command(context, OUTPUT_GET_FRAME_COUNT, frameCount);
@@ -612,15 +696,20 @@ static int32_t PlaybackGetFrameCount(Context_t *context, uint64_t *frameCount)
playback_err("not possible\n"); playback_err("not possible\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
playback_printf(20, "exiting with value %d\n", ret); playback_printf(20, "exiting with value %d\n", ret);
return ret; return ret;
} }
static int32_t PlaybackLength(Context_t *context, int64_t *length) static int32_t PlaybackLength(Context_t *context, int64_t *length)
{ {
int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t ret = cERR_PLAYBACK_NO_ERROR;
playback_printf(20, "\n"); playback_printf(20, "\n");
*length = -1; *length = -1;
if (context->playback->isPlaying) if (context->playback->isPlaying)
{ {
if (context->container && context->container->selectedContainer) if (context->container && context->container->selectedContainer)
@@ -633,6 +722,7 @@ static int32_t PlaybackLength(Context_t *context, int64_t *length)
playback_err("not possible\n"); playback_err("not possible\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
playback_printf(20, "exiting with value %d\n", ret); playback_printf(20, "exiting with value %d\n", ret);
return ret; return ret;
} }
@@ -642,7 +732,9 @@ static int32_t PlaybackSwitchAudio(Context_t *context, int32_t *track)
int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t ret = cERR_PLAYBACK_NO_ERROR;
int32_t curtrackid = 0; int32_t curtrackid = 0;
int32_t nextrackid = 0; int32_t nextrackid = 0;
playback_printf(10, "\n"); playback_printf(10, "\n");
if (context && context->playback && context->playback->isPlaying) if (context && context->playback && context->playback->isPlaying)
{ {
if (context->manager && context->manager->audio) if (context->manager && context->manager->audio)
@@ -656,13 +748,16 @@ static int32_t PlaybackSwitchAudio(Context_t *context, int32_t *track)
playback_err("switch audio not possible\n"); playback_err("switch audio not possible\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
if (nextrackid != curtrackid) if (nextrackid != curtrackid)
{ {
//PlaybackPause(context); //PlaybackPause(context);
if (context->output && context->output->audio) if (context->output && context->output->audio)
{ {
context->output->audio->Command(context, OUTPUT_SWITCH, (void *)"audio"); context->output->audio->Command(context, OUTPUT_SWITCH, (void *)"audio");
} }
if (context->container && context->container->selectedContainer) if (context->container && context->container->selectedContainer)
{ {
context->container->selectedContainer->Command(context, CONTAINER_SWITCH_AUDIO, &nextrackid); context->container->selectedContainer->Command(context, CONTAINER_SWITCH_AUDIO, &nextrackid);
@@ -675,6 +770,7 @@ static int32_t PlaybackSwitchAudio(Context_t *context, int32_t *track)
playback_err("switch audio not possible\n"); playback_err("switch audio not possible\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
playback_printf(10, "exiting with value %d\n", ret); playback_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
@@ -684,7 +780,9 @@ static int32_t PlaybackSwitchSubtitle(Context_t *context, int32_t *track)
int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t ret = cERR_PLAYBACK_NO_ERROR;
int32_t curtrackid = -1; int32_t curtrackid = -1;
int32_t nextrackid = -1; int32_t nextrackid = -1;
playback_printf(10, "Track: %d\n", *track); playback_printf(10, "Track: %d\n", *track);
if (context && context->playback && context->playback->isPlaying) if (context && context->playback && context->playback->isPlaying)
{ {
if (context->manager && context->manager->subtitle) if (context->manager && context->manager->subtitle)
@@ -692,12 +790,14 @@ static int32_t PlaybackSwitchSubtitle(Context_t *context, int32_t *track)
context->manager->subtitle->Command(context, MANAGER_GET, &curtrackid); context->manager->subtitle->Command(context, MANAGER_GET, &curtrackid);
context->manager->subtitle->Command(context, MANAGER_SET, track); context->manager->subtitle->Command(context, MANAGER_SET, track);
context->manager->subtitle->Command(context, MANAGER_GET, &nextrackid); context->manager->subtitle->Command(context, MANAGER_GET, &nextrackid);
if (curtrackid != nextrackid && nextrackid > -1) if (curtrackid != nextrackid && nextrackid > -1)
{ {
if (context->output && context->output->subtitle) if (context->output && context->output->subtitle)
{ {
context->output->subtitle->Command(context, OUTPUT_SWITCH, (void *)"subtitle"); context->output->subtitle->Command(context, OUTPUT_SWITCH, (void *)"subtitle");
} }
if (context->container && context->container->selectedContainer) if (context->container && context->container->selectedContainer)
{ {
context->container->selectedContainer->Command(context, CONTAINER_SWITCH_SUBTITLE, &nextrackid); context->container->selectedContainer->Command(context, CONTAINER_SWITCH_SUBTITLE, &nextrackid);
@@ -715,14 +815,18 @@ static int32_t PlaybackSwitchSubtitle(Context_t *context, int32_t *track)
playback_err("not possible\n"); playback_err("not possible\n");
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
} }
playback_printf(10, "exiting with value %d\n", ret); playback_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
static int32_t PlaybackInfo(Context_t *context, char **infoString) static int32_t PlaybackInfo(Context_t *context, char **infoString)
{ {
int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t ret = cERR_PLAYBACK_NO_ERROR;
playback_printf(10, "\n"); playback_printf(10, "\n");
/* konfetti comment: /* konfetti comment:
* removed if clause here (playback running) because its * removed if clause here (playback running) because its
* not necessary for all container. e.g. in case of ffmpeg * not necessary for all container. e.g. in case of ffmpeg
@@ -732,7 +836,9 @@ static int32_t PlaybackInfo(Context_t *context, char **infoString)
{ {
context->container->selectedContainer->Command(context, CONTAINER_INFO, infoString); context->container->selectedContainer->Command(context, CONTAINER_INFO, infoString);
} }
playback_printf(10, "exiting with value %d\n", ret); playback_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
@@ -742,13 +848,17 @@ static int PlaybackMetadata(Context_t *context, char ***metadata)
if (context->container && context->container->selectedContainer) if (context->container && context->container->selectedContainer)
context->container->selectedContainer->Command(context, CONTAINER_GET_METADATA, metadata); context->container->selectedContainer->Command(context, CONTAINER_GET_METADATA, metadata);
return ret; return ret;
} }
static int32_t Command(Context_t *context, PlaybackCmd_t command, void *argument) static int32_t Command(Context_t *context, PlaybackCmd_t command, void *argument)
{ {
int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t ret = cERR_PLAYBACK_NO_ERROR;
playback_printf(20, "Command %d\n", command); playback_printf(20, "Command %d\n", command);
switch (command) switch (command)
{ {
case PLAYBACK_OPEN: case PLAYBACK_OPEN:
@@ -851,7 +961,9 @@ static int32_t Command(Context_t *context, PlaybackCmd_t command, void *argument
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
break; break;
} }
playback_printf(20, "exiting with value %d\n", ret); playback_printf(20, "exiting with value %d\n", ret);
return ret; return ret;
} }