mirror of
https://github.com/tuxbox-neutrino/libstb-hal.git
synced 2025-08-28 07:51:21 +02:00
add libeplayer3-arm test
This commit is contained in:
1118
libeplayer3-arm/output/linuxdvb_mipsel.c
Normal file
1118
libeplayer3-arm/output/linuxdvb_mipsel.c
Normal file
File diff suppressed because it is too large
Load Diff
1122
libeplayer3-arm/output/linuxdvb_sh4.c
Normal file
1122
libeplayer3-arm/output/linuxdvb_sh4.c
Normal file
File diff suppressed because it is too large
Load Diff
560
libeplayer3-arm/output/output.c
Normal file
560
libeplayer3-arm/output/output.c
Normal file
@@ -0,0 +1,560 @@
|
||||
/*
|
||||
* Output handling.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define OUTPUT_DEBUG
|
||||
#else
|
||||
#define OUTPUT_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef OUTPUT_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define output_printf(level, x...) do { \
|
||||
if (debug_level >= level) fprintf(stderr, x); } while (0)
|
||||
#else
|
||||
#define output_printf(level, x...)
|
||||
#endif
|
||||
|
||||
#ifndef OUTPUT_SILENT
|
||||
#define output_err(x...) do { printf(x); } while (0)
|
||||
#else
|
||||
#define output_err(x...)
|
||||
#endif
|
||||
|
||||
/* Error Constants */
|
||||
#define cERR_OUTPUT_NO_ERROR 0
|
||||
#define cERR_OUTPUT_INTERNAL_ERROR -1
|
||||
|
||||
static const char *FILENAME = "output.c";
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
static Output_t *AvailableOutput[] =
|
||||
{
|
||||
&LinuxDvbOutput,
|
||||
&SubtitleOutput,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static void printOutputCapabilities()
|
||||
{
|
||||
int i, j;
|
||||
output_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||
output_printf(10, "Capabilities:\n");
|
||||
for (i = 0; AvailableOutput[i] != NULL; i++)
|
||||
{
|
||||
output_printf(10, "\t%s : ", AvailableOutput[i]->Name);
|
||||
for (j = 0; AvailableOutput[i]->Capabilities[j] != NULL; j++)
|
||||
{
|
||||
output_printf(10, "%s ", AvailableOutput[i]->Capabilities[j]);
|
||||
}
|
||||
output_printf(10, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Output Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static void OutputAdd(Context_t *context, char *port)
|
||||
{
|
||||
int i, j;
|
||||
output_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||
for (i = 0; AvailableOutput[i] != NULL; i++)
|
||||
{
|
||||
for (j = 0; AvailableOutput[i]->Capabilities[j] != NULL; j++)
|
||||
{
|
||||
if (!strcmp(AvailableOutput[i]->Capabilities[j], port))
|
||||
{
|
||||
if (!strcmp("audio", port))
|
||||
{
|
||||
context->output->audio = AvailableOutput[i];
|
||||
return;
|
||||
}
|
||||
else if (!strcmp("video", port))
|
||||
{
|
||||
context->output->video = AvailableOutput[i];
|
||||
return;
|
||||
}
|
||||
else if (!strcmp("subtitle", port))
|
||||
{
|
||||
context->output->subtitle = AvailableOutput[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void OutputDel(Context_t *context, char *port)
|
||||
{
|
||||
output_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
|
||||
if (!strcmp("audio", port))
|
||||
{
|
||||
context->output->audio = NULL;
|
||||
}
|
||||
else if (!strcmp("video", port))
|
||||
{
|
||||
context->output->video = NULL;
|
||||
}
|
||||
else if (!strcmp("subtitle", port))
|
||||
{
|
||||
context->output->subtitle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
{
|
||||
Context_t *context = (Context_t *) _context;
|
||||
int ret = cERR_OUTPUT_NO_ERROR;
|
||||
output_printf(10, "%s::%s Command %d\n", FILENAME, __FUNCTION__, command);
|
||||
switch (command)
|
||||
{
|
||||
case OUTPUT_OPEN:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo)
|
||||
{
|
||||
ret |= context->output->video->Command(context, OUTPUT_OPEN, "video");
|
||||
}
|
||||
if (context->playback->isAudio)
|
||||
{
|
||||
ret |= context->output->audio->Command(context, OUTPUT_OPEN, "audio");
|
||||
}
|
||||
if (context->playback->isSubtitle)
|
||||
{
|
||||
ret |= context->output->subtitle->Command(context, OUTPUT_OPEN, "subtitle");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_CLOSE:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo)
|
||||
{
|
||||
ret |= context->output->video->Command(context, OUTPUT_CLOSE, "video");
|
||||
}
|
||||
if (context->playback->isAudio)
|
||||
{
|
||||
ret |= context->output->audio->Command(context, OUTPUT_CLOSE, "audio");
|
||||
}
|
||||
if (context->playback->isSubtitle)
|
||||
{
|
||||
ret |= context->output->subtitle->Command(context, OUTPUT_CLOSE, "subtitle");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_ADD:
|
||||
{
|
||||
OutputAdd(context, (char *) argument);
|
||||
break;
|
||||
}
|
||||
case OUTPUT_DEL:
|
||||
{
|
||||
OutputDel(context, (char *) argument);
|
||||
break;
|
||||
}
|
||||
case OUTPUT_CAPABILITIES:
|
||||
{
|
||||
printOutputCapabilities();
|
||||
break;
|
||||
}
|
||||
case OUTPUT_PLAY:
|
||||
{
|
||||
// 4
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo)
|
||||
{
|
||||
ret = context->output->video->Command(context, OUTPUT_PLAY, "video");
|
||||
}
|
||||
// success or not executed, dunn care
|
||||
if (!ret)
|
||||
{
|
||||
if (context->playback->isAudio)
|
||||
{
|
||||
ret = context->output->audio->Command(context, OUTPUT_PLAY, "audio");
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
{
|
||||
if (context->playback->isSubtitle)
|
||||
{
|
||||
ret = context->output->subtitle->Command(context, OUTPUT_PLAY, "subtitle");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_STOP:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo)
|
||||
{
|
||||
ret |= context->output->video->Command(context, OUTPUT_STOP, "video");
|
||||
}
|
||||
if (context->playback->isAudio)
|
||||
{
|
||||
ret |= context->output->audio->Command(context, OUTPUT_STOP, "audio");
|
||||
}
|
||||
if (context->playback->isSubtitle)
|
||||
{
|
||||
ret |= context->output->subtitle->Command(context, OUTPUT_STOP, "subtitle");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_FLUSH:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo)
|
||||
{
|
||||
ret |= context->output->video->Command(context, OUTPUT_FLUSH, "video");
|
||||
}
|
||||
if (context->playback->isAudio)
|
||||
{
|
||||
ret |= context->output->audio->Command(context, OUTPUT_FLUSH, "audio");
|
||||
}
|
||||
if (context->playback->isSubtitle)
|
||||
{
|
||||
ret |= context->output->subtitle->Command(context, OUTPUT_FLUSH, "subtitle");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_PAUSE:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo)
|
||||
{
|
||||
ret |= context->output->video->Command(context, OUTPUT_PAUSE, "video");
|
||||
}
|
||||
if (context->playback->isAudio)
|
||||
{
|
||||
ret |= context->output->audio->Command(context, OUTPUT_PAUSE, "audio");
|
||||
}
|
||||
if (context->playback->isSubtitle)
|
||||
{
|
||||
ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_FASTFORWARD:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo)
|
||||
{
|
||||
ret |= context->output->video->Command(context, OUTPUT_FASTFORWARD, "video");
|
||||
}
|
||||
if (context->playback->isAudio)
|
||||
{
|
||||
ret |= context->output->audio->Command(context, OUTPUT_FASTFORWARD, "audio");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_REVERSE:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo)
|
||||
{
|
||||
ret |= context->output->video->Command(context, OUTPUT_REVERSE, "video");
|
||||
}
|
||||
if (context->playback->isAudio)
|
||||
{
|
||||
ret |= context->output->audio->Command(context, OUTPUT_REVERSE, "audio");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_CONTINUE:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo)
|
||||
{
|
||||
ret |= context->output->video->Command(context, OUTPUT_CONTINUE, "video");
|
||||
}
|
||||
if (context->playback->isAudio)
|
||||
{
|
||||
ret |= context->output->audio->Command(context, OUTPUT_CONTINUE, "audio");
|
||||
}
|
||||
if (context->playback->isSubtitle)
|
||||
{
|
||||
ret |= context->output->subtitle->Command(context, OUTPUT_CONTINUE, "subtitle");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_AVSYNC:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo && context->playback->isAudio)
|
||||
{
|
||||
ret |= context->output->audio->Command(context, OUTPUT_AVSYNC, "audio");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_CLEAR:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo && (argument == NULL || *(char *) argument == 'v'))
|
||||
{
|
||||
ret |= context->output->video->Command(context, OUTPUT_CLEAR, "video");
|
||||
}
|
||||
if (context->playback->isAudio && (argument == NULL || *(char *) argument == 'a'))
|
||||
{
|
||||
ret |= context->output->audio->Command(context, OUTPUT_CLEAR, "audio");
|
||||
}
|
||||
if (context->playback->isSubtitle && (argument == NULL || *(char *) argument == 's'))
|
||||
{
|
||||
ret |= context->output->subtitle->Command(context, OUTPUT_CLEAR, "subtitle");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_PTS:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo)
|
||||
{
|
||||
return context->output->video->Command(context, OUTPUT_PTS, argument);
|
||||
}
|
||||
if (context->playback->isAudio)
|
||||
{
|
||||
return context->output->audio->Command(context, OUTPUT_PTS, argument);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_SWITCH:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isAudio)
|
||||
{
|
||||
return context->output->audio->Command(context, OUTPUT_SWITCH, "audio");
|
||||
}
|
||||
if (context->playback->isVideo)
|
||||
{
|
||||
return context->output->video->Command(context, OUTPUT_SWITCH, "video");
|
||||
}
|
||||
if (context->playback->isSubtitle)
|
||||
{
|
||||
return context->output->subtitle->Command(context, OUTPUT_SWITCH, "subtitle");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_SLOWMOTION:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo)
|
||||
{
|
||||
ret |= context->output->video->Command(context, OUTPUT_SLOWMOTION, "video");
|
||||
}
|
||||
if (context->playback->isAudio)
|
||||
{
|
||||
ret |= context->output->audio->Command(context, OUTPUT_SLOWMOTION, "audio");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_AUDIOMUTE:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isAudio)
|
||||
{
|
||||
ret |= context->output->audio->Command(context, OUTPUT_AUDIOMUTE, (char *) argument);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_DISCONTINUITY_REVERSE:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo)
|
||||
{
|
||||
ret |= context->output->video->Command(context, OUTPUT_DISCONTINUITY_REVERSE, (void *) argument);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTPUT_GET_FRAME_COUNT:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo)
|
||||
{
|
||||
return context->output->video->Command(context, OUTPUT_GET_FRAME_COUNT, argument);
|
||||
}
|
||||
if (context->playback->isAudio)
|
||||
{
|
||||
return context->output->audio->Command(context, OUTPUT_GET_FRAME_COUNT, argument);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
case OUTPUT_GET_PROGRESSIVE:
|
||||
{
|
||||
if (context && context->playback)
|
||||
{
|
||||
if (context->playback->isVideo)
|
||||
{
|
||||
return context->output->video->Command(context, OUTPUT_GET_PROGRESSIVE, (void *) argument);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
output_err("%s::%s OutputCmd %d not supported!\n", FILENAME, __FUNCTION__, command);
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
output_printf(10, "%s::%s exiting with value %d\n", FILENAME, __FUNCTION__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
OutputHandler_t OutputHandler =
|
||||
{
|
||||
"Output",
|
||||
NULL, //audio
|
||||
NULL, //video
|
||||
NULL, //subtitle
|
||||
&Command
|
||||
};
|
332
libeplayer3-arm/output/output_subtitle.c
Normal file
332
libeplayer3-arm/output/output_subtitle.c
Normal file
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* Subtitle output to one registered client.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
//SULGE DEBUG ENABLED
|
||||
//#define SAM_WITH_DEBUG
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define SUBTITLE_DEBUG
|
||||
#else
|
||||
#define SUBTITLE_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef SUBTITLE_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define subtitle_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define subtitle_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef SUBTITLE_SILENT
|
||||
#define subtitle_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define subtitle_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* Error Constants */
|
||||
#define cERR_SUBTITLE_NO_ERROR 0
|
||||
#define cERR_SUBTITLE_ERROR -1
|
||||
|
||||
static const char FILENAME[] = __FILE__;
|
||||
|
||||
/*
|
||||
Number, Style, Name,, MarginL, MarginR, MarginV, Effect,, Text
|
||||
|
||||
1038,0,tdk,,0000,0000,0000,,That's not good.
|
||||
1037,0,tdk,,0000,0000,0000,,{\i1}Rack them up, rack them up,{\i0}\N{\i1}rack them up.{\i0} [90]
|
||||
1036,0,tdk,,0000,0000,0000,,Okay, rack them up.
|
||||
*/
|
||||
|
||||
#define PUFFERSIZE 20
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
static pthread_mutex_t mutex;
|
||||
static int isSubtitleOpened = 0;
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
static void getMutex(int line)
|
||||
{
|
||||
subtitle_printf(100, "%d requesting mutex\n", line);
|
||||
pthread_mutex_lock(&mutex);
|
||||
subtitle_printf(100, "%d received mutex\n", line);
|
||||
}
|
||||
|
||||
static void releaseMutex(int line)
|
||||
{
|
||||
pthread_mutex_unlock(&mutex);
|
||||
subtitle_printf(100, "%d released mutex\n", line);
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static char *ass_get_text(char *str)
|
||||
{
|
||||
// Events are stored in the Block in this order:
|
||||
// ReadOrder, Layer, Style, Name, MarginL, MarginR, MarginV, Effect, Text
|
||||
// 91,0,Default,,0,0,0,,maar hij smaakt vast tof.
|
||||
int i = 0;
|
||||
char *p_str = str;
|
||||
while (i < 8 && *p_str != '\0')
|
||||
{
|
||||
if (*p_str == ',')
|
||||
i++;
|
||||
p_str++;
|
||||
}
|
||||
// standardize hard break: '\N' -> '\n'
|
||||
// http://docs.aegisub.org/3.2/ASS_Tags/
|
||||
char *p_newline = NULL;
|
||||
while ((p_newline = strstr(p_str, "\\N")) != NULL)
|
||||
* (p_newline + 1) = 'n';
|
||||
return p_str;
|
||||
}
|
||||
|
||||
static char *json_string_escape(char *str)
|
||||
{
|
||||
static char tmp[2048];
|
||||
char *ptr1 = tmp;
|
||||
char *ptr2 = str;
|
||||
while (*ptr2 != '\0')
|
||||
{
|
||||
switch (*ptr2)
|
||||
{
|
||||
case '"':
|
||||
*ptr1++ = '\\';
|
||||
*ptr1++ = '\"';
|
||||
break;
|
||||
case '\\':
|
||||
*ptr1++ = '\\';
|
||||
*ptr1++ = '\\';
|
||||
break;
|
||||
case '\b':
|
||||
*ptr1++ = '\\';
|
||||
*ptr1++ = 'b';
|
||||
break;
|
||||
case '\f':
|
||||
*ptr1++ = '\\';
|
||||
*ptr1++ = 'f';
|
||||
break;
|
||||
case '\n':
|
||||
*ptr1++ = '\\';
|
||||
*ptr1++ = 'n';
|
||||
break;
|
||||
case '\r':
|
||||
*ptr1++ = '\\';
|
||||
*ptr1++ = 'r';
|
||||
break;
|
||||
case '\t':
|
||||
*ptr1++ = '\\';
|
||||
*ptr1++ = 't';
|
||||
break;
|
||||
default:
|
||||
*ptr1++ = *ptr2;
|
||||
break;
|
||||
}
|
||||
++ptr2;
|
||||
}
|
||||
*ptr1 = '\0';
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static int Flush()
|
||||
{
|
||||
fprintf(stderr, "{\"s_f\":{\"r\":0}}\n");
|
||||
return cERR_SUBTITLE_NO_ERROR;
|
||||
}
|
||||
|
||||
static int Write(void *_context, void *data)
|
||||
{
|
||||
Context_t *context = (Context_t *)_context;
|
||||
char *Encoding = NULL;
|
||||
SubtitleOut_t *out = NULL;
|
||||
int32_t curtrackid = -1;
|
||||
subtitle_printf(10, "\n");
|
||||
if (data == NULL)
|
||||
{
|
||||
subtitle_err("null pointer passed\n");
|
||||
return cERR_SUBTITLE_ERROR;
|
||||
}
|
||||
out = (SubtitleOut_t *) data;
|
||||
context->manager->subtitle->Command(context, MANAGER_GET, &curtrackid);
|
||||
if (curtrackid != out->trackId)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
context->manager->subtitle->Command(context, MANAGER_GETENCODING, &Encoding);
|
||||
if (Encoding == NULL)
|
||||
{
|
||||
subtitle_err("encoding unknown\n");
|
||||
return cERR_SUBTITLE_ERROR;
|
||||
}
|
||||
subtitle_printf(20, "Encoding:%s Text:%s Len:%d\n", Encoding, (const char *) out->data, out->len);
|
||||
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));
|
||||
}
|
||||
else if (!strncmp("S_TEXT/ASS", Encoding, 10))
|
||||
{
|
||||
fprintf(stderr, "{\"s_a\":{\"id\":%d,\"s\":%lld,\"e\":%lld,\"t\":\"%s\"}}\n", out->trackId, out->pts / 90, out->pts / 90 + out->durationMS, ass_get_text((char *)out->data));
|
||||
}
|
||||
else
|
||||
{
|
||||
subtitle_err("unknown encoding %s\n", Encoding);
|
||||
return cERR_SUBTITLE_ERROR;
|
||||
}
|
||||
subtitle_printf(10, "<\n");
|
||||
return cERR_SUBTITLE_NO_ERROR;
|
||||
}
|
||||
|
||||
static int32_t subtitle_Open(Context_t *context __attribute__((unused)))
|
||||
{
|
||||
uint32_t i = 0 ;
|
||||
subtitle_printf(10, "\n");
|
||||
if (isSubtitleOpened == 1)
|
||||
{
|
||||
subtitle_err("already opened! ignoring\n");
|
||||
return cERR_SUBTITLE_ERROR;
|
||||
}
|
||||
getMutex(__LINE__);
|
||||
isSubtitleOpened = 1;
|
||||
releaseMutex(__LINE__);
|
||||
subtitle_printf(10, "<\n");
|
||||
return cERR_SUBTITLE_NO_ERROR;
|
||||
}
|
||||
|
||||
static int32_t subtitle_Close(Context_t *context __attribute__((unused)))
|
||||
{
|
||||
uint32_t i = 0 ;
|
||||
subtitle_printf(10, "\n");
|
||||
getMutex(__LINE__);
|
||||
isSubtitleOpened = 0;
|
||||
releaseMutex(__LINE__);
|
||||
subtitle_printf(10, "<\n");
|
||||
return cERR_SUBTITLE_NO_ERROR;
|
||||
}
|
||||
|
||||
static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
{
|
||||
Context_t *context = (Context_t *) _context;
|
||||
int ret = cERR_SUBTITLE_NO_ERROR;
|
||||
subtitle_printf(50, "%d\n", command);
|
||||
switch (command)
|
||||
{
|
||||
case OUTPUT_OPEN:
|
||||
{
|
||||
ret = subtitle_Open(context);
|
||||
break;
|
||||
}
|
||||
case OUTPUT_CLOSE:
|
||||
{
|
||||
ret = subtitle_Close(context);
|
||||
break;
|
||||
}
|
||||
case OUTPUT_PLAY:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case OUTPUT_STOP:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case OUTPUT_SWITCH:
|
||||
{
|
||||
ret = Flush();
|
||||
break;
|
||||
}
|
||||
case OUTPUT_FLUSH:
|
||||
{
|
||||
ret = Flush();
|
||||
break;
|
||||
}
|
||||
case OUTPUT_CLEAR:
|
||||
{
|
||||
ret = Flush();
|
||||
break;
|
||||
}
|
||||
case OUTPUT_PAUSE:
|
||||
{
|
||||
subtitle_err("Subtitle Pause not implemented\n");
|
||||
ret = cERR_SUBTITLE_ERROR;
|
||||
break;
|
||||
}
|
||||
case OUTPUT_CONTINUE:
|
||||
{
|
||||
subtitle_err("Subtitle Continue not implemented\n");
|
||||
ret = cERR_SUBTITLE_ERROR;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
subtitle_err("OutputCmd %d not supported!\n", command);
|
||||
ret = cERR_SUBTITLE_ERROR;
|
||||
break;
|
||||
}
|
||||
subtitle_printf(50, "exiting with value %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static char *SubtitleCapabilitis[] = { "subtitle", NULL };
|
||||
|
||||
Output_t SubtitleOutput =
|
||||
{
|
||||
"Subtitle",
|
||||
&Command,
|
||||
&Write,
|
||||
SubtitleCapabilitis
|
||||
};
|
123
libeplayer3-arm/output/writer/common/misc.c
Normal file
123
libeplayer3-arm/output/writer/common/misc.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* LinuxDVB Output handling.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
void PutBits(BitPacker_t *ld, unsigned int code, unsigned int length)
|
||||
{
|
||||
unsigned int bit_buf;
|
||||
unsigned int bit_left;
|
||||
bit_buf = ld->BitBuffer;
|
||||
bit_left = ld->Remaining;
|
||||
#ifdef DEBUG_PUTBITS
|
||||
if (ld->debug)
|
||||
dprintf("code = %d, length = %d, bit_buf = 0x%x, bit_left = %d\n", code, length, bit_buf, bit_left);
|
||||
#endif /* DEBUG_PUTBITS */
|
||||
if (length < bit_left)
|
||||
{
|
||||
/* fits into current buffer */
|
||||
bit_buf = (bit_buf << length) | code;
|
||||
bit_left -= length;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* doesn't fit */
|
||||
bit_buf <<= bit_left;
|
||||
bit_buf |= code >> (length - bit_left);
|
||||
ld->Ptr[0] = (char)(bit_buf >> 24);
|
||||
ld->Ptr[1] = (char)(bit_buf >> 16);
|
||||
ld->Ptr[2] = (char)(bit_buf >> 8);
|
||||
ld->Ptr[3] = (char)bit_buf;
|
||||
ld->Ptr += 4;
|
||||
length -= bit_left;
|
||||
bit_buf = code & ((1 << length) - 1);
|
||||
bit_left = 32 - length;
|
||||
bit_buf = code;
|
||||
}
|
||||
#ifdef DEBUG_PUTBITS
|
||||
if (ld->debug)
|
||||
dprintf("bit_left = %d, bit_buf = 0x%x\n", bit_left, bit_buf);
|
||||
#endif /* DEBUG_PUTBITS */
|
||||
/* writeback */
|
||||
ld->BitBuffer = bit_buf;
|
||||
ld->Remaining = bit_left;
|
||||
}
|
||||
|
||||
void FlushBits(BitPacker_t *ld)
|
||||
{
|
||||
ld->BitBuffer <<= ld->Remaining;
|
||||
while (ld->Remaining < 32)
|
||||
{
|
||||
#ifdef DEBUG_PUTBITS
|
||||
if (ld->debug)
|
||||
dprintf("flushing 0x%2.2x\n", ld->BitBuffer >> 24);
|
||||
#endif /* DEBUG_PUTBITS */
|
||||
*ld->Ptr++ = ld->BitBuffer >> 24;
|
||||
ld->BitBuffer <<= 8;
|
||||
ld->Remaining += 8;
|
||||
}
|
||||
ld->Remaining = 32;
|
||||
ld->BitBuffer = 0;
|
||||
}
|
163
libeplayer3-arm/output/writer/common/pes.c
Normal file
163
libeplayer3-arm/output/writer/common/pes.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Functions */
|
||||
/* ***************************** */
|
||||
|
||||
int32_t InsertVideoPrivateDataHeader(uint8_t *data, int32_t payload_size)
|
||||
{
|
||||
BitPacker_t ld2 = {data, 0, 32};
|
||||
int32_t i = 0;
|
||||
PutBits(&ld2, PES_PRIVATE_DATA_FLAG, 8);
|
||||
PutBits(&ld2, payload_size & 0xff, 8);
|
||||
PutBits(&ld2, (payload_size >> 8) & 0xff, 8);
|
||||
PutBits(&ld2, (payload_size >> 16) & 0xff, 8);
|
||||
for (i = 4; i < (PES_PRIVATE_DATA_LENGTH + 1); i++)
|
||||
{
|
||||
PutBits(&ld2, 0, 8);
|
||||
}
|
||||
FlushBits(&ld2);
|
||||
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)
|
||||
{
|
||||
BitPacker_t ld2 = {data, 0, 32};
|
||||
if (size > (MAX_PES_PACKET_SIZE - 13))
|
||||
{
|
||||
size = -1; // unbounded
|
||||
}
|
||||
PutBits(&ld2, 0x0, 8);
|
||||
PutBits(&ld2, 0x0, 8);
|
||||
PutBits(&ld2, 0x1, 8); // Start Code
|
||||
PutBits(&ld2, stream_id, 8); // Stream_id = Audio Stream
|
||||
//4
|
||||
if (-1 == size)
|
||||
{
|
||||
PutBits(&ld2, 0x0, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
PutBits(&ld2, size + 3 + (pts != INVALID_PTS_VALUE ? 5 : 0) + (pic_start_code ? (5) : 0), 16); // PES_packet_length
|
||||
}
|
||||
//6 = 4+2
|
||||
PutBits(&ld2, 0x2, 2); // 10
|
||||
PutBits(&ld2, 0x0, 2); // PES_Scrambling_control
|
||||
PutBits(&ld2, 0x0, 1); // PES_Priority
|
||||
PutBits(&ld2, 0x0, 1); // data_alignment_indicator
|
||||
PutBits(&ld2, 0x0, 1); // Copyright
|
||||
PutBits(&ld2, 0x0, 1); // Original or Copy
|
||||
//7 = 6+1
|
||||
if (pts != INVALID_PTS_VALUE)
|
||||
{
|
||||
PutBits(&ld2, 0x2, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
PutBits(&ld2, 0x0, 2); // PTS_DTS flag
|
||||
}
|
||||
PutBits(&ld2, 0x0, 1); // ESCR_flag
|
||||
PutBits(&ld2, 0x0, 1); // ES_rate_flag
|
||||
PutBits(&ld2, 0x0, 1); // DSM_trick_mode_flag
|
||||
PutBits(&ld2, 0x0, 1); // additional_copy_ingo_flag
|
||||
PutBits(&ld2, 0x0, 1); // PES_CRC_flag
|
||||
PutBits(&ld2, 0x0, 1); // PES_extension_flag
|
||||
//8 = 7+1
|
||||
if (pts != INVALID_PTS_VALUE)
|
||||
{
|
||||
PutBits(&ld2, 0x5, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
PutBits(&ld2, 0x0, 8); // PES_header_data_length
|
||||
}
|
||||
//9 = 8+1
|
||||
if (pts != INVALID_PTS_VALUE)
|
||||
{
|
||||
PutBits(&ld2, 0x2, 4);
|
||||
PutBits(&ld2, (pts >> 30) & 0x7, 3);
|
||||
PutBits(&ld2, 0x1, 1);
|
||||
PutBits(&ld2, (pts >> 15) & 0x7fff, 15);
|
||||
PutBits(&ld2, 0x1, 1);
|
||||
PutBits(&ld2, pts & 0x7fff, 15);
|
||||
PutBits(&ld2, 0x1, 1);
|
||||
}
|
||||
//14 = 9+5
|
||||
if (pic_start_code)
|
||||
{
|
||||
PutBits(&ld2, 0x0, 8);
|
||||
PutBits(&ld2, 0x0, 8);
|
||||
PutBits(&ld2, 0x1, 8); // Start Code
|
||||
PutBits(&ld2, pic_start_code & 0xff, 8); // 00, for picture start
|
||||
PutBits(&ld2, (pic_start_code >> 8) & 0xff, 8); // For any extra information (like in mpeg4p2, the pic_start_code)
|
||||
//14 + 4 = 18
|
||||
}
|
||||
FlushBits(&ld2);
|
||||
return (ld2.Ptr - data);
|
||||
}
|
374
libeplayer3-arm/output/writer/mipsel/aac.c
Normal file
374
libeplayer3-arm/output/writer/mipsel/aac.c
Normal file
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <libavutil/intreadwrite.h>
|
||||
#include "ffmpeg/latmenc.h"
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
#include "aac.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
//#define SAM_WITH_DEBUG
|
||||
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define AAC_DEBUG
|
||||
#else
|
||||
#define AAC_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef AAC_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define aac_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define aac_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef AAC_SILENT
|
||||
#define aac_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define aac_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/// ** AAC ADTS format **
|
||||
///
|
||||
/// AAAAAAAA AAAABCCD EEFFFFGH HHIJKLMM
|
||||
/// MMMMMMMM MMMNNNNN NNNNNNOO ........
|
||||
///
|
||||
/// Sign Length Position Description
|
||||
///
|
||||
/// A 12 (31-20) Sync code
|
||||
/// B 1 (19) ID
|
||||
/// C 2 (18-17) layer
|
||||
/// D 1 (16) protect absent
|
||||
/// E 2 (15-14) profile
|
||||
/// F 4 (13-10) sample freq index
|
||||
/// G 1 (9) private
|
||||
/// H 3 (8-6) channel config
|
||||
/// I 1 (5) original/copy
|
||||
/// J 1 (4) home
|
||||
/// K 1 (3) copyright id
|
||||
/// L 1 (2) copyright start
|
||||
/// M 13 (1-0,31-21) frame length
|
||||
/// N 11 (20-10) adts buffer fullness
|
||||
/// O 2 (9-8) num of raw data blocks in frame
|
||||
|
||||
/*
|
||||
LC: Audio: aac, 44100 Hz, stereo, s16, 192 kb/ ->ff f1 50 80 00 1f fc
|
||||
HE: Audio: aac, 48000 Hz, stereo, s16, 77 kb/s ->ff f1 4c 80 00 1f fc
|
||||
*/
|
||||
|
||||
/*
|
||||
ADIF = basic format called Audio Data Interchange Format (ADIF)
|
||||
consisting of a single header followed by the raw AAC audio data blocks
|
||||
ADTS = streaming format called Audio Data Transport Stream (ADTS)
|
||||
consisting of a series of frames, each frame having a header followed by the AAC audio data
|
||||
LOAS = Low Overhead Audio Stream (LOAS), a self-synchronizing streaming format
|
||||
*/
|
||||
|
||||
static unsigned char DefaultAACHeader[] =
|
||||
{
|
||||
0xff,
|
||||
0xf1,
|
||||
/*0x00, 0x00*/0x50, //((Profile & 0x03) << 6) | (SampleIndex << 2) | ((Channels >> 2) & 0x01);s
|
||||
0x80, //(Channels & 0x03) << 6;
|
||||
0x00,
|
||||
0x1f,
|
||||
0xfc
|
||||
};
|
||||
|
||||
LATMContext *pLATMCtx = NULL;
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int reset()
|
||||
{
|
||||
if (pLATMCtx)
|
||||
{
|
||||
free(pLATMCtx);
|
||||
pLATMCtx = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _writeData(void *_call, int type)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
aac_printf(10, "\n _writeData type[%d]\n", type);
|
||||
if (call == NULL)
|
||||
{
|
||||
aac_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->data == NULL) || (call->len < 8))
|
||||
{
|
||||
aac_err("parsing Data with missing AAC header. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
/* simple validation */
|
||||
if (0 == type) // check ADTS header
|
||||
{
|
||||
if (0xFF != call->data[0] || 0xF0 != (0xF0 & call->data[1]))
|
||||
{
|
||||
aac_err("parsing Data with missing syncword. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else // check LOAS header
|
||||
{
|
||||
if (!(call->len > 2 && call->data[0] == 0x56 && (call->data[1] >> 4) == 0xe &&
|
||||
(AV_RB16(call->data + 1) & 0x1FFF) + 3 == call->len))
|
||||
{
|
||||
aac_err("parsing Data with wrong latm header. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
aac_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
unsigned int HeaderLength = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = HeaderLength;
|
||||
iov[1].iov_base = call->data;
|
||||
iov[1].iov_len = call->len;
|
||||
return writev_with_retry(call->fd, iov, 2);
|
||||
}
|
||||
|
||||
static int writeDataADTS(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
aac_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
aac_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
aac_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
aac_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->private_data && 0 == strncmp("ADTS", call->private_data, call->private_size)) ||
|
||||
HasADTSHeader(call->data, call->len))
|
||||
{
|
||||
return _writeData(_call, 0);
|
||||
}
|
||||
uint32_t PacketLength = call->len + 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);
|
||||
uint8_t *pExtraData = &PesHeader[headerSize];
|
||||
aac_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if (call->private_data == NULL)
|
||||
{
|
||||
aac_printf(10, "private_data = NULL\n");
|
||||
memcpy(pExtraData, DefaultAACHeader, AAC_HEADER_LENGTH);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pExtraData, call->private_data, AAC_HEADER_LENGTH);
|
||||
}
|
||||
pExtraData[3] &= 0xC0;
|
||||
/* frame size over last 2 bits */
|
||||
pExtraData[3] |= (PacketLength & 0x1800) >> 11;
|
||||
/* frame size continued over full byte */
|
||||
pExtraData[4] = (PacketLength & 0x1FF8) >> 3;
|
||||
/* frame size continued first 3 bits */
|
||||
pExtraData[5] = (PacketLength & 7) << 5;
|
||||
/* buffer fullness(0x7FF for VBR) over 5 last bits */
|
||||
pExtraData[5] |= 0x1F;
|
||||
/* buffer fullness(0x7FF for VBR) continued over 6 first bits + 2 zeros for
|
||||
* number of raw data blocks */
|
||||
pExtraData[6] = 0xFC;
|
||||
//PesHeader[6] = 0x81;
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = headerSize + AAC_HEADER_LENGTH;
|
||||
iov[1].iov_base = call->data;
|
||||
iov[1].iov_len = call->len;
|
||||
return writev_with_retry(call->fd, iov, 2);
|
||||
}
|
||||
|
||||
static int writeDataLATM(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
aac_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
aac_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
aac_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->private_data && 0 == strncmp("LATM", call->private_data, call->private_size))
|
||||
{
|
||||
return _writeData(_call, 1);
|
||||
}
|
||||
aac_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if (!pLATMCtx)
|
||||
{
|
||||
pLATMCtx = malloc(sizeof(LATMContext));
|
||||
memset(pLATMCtx, 0x00, sizeof(LATMContext));
|
||||
pLATMCtx->mod = 14;
|
||||
pLATMCtx->counter = 0;
|
||||
}
|
||||
if (!pLATMCtx)
|
||||
{
|
||||
aac_err("parsing NULL pLATMCtx. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
int ret = latmenc_decode_extradata(pLATMCtx, call->private_data, call->private_size);
|
||||
if (ret)
|
||||
{
|
||||
printf("%02x %02x %02x %02x %02x %02x %02x %02x\n", (int)call->data[0], (int)call->data[1], (int)call->data[2], (int)call->data[3], \
|
||||
(int)call->data[4], (int)call->data[5], (int)call->data[6], (int)call->data[7]);
|
||||
aac_err("latm_decode_extradata failed. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
ret = latmenc_write_packet(pLATMCtx, call->data, call->len, call->private_data, call->private_size);
|
||||
if (ret)
|
||||
{
|
||||
aac_err("latm_write_packet failed. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
unsigned int HeaderLength = InsertPesHeader(PesHeader, pLATMCtx->len + 3, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
|
||||
struct iovec iov[3];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = HeaderLength;
|
||||
iov[1].iov_base = pLATMCtx->loas_header;
|
||||
iov[1].iov_len = 3;
|
||||
iov[2].iov_base = pLATMCtx->buffer;
|
||||
iov[2].iov_len = pLATMCtx->len;
|
||||
return writev_with_retry(call->fd, iov, 3);
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps =
|
||||
{
|
||||
"aac",
|
||||
eAudio,
|
||||
"A_AAC",
|
||||
-1,
|
||||
AUDIOTYPE_AAC_PLUS,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioAAC =
|
||||
{
|
||||
&reset,
|
||||
&writeDataADTS,
|
||||
NULL,
|
||||
&caps
|
||||
};
|
||||
|
||||
static WriterCaps_t caps_aac_latm =
|
||||
{
|
||||
"aac",
|
||||
eAudio,
|
||||
"A_AAC_LATM",
|
||||
-1,
|
||||
AUDIOTYPE_AAC_HE, // it is some misunderstanding, this should be AUDIOTYPE_AAC_LATM
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioAACLATM =
|
||||
{
|
||||
&reset,
|
||||
&writeDataLATM,
|
||||
NULL,
|
||||
&caps_aac_latm
|
||||
};
|
||||
|
||||
static WriterCaps_t caps_aacplus =
|
||||
{
|
||||
"aac",
|
||||
eAudio,
|
||||
"A_AAC_PLUS",
|
||||
-1,
|
||||
AUDIOTYPE_AAC_PLUS,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioAACPLUS =
|
||||
{
|
||||
&reset,
|
||||
&writeDataADTS,
|
||||
NULL,
|
||||
&caps_aacplus
|
||||
};
|
170
libeplayer3-arm/output/writer/mipsel/ac3.c
Normal file
170
libeplayer3-arm/output/writer/mipsel/ac3.c
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
#define AC3_HEADER_LENGTH 7
|
||||
|
||||
#define AC3_DEBUG
|
||||
|
||||
#ifdef AC3_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define ac3_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define ac3_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef AC3_SILENT
|
||||
#define ac3_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define ac3_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
unsigned char AC3_SYNC_HEADER[] = {0x80, 0x01, 0x00, 0x01};
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int reset()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
ac3_printf(10, "\n");
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
if (call == NULL)
|
||||
{
|
||||
ac3_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
ac3_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
ac3_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
ac3_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
struct iovec iov[3];
|
||||
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)
|
||||
//PesHeader[6] = 0x81;
|
||||
//PesHeader[7] = 0x80;
|
||||
//PesHeader[8] = 0x09;
|
||||
//iov[1].iov_base = AC3_SYNC_HEADER;
|
||||
//iov[1].iov_len = sizeof(AC3_SYNC_HEADER);
|
||||
iov[1].iov_base = call->data;
|
||||
iov[1].iov_len = call->len;
|
||||
ac3_printf(40, "PES HEADER LEN %d\n", iov[0].iov_len);
|
||||
return writev_with_retry(call->fd, iov, 2);
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps_ac3 =
|
||||
{
|
||||
"ac3",
|
||||
eAudio,
|
||||
"A_AC3",
|
||||
AUDIO_ENCODING_AC3,
|
||||
AUDIOTYPE_AC3,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioAC3 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_ac3
|
||||
};
|
||||
|
||||
static WriterCaps_t caps_eac3 =
|
||||
{
|
||||
"ac3",
|
||||
eAudio,
|
||||
"A_EAC3",
|
||||
AUDIO_ENCODING_AC3,
|
||||
AUDIOTYPE_AC3_PLUS,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioEAC3 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_eac3
|
||||
};
|
176
libeplayer3-arm/output/writer/mipsel/amr.c
Normal file
176
libeplayer3-arm/output/writer/mipsel/amr.c
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
#define SAM_WITH_DEBUG
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define AMR_DEBUG
|
||||
#else
|
||||
#define AMR_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef AMR_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define amr_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define amr_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef AMR_SILENT
|
||||
#define amr_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define amr_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int reset()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4 + 9];
|
||||
amr_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
amr_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
amr_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
amr_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
amr_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
uint8_t hasCodecData = 1;
|
||||
if (NULL != call->private_data && call->private_size >= 17)
|
||||
{
|
||||
amr_err("wrong private_data. ignoring ...\n");
|
||||
hasCodecData = 1;
|
||||
}
|
||||
size_t payload_len = call->len;
|
||||
if (hasCodecData)
|
||||
{
|
||||
payload_len += 9;
|
||||
}
|
||||
payload_len += 4;
|
||||
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 >> 16) & 0xff;
|
||||
PesHeader[headerSize++] = (payload_len >> 8) & 0xff;
|
||||
PesHeader[headerSize++] = payload_len & 0xff;
|
||||
if (hasCodecData)
|
||||
{
|
||||
uint8_t tmp[] = {0x45, 0x4d, 0x50, 0x20, 0x00, 0x00, 0x80, 0x00, 0x01};
|
||||
memcpy(&PesHeader[headerSize], tmp, 9);
|
||||
//memcpy(&PesHeader[headerSize], call->private_data + 8, 9);
|
||||
//memset(&PesHeader[headerSize], 0, 9);
|
||||
}
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = headerSize;
|
||||
iov[1].iov_base = call->data;
|
||||
iov[1].iov_len = call->len;
|
||||
int len = writev_with_retry(call->fd, iov, 2);
|
||||
amr_printf(10, "amr_Write-< len=%d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps_amr =
|
||||
{
|
||||
"amr",
|
||||
eAudio,
|
||||
"A_AMR",
|
||||
-1,
|
||||
AUDIOTYPE_AMR,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioAMR =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_amr
|
||||
};
|
||||
|
||||
|
196
libeplayer3-arm/output/writer/mipsel/divx3.c
Normal file
196
libeplayer3-arm/output/writer/mipsel/divx3.c
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
#define B_GET_BITS(w,e,b) (((w)>>(b))&(((unsigned)(-1))>>((sizeof(unsigned))*8-(e+1-b))))
|
||||
#define B_SET_BITS(name,v,e,b) (((unsigned)(v))<<(b))
|
||||
|
||||
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define DIVX_DEBUG
|
||||
#else
|
||||
#define DIVX_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef DIVX_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define divx_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define divx_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef DIVX_SILENT
|
||||
#define divx_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define divx_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
static uint8_t initialHeader = 1;
|
||||
static uint8_t brcm_divx311_sequence_header[] =
|
||||
{
|
||||
0x00, 0x00, 0x01, 0xE0, 0x00, 0x34, 0x80, 0x80, // PES HEADER
|
||||
0x05, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20, /* 0 .. 7 */
|
||||
0x08, 0xC8, 0x0D, 0x40, 0x00, 0x53, 0x88, 0x40, /* 8 .. 15 */
|
||||
0x0C, 0x40, 0x01, 0x90, 0x00, 0x97, 0x53, 0x0A, /* 16 .. 24 */
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0x7F, 0x00, 0x00, 0x01, 0xB2, 0x44, 0x69, /* 0 .. 7 */
|
||||
0x76, 0x58, 0x33, 0x31, 0x31, 0x41, 0x4E, 0x44 /* 8 .. 15 */
|
||||
};
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
static int reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4];
|
||||
unsigned char Version = 5;
|
||||
unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE;
|
||||
divx_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
divx_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
divx_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
divx_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
divx_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
struct iovec iov[8];
|
||||
int ic = 0;
|
||||
if (initialHeader)
|
||||
{
|
||||
initialHeader = 0;
|
||||
uint8_t *data = brcm_divx311_sequence_header;
|
||||
int32_t height = call->Height;
|
||||
int32_t width = call->Width;
|
||||
data += 38;
|
||||
data[0] = B_GET_BITS(width, 11, 4);
|
||||
data[1] = B_SET_BITS("width [3..0]", B_GET_BITS(width, 3, 0), 7, 4) |
|
||||
B_SET_BITS("'10'", 0x02, 3, 2) |
|
||||
B_SET_BITS("height [11..10]", B_GET_BITS(height, 11, 10), 1, 0);
|
||||
data[2] = B_GET_BITS(height, 9, 2);
|
||||
data[3] = B_SET_BITS("height [1.0]", B_GET_BITS(height, 1, 0), 7, 6) |
|
||||
B_SET_BITS("'100000'", 0x20, 5, 0);
|
||||
iov[ic].iov_base = brcm_divx311_sequence_header;
|
||||
iov[ic++].iov_len = sizeof(brcm_divx311_sequence_header);
|
||||
}
|
||||
iov[ic].iov_base = PesHeader;
|
||||
uint32_t headerSize = 0;
|
||||
if (memcmp(call->data, "\x00\x00\x01\xb6", 4))
|
||||
{
|
||||
headerSize = InsertPesHeader(PesHeader, call->len + 4, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
|
||||
memcpy(PesHeader + headerSize, "\x00\x00\x01\xb6", 4);
|
||||
headerSize += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
headerSize = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
|
||||
}
|
||||
iov[ic++].iov_len = headerSize;
|
||||
iov[ic].iov_base = call->data;
|
||||
iov[ic++].iov_len = call->len;
|
||||
int len = writev_with_retry(call->fd, iov, ic);
|
||||
divx_printf(10, "xvid_Write < len=%d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t divix3_caps =
|
||||
{
|
||||
"divix3",
|
||||
eVideo,
|
||||
"V_DIVX3",
|
||||
VIDEO_ENCODING_MPEG4P2,
|
||||
STREAMTYPE_DIVX311,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoDIVX3 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&divix3_caps
|
||||
};
|
178
libeplayer3-arm/output/writer/mipsel/dts.c
Normal file
178
libeplayer3-arm/output/writer/mipsel/dts.c
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
#define PES_AUDIO_PRIVATE_HEADER_SIZE 16 // consider maximum private header size.
|
||||
#define PES_AUDIO_HEADER_SIZE (32 + PES_AUDIO_PRIVATE_HEADER_SIZE)
|
||||
#define PES_AUDIO_PACKET_SIZE 2028
|
||||
#define SPDIF_AUDIO_PACKET_SIZE (1024 * sizeof(unsigned int) * 2) // stereo 32bit samples.
|
||||
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define DTS_DEBUG
|
||||
#else
|
||||
#define DTS_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef DTS_DEBUG
|
||||
|
||||
static int16_t debug_level = 0;
|
||||
|
||||
#define dts_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define dts_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef DTS_SILENT
|
||||
#define dts_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define dts_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
static int32_t reset()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
uint8_t PesHeader[PES_AUDIO_HEADER_SIZE];
|
||||
dts_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
dts_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
dts_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
dts_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
dts_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
uint8_t *Data = call->data;
|
||||
int32_t Size = call->len;
|
||||
#ifdef CHECK_FOR_DTS_HD
|
||||
int32_t pos = 0;
|
||||
while ((pos + 4) <= Size)
|
||||
{
|
||||
// check for DTS-HD
|
||||
if (!strcmp((char *)(Data + pos), "\x64\x58\x20\x25"))
|
||||
{
|
||||
Size = pos;
|
||||
break;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
#endif
|
||||
// #define DO_BYTESWAP
|
||||
#ifdef DO_BYTESWAP
|
||||
/* 16-bit byte swap all data before injecting it */
|
||||
for (i = 0; i < Size; i += 2)
|
||||
{
|
||||
uint8_t Tmp = Data[i];
|
||||
Data[i] = Data[i + 1];
|
||||
Data[i + 1] = Tmp;
|
||||
}
|
||||
#endif
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = InsertPesHeader(PesHeader, Size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
|
||||
iov[1].iov_base = Data;
|
||||
iov[1].iov_len = Size;
|
||||
int32_t len = writev_with_retry(call->fd, iov, 2);
|
||||
dts_printf(10, "< len %d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps =
|
||||
{
|
||||
"dts",
|
||||
eAudio,
|
||||
"A_DTS",
|
||||
AUDIO_ENCODING_DTS,
|
||||
AUDIOTYPE_DTS,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioDTS =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps
|
||||
};
|
171
libeplayer3-arm/output/writer/mipsel/h263.c
Normal file
171
libeplayer3-arm/output/writer/mipsel/h263.c
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* crow 2010
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
//#define H263_DEBUG
|
||||
|
||||
#ifdef H263_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define h263_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define h263_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef H263_SILENT
|
||||
#define h263_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define h263_err(fmt, x...)
|
||||
#endif
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int32_t reset()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
uint8_t PesHeader[PES_MAX_HEADER_SIZE];
|
||||
int32_t len = 0;
|
||||
h263_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
h263_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
h263_printf(10, "VideoPts %lld\n", call->Pts);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
h263_err("NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
h263_err("file pointer < 0. ignoring ...\n");
|
||||
return 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 PesLength = PesHeader[PES_LENGTH_BYTE_0] + (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength;
|
||||
PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff;
|
||||
PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff;
|
||||
PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength;
|
||||
PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT;
|
||||
HeaderLength += PrivateHeaderLength;
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = HeaderLength;
|
||||
iov[1].iov_base = call->data;
|
||||
iov[1].iov_len = call->len;
|
||||
len = writev_with_retry(call->fd, iov, 2);
|
||||
h263_printf(10, "< len %d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps_h263 =
|
||||
{
|
||||
"h263",
|
||||
eVideo,
|
||||
"V_H263",
|
||||
VIDEO_ENCODING_H263,
|
||||
STREAMTYPE_H263,
|
||||
CT_MPEG4_PART2
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoH263 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_h263
|
||||
};
|
||||
|
||||
static WriterCaps_t caps_flv =
|
||||
{
|
||||
"FLV",
|
||||
eVideo,
|
||||
"V_FLV",
|
||||
VIDEO_ENCODING_FLV1,
|
||||
STREAMTYPE_H263,
|
||||
CT_MPEG4_PART2
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoFLV =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_flv
|
||||
};
|
441
libeplayer3-arm/output/writer/mipsel/h264.c
Normal file
441
libeplayer3-arm/output/writer/mipsel/h264.c
Normal file
@@ -0,0 +1,441 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
//#define H264_DEBUG
|
||||
#ifdef H264_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define h264_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define h264_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef H264_SILENT
|
||||
#define h264_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define h264_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
#define IOVEC_SIZE 128
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
static unsigned char Head[] = {0, 0, 0, 1};
|
||||
static int initialHeader = 1;
|
||||
static unsigned int NalLengthBytes = 1;
|
||||
static unsigned char *CodecData = NULL;
|
||||
static unsigned int CodecDataLen = 0;
|
||||
static int avc3 = 0;
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
// Please see: https://bugzilla.mozilla.org/show_bug.cgi?id=1105771
|
||||
static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize, uint8_t *pData, uint32_t dataSize)
|
||||
{
|
||||
uint8_t *aExtraData = *ppExtraData;
|
||||
if (aExtraData[0] != 1 || !pData)
|
||||
{
|
||||
// Not AVCC or nothing to update with.
|
||||
return -1;
|
||||
}
|
||||
int32_t nalsize = (aExtraData[4] & 3) + 1;
|
||||
uint8_t sps[256];
|
||||
uint8_t spsIdx = 0;
|
||||
uint8_t numSps = 0;
|
||||
uint8_t pps[256];
|
||||
uint8_t ppsIdx = 0;
|
||||
uint8_t numPps = 0;
|
||||
if (nalsize != 4)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
// Find SPS and PPS NALUs in AVCC data
|
||||
uint8_t *d = pData;
|
||||
while (d + 4 < pData + dataSize)
|
||||
{
|
||||
uint32_t nalLen = ReadUint32(d);
|
||||
uint8_t nalType = d[4] & 0x1f;
|
||||
if (nalType == 7)
|
||||
{
|
||||
/* SPS */
|
||||
// 16 bits size
|
||||
sps[spsIdx++] = (uint8_t)(0xFF & (nalLen >> 8));
|
||||
sps[spsIdx++] = (uint8_t)(0xFF & nalLen);
|
||||
if (spsIdx + nalLen >= sizeof(sps))
|
||||
{
|
||||
h264_err("SPS no free space to copy...\n");
|
||||
return -1;
|
||||
}
|
||||
memcpy(&(sps[spsIdx]), d + 4, nalLen);
|
||||
spsIdx += nalLen;
|
||||
numSps += 1;
|
||||
h264_printf(10, "SPS len[%u]...\n", nalLen);
|
||||
}
|
||||
else if (nalType == 8)
|
||||
{
|
||||
/* PPS */
|
||||
// 16 bits size
|
||||
pps[ppsIdx++] = (uint8_t)(0xFF & (nalLen >> 8));
|
||||
pps[ppsIdx++] = (uint8_t)(0xFF & nalLen);
|
||||
if (ppsIdx + nalLen >= sizeof(sps))
|
||||
{
|
||||
h264_err("PPS not free space to copy...\n");
|
||||
return -1;
|
||||
}
|
||||
memcpy(&(pps[ppsIdx]), d + 4, nalLen);
|
||||
ppsIdx += nalLen;
|
||||
numPps += 1;
|
||||
h264_printf(10, "PPS len[%u]...\n", nalLen);
|
||||
}
|
||||
d += 4 + nalLen;
|
||||
}
|
||||
uint32_t idx = 0;
|
||||
*ppExtraData = malloc(7 + spsIdx + ppsIdx);
|
||||
aExtraData = *ppExtraData;
|
||||
aExtraData[idx++] = 0x1; // version
|
||||
aExtraData[idx++] = sps[3]; // profile
|
||||
aExtraData[idx++] = sps[4]; // profile compat
|
||||
aExtraData[idx++] = sps[5]; // level
|
||||
aExtraData[idx++] = 0xff; // nal size - 1
|
||||
aExtraData[idx++] = 0xe0 | numSps;
|
||||
if (numSps)
|
||||
{
|
||||
memcpy(&(aExtraData[idx]), sps, spsIdx);
|
||||
idx += spsIdx;
|
||||
}
|
||||
aExtraData[idx++] = numPps;
|
||||
if (numPps)
|
||||
{
|
||||
memcpy(&(aExtraData[idx]), pps, ppsIdx);
|
||||
idx += ppsIdx;
|
||||
}
|
||||
h264_printf(10, "aExtraData len[%u]...\n", idx);
|
||||
*pExtraDataSize = idx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigned int *NalLength)
|
||||
{
|
||||
h264_printf(10, "H264 check codec data..!\n");
|
||||
int32_t ret = -100;
|
||||
if (data)
|
||||
{
|
||||
unsigned char tmp[2048];
|
||||
unsigned int tmp_len = 0;
|
||||
unsigned int cd_pos = 0;
|
||||
h264_printf(10, "H264 have codec data..!\n");
|
||||
if (cd_len > 7 && data[0] == 1)
|
||||
{
|
||||
unsigned short len = (data[6] << 8) | data[7];
|
||||
if (cd_len >= (len + 8))
|
||||
{
|
||||
unsigned int i = 0;
|
||||
uint8_t profile_num[] = { 66, 77, 88, 100 };
|
||||
uint8_t profile_cmp[2] = { 0x67, 0x00 };
|
||||
const char *profile_str[] = { "baseline", "main", "extended", "high" };
|
||||
memcpy(tmp, Head, sizeof(Head));
|
||||
tmp_len += 4;
|
||||
memcpy(tmp + tmp_len, data + 8, len);
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
profile_cmp[1] = profile_num[i];
|
||||
if (!memcmp(tmp + tmp_len, profile_cmp, 2))
|
||||
{
|
||||
uint8_t level_org = tmp[tmp_len + 3];
|
||||
if (level_org > 0x29)
|
||||
{
|
||||
h264_printf(10, "H264 %s profile@%d.%d patched down to 4.1!", profile_str[i], level_org / 10, level_org % 10);
|
||||
tmp[tmp_len + 3] = 0x29; // level 4.1
|
||||
}
|
||||
else
|
||||
{
|
||||
h264_printf(10, "H264 %s profile@%d.%d", profile_str[i], level_org / 10, level_org % 10);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
tmp_len += len;
|
||||
cd_pos = 8 + len;
|
||||
if (cd_len > (cd_pos + 2))
|
||||
{
|
||||
len = (data[cd_pos + 1] << 8) | data[cd_pos + 2];
|
||||
cd_pos += 3;
|
||||
if (cd_len >= (cd_pos + len))
|
||||
{
|
||||
memcpy(tmp + tmp_len, "\x00\x00\x00\x01", 4);
|
||||
tmp_len += 4;
|
||||
memcpy(tmp + tmp_len, data + cd_pos, len);
|
||||
tmp_len += len;
|
||||
CodecData = malloc(tmp_len);
|
||||
memcpy(CodecData, tmp, tmp_len);
|
||||
CodecDataLen = tmp_len;
|
||||
*NalLength = (data[4] & 0x03) + 1;
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
h264_printf(10, "codec_data too short(4)");
|
||||
ret = -4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
h264_printf(10, "codec_data too short(3)");
|
||||
ret = -3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
h264_printf(10, "codec_data too short(2)");
|
||||
ret = -2;
|
||||
}
|
||||
}
|
||||
else if (cd_len <= 7)
|
||||
{
|
||||
h264_printf(10, "codec_data too short(1)");
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
h264_printf(10, "wrong avcC version %d!", data[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*NalLength = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
avc3 = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
unsigned long long int VideoPts;
|
||||
unsigned int TimeDelta;
|
||||
unsigned int TimeScale;
|
||||
int len = 0;
|
||||
int ic = 0;
|
||||
struct iovec iov[IOVEC_SIZE];
|
||||
h264_printf(20, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
h264_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
TimeDelta = call->FrameRate;
|
||||
TimeScale = call->FrameScale;
|
||||
VideoPts = call->Pts;
|
||||
h264_printf(20, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
h264_err("NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
h264_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
/* AnnexA */
|
||||
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->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff))))
|
||||
{
|
||||
uint32_t PacketLength = 0;
|
||||
uint32_t FakeStartCode = (call->Version << 8) | PES_VERSION_FAKE_START_CODE;
|
||||
iov[ic++].iov_base = PesHeader;
|
||||
initialHeader = 0;
|
||||
//if (initialHeader) // some rtsp streams can update codec data at runtime
|
||||
{
|
||||
initialHeader = 0;
|
||||
iov[ic].iov_base = call->private_data;
|
||||
iov[ic++].iov_len = call->private_size;
|
||||
PacketLength += call->private_size;
|
||||
}
|
||||
iov[ic].iov_base = "";
|
||||
iov[ic++].iov_len = 1;
|
||||
iov[ic].iov_base = call->data;
|
||||
iov[ic++].iov_len = call->len;
|
||||
PacketLength += call->len;
|
||||
iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode);
|
||||
return writev_with_retry(call->fd, iov, ic);
|
||||
}
|
||||
else if (!call->private_data || call->private_size < 7 || 1 != call->private_data[0])
|
||||
{
|
||||
h264_err("No valid private data available! [%d]\n", (int)call->private_size);
|
||||
return 0;
|
||||
}
|
||||
uint32_t PacketLength = 0;
|
||||
ic = 0;
|
||||
iov[ic++].iov_base = PesHeader;
|
||||
if (initialHeader)
|
||||
{
|
||||
if (CodecData)
|
||||
{
|
||||
free(CodecData);
|
||||
CodecData = NULL;
|
||||
}
|
||||
uint8_t *private_data = call->private_data;
|
||||
uint32_t private_size = call->private_size;
|
||||
if (PreparCodecData(private_data, private_size, &NalLengthBytes))
|
||||
{
|
||||
UpdateExtraData(&private_data, &private_size, call->data, call->len);
|
||||
PreparCodecData(private_data, private_size, &NalLengthBytes);
|
||||
}
|
||||
if (private_data != call->private_data)
|
||||
{
|
||||
avc3 = 1;
|
||||
free(private_data);
|
||||
private_data = NULL;
|
||||
}
|
||||
if (CodecData != NULL)
|
||||
{
|
||||
iov[ic].iov_base = CodecData;
|
||||
iov[ic++].iov_len = CodecDataLen;
|
||||
PacketLength += CodecDataLen;
|
||||
initialHeader = 0;
|
||||
}
|
||||
}
|
||||
if (CodecData != NULL)
|
||||
{
|
||||
uint32_t pos = 0;
|
||||
do
|
||||
{
|
||||
if (ic >= IOVEC_SIZE)
|
||||
{
|
||||
h264_err(">> Drop data due to ic overflow\n");
|
||||
break;
|
||||
}
|
||||
uint32_t pack_len = 0;
|
||||
uint32_t i = 0;
|
||||
for (i = 0; i < NalLengthBytes; i++, pos++)
|
||||
{
|
||||
pack_len <<= 8;
|
||||
pack_len += call->data[pos];
|
||||
}
|
||||
if ((pos + pack_len) > call->len)
|
||||
{
|
||||
pack_len = call->len - pos;
|
||||
}
|
||||
iov[ic].iov_base = Head;
|
||||
iov[ic++].iov_len = sizeof(Head);
|
||||
PacketLength += sizeof(Head);
|
||||
iov[ic].iov_base = call->data + pos;
|
||||
iov[ic++].iov_len = pack_len;
|
||||
PacketLength += pack_len;
|
||||
pos += pack_len;
|
||||
}
|
||||
while ((pos + NalLengthBytes) < call->len);
|
||||
h264_printf(10, "<<<< PacketLength [%d]\n", PacketLength);
|
||||
iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, 0);
|
||||
len = writev_with_retry(call->fd, iov, ic);
|
||||
PacketLength += iov[0].iov_len;
|
||||
if (PacketLength != len)
|
||||
{
|
||||
h264_err("<<<< not all data have been written [%d/%d]\n", len, PacketLength);
|
||||
}
|
||||
}
|
||||
h264_printf(10, "< len %d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
static int writeReverseData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
return 0;
|
||||
}
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps =
|
||||
{
|
||||
"h264",
|
||||
eVideo,
|
||||
"V_MPEG4/ISO/AVC",
|
||||
VIDEO_ENCODING_H264,
|
||||
STREAMTYPE_MPEG4_H264,
|
||||
CT_H264
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoH264 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
&writeReverseData,
|
||||
&caps
|
||||
};
|
310
libeplayer3-arm/output/writer/mipsel/h265.c
Normal file
310
libeplayer3-arm/output/writer/mipsel/h265.c
Normal file
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
//#define H265_DEBUG
|
||||
#ifdef H265_DEBUG
|
||||
|
||||
static short debug_level = 10;
|
||||
|
||||
#define h264_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define h264_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef H265_SILENT
|
||||
#define h264_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define h264_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
#define IOVEC_SIZE 128
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
static unsigned char Head[] = {0, 0, 0, 1};
|
||||
static int initialHeader = 1;
|
||||
static unsigned int NalLengthBytes = 1;
|
||||
static unsigned char *CodecData = NULL;
|
||||
static unsigned int CodecDataLen = 0;
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigned int *NalLength)
|
||||
{
|
||||
h264_printf(10, "H265 check codec data..!\n");
|
||||
int32_t ret = -100;
|
||||
if (data)
|
||||
{
|
||||
unsigned char tmp[2048];
|
||||
unsigned int tmp_len = 0;
|
||||
h264_printf(10, "H265 have codec data..!");
|
||||
if (cd_len > 3 && (data[0] || data[1] || data[2] > 1))
|
||||
{
|
||||
if (cd_len > 22)
|
||||
{
|
||||
int i;
|
||||
if (data[0] != 0)
|
||||
{
|
||||
h264_printf(10, "Unsupported extra data version %d, decoding may fail", (int)data[0]);
|
||||
}
|
||||
*NalLength = (data[21] & 3) + 1;
|
||||
int num_param_sets = data[22];
|
||||
int pos = 23;
|
||||
for (i = 0; i < num_param_sets; i++)
|
||||
{
|
||||
int j;
|
||||
if (pos + 3 > cd_len)
|
||||
{
|
||||
h264_printf(10, "Buffer underrun in extra header (%d >= %u)", pos + 3, cd_len);
|
||||
break;
|
||||
}
|
||||
// ignore flags + NAL type (1 byte)
|
||||
int nal_count = data[pos + 1] << 8 | data[pos + 2];
|
||||
pos += 3;
|
||||
for (j = 0; j < nal_count; j++)
|
||||
{
|
||||
if (pos + 2 > cd_len)
|
||||
{
|
||||
h264_printf(10, "Buffer underrun in extra nal header (%d >= %u)", pos + 2, cd_len);
|
||||
break;
|
||||
}
|
||||
int nal_size = data[pos] << 8 | data[pos + 1];
|
||||
pos += 2;
|
||||
if (pos + nal_size > cd_len)
|
||||
{
|
||||
h264_printf(10, "Buffer underrun in extra nal (%d >= %u)", pos + 2 + nal_size, cd_len);
|
||||
break;
|
||||
}
|
||||
memcpy(tmp + tmp_len, "\x00\x00\x00\x01", 4);
|
||||
tmp_len += 4;
|
||||
memcpy(tmp + tmp_len, data + pos, nal_size);
|
||||
tmp_len += nal_size;
|
||||
pos += nal_size;
|
||||
}
|
||||
}
|
||||
CodecData = malloc(tmp_len);
|
||||
memcpy(CodecData, tmp, tmp_len);
|
||||
CodecDataLen = tmp_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*NalLength = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
unsigned long long int VideoPts;
|
||||
unsigned int TimeDelta;
|
||||
unsigned int TimeScale;
|
||||
int len = 0;
|
||||
int ic = 0;
|
||||
struct iovec iov[IOVEC_SIZE];
|
||||
h264_printf(20, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
h264_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
TimeDelta = call->FrameRate;
|
||||
TimeScale = call->FrameScale;
|
||||
VideoPts = call->Pts;
|
||||
h264_printf(20, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
h264_err("NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
h264_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->InfoFlags & 0x1) // TS container
|
||||
{
|
||||
h264_printf(10, "H265 simple inject method!\n");
|
||||
uint32_t PacketLength = 0;
|
||||
uint32_t FakeStartCode = (call->Version << 8) | PES_VERSION_FAKE_START_CODE;
|
||||
iov[ic++].iov_base = PesHeader;
|
||||
initialHeader = 0;
|
||||
if (initialHeader)
|
||||
{
|
||||
initialHeader = 0;
|
||||
iov[ic].iov_base = call->private_data;
|
||||
iov[ic++].iov_len = call->private_size;
|
||||
PacketLength += call->private_size;
|
||||
}
|
||||
iov[ic].iov_base = "";
|
||||
iov[ic++].iov_len = 1;
|
||||
iov[ic].iov_base = call->data;
|
||||
iov[ic++].iov_len = call->len;
|
||||
PacketLength += call->len;
|
||||
iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode);
|
||||
return writev_with_retry(call->fd, iov, ic);
|
||||
}
|
||||
uint32_t PacketLength = 0;
|
||||
ic = 0;
|
||||
iov[ic++].iov_base = PesHeader;
|
||||
if (initialHeader)
|
||||
{
|
||||
if (CodecData)
|
||||
{
|
||||
free(CodecData);
|
||||
CodecData = NULL;
|
||||
}
|
||||
uint8_t *private_data = call->private_data;
|
||||
uint32_t private_size = call->private_size;
|
||||
PreparCodecData(private_data, private_size, &NalLengthBytes);
|
||||
if (CodecData != NULL)
|
||||
{
|
||||
iov[ic].iov_base = CodecData;
|
||||
iov[ic++].iov_len = CodecDataLen;
|
||||
PacketLength += CodecDataLen;
|
||||
initialHeader = 0;
|
||||
}
|
||||
}
|
||||
if (CodecData != NULL)
|
||||
{
|
||||
uint32_t pos = 0;
|
||||
do
|
||||
{
|
||||
if (ic >= IOVEC_SIZE)
|
||||
{
|
||||
h264_err(">> Drop data due to ic overflow\n");
|
||||
break;
|
||||
}
|
||||
uint32_t pack_len = 0;
|
||||
uint32_t i = 0;
|
||||
for (i = 0; i < NalLengthBytes; i++, pos++)
|
||||
{
|
||||
pack_len <<= 8;
|
||||
pack_len += call->data[pos];
|
||||
}
|
||||
if ((pos + pack_len) > call->len)
|
||||
{
|
||||
pack_len = call->len - pos;
|
||||
}
|
||||
iov[ic].iov_base = Head;
|
||||
iov[ic++].iov_len = sizeof(Head);
|
||||
PacketLength += sizeof(Head);
|
||||
iov[ic].iov_base = call->data + pos;
|
||||
iov[ic++].iov_len = pack_len;
|
||||
PacketLength += pack_len;
|
||||
pos += pack_len;
|
||||
}
|
||||
while ((pos + NalLengthBytes) < call->len);
|
||||
h264_printf(10, "<<<< PacketLength [%d]\n", PacketLength);
|
||||
iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, 0);
|
||||
len = writev_with_retry(call->fd, iov, ic);
|
||||
PacketLength += iov[0].iov_len;
|
||||
if (PacketLength != len)
|
||||
{
|
||||
h264_err("<<<< not all data have been written [%d/%d]\n", len, PacketLength);
|
||||
}
|
||||
}
|
||||
h264_printf(10, "< len %d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
static int writeReverseData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
return 0;
|
||||
}
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps =
|
||||
{
|
||||
"h265",
|
||||
eVideo,
|
||||
"V_HEVC",
|
||||
-1,
|
||||
STREAMTYPE_MPEG4_H265,
|
||||
CT_H265
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoH265 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
&writeReverseData,
|
||||
&caps
|
||||
};
|
266
libeplayer3-arm/output/writer/mipsel/lpcm.c
Normal file
266
libeplayer3-arm/output/writer/mipsel/lpcm.c
Normal file
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#define _XOPEN_SOURCE
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
#include "pcm.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
//#define SAM_WITH_DEBUG
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define LPCM_DEBUG
|
||||
#else
|
||||
#define LPCM_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef LPCM_DEBUG
|
||||
|
||||
static uint16_t debug_level = 1;
|
||||
|
||||
#define lpcm_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define lpcm_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef LPCM_SILENT
|
||||
#define lpcm_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define lpcm_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
#define LLPCM_VOB_HEADER_LEN (6)
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
static uint8_t PesHeader[PES_MAX_HEADER_SIZE];
|
||||
static uint8_t initialHeader = 1;
|
||||
|
||||
static uint8_t i_freq_code = 0;
|
||||
static int32_t i_frame_samples;
|
||||
static int32_t i_frame_size;
|
||||
static int32_t i_buffer_used;
|
||||
static int32_t i_frame_num;
|
||||
static int32_t i_bitspersample;
|
||||
static uint8_t *p_buffer = 0;
|
||||
static uint8_t *p_frame_buffer = 0;
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
/* https://www.videolan.org/developers/vlc/modules/codec/lpcm.c
|
||||
* LPCM DVD header :
|
||||
* - number of frames in this packet (8 bits)
|
||||
* - first access unit (16 bits) == 0x0003 ?
|
||||
* - emphasis (1 bit)
|
||||
* - mute (1 bit)
|
||||
* - reserved (1 bit)
|
||||
* - current frame (5 bits)
|
||||
* - quantisation (2 bits) 0 == 16bps, 1 == 20bps, 2 == 24bps, 3 == illegal
|
||||
* - frequency (2 bits) 0 == 48 kHz, 1 == 96 kHz, 2 == 44.1 kHz, 3 == 32 kHz
|
||||
* - reserved (1 bit)
|
||||
* - number of channels - 1 (3 bits) 1 == 2 channels
|
||||
* - dynamic range (8 bits) 0x80 == neutral
|
||||
*/
|
||||
|
||||
static int32_t reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
lpcm_printf(10, "\n");
|
||||
if (!call)
|
||||
{
|
||||
lpcm_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
lpcm_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if (!call->data || (call->len <= 0))
|
||||
{
|
||||
lpcm_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
lpcm_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
pcmPrivateData_t *pcmPrivateData = (pcmPrivateData_t *)call->private_data;
|
||||
int32_t i_rate = (int32_t)pcmPrivateData->sample_rate;
|
||||
int32_t i_channels = (int32_t)pcmPrivateData->channels;
|
||||
int32_t i_nb_samples = call->len / (i_channels * 2);
|
||||
int32_t i_ret_size = 0;
|
||||
if (i_channels > 8)
|
||||
{
|
||||
lpcm_err("Error DVD LPCM supports a maximum of eight channels i_channels[%d]\n", i_channels);
|
||||
return 0;
|
||||
}
|
||||
if (pcmPrivateData->bResampling || NULL == p_buffer)
|
||||
{
|
||||
lpcm_printf(1, "i_rate: [%d]\n", i_rate);
|
||||
lpcm_printf(1, "i_channels: [%d]\n", i_channels);
|
||||
switch (i_rate)
|
||||
{
|
||||
case 48000:
|
||||
i_freq_code = 0;
|
||||
break;
|
||||
case 96000:
|
||||
i_freq_code = 1;
|
||||
break;
|
||||
case 44100:
|
||||
i_freq_code = 2;
|
||||
break;
|
||||
case 32000:
|
||||
i_freq_code = 3;
|
||||
break;
|
||||
default:
|
||||
lpcm_err("Error DVD LPCM sample_rate not supported [%d]\n", i_rate);
|
||||
return 0;
|
||||
}
|
||||
/* In DVD LCPM, a frame is always 150 PTS ticks. */
|
||||
i_frame_samples = i_rate * 150 / 90000;
|
||||
i_frame_size = i_frame_samples * i_channels * 2 + LLPCM_VOB_HEADER_LEN;
|
||||
if (NULL != p_buffer)
|
||||
{
|
||||
free(p_buffer);
|
||||
}
|
||||
p_buffer = malloc(i_frame_samples * i_channels * 16);
|
||||
if (NULL != p_frame_buffer)
|
||||
{
|
||||
free(p_frame_buffer);
|
||||
}
|
||||
p_frame_buffer = malloc(i_frame_size);
|
||||
i_buffer_used = 0;
|
||||
i_frame_num = 0;
|
||||
i_bitspersample = 16;
|
||||
}
|
||||
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_start_offset = -i_buffer_used;
|
||||
int32_t i_bytes_consumed = 0;
|
||||
int32_t i = 0;
|
||||
for (i = 0; i < i_num_frames; ++i)
|
||||
{
|
||||
uint8_t *frame = (uint8_t *)p_frame_buffer;
|
||||
frame[0] = 1; /* one frame in packet */
|
||||
frame[1] = 0;
|
||||
frame[2] = 0; /* no first access unit */
|
||||
frame[3] = (i_frame_num + i) & 0x1f; /* no emphasis, no mute */
|
||||
frame[4] = (i_freq_code << 4) | (i_channels - 1);
|
||||
frame[5] = 0x80; /* neutral dynamic range */
|
||||
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_consume_bytes = i_consume_samples * i_channels * 2;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
memcpy(frame + 6, p_buffer, i_kept_bytes);
|
||||
memcpy(frame + 6 + i_kept_bytes, call->data + i_bytes_consumed, i_consume_bytes);
|
||||
#else
|
||||
swab(p_buffer, frame + 6, i_kept_bytes);
|
||||
swab(call->data + i_bytes_consumed, frame + 6 + i_kept_bytes, i_consume_bytes);
|
||||
#endif
|
||||
i_frame_num++;
|
||||
i_buffer_used = 0;
|
||||
i_bytes_consumed += i_consume_bytes;
|
||||
/* 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;
|
||||
uint32_t pes_header_size = 0;
|
||||
pes_header_size = InsertPesHeader(PesHeader, i_frame_size + 1, MPEG_AUDIO_PES_START_CODE, this_pts, 0);
|
||||
PesHeader[pes_header_size] = 0xa0;
|
||||
pes_header_size += 1;
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = pes_header_size;
|
||||
iov[1].iov_base = frame;
|
||||
iov[1].iov_len = i_frame_size;
|
||||
i_ret_size += writev_with_retry(call->fd, iov, 2);
|
||||
}
|
||||
memcpy(p_buffer, call->data + i_bytes_consumed, i_leftover_samples * i_channels * 2);
|
||||
i_buffer_used = i_leftover_samples;
|
||||
return i_ret_size;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps_lpcm =
|
||||
{
|
||||
"ipcm",
|
||||
eAudio,
|
||||
"A_LPCM",
|
||||
AUDIO_ENCODING_LPCMA,
|
||||
AUDIOTYPE_LPCM,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioLPCM =
|
||||
{
|
||||
&reset,
|
||||
&writeData, /* writeDataLPCM */
|
||||
NULL,
|
||||
&caps_lpcm
|
||||
};
|
189
libeplayer3-arm/output/writer/mipsel/mp3.c
Normal file
189
libeplayer3-arm/output/writer/mipsel/mp3.c
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
#define MP3_DEBUG
|
||||
|
||||
#ifdef MP3_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define mp3_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define mp3_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef MP3_SILENT
|
||||
#define mp3_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define mp3_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int reset()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE + 22];
|
||||
mp3_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
mp3_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
mp3_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
mp3_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
mp3_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
call->private_size = 0;
|
||||
uint32_t headerSize = InsertPesHeader(PesHeader, call->len + call->private_size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
|
||||
if (call->private_size > 0)
|
||||
{
|
||||
memcpy(&PesHeader[headerSize], call->private_data, call->private_size);
|
||||
headerSize += call->private_size;
|
||||
}
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = headerSize;
|
||||
iov[1].iov_base = call->data;
|
||||
iov[1].iov_len = call->len;
|
||||
int len = writev_with_retry(call->fd, iov, 2);
|
||||
mp3_printf(10, "mp3_Write-< len=%d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps_mp3 =
|
||||
{
|
||||
"mp3",
|
||||
eAudio,
|
||||
"A_MP3",
|
||||
AUDIO_ENCODING_MP3,
|
||||
AUDIOTYPE_MP3,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioMP3 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_mp3
|
||||
};
|
||||
|
||||
static WriterCaps_t caps_mpegl3 =
|
||||
{
|
||||
"mpeg/l3",
|
||||
eAudio,
|
||||
"A_MPEG/L3",
|
||||
AUDIO_ENCODING_MPEG2,
|
||||
AUDIOTYPE_MP3,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioMPEGL3 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_mpegl3
|
||||
};
|
||||
|
||||
static WriterCaps_t caps_vorbis =
|
||||
{
|
||||
"vorbis",
|
||||
eAudio,
|
||||
"A_VORBIS",
|
||||
AUDIO_ENCODING_VORBIS,
|
||||
AUDIO_ENCODING_MP3,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioVORBIS =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_vorbis
|
||||
};
|
||||
|
180
libeplayer3-arm/output/writer/mipsel/mpeg2.c
Normal file
180
libeplayer3-arm/output/writer/mipsel/mpeg2.c
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
#define MPEG2_DEBUG
|
||||
|
||||
#ifdef MPEG2_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define mpeg2_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define mpeg2_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef MPEG2_SILENT
|
||||
#define mpeg2_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define mpeg2_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int reset()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
int len = 0;
|
||||
unsigned int Position = 0;
|
||||
mpeg2_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
mpeg2_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
mpeg2_printf(10, "VideoPts %lld\n", call->Pts);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
mpeg2_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
mpeg2_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
while (Position < call->len)
|
||||
{
|
||||
int PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ?
|
||||
(call->len - Position) : MAX_PES_PACKET_SIZE;
|
||||
int Remaining = call->len - Position - PacketLength;
|
||||
mpeg2_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", PacketLength, Remaining, Position);
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, 0xe0, call->Pts, 0);
|
||||
iov[1].iov_base = call->data + Position;
|
||||
iov[1].iov_len = PacketLength;
|
||||
ssize_t l = writev_with_retry(call->fd, iov, 2);
|
||||
if (l < 0)
|
||||
{
|
||||
len = l;
|
||||
break;
|
||||
}
|
||||
len += l;
|
||||
Position += PacketLength;
|
||||
call->Pts = INVALID_PTS_VALUE;
|
||||
}
|
||||
mpeg2_printf(10, "< len %d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
static WriterCaps_t caps =
|
||||
{
|
||||
"mpeg2",
|
||||
eVideo,
|
||||
"V_MPEG2",
|
||||
VIDEO_ENCODING_AUTO,
|
||||
STREAMTYPE_MPEG2,
|
||||
CT_MPEG2
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoMPEG2 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps
|
||||
};
|
||||
|
||||
static WriterCaps_t mpg1_caps =
|
||||
{
|
||||
"mpge1",
|
||||
eVideo,
|
||||
"V_MPEG1",
|
||||
VIDEO_ENCODING_H264,
|
||||
STREAMTYPE_MPEG1,
|
||||
CT_MPEG1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoMPEG1 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&mpg1_caps
|
||||
};
|
164
libeplayer3-arm/output/writer/mipsel/mpeg4.c
Normal file
164
libeplayer3-arm/output/writer/mipsel/mpeg4.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
//#define SAM_WITH_DEBUG
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define MPEG4_DEBUG
|
||||
#else
|
||||
#define MPEG4_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef MPEG4_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define mpeg4_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define mpeg4_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef MPEG4_SILENT
|
||||
#define mpeg4_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define mpeg4_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
static int initialHeader = 1;
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
static int reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
mpeg4_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
mpeg4_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
mpeg4_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
mpeg4_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
mpeg4_printf(10, "VideoPts %lld\n", call->Pts);
|
||||
unsigned int PacketLength = call->len;
|
||||
if (initialHeader && call->private_size && call->private_data != NULL)
|
||||
{
|
||||
PacketLength += call->private_size;
|
||||
}
|
||||
struct iovec iov[3];
|
||||
int ic = 0;
|
||||
iov[ic].iov_base = PesHeader;
|
||||
iov[ic++].iov_len = InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
|
||||
if (initialHeader && call->private_size && call->private_data != NULL)
|
||||
{
|
||||
initialHeader = 0;
|
||||
iov[ic].iov_base = call->private_data;
|
||||
iov[ic++].iov_len = call->private_size;
|
||||
}
|
||||
iov[ic].iov_base = call->data;
|
||||
iov[ic++].iov_len = call->len;
|
||||
int len = writev_with_retry(call->fd, iov, ic);
|
||||
mpeg4_printf(10, "xvid_Write < len=%d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t mpeg4p2_caps =
|
||||
{
|
||||
"mpeg4p2",
|
||||
eVideo,
|
||||
"V_MPEG4",
|
||||
VIDEO_ENCODING_MPEG4P2,
|
||||
STREAMTYPE_MPEG4_Part2,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoMPEG4 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&mpeg4p2_caps
|
||||
};
|
312
libeplayer3-arm/output/writer/mipsel/pcm.c
Normal file
312
libeplayer3-arm/output/writer/mipsel/pcm.c
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
#include "pcm.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define PCM_DEBUG
|
||||
#else
|
||||
#define PCM_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef PCM_DEBUG
|
||||
|
||||
static uint16_t debug_level = 0;
|
||||
|
||||
#define pcm_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define pcm_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef PCM_SILENT
|
||||
#define pcm_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define pcm_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
static uint8_t initialHeader = 1;
|
||||
static uint8_t codec_data[18];
|
||||
static uint64_t fixed_buffertimestamp;
|
||||
static uint64_t fixed_bufferduration;
|
||||
static uint32_t fixed_buffersize;
|
||||
static uint8_t *fixed_buffer;
|
||||
static uint32_t fixed_bufferfilled;
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
|
||||
static int32_t reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
pcm_printf(10, "\n");
|
||||
if (!call)
|
||||
{
|
||||
pcm_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
pcm_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if (!call->data || (call->len <= 0))
|
||||
{
|
||||
pcm_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
pcm_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
static uint8_t PesHeader[PES_MAX_HEADER_SIZE + 22];
|
||||
pcmPrivateData_t *pcmPrivateData = (pcmPrivateData_t *)call->private_data;
|
||||
uint8_t *buffer = call->data;
|
||||
uint32_t size = call->len;
|
||||
if (pcmPrivateData->bResampling || NULL == fixed_buffer)
|
||||
{
|
||||
if (0)
|
||||
{
|
||||
printf("ioctl %d", ioctl(call->fd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY));
|
||||
printf("ioctl %d", ioctl(call->fd, AUDIO_PAUSE));
|
||||
printf("ioctl %d", ioctl(call->fd, AUDIO_SET_BYPASS_MODE, 0x30));
|
||||
printf("ioctl %d", ioctl(call->fd, AUDIO_PLAY));
|
||||
printf("ioctl %d", ioctl(call->fd, AUDIO_CONTINUE));
|
||||
}
|
||||
int32_t format = 0x01;
|
||||
int32_t width = 0;
|
||||
int32_t depth = 0;
|
||||
int32_t rate = (uint64_t)pcmPrivateData->sample_rate;
|
||||
int32_t channels = (uint8_t) pcmPrivateData->channels;
|
||||
int32_t block_align = 0;
|
||||
int32_t byterate = 0;
|
||||
uint32_t codecID = (uint32_t)pcmPrivateData->ffmpeg_codec_id;
|
||||
uint8_t dataPrecision = 0;
|
||||
uint8_t LE = 0;
|
||||
switch (codecID)
|
||||
{
|
||||
case AV_CODEC_ID_PCM_S8:
|
||||
case AV_CODEC_ID_PCM_U8:
|
||||
width = depth = 8;
|
||||
break;
|
||||
case AV_CODEC_ID_PCM_S16LE:
|
||||
case AV_CODEC_ID_PCM_U16LE:
|
||||
LE = 1;
|
||||
case AV_CODEC_ID_PCM_S16BE:
|
||||
case AV_CODEC_ID_PCM_U16BE:
|
||||
width = depth = 16;
|
||||
break;
|
||||
case AV_CODEC_ID_PCM_S24LE:
|
||||
case AV_CODEC_ID_PCM_U24LE:
|
||||
LE = 1;
|
||||
case AV_CODEC_ID_PCM_S24BE:
|
||||
case AV_CODEC_ID_PCM_U24BE:
|
||||
width = depth = 24;
|
||||
break;
|
||||
case AV_CODEC_ID_PCM_S32LE:
|
||||
case AV_CODEC_ID_PCM_U32LE:
|
||||
LE = 1;
|
||||
case AV_CODEC_ID_PCM_S32BE:
|
||||
case AV_CODEC_ID_PCM_U32BE:
|
||||
width = depth = 32;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
uint8_t *data = codec_data;
|
||||
byterate = channels * rate * width / 8;
|
||||
block_align = channels * width / 8;
|
||||
memset(data, 0, sizeof(codec_data));
|
||||
/* format tag */
|
||||
*(data++) = format & 0xff;
|
||||
*(data++) = (format >> 8) & 0xff;
|
||||
/* channels */
|
||||
*(data++) = channels & 0xff;
|
||||
*(data++) = (channels >> 8) & 0xff;
|
||||
/* sample rate */
|
||||
*(data++) = rate & 0xff;
|
||||
*(data++) = (rate >> 8) & 0xff;
|
||||
*(data++) = (rate >> 16) & 0xff;
|
||||
*(data++) = (rate >> 24) & 0xff;
|
||||
/* byte rate */
|
||||
*(data++) = byterate & 0xff;
|
||||
*(data++) = (byterate >> 8) & 0xff;
|
||||
*(data++) = (byterate >> 16) & 0xff;
|
||||
*(data++) = (byterate >> 24) & 0xff;
|
||||
/* block align */
|
||||
*(data++) = block_align & 0xff;
|
||||
*(data++) = (block_align >> 8) & 0xff;
|
||||
/* word size */
|
||||
*(data++) = depth & 0xff;
|
||||
*(data++) = (depth >> 8) & 0xff;
|
||||
uint32_t nfixed_buffersize = rate * 30 / 1000;
|
||||
nfixed_buffersize *= channels * depth / 8;
|
||||
fixed_buffertimestamp = call->Pts;
|
||||
fixed_bufferduration = 90000 * nfixed_buffersize / byterate;
|
||||
if (fixed_buffersize != nfixed_buffersize || NULL == fixed_buffer)
|
||||
{
|
||||
fixed_buffersize = nfixed_buffersize;
|
||||
if (NULL != fixed_buffer)
|
||||
{
|
||||
free(fixed_buffer);
|
||||
}
|
||||
fixed_buffer = malloc(fixed_buffersize);
|
||||
}
|
||||
fixed_bufferfilled = 0;
|
||||
//printf("PCM fixed_buffersize [%u] [%s]\n", fixed_buffersize, LE ? "LE":"BE");
|
||||
}
|
||||
while (size > 0)
|
||||
{
|
||||
uint32_t cpSize = (fixed_buffersize - fixed_bufferfilled);
|
||||
if (cpSize > size)
|
||||
{
|
||||
memcpy(fixed_buffer + fixed_bufferfilled, buffer, size);
|
||||
fixed_bufferfilled += size;
|
||||
return size;
|
||||
}
|
||||
memcpy(fixed_buffer + fixed_bufferfilled, buffer, cpSize);
|
||||
fixed_bufferfilled = 0;
|
||||
buffer += cpSize;
|
||||
size -= cpSize;
|
||||
uint32_t addHeaderSize = 0;
|
||||
if (IsDreambox())
|
||||
{
|
||||
addHeaderSize = 4;
|
||||
}
|
||||
uint32_t headerSize = InsertPesHeader(PesHeader, fixed_buffersize + 4 + addHeaderSize + sizeof(codec_data), MPEG_AUDIO_PES_START_CODE, fixed_buffertimestamp, 0);
|
||||
if (IsDreambox())
|
||||
{
|
||||
PesHeader[headerSize++] = 0x42; // B
|
||||
PesHeader[headerSize++] = 0x43; // C
|
||||
PesHeader[headerSize++] = 0x4D; // M
|
||||
PesHeader[headerSize++] = 0x41; // A
|
||||
}
|
||||
PesHeader[headerSize++] = (fixed_buffersize >> 24) & 0xff;
|
||||
PesHeader[headerSize++] = (fixed_buffersize >> 16) & 0xff;
|
||||
PesHeader[headerSize++] = (fixed_buffersize >> 8) & 0xff;
|
||||
PesHeader[headerSize++] = fixed_buffersize & 0xff;
|
||||
memcpy(PesHeader + headerSize, codec_data, sizeof(codec_data));
|
||||
headerSize += sizeof(codec_data);
|
||||
PesHeader[6] |= 1;
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = headerSize;
|
||||
iov[1].iov_base = fixed_buffer;
|
||||
iov[1].iov_len = fixed_buffersize;
|
||||
writev_with_retry(call->fd, iov, 2);
|
||||
fixed_buffertimestamp += fixed_bufferduration;
|
||||
int g_fd_dump = open("/hdd/lpcm/ffmpeg.pes", O_CREAT |
|
||||
O_RDWR | O_APPEND, S_IRUSR | S_IWUSR);
|
||||
writev_with_retry(g_fd_dump, iov, 2);
|
||||
close(g_fd_dump);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps_pcm =
|
||||
{
|
||||
"pcm",
|
||||
eAudio,
|
||||
"A_PCM",
|
||||
AUDIO_ENCODING_LPCMA,
|
||||
0x30,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioPCM =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_pcm
|
||||
};
|
||||
|
||||
static WriterCaps_t caps_ipcm =
|
||||
{
|
||||
"ipcm",
|
||||
eAudio,
|
||||
"A_IPCM",
|
||||
AUDIO_ENCODING_LPCMA,
|
||||
0x30,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioIPCM =
|
||||
{
|
||||
&reset,
|
||||
&writeData, /* writeDataIPCM */
|
||||
NULL,
|
||||
&caps_ipcm
|
||||
};
|
200
libeplayer3-arm/output/writer/mipsel/vc1.c
Normal file
200
libeplayer3-arm/output/writer/mipsel/vc1.c
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
#define VC1_SEQUENCE_LAYER_METADATA_START_CODE 0x80
|
||||
#define VC1_FRAME_START_CODE 0x0d
|
||||
|
||||
#define SAM_WITH_DEBUG
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define VC1_DEBUG
|
||||
#else
|
||||
#define VC1_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef VC1_DEBUG
|
||||
|
||||
static short debug_level = 10;
|
||||
|
||||
#define vc1_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define vc1_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef VC1_SILENT
|
||||
#define vc1_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define vc1_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
static const unsigned char SequenceLayerStartCode[] = {0x00, 0x00, 0x01, VC1_SEQUENCE_LAYER_METADATA_START_CODE};
|
||||
static const uint8_t Vc1FrameStartCode[] = {0, 0, 1, VC1_FRAME_START_CODE};
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
static int initialHeader = 1;
|
||||
static video_codec_data_t videocodecdata = {0, 0};
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
static int reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
int len = 0;
|
||||
vc1_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
vc1_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
vc1_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
vc1_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
vc1_printf(10, "VideoPts %lld\n", call->Pts);
|
||||
vc1_printf(10, "Got Private Size %d\n", call->private_size);
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE + sizeof(Vc1FrameStartCode)];
|
||||
int32_t ic = 0;
|
||||
struct iovec iov[5];
|
||||
unsigned int PacketLength = 0;
|
||||
iov[ic++].iov_base = PesHeader;
|
||||
if (initialHeader)
|
||||
{
|
||||
initialHeader = 0;
|
||||
if (videocodecdata.data)
|
||||
{
|
||||
free(videocodecdata.data);
|
||||
videocodecdata.data = NULL;
|
||||
}
|
||||
videocodecdata.length = call->private_size + 8;
|
||||
videocodecdata.data = malloc(videocodecdata.length);
|
||||
memset(videocodecdata.data, 0, videocodecdata.length);
|
||||
memcpy(videocodecdata.data + 8, call->private_data, call->private_size);
|
||||
if (IsDreambox() || 0 != ioctl(call->fd, VIDEO_SET_CODEC_DATA, &videocodecdata))
|
||||
{
|
||||
iov[ic].iov_base = videocodecdata.data;
|
||||
iov[ic++].iov_len = videocodecdata.length;
|
||||
PacketLength += videocodecdata.length;
|
||||
}
|
||||
}
|
||||
uint8_t needFrameStartCode = 0;
|
||||
if (sizeof(Vc1FrameStartCode) >= call->len
|
||||
|| memcmp(call->data, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)) != 0)
|
||||
{
|
||||
needFrameStartCode = 1;
|
||||
PacketLength += sizeof(Vc1FrameStartCode);
|
||||
}
|
||||
iov[ic].iov_base = call->data;
|
||||
iov[ic++].iov_len = call->len;
|
||||
PacketLength += call->len;
|
||||
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 */
|
||||
PesHeader[6] |= 1;
|
||||
if (needFrameStartCode)
|
||||
{
|
||||
memcpy(PesHeader + iov[0].iov_len, Vc1FrameStartCode, sizeof(Vc1FrameStartCode));
|
||||
iov[0].iov_len += sizeof(Vc1FrameStartCode);
|
||||
}
|
||||
if (videocodecdata.data)
|
||||
{
|
||||
free(videocodecdata.data);
|
||||
videocodecdata.data = NULL;
|
||||
}
|
||||
return writev_with_retry(call->fd, iov, ic);
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps =
|
||||
{
|
||||
"vc1",
|
||||
eVideo,
|
||||
"V_VC1",
|
||||
VIDEO_ENCODING_VC1,
|
||||
STREAMTYPE_VC1,
|
||||
CT_MPEG4_PART2
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoVC1 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps
|
||||
};
|
228
libeplayer3-arm/output/writer/mipsel/vp.c
Normal file
228
libeplayer3-arm/output/writer/mipsel/vp.c
Normal file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
//#define SAM_WITH_DEBUG
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define VP_DEBUG
|
||||
#else
|
||||
#define VP_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef VP_DEBUG
|
||||
|
||||
static short debug_level = 10;
|
||||
|
||||
#define vp_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define vp_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef VP_SILENT
|
||||
#define vp_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define vp_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
static int reset()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call, int is_vp6)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
vp_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
vp_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
vp_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
vp_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
vp_printf(10, "VideoPts %lld\n", call->Pts);
|
||||
vp_printf(10, "Got Private Size %d\n", call->private_size);
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
uint32_t pes_header_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
|
||||
uint32_t len = call->len + 4 + 6;
|
||||
memcpy(PesHeader + pes_header_len, "BCMV", 4);
|
||||
pes_header_len += 4;
|
||||
if (is_vp6)
|
||||
++len;
|
||||
PesHeader[pes_header_len++] = (len & 0xFF000000) >> 24;
|
||||
PesHeader[pes_header_len++] = (len & 0x00FF0000) >> 16;
|
||||
PesHeader[pes_header_len++] = (len & 0x0000FF00) >> 8;
|
||||
PesHeader[pes_header_len++] = (len & 0x000000FF) >> 0;
|
||||
PesHeader[pes_header_len++] = 0;
|
||||
PesHeader[pes_header_len++] = 0;
|
||||
if (is_vp6)
|
||||
PesHeader[pes_header_len++] = 0;
|
||||
iov[0].iov_len = pes_header_len;
|
||||
iov[1].iov_base = call->data;
|
||||
iov[1].iov_len = call->len;
|
||||
return writev_with_retry(call->fd, iov, 2);
|
||||
}
|
||||
|
||||
static int writeDataVP6(void *_call)
|
||||
{
|
||||
return writeData(_call, 1);
|
||||
}
|
||||
|
||||
static int writeDataVP89(void *_call)
|
||||
{
|
||||
return writeData(_call, 0);
|
||||
}
|
||||
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t capsVP6 =
|
||||
{
|
||||
"vp6",
|
||||
eVideo,
|
||||
"V_VP6",
|
||||
VIDEO_ENCODING_VC1,
|
||||
STREAMTYPE_VB6,
|
||||
CT_VP6
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoVP6 =
|
||||
{
|
||||
&reset,
|
||||
&writeDataVP6,
|
||||
NULL,
|
||||
&capsVP6
|
||||
};
|
||||
|
||||
static WriterCaps_t capsVP8 =
|
||||
{
|
||||
"vp8",
|
||||
eVideo,
|
||||
"V_VP8",
|
||||
VIDEO_ENCODING_VC1,
|
||||
STREAMTYPE_VB8,
|
||||
CT_VP8
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoVP8 =
|
||||
{
|
||||
&reset,
|
||||
&writeDataVP89,
|
||||
NULL,
|
||||
&capsVP8
|
||||
};
|
||||
|
||||
static WriterCaps_t capsVP9 =
|
||||
{
|
||||
"vp9",
|
||||
eVideo,
|
||||
"V_VP9",
|
||||
VIDEO_ENCODING_VC1,
|
||||
STREAMTYPE_VB9,
|
||||
CT_VP9
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoVP9 =
|
||||
{
|
||||
&reset,
|
||||
&writeDataVP89,
|
||||
NULL,
|
||||
&capsVP9
|
||||
};
|
||||
|
||||
static WriterCaps_t capsSPARK =
|
||||
{
|
||||
"spark",
|
||||
eVideo,
|
||||
"V_SPARK",
|
||||
VIDEO_ENCODING_VC1,
|
||||
STREAMTYPE_SPARK,
|
||||
CT_SPARK
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoSPARK =
|
||||
{
|
||||
&reset,
|
||||
&writeDataVP89,
|
||||
NULL,
|
||||
&capsSPARK
|
||||
};
|
202
libeplayer3-arm/output/writer/mipsel/wma.c
Normal file
202
libeplayer3-arm/output/writer/mipsel/wma.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define WMA_DEBUG
|
||||
#else
|
||||
#define WMA_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef WMA_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define wma_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define wma_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef WMA_SILENT
|
||||
#define wma_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define wma_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
static int initialHeader = 1;
|
||||
static uint8_t *PesHeader = NULL;
|
||||
static uint32_t MaxPesHeader = 0;
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
int len = 0;
|
||||
wma_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
wma_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
wma_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
wma_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
wma_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
uint32_t packetLength = 4 + call->private_size + call->len;
|
||||
if (IsDreambox())
|
||||
{
|
||||
packetLength += 4;
|
||||
}
|
||||
if ((packetLength + PES_MAX_HEADER_SIZE) > MaxPesHeader)
|
||||
{
|
||||
if (PesHeader)
|
||||
{
|
||||
free(PesHeader);
|
||||
}
|
||||
MaxPesHeader = packetLength + PES_MAX_HEADER_SIZE;
|
||||
PesHeader = malloc(MaxPesHeader);
|
||||
}
|
||||
uint32_t headerSize = InsertPesHeader(PesHeader, packetLength, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
|
||||
if (IsDreambox())
|
||||
{
|
||||
PesHeader[headerSize++] = 0x42; // B
|
||||
PesHeader[headerSize++] = 0x43; // C
|
||||
PesHeader[headerSize++] = 0x4D; // M
|
||||
PesHeader[headerSize++] = 0x41; // A
|
||||
}
|
||||
size_t payload_len = call->len;
|
||||
PesHeader[headerSize++] = (payload_len >> 24) & 0xff;
|
||||
PesHeader[headerSize++] = (payload_len >> 16) & 0xff;
|
||||
PesHeader[headerSize++] = (payload_len >> 8) & 0xff;
|
||||
PesHeader[headerSize++] = payload_len & 0xff;
|
||||
memcpy(PesHeader + headerSize, call->private_data, call->private_size);
|
||||
headerSize += call->private_size;
|
||||
PesHeader[6] |= 1;
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = headerSize;
|
||||
iov[1].iov_base = call->data;
|
||||
iov[1].iov_len = call->len;
|
||||
return writev_with_retry(call->fd, iov, 2);
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t capsWMAPRO =
|
||||
{
|
||||
"wma/pro",
|
||||
eAudio,
|
||||
"A_WMA/PRO",
|
||||
AUDIO_ENCODING_WMA,
|
||||
AUDIOTYPE_WMA_PRO,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioWMAPRO =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&capsWMAPRO
|
||||
};
|
||||
|
||||
|
||||
static WriterCaps_t capsWMA =
|
||||
{
|
||||
"wma",
|
||||
eAudio,
|
||||
"A_WMA",
|
||||
AUDIO_ENCODING_WMA,
|
||||
AUDIOTYPE_WMA,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioWMA =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&capsWMA
|
||||
};
|
206
libeplayer3-arm/output/writer/mipsel/wmv.c
Normal file
206
libeplayer3-arm/output/writer/mipsel/wmv.c
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "stm_ioctls.h"
|
||||
#include "bcm_ioctls.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
#define WMV_FRAME_START_CODE 0x0d
|
||||
|
||||
//#define SAM_WITH_DEBUG
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define WMV_DEBUG
|
||||
#else
|
||||
#define WMV_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef WMV_DEBUG
|
||||
|
||||
static short debug_level = 10;
|
||||
|
||||
#define wmv_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define wmv_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef WMV_SILENT
|
||||
#define wmv_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define wmv_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
static const uint8_t Vc1FrameStartCode[] = {0, 0, 1, WMV_FRAME_START_CODE};
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
static int initialHeader = 1;
|
||||
static video_codec_data_t videocodecdata = {0, 0};
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
static int reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
wmv_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
wmv_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
wmv_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
wmv_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
wmv_printf(10, "VideoPts %lld\n", call->Pts);
|
||||
wmv_printf(10, "Got Private Size %d\n", call->private_size);
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE + sizeof(Vc1FrameStartCode)];
|
||||
int32_t ic = 0;
|
||||
struct iovec iov[5];
|
||||
unsigned int PacketLength = 0;
|
||||
iov[ic++].iov_base = PesHeader;
|
||||
if (initialHeader)
|
||||
{
|
||||
initialHeader = 0;
|
||||
if (videocodecdata.data)
|
||||
{
|
||||
free(videocodecdata.data);
|
||||
videocodecdata.data = NULL;
|
||||
}
|
||||
unsigned int codec_size = call->private_size;
|
||||
if (codec_size > 4) codec_size = 4;
|
||||
videocodecdata.length = 33;
|
||||
uint8_t *data = videocodecdata.data = malloc(videocodecdata.length);
|
||||
memset(videocodecdata.data, 0, videocodecdata.length);
|
||||
data += 18;
|
||||
/* width */
|
||||
*(data++) = (call->Width >> 8) & 0xff;
|
||||
*(data++) = call->Width & 0xff;
|
||||
/* height */
|
||||
*(data++) = (call->Height >> 8) & 0xff;
|
||||
*(data++) = call->Height & 0xff;
|
||||
if (call->private_data && codec_size) memcpy(data, call->private_data, codec_size);
|
||||
if (IsDreambox() || 0 != ioctl(call->fd, VIDEO_SET_CODEC_DATA, &videocodecdata))
|
||||
{
|
||||
iov[ic].iov_base = videocodecdata.data;
|
||||
iov[ic++].iov_len = videocodecdata.length;
|
||||
PacketLength += videocodecdata.length;
|
||||
}
|
||||
}
|
||||
uint8_t needFrameStartCode = 0;
|
||||
if (sizeof(Vc1FrameStartCode) >= call->len
|
||||
|| memcmp(call->data, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)) != 0)
|
||||
{
|
||||
needFrameStartCode = 1;
|
||||
PacketLength += sizeof(Vc1FrameStartCode);
|
||||
}
|
||||
iov[ic].iov_base = call->data;
|
||||
iov[ic++].iov_len = call->len;
|
||||
PacketLength += call->len;
|
||||
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 */
|
||||
PesHeader[6] |= 1;
|
||||
if (needFrameStartCode)
|
||||
{
|
||||
memcpy(PesHeader + iov[0].iov_len, Vc1FrameStartCode, sizeof(Vc1FrameStartCode));
|
||||
iov[0].iov_len += sizeof(Vc1FrameStartCode);
|
||||
}
|
||||
if (videocodecdata.data)
|
||||
{
|
||||
free(videocodecdata.data);
|
||||
videocodecdata.data = NULL;
|
||||
}
|
||||
return writev_with_retry(call->fd, iov, ic);
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps =
|
||||
{
|
||||
"wmv",
|
||||
eVideo,
|
||||
"V_WMV",
|
||||
VIDEO_ENCODING_WMV,
|
||||
STREAMTYPE_VC1_SM,
|
||||
CT_MPEG4_PART2
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoWMV =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps
|
||||
};
|
204
libeplayer3-arm/output/writer/mipsel/writer.c
Normal file
204
libeplayer3-arm/output/writer/mipsel/writer.c
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
#define WRITER_DEBUG
|
||||
|
||||
#ifdef WRITER_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define writer_printf(level, x...) do { \
|
||||
if (debug_level >= level) printf(x); } while (0)
|
||||
#else
|
||||
#define writer_printf(level, x...)
|
||||
#endif
|
||||
|
||||
#ifndef WRITER_SILENT
|
||||
#define writer_err(x...) do { printf(x); } while (0)
|
||||
#else
|
||||
#define writer_err(x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
static Writer_t *AvailableWriter[] =
|
||||
{
|
||||
&WriterAudioAAC,
|
||||
&WriterAudioAACLATM,
|
||||
&WriterAudioAACLATM,
|
||||
&WriterAudioAACPLUS,
|
||||
&WriterAudioAC3,
|
||||
&WriterAudioEAC3,
|
||||
&WriterAudioMP3,
|
||||
&WriterAudioMPEGL3,
|
||||
&WriterAudioPCM,
|
||||
&WriterAudioIPCM,
|
||||
&WriterAudioLPCM,
|
||||
&WriterAudioDTS,
|
||||
&WriterAudioWMA,
|
||||
&WriterAudioWMAPRO,
|
||||
|
||||
&WriterVideoH264,
|
||||
&WriterVideoH265,
|
||||
&WriterVideoH263,
|
||||
&WriterVideoMPEG4,
|
||||
&WriterVideoMPEG2,
|
||||
&WriterVideoMPEG1,
|
||||
&WriterVideoVC1,
|
||||
&WriterVideoDIVX3,
|
||||
&WriterVideoVP6,
|
||||
&WriterVideoVP8,
|
||||
&WriterVideoVP9,
|
||||
&WriterVideoSPARK,
|
||||
&WriterVideoWMV,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Functions */
|
||||
/* ***************************** */
|
||||
ssize_t write_with_retry(int fd, const void *buf, size_t size)
|
||||
{
|
||||
ssize_t ret;
|
||||
int retval = 0;
|
||||
while (size > 0 && 0 == PlaybackDieNow(0))
|
||||
{
|
||||
ret = write(fd, buf, size);
|
||||
//printf("[%d] write [%lld]\n", fd, ret);
|
||||
if (ret < 0)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case EINTR:
|
||||
case EAGAIN:
|
||||
usleep(1000);
|
||||
continue;
|
||||
default:
|
||||
retval = -3;
|
||||
break;
|
||||
}
|
||||
if (retval < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
size -= ret;
|
||||
buf += ret;
|
||||
if (size > 0)
|
||||
{
|
||||
if (usleep(1000))
|
||||
{
|
||||
writer_err("usleep error \n");
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t writev_with_retry(int fd, const struct iovec *iov, size_t ic)
|
||||
{
|
||||
ssize_t len = 0;
|
||||
int i = 0;
|
||||
for (i = 0; i < ic; ++i)
|
||||
{
|
||||
write_with_retry(fd, iov[i].iov_base, iov[i].iov_len);
|
||||
len += iov[i].iov_len;
|
||||
if (PlaybackDieNow(0))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
Writer_t *getWriter(char *encoding)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; AvailableWriter[i] != NULL; i++)
|
||||
{
|
||||
if (strcmp(AvailableWriter[i]->caps->textEncoding, encoding) == 0)
|
||||
{
|
||||
writer_printf(50, "%s: found writer \"%s\" for \"%s\"\n", __func__, AvailableWriter[i]->caps->name, encoding);
|
||||
return AvailableWriter[i];
|
||||
}
|
||||
}
|
||||
writer_printf(1, "%s: no writer found for \"%s\"\n", __func__, encoding);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Writer_t *getDefaultVideoWriter()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; AvailableWriter[i] != NULL; i++)
|
||||
{
|
||||
if (strcmp(AvailableWriter[i]->caps->textEncoding, "V_MPEG2") == 0)
|
||||
{
|
||||
writer_printf(50, "%s: found writer \"%s\"\n", __func__, AvailableWriter[i]->caps->name);
|
||||
return AvailableWriter[i];
|
||||
}
|
||||
}
|
||||
writer_printf(1, "%s: no writer found\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Writer_t *getDefaultAudioWriter()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; AvailableWriter[i] != NULL; i++)
|
||||
{
|
||||
if (strcmp(AvailableWriter[i]->caps->textEncoding, "A_MP3") == 0)
|
||||
{
|
||||
writer_printf(50, "%s: found writer \"%s\"\n", __func__, AvailableWriter[i]->caps->name);
|
||||
return AvailableWriter[i];
|
||||
}
|
||||
}
|
||||
writer_printf(1, "%s: no writer found\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
372
libeplayer3-arm/output/writer/sh4/aac.c
Normal file
372
libeplayer3-arm/output/writer/sh4/aac.c
Normal file
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/stm_ioctls.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <libavutil/intreadwrite.h>
|
||||
#include "ffmpeg/latmenc.h"
|
||||
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
#include "aac.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
//#define SAM_WITH_DEBUG
|
||||
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define AAC_DEBUG
|
||||
#else
|
||||
#define AAC_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef AAC_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define aac_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define aac_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef AAC_SILENT
|
||||
#define aac_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define aac_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/// ** AAC ADTS format **
|
||||
///
|
||||
/// AAAAAAAA AAAABCCD EEFFFFGH HHIJKLMM
|
||||
/// MMMMMMMM MMMNNNNN NNNNNNOO ........
|
||||
///
|
||||
/// Sign Length Position Description
|
||||
///
|
||||
/// A 12 (31-20) Sync code
|
||||
/// B 1 (19) ID
|
||||
/// C 2 (18-17) layer
|
||||
/// D 1 (16) protect absent
|
||||
/// E 2 (15-14) profile
|
||||
/// F 4 (13-10) sample freq index
|
||||
/// G 1 (9) private
|
||||
/// H 3 (8-6) channel config
|
||||
/// I 1 (5) original/copy
|
||||
/// J 1 (4) home
|
||||
/// K 1 (3) copyright id
|
||||
/// L 1 (2) copyright start
|
||||
/// M 13 (1-0,31-21) frame length
|
||||
/// N 11 (20-10) adts buffer fullness
|
||||
/// O 2 (9-8) num of raw data blocks in frame
|
||||
|
||||
/*
|
||||
LC: Audio: aac, 44100 Hz, stereo, s16, 192 kb/ ->ff f1 50 80 00 1f fc
|
||||
HE: Audio: aac, 48000 Hz, stereo, s16, 77 kb/s ->ff f1 4c 80 00 1f fc
|
||||
*/
|
||||
|
||||
/*
|
||||
ADIF = basic format called Audio Data Interchange Format (ADIF)
|
||||
consisting of a single header followed by the raw AAC audio data blocks
|
||||
ADTS = streaming format called Audio Data Transport Stream (ADTS)
|
||||
consisting of a series of frames, each frame having a header followed by the AAC audio data
|
||||
LOAS = Low Overhead Audio Stream (LOAS), a self-synchronizing streaming format
|
||||
*/
|
||||
|
||||
static unsigned char DefaultAACHeader[] =
|
||||
{
|
||||
0xff,
|
||||
0xf1,
|
||||
/*0x00, 0x00*/0x50, //((Profile & 0x03) << 6) | (SampleIndex << 2) | ((Channels >> 2) & 0x01);s
|
||||
0x80, //(Channels & 0x03) << 6;
|
||||
0x00,
|
||||
0x1f,
|
||||
0xfc
|
||||
};
|
||||
|
||||
LATMContext *pLATMCtx = NULL;
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int reset()
|
||||
{
|
||||
if (pLATMCtx)
|
||||
{
|
||||
free(pLATMCtx);
|
||||
pLATMCtx = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _writeData(void *_call, int type)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
aac_printf(10, "\n _writeData type[%d]\n", type);
|
||||
if (call == NULL)
|
||||
{
|
||||
aac_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->data == NULL) || (call->len < 8))
|
||||
{
|
||||
aac_err("parsing Data with missing AAC header. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
/* simple validation */
|
||||
if (0 == type) // check ADTS header
|
||||
{
|
||||
if (0xFF != call->data[0] || 0xF0 != (0xF0 & call->data[1]))
|
||||
{
|
||||
aac_err("parsing Data with missing syncword. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else // check LOAS header
|
||||
{
|
||||
if (!(call->len > 2 && call->data[0] == 0x56 && (call->data[1] >> 4) == 0xe &&
|
||||
(AV_RB16(call->data + 1) & 0x1FFF) + 3 == call->len))
|
||||
{
|
||||
aac_err("parsing Data with wrong latm header. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
aac_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
unsigned int HeaderLength = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = HeaderLength;
|
||||
iov[1].iov_base = call->data;
|
||||
iov[1].iov_len = call->len;
|
||||
return writev(call->fd, iov, 2);
|
||||
}
|
||||
|
||||
static int writeDataADTS(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
aac_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
aac_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
aac_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
aac_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->private_data && 0 == strncmp("ADTS", call->private_data, call->private_size)) ||
|
||||
HasADTSHeader(call->data, call->len))
|
||||
{
|
||||
return _writeData(_call, 0);
|
||||
}
|
||||
uint32_t PacketLength = call->len + 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);
|
||||
uint8_t *pExtraData = &PesHeader[headerSize];
|
||||
aac_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if (call->private_data == NULL)
|
||||
{
|
||||
aac_printf(10, "private_data = NULL\n");
|
||||
memcpy(pExtraData, DefaultAACHeader, AAC_HEADER_LENGTH);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pExtraData, call->private_data, AAC_HEADER_LENGTH);
|
||||
}
|
||||
pExtraData[3] &= 0xC0;
|
||||
/* frame size over last 2 bits */
|
||||
pExtraData[3] |= (PacketLength & 0x1800) >> 11;
|
||||
/* frame size continued over full byte */
|
||||
pExtraData[4] = (PacketLength & 0x1FF8) >> 3;
|
||||
/* frame size continued first 3 bits */
|
||||
pExtraData[5] = (PacketLength & 7) << 5;
|
||||
/* buffer fullness(0x7FF for VBR) over 5 last bits */
|
||||
pExtraData[5] |= 0x1F;
|
||||
/* buffer fullness(0x7FF for VBR) continued over 6 first bits + 2 zeros for
|
||||
* number of raw data blocks */
|
||||
pExtraData[6] = 0xFC;
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = headerSize + AAC_HEADER_LENGTH;
|
||||
iov[1].iov_base = call->data;
|
||||
iov[1].iov_len = call->len;
|
||||
return writev(call->fd, iov, 2);
|
||||
}
|
||||
|
||||
static int writeDataLATM(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
aac_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
aac_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
aac_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->private_data && 0 == strncmp("LATM", call->private_data, call->private_size))
|
||||
{
|
||||
return _writeData(_call, 1);
|
||||
}
|
||||
aac_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if (!pLATMCtx)
|
||||
{
|
||||
pLATMCtx = malloc(sizeof(LATMContext));
|
||||
memset(pLATMCtx, 0x00, sizeof(LATMContext));
|
||||
pLATMCtx->mod = 14;
|
||||
pLATMCtx->counter = 0;
|
||||
}
|
||||
if (!pLATMCtx)
|
||||
{
|
||||
aac_err("parsing NULL pLATMCtx. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
int ret = latmenc_decode_extradata(pLATMCtx, call->private_data, call->private_size);
|
||||
if (ret)
|
||||
{
|
||||
printf("%02x %02x %02x %02x %02x %02x %02x %02x\n", (int)call->data[0], (int)call->data[1], (int)call->data[2], (int)call->data[3], \
|
||||
(int)call->data[4], (int)call->data[5], (int)call->data[6], (int)call->data[7]);
|
||||
aac_err("latm_decode_extradata failed. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
ret = latmenc_write_packet(pLATMCtx, call->data, call->len, call->private_data, call->private_size);
|
||||
if (ret)
|
||||
{
|
||||
aac_err("latm_write_packet failed. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
unsigned int HeaderLength = InsertPesHeader(PesHeader, pLATMCtx->len + 3, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
|
||||
struct iovec iov[3];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = HeaderLength;
|
||||
iov[1].iov_base = pLATMCtx->loas_header;
|
||||
iov[1].iov_len = 3;
|
||||
iov[2].iov_base = pLATMCtx->buffer;
|
||||
iov[2].iov_len = pLATMCtx->len;
|
||||
return writev(call->fd, iov, 3);
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps =
|
||||
{
|
||||
"aac",
|
||||
eAudio,
|
||||
"A_AAC",
|
||||
AUDIO_ENCODING_AAC,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioAAC =
|
||||
{
|
||||
&reset,
|
||||
&writeDataADTS,
|
||||
NULL,
|
||||
&caps
|
||||
};
|
||||
|
||||
static WriterCaps_t caps_aac_latm =
|
||||
{
|
||||
"aac",
|
||||
eAudio,
|
||||
"A_AAC_LATM",
|
||||
AUDIO_ENCODING_AAC,
|
||||
-1, // it is some misunderstanding, this should be AUDIOTYPE_AAC_LATM
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioAACLATM =
|
||||
{
|
||||
&reset,
|
||||
&writeDataLATM,
|
||||
NULL,
|
||||
&caps_aac_latm
|
||||
};
|
||||
|
||||
static WriterCaps_t caps_aacplus =
|
||||
{
|
||||
"aac",
|
||||
eAudio,
|
||||
"A_AAC_PLUS",
|
||||
AUDIO_ENCODING_AAC,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioAACPLUS =
|
||||
{
|
||||
&reset,
|
||||
&writeDataADTS,
|
||||
NULL,
|
||||
&caps_aacplus
|
||||
};
|
165
libeplayer3-arm/output/writer/sh4/ac3.c
Normal file
165
libeplayer3-arm/output/writer/sh4/ac3.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/stm_ioctls.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
#define AC3_HEADER_LENGTH 7
|
||||
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define AC3_DEBUG
|
||||
#else
|
||||
#define AC3_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef AC3_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define ac3_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define ac3_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef AC3_SILENT
|
||||
#define ac3_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define ac3_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int reset()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
ac3_printf(10, "\n");
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
if (call == NULL)
|
||||
{
|
||||
ac3_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
ac3_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
ac3_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
ac3_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
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_len = call->len;
|
||||
return writev(call->fd, iov, 2);
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps_ac3 =
|
||||
{
|
||||
"ac3",
|
||||
eAudio,
|
||||
"A_AC3",
|
||||
AUDIO_ENCODING_AC3,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioAC3 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_ac3
|
||||
};
|
||||
|
||||
static WriterCaps_t caps_eac3 =
|
||||
{
|
||||
"ac3",
|
||||
eAudio,
|
||||
"A_EAC3",
|
||||
AUDIO_ENCODING_AC3,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioEAC3 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_eac3
|
||||
};
|
237
libeplayer3-arm/output/writer/sh4/divx.c
Normal file
237
libeplayer3-arm/output/writer/sh4/divx.c
Normal file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/stm_ioctls.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define DIVX_DEBUG
|
||||
#else
|
||||
#define DIVX_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef DIVX_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define divx_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define divx_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef DIVX_SILENT
|
||||
#define divx_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define divx_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
static int initialHeader = 1;
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
static int reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t updateCodecData(uint8_t *data, int32_t size)
|
||||
{
|
||||
static uint8_t *oldData = NULL;
|
||||
static int32_t oldSize = 0;
|
||||
uint8_t update = 0;
|
||||
if (data != NULL && size > 0)
|
||||
{
|
||||
if (size != oldSize)
|
||||
{
|
||||
update = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t i = 0;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
if (data[i] != oldData[i])
|
||||
{
|
||||
update = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (update)
|
||||
{
|
||||
if (oldData != NULL)
|
||||
{
|
||||
free(oldData);
|
||||
}
|
||||
oldData = malloc(size);
|
||||
memcpy(oldData, data, size);
|
||||
oldSize = size;
|
||||
}
|
||||
return update;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
divx_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
divx_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
divx_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
divx_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
divx_printf(10, "VideoPts %lld\n", call->Pts);
|
||||
struct iovec iov[4];
|
||||
int ic = 0;
|
||||
iov[ic].iov_base = PesHeader;
|
||||
iov[ic++].iov_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
|
||||
if (updateCodecData(call->private_data, call->private_size))
|
||||
{
|
||||
iov[ic].iov_base = call->private_data;
|
||||
iov[ic++].iov_len = call->private_size;
|
||||
}
|
||||
iov[ic].iov_base = call->data;
|
||||
iov[ic++].iov_len = call->len;
|
||||
int len = writev(call->fd, iov, ic);
|
||||
divx_printf(10, "xvid_Write < len=%d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t mpeg4p2_caps =
|
||||
{
|
||||
"mpeg4p2",
|
||||
eVideo,
|
||||
"V_MPEG4",
|
||||
VIDEO_ENCODING_MPEG4P2,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoMPEG4 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&mpeg4p2_caps
|
||||
};
|
||||
|
||||
|
||||
struct Writer_s WriterVideoMSCOMP =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&mpeg4p2_caps
|
||||
};
|
||||
|
||||
static WriterCaps_t fourcc_caps =
|
||||
{
|
||||
"fourcc",
|
||||
eVideo,
|
||||
"V_MS/VFW/FOURCC",
|
||||
VIDEO_ENCODING_MPEG4P2,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoFOURCC =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&fourcc_caps
|
||||
};
|
||||
|
||||
static WriterCaps_t divx_caps =
|
||||
{
|
||||
"divx",
|
||||
eVideo,
|
||||
"V_MKV/XVID",
|
||||
VIDEO_ENCODING_MPEG4P2,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoDIVX =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&divx_caps
|
||||
};
|
263
libeplayer3-arm/output/writer/sh4/divx2.c
Normal file
263
libeplayer3-arm/output/writer/sh4/divx2.c
Normal file
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/stm_ioctls.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define DIVX_DEBUG
|
||||
#else
|
||||
#define DIVX_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef DIVX_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define divx_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define divx_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef DIVX_SILENT
|
||||
#define divx_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define divx_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
static int initialHeader = 1;
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
static int reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t updateCodecData(uint8_t *data, int32_t size)
|
||||
{
|
||||
static uint8_t *oldData = NULL;
|
||||
static int32_t oldSize = 0;
|
||||
uint8_t update = 0;
|
||||
if (data != NULL && size > 0)
|
||||
{
|
||||
if (size != oldSize)
|
||||
{
|
||||
update = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t i = 0;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
if (data[i] != oldData[i])
|
||||
{
|
||||
update = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (update)
|
||||
{
|
||||
if (oldData != NULL)
|
||||
{
|
||||
free(oldData);
|
||||
}
|
||||
oldData = malloc(size);
|
||||
memcpy(oldData, data, size);
|
||||
oldSize = size;
|
||||
}
|
||||
return update;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
unsigned char FakeHeaders[64]; // 64bytes should be enough to make the fake headers
|
||||
unsigned int FakeHeaderLength;
|
||||
unsigned char Version = 5;
|
||||
unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE;
|
||||
unsigned int usecPerFrame = 41708; /* Hellmaster1024: default value */
|
||||
BitPacker_t ld = {FakeHeaders, 0, 32};
|
||||
divx_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
divx_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
divx_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
divx_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
divx_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
usecPerFrame = 1000000000 / call->FrameRate;
|
||||
divx_printf(10, "Microsecends per frame = %d\n", usecPerFrame);
|
||||
memset(FakeHeaders, 0, sizeof(FakeHeaders));
|
||||
/* Create info record for frame parser */
|
||||
/* divx4 & 5
|
||||
VOS
|
||||
PutBits(&ld, 0x0, 8);
|
||||
PutBits(&ld, 0x0, 8);
|
||||
*/
|
||||
PutBits(&ld, 0x1b0, 32); // startcode
|
||||
PutBits(&ld, 0, 8); // profile = reserved
|
||||
PutBits(&ld, 0x1b2, 32); // startcode (user data)
|
||||
PutBits(&ld, 0x53545443, 32); // STTC - an embedded ST timecode from an avi file
|
||||
PutBits(&ld, usecPerFrame, 32);
|
||||
// microseconds per frame
|
||||
FlushBits(&ld);
|
||||
FakeHeaderLength = (ld.Ptr - (FakeHeaders));
|
||||
struct iovec iov[4];
|
||||
int ic = 0;
|
||||
iov[ic].iov_base = PesHeader;
|
||||
iov[ic++].iov_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, FakeStartCode);
|
||||
iov[ic].iov_base = FakeHeaders;
|
||||
iov[ic++].iov_len = FakeHeaderLength;
|
||||
if (initialHeader)
|
||||
{
|
||||
iov[ic].iov_base = call->private_data;
|
||||
iov[ic++].iov_len = call->private_size;
|
||||
initialHeader = 0;
|
||||
}
|
||||
iov[ic].iov_base = call->data;
|
||||
iov[ic++].iov_len = call->len;
|
||||
int len = writev(call->fd, iov, ic);
|
||||
divx_printf(10, "xvid_Write < len=%d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t mpeg4p2_caps =
|
||||
{
|
||||
"mpeg4p2",
|
||||
eVideo,
|
||||
"V_MPEG4",
|
||||
VIDEO_ENCODING_MPEG4P2,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoMPEG4 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&mpeg4p2_caps
|
||||
};
|
||||
|
||||
|
||||
struct Writer_s WriterVideoMSCOMP =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&mpeg4p2_caps
|
||||
};
|
||||
|
||||
static WriterCaps_t fourcc_caps =
|
||||
{
|
||||
"fourcc",
|
||||
eVideo,
|
||||
"V_MS/VFW/FOURCC",
|
||||
VIDEO_ENCODING_MPEG4P2,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoFOURCC =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&fourcc_caps
|
||||
};
|
||||
|
||||
static WriterCaps_t divx_caps =
|
||||
{
|
||||
"divx",
|
||||
eVideo,
|
||||
"V_MKV/XVID",
|
||||
VIDEO_ENCODING_MPEG4P2,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoDIVX =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&divx_caps
|
||||
};
|
176
libeplayer3-arm/output/writer/sh4/dts.c
Normal file
176
libeplayer3-arm/output/writer/sh4/dts.c
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/stm_ioctls.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
#define PES_AUDIO_PRIVATE_HEADER_SIZE 16 // consider maximum private header size.
|
||||
#define PES_AUDIO_HEADER_SIZE (32 + PES_AUDIO_PRIVATE_HEADER_SIZE)
|
||||
#define PES_AUDIO_PACKET_SIZE 2028
|
||||
#define SPDIF_AUDIO_PACKET_SIZE (1024 * sizeof(unsigned int) * 2) // stereo 32bit samples.
|
||||
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define DTS_DEBUG
|
||||
#else
|
||||
#define DTS_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef DTS_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define dts_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define dts_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef DTS_SILENT
|
||||
#define dts_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define dts_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
static int reset()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
uint8_t PesHeader[PES_AUDIO_HEADER_SIZE];
|
||||
dts_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
dts_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
dts_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
dts_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
dts_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
uint8_t *Data = call->data;
|
||||
int32_t Size = call->len;
|
||||
#ifdef CHECK_FOR_DTS_HD
|
||||
int32_t pos = 0;
|
||||
while ((pos + 4) <= Size)
|
||||
{
|
||||
// check for DTS-HD
|
||||
if (!strcmp((char *)(Data + pos), "\x64\x58\x20\x25"))
|
||||
{
|
||||
Size = pos;
|
||||
break;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
#endif
|
||||
// #define DO_BYTESWAP
|
||||
#ifdef DO_BYTESWAP
|
||||
/* 16-bit byte swap all data before injecting it */
|
||||
for (i = 0; i < Size; i += 2)
|
||||
{
|
||||
uint8_t Tmp = Data[i];
|
||||
Data[i] = Data[i + 1];
|
||||
Data[i + 1] = Tmp;
|
||||
}
|
||||
#endif
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = InsertPesHeader(PesHeader, Size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
|
||||
iov[1].iov_base = Data;
|
||||
iov[1].iov_len = Size;
|
||||
int32_t len = writev(call->fd, iov, 2);
|
||||
dts_printf(10, "< len %d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps =
|
||||
{
|
||||
"dts",
|
||||
eAudio,
|
||||
"A_DTS",
|
||||
AUDIO_ENCODING_DTS,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioDTS =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps
|
||||
};
|
173
libeplayer3-arm/output/writer/sh4/h263.c
Normal file
173
libeplayer3-arm/output/writer/sh4/h263.c
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* crow 2010
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/stm_ioctls.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define H263_DEBUG
|
||||
#else
|
||||
#define H263_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef H263_DEBUG
|
||||
static short debug_level = 0;
|
||||
static const char *FILENAME = "h263.c";
|
||||
|
||||
#define h263_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, FILENAME, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define h263_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef H263_SILENT
|
||||
#define h263_err(fmt, x...) do { printf("[%s:%s] " fmt, FILENAME, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define h263_err(fmt, x...)
|
||||
#endif
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int reset()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
int len = 0;
|
||||
h263_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
h263_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
h263_printf(10, "VideoPts %lld\n", call->Pts);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
h263_err("NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
h263_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
int HeaderLength = InsertPesHeader(PesHeader, call->len, H263_VIDEO_PES_START_CODE, call->Pts, 0);
|
||||
int PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], call->len);
|
||||
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_1] = (PesLength >> 8) & 0xff;
|
||||
PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength;
|
||||
PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT;
|
||||
HeaderLength += PrivateHeaderLength;
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = HeaderLength;
|
||||
iov[1].iov_base = call->data;
|
||||
iov[1].iov_len = call->len;
|
||||
len = writev(call->fd, iov, 2);
|
||||
h263_printf(10, "< len %d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps_h263 =
|
||||
{
|
||||
"h263",
|
||||
eVideo,
|
||||
"V_H263",
|
||||
VIDEO_ENCODING_H263,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoH263 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_h263
|
||||
};
|
||||
|
||||
static WriterCaps_t caps_flv =
|
||||
{
|
||||
"FLV",
|
||||
eVideo,
|
||||
"V_FLV",
|
||||
VIDEO_ENCODING_FLV1,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoFLV =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_flv
|
||||
};
|
480
libeplayer3-arm/output/writer/sh4/h264.c
Normal file
480
libeplayer3-arm/output/writer/sh4/h264.c
Normal file
@@ -0,0 +1,480 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/stm_ioctls.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define H264_DEBUG
|
||||
#else
|
||||
#define H264_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef H264_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define h264_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define h264_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef H264_SILENT
|
||||
#define h264_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define h264_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
#define NALU_TYPE_PLAYER2_CONTAINER_PARAMETERS 24
|
||||
#define CONTAINER_PARAMETERS_VERSION 0x00
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
typedef struct avcC_s
|
||||
{
|
||||
unsigned char Version; /* configurationVersion */
|
||||
unsigned char Profile; /* AVCProfileIndication */
|
||||
unsigned char Compatibility; /* profile_compatibility */
|
||||
unsigned char Level; /* AVCLevelIndication */
|
||||
unsigned char NalLengthMinusOne; /* held in bottom two bits */
|
||||
unsigned char NumParamSets; /* held in bottom 5 bits */
|
||||
unsigned char Params[1]; /* {length,params}{length,params}...sequence then picture*/
|
||||
} avcC_t;
|
||||
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
const uint8_t Head[] = {0, 0, 0, 1};
|
||||
static int32_t initialHeader = 1;
|
||||
static uint32_t NalLengthBytes = 1;
|
||||
static int avc3 = 0;
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
// Please see: https://bugzilla.mozilla.org/show_bug.cgi?id=1105771
|
||||
static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize, uint8_t *pData, uint32_t dataSize)
|
||||
{
|
||||
uint8_t *aExtraData = *ppExtraData;
|
||||
if (aExtraData[0] != 1 || !pData)
|
||||
{
|
||||
// Not AVCC or nothing to update with.
|
||||
return -1;
|
||||
}
|
||||
int32_t nalsize = (aExtraData[4] & 3) + 1;
|
||||
uint8_t sps[256];
|
||||
uint8_t spsIdx = 0;
|
||||
uint8_t numSps = 0;
|
||||
uint8_t pps[256];
|
||||
uint8_t ppsIdx = 0;
|
||||
uint8_t numPps = 0;
|
||||
if (nalsize != 4)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
// Find SPS and PPS NALUs in AVCC data
|
||||
uint8_t *d = pData;
|
||||
while (d + 4 < pData + dataSize)
|
||||
{
|
||||
uint32_t nalLen = ReadUint32(d);
|
||||
uint8_t nalType = d[4] & 0x1f;
|
||||
if (nalType == 7)
|
||||
{
|
||||
/* SPS */
|
||||
// 16 bits size
|
||||
sps[spsIdx++] = (uint8_t)(0xFF & (nalLen >> 8));
|
||||
sps[spsIdx++] = (uint8_t)(0xFF & nalLen);
|
||||
if (spsIdx + nalLen >= sizeof(sps))
|
||||
{
|
||||
h264_err("SPS no free space to copy...\n");
|
||||
return -1;
|
||||
}
|
||||
memcpy(&(sps[spsIdx]), d + 4, nalLen);
|
||||
spsIdx += nalLen;
|
||||
numSps += 1;
|
||||
h264_printf(10, "SPS len[%u]...\n", nalLen);
|
||||
}
|
||||
else if (nalType == 8)
|
||||
{
|
||||
/* PPS */
|
||||
// 16 bits size
|
||||
pps[ppsIdx++] = (uint8_t)(0xFF & (nalLen >> 8));
|
||||
pps[ppsIdx++] = (uint8_t)(0xFF & nalLen);
|
||||
if (ppsIdx + nalLen >= sizeof(sps))
|
||||
{
|
||||
h264_err("PPS not free space to copy...\n");
|
||||
return -1;
|
||||
}
|
||||
memcpy(&(pps[ppsIdx]), d + 4, nalLen);
|
||||
ppsIdx += nalLen;
|
||||
numPps += 1;
|
||||
h264_printf(10, "PPS len[%u]...\n", nalLen);
|
||||
}
|
||||
d += 4 + nalLen;
|
||||
}
|
||||
uint32_t idx = 0;
|
||||
*ppExtraData = malloc(7 + spsIdx + ppsIdx);
|
||||
aExtraData = *ppExtraData;
|
||||
aExtraData[idx++] = 0x1; // version
|
||||
aExtraData[idx++] = sps[3]; // profile
|
||||
aExtraData[idx++] = sps[4]; // profile compat
|
||||
aExtraData[idx++] = sps[5]; // level
|
||||
aExtraData[idx++] = 0xff; // nal size - 1
|
||||
aExtraData[idx++] = 0xe0 | numSps;
|
||||
if (numSps)
|
||||
{
|
||||
memcpy(&(aExtraData[idx]), sps, spsIdx);
|
||||
idx += spsIdx;
|
||||
}
|
||||
aExtraData[idx++] = numPps;
|
||||
if (numPps)
|
||||
{
|
||||
memcpy(&(aExtraData[idx]), pps, ppsIdx);
|
||||
idx += ppsIdx;
|
||||
}
|
||||
h264_printf(10, "aExtraData len[%u]...\n", idx);
|
||||
*pExtraDataSize = idx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
avc3 = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
uint8_t PesHeader[PES_MAX_HEADER_SIZE];
|
||||
uint64_t VideoPts;
|
||||
uint32_t TimeDelta;
|
||||
uint32_t TimeScale;
|
||||
int32_t len = 0;
|
||||
int32_t ic = 0;
|
||||
struct iovec iov[128];
|
||||
h264_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
h264_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
TimeDelta = call->FrameRate;
|
||||
TimeScale = call->FrameScale;
|
||||
VideoPts = call->Pts;
|
||||
h264_printf(10, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
h264_err("NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
h264_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
/* AnnexA */
|
||||
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->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff))))
|
||||
{
|
||||
uint32_t PacketLength = 0;
|
||||
uint32_t FakeStartCode = /*(call->Version << 8) | */PES_VERSION_FAKE_START_CODE;
|
||||
iov[ic++].iov_base = PesHeader;
|
||||
initialHeader = 0;
|
||||
if (initialHeader)
|
||||
{
|
||||
initialHeader = 0;
|
||||
iov[ic].iov_base = call->private_data;
|
||||
iov[ic++].iov_len = call->private_size;
|
||||
PacketLength += call->private_size;
|
||||
}
|
||||
iov[ic].iov_base = "";
|
||||
iov[ic++].iov_len = 1;
|
||||
iov[ic].iov_base = call->data;
|
||||
iov[ic++].iov_len = call->len;
|
||||
PacketLength += call->len;
|
||||
/*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
|
||||
by the player */
|
||||
iov[ic].iov_base = "\0";
|
||||
iov[ic++].iov_len = 1;
|
||||
iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode);
|
||||
int ret = writev(call->fd, iov, ic);
|
||||
return ret;
|
||||
}
|
||||
else if (!call->private_data || call->private_size < 7 || 1 != call->private_data[0])
|
||||
{
|
||||
h264_err("No valid private data available!\n");
|
||||
return 0;
|
||||
}
|
||||
if (initialHeader)
|
||||
{
|
||||
uint8_t *private_data = call->private_data;
|
||||
uint32_t private_size = call->private_size;
|
||||
avcC_t *avcCHeader = (avcC_t *)private_data;
|
||||
unsigned int i;
|
||||
unsigned int ParamSets;
|
||||
unsigned int ParamOffset;
|
||||
unsigned int InitialHeaderLength = 0;
|
||||
unsigned int ParametersLength;
|
||||
ParametersLength = 0;
|
||||
unsigned char HeaderData[19];
|
||||
if (private_size <= sizeof(avcC_t))
|
||||
{
|
||||
UpdateExtraData(&private_data, &private_size, call->data, call->len);
|
||||
if (private_data != call->private_data)
|
||||
{
|
||||
avc3 = 1;
|
||||
avcCHeader = (avcC_t *)private_data;
|
||||
}
|
||||
}
|
||||
HeaderData[ParametersLength++] = 0x00; // Start code
|
||||
HeaderData[ParametersLength++] = 0x00;
|
||||
HeaderData[ParametersLength++] = 0x01;
|
||||
HeaderData[ParametersLength++] = NALU_TYPE_PLAYER2_CONTAINER_PARAMETERS;
|
||||
// Container message version - changes when/if we vary the format of the message
|
||||
HeaderData[ParametersLength++] = CONTAINER_PARAMETERS_VERSION;
|
||||
HeaderData[ParametersLength++] = 0xff; // Field separator
|
||||
if (TimeDelta == 0xffffffff)
|
||||
TimeDelta = (TimeScale > 1000) ? 1001 : 1;
|
||||
HeaderData[ParametersLength++] = (TimeScale >> 24) & 0xff; // Output the timescale
|
||||
HeaderData[ParametersLength++] = (TimeScale >> 16) & 0xff;
|
||||
HeaderData[ParametersLength++] = 0xff;
|
||||
HeaderData[ParametersLength++] = (TimeScale >> 8) & 0xff;
|
||||
HeaderData[ParametersLength++] = TimeScale & 0xff;
|
||||
HeaderData[ParametersLength++] = 0xff;
|
||||
HeaderData[ParametersLength++] = (TimeDelta >> 24) & 0xff; // Output frame period
|
||||
HeaderData[ParametersLength++] = (TimeDelta >> 16) & 0xff;
|
||||
HeaderData[ParametersLength++] = 0xff;
|
||||
HeaderData[ParametersLength++] = (TimeDelta >> 8) & 0xff;
|
||||
HeaderData[ParametersLength++] = TimeDelta & 0xff;
|
||||
HeaderData[ParametersLength++] = 0xff;
|
||||
HeaderData[ParametersLength++] = 0x80; // Rsbp trailing bits
|
||||
assert(ParametersLength <= sizeof(HeaderData));
|
||||
ic = 0;
|
||||
iov[ic].iov_base = PesHeader;
|
||||
iov[ic++].iov_len = InsertPesHeader(PesHeader, ParametersLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
|
||||
iov[ic].iov_base = HeaderData;
|
||||
iov[ic++].iov_len = ParametersLength;
|
||||
len = writev(call->fd, iov, ic);
|
||||
if (len < 0)
|
||||
{
|
||||
return len;
|
||||
}
|
||||
NalLengthBytes = (avcCHeader->NalLengthMinusOne & 0x03) + 1;
|
||||
ParamSets = avcCHeader->NumParamSets & 0x1f;
|
||||
h264_printf(20, "avcC contents:\n");
|
||||
h264_printf(20, " version: %d\n", avcCHeader->Version);
|
||||
h264_printf(20, " profile: %d\n", avcCHeader->Profile);
|
||||
h264_printf(20, " profile compatibility: %d\n", avcCHeader->Compatibility);
|
||||
h264_printf(20, " level: %d\n", avcCHeader->Level);
|
||||
h264_printf(20, " nal length bytes: %d\n", NalLengthBytes);
|
||||
h264_printf(20, " number of sequence param sets: %d\n", ParamSets);
|
||||
ParamOffset = 0;
|
||||
ic = 0;
|
||||
iov[ic++].iov_base = PesHeader;
|
||||
for (i = 0; i < ParamSets; i++)
|
||||
{
|
||||
unsigned int PsLength = (avcCHeader->Params[ParamOffset] << 8) + avcCHeader->Params[ParamOffset + 1];
|
||||
h264_printf(20, " sps %d has length %d\n", i, PsLength);
|
||||
iov[ic].iov_base = (char *)Head;
|
||||
iov[ic++].iov_len = sizeof(Head);
|
||||
InitialHeaderLength += sizeof(Head);
|
||||
iov[ic].iov_base = &avcCHeader->Params[ParamOffset + 2];
|
||||
iov[ic++].iov_len = PsLength;
|
||||
InitialHeaderLength += PsLength;
|
||||
ParamOffset += PsLength + 2;
|
||||
}
|
||||
ParamSets = avcCHeader->Params[ParamOffset];
|
||||
h264_printf(20, " number of picture param sets: %d\n", ParamSets);
|
||||
ParamOffset++;
|
||||
for (i = 0; i < ParamSets; i++)
|
||||
{
|
||||
unsigned int PsLength = (avcCHeader->Params[ParamOffset] << 8) + avcCHeader->Params[ParamOffset + 1];
|
||||
h264_printf(20, " pps %d has length %d\n", i, PsLength);
|
||||
iov[ic].iov_base = (char *) Head;
|
||||
iov[ic++].iov_len = sizeof(Head);
|
||||
InitialHeaderLength += sizeof(Head);
|
||||
iov[ic].iov_base = &avcCHeader->Params[ParamOffset + 2];
|
||||
iov[ic++].iov_len = PsLength;
|
||||
InitialHeaderLength += PsLength;
|
||||
ParamOffset += PsLength + 2;
|
||||
}
|
||||
iov[0].iov_len = InsertPesHeader(PesHeader, InitialHeaderLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
|
||||
ssize_t l = writev(call->fd, iov, ic);
|
||||
if (private_data != call->private_data)
|
||||
{
|
||||
free(private_data);
|
||||
}
|
||||
if (l < 0)
|
||||
{
|
||||
return l;
|
||||
}
|
||||
len += l;
|
||||
initialHeader = 0;
|
||||
}
|
||||
unsigned int SampleSize = call->len;
|
||||
unsigned int NalStart = 0;
|
||||
unsigned int VideoPosition = 0;
|
||||
do
|
||||
{
|
||||
unsigned int NalLength;
|
||||
unsigned char NalData[4];
|
||||
int NalPresent = 1;
|
||||
memcpy(NalData, call->data + VideoPosition, NalLengthBytes);
|
||||
VideoPosition += NalLengthBytes;
|
||||
NalStart += NalLengthBytes;
|
||||
switch (NalLengthBytes)
|
||||
{
|
||||
case 1:
|
||||
NalLength = (NalData[0]);
|
||||
break;
|
||||
case 2:
|
||||
NalLength = (NalData[0] << 8) | (NalData[1]);
|
||||
break;
|
||||
case 3:
|
||||
NalLength = (NalData[0] << 16) | (NalData[1] << 8) | (NalData[2]);
|
||||
break;
|
||||
default:
|
||||
NalLength = (NalData[0] << 24) | (NalData[1] << 16) | (NalData[2] << 8) | (NalData[3]);
|
||||
break;
|
||||
}
|
||||
h264_printf(20, "NalStart = %u + NalLength = %u > SampleSize = %u\n", NalStart, NalLength, SampleSize);
|
||||
if (NalStart + NalLength > SampleSize)
|
||||
{
|
||||
h264_printf(20, "nal length past end of buffer - size %u frame offset %u left %u\n",
|
||||
NalLength, NalStart, SampleSize - NalStart);
|
||||
NalStart = SampleSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
NalStart += NalLength;
|
||||
ic = 0;
|
||||
iov[ic++].iov_base = PesHeader;
|
||||
if (NalPresent)
|
||||
{
|
||||
NalPresent = 0;
|
||||
iov[ic].iov_base = (char *)Head;
|
||||
iov[ic++].iov_len = sizeof(Head);
|
||||
}
|
||||
iov[ic].iov_base = call->data + VideoPosition;
|
||||
iov[ic++].iov_len = NalLength;
|
||||
VideoPosition += NalLength;
|
||||
h264_printf(20, " pts=%llu\n", VideoPts);
|
||||
iov[0].iov_len = InsertPesHeader(PesHeader, NalLength, MPEG_VIDEO_PES_START_CODE, VideoPts, 0);
|
||||
ssize_t l = writev(call->fd, iov, ic);
|
||||
if (l < 0)
|
||||
return l;
|
||||
len += l;
|
||||
VideoPts = INVALID_PTS_VALUE;
|
||||
}
|
||||
}
|
||||
while (NalStart < SampleSize);
|
||||
if (len < 0)
|
||||
{
|
||||
h264_err("error writing data errno = %d\n", errno);
|
||||
h264_err("%s\n", strerror(errno));
|
||||
}
|
||||
h264_printf(10, "< len %d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
static int writeReverseData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
h264_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
h264_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
h264_printf(10, "VideoPts %lld\n", call->Pts);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
h264_err("NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
h264_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps =
|
||||
{
|
||||
"h264",
|
||||
eVideo,
|
||||
"V_MPEG4/ISO/AVC",
|
||||
VIDEO_ENCODING_H264,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoH264 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
&writeReverseData,
|
||||
&caps
|
||||
};
|
178
libeplayer3-arm/output/writer/sh4/mp3.c
Normal file
178
libeplayer3-arm/output/writer/sh4/mp3.c
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/stm_ioctls.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define MP3_DEBUG
|
||||
#else
|
||||
#define MP3_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef MP3_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define mp3_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define mp3_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef MP3_SILENT
|
||||
#define mp3_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define mp3_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int reset()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
mp3_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
mp3_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
mp3_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
mp3_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
mp3_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
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_len = call->len;
|
||||
int len = writev(call->fd, iov, 2);
|
||||
mp3_printf(10, "mp3_Write-< len=%d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps_mp3 =
|
||||
{
|
||||
"mp3",
|
||||
eAudio,
|
||||
"A_MP3",
|
||||
AUDIO_ENCODING_MP3
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioMP3 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_mp3
|
||||
};
|
||||
|
||||
static WriterCaps_t caps_mpegl3 =
|
||||
{
|
||||
"mpeg/l3",
|
||||
eAudio,
|
||||
"A_MPEG/L3",
|
||||
AUDIO_ENCODING_MPEG2
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioMPEGL3 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_mpegl3
|
||||
};
|
||||
|
||||
static WriterCaps_t caps_vorbis =
|
||||
{
|
||||
"vorbis",
|
||||
eAudio,
|
||||
"A_VORBIS",
|
||||
AUDIO_ENCODING_VORBIS
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioVORBIS =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_vorbis
|
||||
};
|
||||
|
181
libeplayer3-arm/output/writer/sh4/mpeg2.c
Normal file
181
libeplayer3-arm/output/writer/sh4/mpeg2.c
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/stm_ioctls.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define MPEG2_DEBUG
|
||||
#else
|
||||
#define MPEG2_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef MPEG2_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define mpeg2_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define mpeg2_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef MPEG2_SILENT
|
||||
#define mpeg2_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define mpeg2_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int reset()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
int len = 0;
|
||||
unsigned int Position = 0;
|
||||
mpeg2_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
mpeg2_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
mpeg2_printf(10, "VideoPts %lld\n", call->Pts);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
mpeg2_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
mpeg2_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
while (Position < call->len)
|
||||
{
|
||||
int32_t PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ?
|
||||
(call->len - Position) : MAX_PES_PACKET_SIZE;
|
||||
int32_t Remaining = call->len - Position - PacketLength;
|
||||
mpeg2_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", PacketLength, Remaining, Position);
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, 0xe0, call->Pts, 0);
|
||||
iov[1].iov_base = call->data + Position;
|
||||
iov[1].iov_len = PacketLength;
|
||||
ssize_t l = writev(call->fd, iov, 2);
|
||||
if (l < 0)
|
||||
{
|
||||
len = l;
|
||||
break;
|
||||
}
|
||||
len += l;
|
||||
Position += PacketLength;
|
||||
call->Pts = INVALID_PTS_VALUE;
|
||||
}
|
||||
mpeg2_printf(10, "< len %d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
static WriterCaps_t caps =
|
||||
{
|
||||
"mpeg2",
|
||||
eVideo,
|
||||
"V_MPEG2",
|
||||
VIDEO_ENCODING_AUTO,
|
||||
-1,
|
||||
-1,
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoMPEG2 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps
|
||||
};
|
||||
|
||||
static WriterCaps_t h264_caps =
|
||||
{
|
||||
"mpges_h264",
|
||||
eVideo,
|
||||
"V_MPEG2/H264",
|
||||
VIDEO_ENCODING_H264,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoMPEGH264 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&h264_caps
|
||||
};
|
354
libeplayer3-arm/output/writer/sh4/pcm.c
Normal file
354
libeplayer3-arm/output/writer/sh4/pcm.c
Normal file
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/stm_ioctls.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
#include "pcm.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define PCM_DEBUG
|
||||
#else
|
||||
#define PCM_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef PCM_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define pcm_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define pcm_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef PCM_SILENT
|
||||
#define pcm_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define pcm_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
static int32_t initialHeader = 1;
|
||||
static uint32_t SubFrameLen = 0;
|
||||
static uint32_t SubFramesPerPES = 0;
|
||||
|
||||
// reference: search for TypeLpcmDVDAudio in player/frame_parser/frame_parser_audio_lpcm.cpp
|
||||
static const uint8_t clpcm_prv[14] =
|
||||
{
|
||||
0xA0, //sub_stream_id
|
||||
0, 0, //resvd and UPC_EAN_ISRC stuff, unused
|
||||
0x0A, //private header length
|
||||
0, 9, //first_access_unit_pointer
|
||||
0x00, //emph,rsvd,stereo,downmix
|
||||
0x0F, //quantisation word length 1,2
|
||||
0x0F, //audio sampling freqency 1,2
|
||||
0, //resvd, multi channel type
|
||||
0, //bit shift on channel GR2, assignment
|
||||
0x80, //dynamic range control
|
||||
0, 0 //resvd for copyright management
|
||||
};
|
||||
|
||||
static uint8_t lpcm_prv[14];
|
||||
static uint8_t breakBuffer[8192];
|
||||
static uint32_t breakBufferFillSize = 0;
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int32_t prepareClipPlay(int32_t uNoOfChannels, int32_t uSampleRate, int32_t uBitsPerSample, uint8_t bLittleEndian __attribute__((unused)))
|
||||
{
|
||||
printf("rate: %d ch: %d bits: %d (%d bps)\n",
|
||||
uSampleRate/*Format->dwSamplesPerSec*/,
|
||||
uNoOfChannels/*Format->wChannels*/,
|
||||
uBitsPerSample/*Format->wBitsPerSample*/,
|
||||
(uBitsPerSample/*Format->wBitsPerSample*/ / 8)
|
||||
);
|
||||
SubFrameLen = 0;
|
||||
SubFramesPerPES = 0;
|
||||
breakBufferFillSize = 0;
|
||||
memcpy(lpcm_prv, clpcm_prv, sizeof(lpcm_prv));
|
||||
//figure out size of subframe
|
||||
//and set up sample rate
|
||||
switch (uSampleRate)
|
||||
{
|
||||
case 48000:
|
||||
SubFrameLen = 40;
|
||||
break;
|
||||
case 96000:
|
||||
lpcm_prv[8] |= 0x10;
|
||||
SubFrameLen = 80;
|
||||
break;
|
||||
case 192000:
|
||||
lpcm_prv[8] |= 0x20;
|
||||
SubFrameLen = 160;
|
||||
break;
|
||||
case 44100:
|
||||
lpcm_prv[8] |= 0x80;
|
||||
SubFrameLen = 40;
|
||||
break;
|
||||
case 88200:
|
||||
lpcm_prv[8] |= 0x90;
|
||||
SubFrameLen = 80;
|
||||
break;
|
||||
case 176400:
|
||||
lpcm_prv[8] |= 0xA0;
|
||||
SubFrameLen = 160;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SubFrameLen *= uNoOfChannels;
|
||||
SubFrameLen *= (uBitsPerSample / 8);
|
||||
//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.
|
||||
SubFramesPerPES = ((2048 - 18) - sizeof(lpcm_prv)) / SubFrameLen;
|
||||
SubFrameLen *= SubFramesPerPES;
|
||||
//set number of channels
|
||||
lpcm_prv[10] = uNoOfChannels - 1;
|
||||
switch (uBitsPerSample)
|
||||
{
|
||||
case 24:
|
||||
lpcm_prv[7] |= 0x20;
|
||||
case 16:
|
||||
break;
|
||||
default:
|
||||
printf("inappropriate bits per sample (%d) - must be 16 or 24\n", uBitsPerSample);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
pcm_printf(10, "\n");
|
||||
if (!call)
|
||||
{
|
||||
pcm_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
pcm_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if (!call->data || (call->len <= 0))
|
||||
{
|
||||
pcm_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
pcm_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
pcmPrivateData_t *pcmPrivateData = (pcmPrivateData_t *)call->private_data;
|
||||
if (initialHeader)
|
||||
{
|
||||
uint32_t codecID = (uint32_t)pcmPrivateData->ffmpeg_codec_id;
|
||||
uint8_t LE = 0;
|
||||
switch (codecID)
|
||||
{
|
||||
case AV_CODEC_ID_PCM_S8:
|
||||
case AV_CODEC_ID_PCM_U8:
|
||||
break;
|
||||
case AV_CODEC_ID_PCM_S16LE:
|
||||
case AV_CODEC_ID_PCM_U16LE:
|
||||
LE = 1;
|
||||
case AV_CODEC_ID_PCM_S16BE:
|
||||
case AV_CODEC_ID_PCM_U16BE:
|
||||
break;
|
||||
case AV_CODEC_ID_PCM_S24LE:
|
||||
case AV_CODEC_ID_PCM_U24LE:
|
||||
LE = 1;
|
||||
case AV_CODEC_ID_PCM_S24BE:
|
||||
case AV_CODEC_ID_PCM_U24BE:
|
||||
break;
|
||||
case AV_CODEC_ID_PCM_S32LE:
|
||||
case AV_CODEC_ID_PCM_U32LE:
|
||||
LE = 1;
|
||||
case AV_CODEC_ID_PCM_S32BE:
|
||||
case AV_CODEC_ID_PCM_U32BE:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
initialHeader = 0;
|
||||
prepareClipPlay(pcmPrivateData->channels, pcmPrivateData->sample_rate, pcmPrivateData->bits_per_coded_sample, LE);
|
||||
}
|
||||
uint8_t *buffer = call->data;
|
||||
uint32_t size = call->len;
|
||||
uint32_t n;
|
||||
uint8_t *injectBuffer = malloc(SubFrameLen);
|
||||
uint32_t pos;
|
||||
for (pos = 0; pos < size;)
|
||||
{
|
||||
//printf("PCM %s - Position=%d\n", __FUNCTION__, pos);
|
||||
if ((size - pos) < SubFrameLen)
|
||||
{
|
||||
breakBufferFillSize = size - pos;
|
||||
memcpy(breakBuffer, &buffer[pos], sizeof(uint8_t) * breakBufferFillSize);
|
||||
//printf("PCM %s - Unplayed=%d\n", __FUNCTION__, breakBufferFillSize);
|
||||
break;
|
||||
}
|
||||
//get first PES's worth
|
||||
if (breakBufferFillSize > 0)
|
||||
{
|
||||
memcpy(injectBuffer, breakBuffer, sizeof(uint8_t)*breakBufferFillSize);
|
||||
memcpy(&injectBuffer[breakBufferFillSize], &buffer[pos], sizeof(unsigned char) * (SubFrameLen - breakBufferFillSize));
|
||||
pos += (SubFrameLen - breakBufferFillSize);
|
||||
breakBufferFillSize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(injectBuffer, &buffer[pos], sizeof(uint8_t)*SubFrameLen);
|
||||
pos += SubFrameLen;
|
||||
}
|
||||
struct iovec iov[3];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[1].iov_base = lpcm_prv;
|
||||
iov[1].iov_len = sizeof(lpcm_prv);
|
||||
iov[2].iov_base = injectBuffer;
|
||||
iov[2].iov_len = SubFrameLen;
|
||||
//write the PCM data
|
||||
if (16 == pcmPrivateData->bits_per_coded_sample)
|
||||
{
|
||||
for (n = 0; n < SubFrameLen; n += 2)
|
||||
{
|
||||
uint8_t tmp;
|
||||
tmp = injectBuffer[n];
|
||||
injectBuffer[n] = injectBuffer[n + 1];
|
||||
injectBuffer[n + 1] = tmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11
|
||||
// A1c A1b A1a-B1c B1b B1a-A2c A2b A2a-B2c B2b B2a
|
||||
// to A1a A1b B1a B1b.A2a A2b B2a B2b-A1c B1c A2c B2c
|
||||
for (n = 0; n < SubFrameLen; n += 12)
|
||||
{
|
||||
unsigned char t, *p = &injectBuffer[n];
|
||||
t = p[0];
|
||||
p[ 0] = p[ 2];
|
||||
p[ 2] = p[ 5];
|
||||
p[ 5] = p[ 7];
|
||||
p[ 7] = p[11];
|
||||
p[11] = p[ 9];
|
||||
p[ 9] = p[ 3];
|
||||
p[ 3] = p[ 4];
|
||||
p[ 4] = p[ 8];
|
||||
p[ 8] = t;
|
||||
}
|
||||
}
|
||||
//increment err... subframe count?
|
||||
lpcm_prv[1] = ((lpcm_prv[1] + SubFramesPerPES) & 0x1F);
|
||||
iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len + iov[2].iov_len, PCM_PES_START_CODE, call->Pts, 0);
|
||||
int32_t len = writev(call->fd, iov, 3);
|
||||
if (len < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(injectBuffer);
|
||||
return size;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps_pcm =
|
||||
{
|
||||
"pcm",
|
||||
eAudio,
|
||||
"A_PCM",
|
||||
AUDIO_ENCODING_LPCMA
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioPCM =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_pcm
|
||||
};
|
||||
|
||||
static WriterCaps_t caps_ipcm =
|
||||
{
|
||||
"ipcm",
|
||||
eAudio,
|
||||
"A_IPCM",
|
||||
AUDIO_ENCODING_LPCMA
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioIPCM =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_ipcm
|
||||
};
|
154
libeplayer3-arm/output/writer/sh4/pes.c
Normal file
154
libeplayer3-arm/output/writer/sh4/pes.c
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/stm_ioctls.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Functions */
|
||||
/* ***************************** */
|
||||
|
||||
int InsertVideoPrivateDataHeader(unsigned char *data, int payload_size)
|
||||
{
|
||||
BitPacker_t ld2 = {data, 0, 32};
|
||||
int i;
|
||||
PutBits(&ld2, PES_PRIVATE_DATA_FLAG, 8);
|
||||
PutBits(&ld2, payload_size & 0xff, 8);
|
||||
PutBits(&ld2, (payload_size >> 8) & 0xff, 8);
|
||||
PutBits(&ld2, (payload_size >> 16) & 0xff, 8);
|
||||
for (i = 4; i < (PES_PRIVATE_DATA_LENGTH + 1); i++)
|
||||
PutBits(&ld2, 0, 8);
|
||||
FlushBits(&ld2);
|
||||
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)
|
||||
{
|
||||
BitPacker_t ld2 = {data, 0, 32};
|
||||
if (size > (MAX_PES_PACKET_SIZE - 13))
|
||||
{
|
||||
size = -1; // unbounded
|
||||
}
|
||||
PutBits(&ld2, 0x0, 8);
|
||||
PutBits(&ld2, 0x0, 8);
|
||||
PutBits(&ld2, 0x1, 8); // Start Code
|
||||
PutBits(&ld2, stream_id, 8); // Stream_id = Audio Stream
|
||||
//4
|
||||
if (-1 == size)
|
||||
{
|
||||
PutBits(&ld2, 0x0, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
PutBits(&ld2, size + 3 + (pts != INVALID_PTS_VALUE ? 5 : 0) + (pic_start_code ? (5) : 0), 16); // PES_packet_length
|
||||
}
|
||||
//6 = 4+2
|
||||
PutBits(&ld2, 0x2, 2); // 10
|
||||
PutBits(&ld2, 0x0, 2); // PES_Scrambling_control
|
||||
PutBits(&ld2, 0x0, 1); // PES_Priority
|
||||
PutBits(&ld2, 0x0, 1); // data_alignment_indicator
|
||||
PutBits(&ld2, 0x0, 1); // Copyright
|
||||
PutBits(&ld2, 0x0, 1); // Original or Copy
|
||||
//7 = 6+1
|
||||
if (pts != INVALID_PTS_VALUE)
|
||||
{
|
||||
PutBits(&ld2, 0x2, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
PutBits(&ld2, 0x0, 2); // PTS_DTS flag
|
||||
}
|
||||
PutBits(&ld2, 0x0, 1); // ESCR_flag
|
||||
PutBits(&ld2, 0x0, 1); // ES_rate_flag
|
||||
PutBits(&ld2, 0x0, 1); // DSM_trick_mode_flag
|
||||
PutBits(&ld2, 0x0, 1); // additional_copy_ingo_flag
|
||||
PutBits(&ld2, 0x0, 1); // PES_CRC_flag
|
||||
PutBits(&ld2, 0x0, 1); // PES_extension_flag
|
||||
//8 = 7+1
|
||||
if (pts != INVALID_PTS_VALUE)
|
||||
PutBits(&ld2, 0x5, 8);
|
||||
else
|
||||
PutBits(&ld2, 0x0, 8); // PES_header_data_length
|
||||
//9 = 8+1
|
||||
if (pts != INVALID_PTS_VALUE)
|
||||
{
|
||||
PutBits(&ld2, 0x2, 4);
|
||||
PutBits(&ld2, (pts >> 30) & 0x7, 3);
|
||||
PutBits(&ld2, 0x1, 1);
|
||||
PutBits(&ld2, (pts >> 15) & 0x7fff, 15);
|
||||
PutBits(&ld2, 0x1, 1);
|
||||
PutBits(&ld2, pts & 0x7fff, 15);
|
||||
PutBits(&ld2, 0x1, 1);
|
||||
}
|
||||
//14 = 9+5
|
||||
if (pic_start_code)
|
||||
{
|
||||
PutBits(&ld2, 0x0, 8);
|
||||
PutBits(&ld2, 0x0, 8);
|
||||
PutBits(&ld2, 0x1, 8); // Start Code
|
||||
PutBits(&ld2, pic_start_code & 0xff, 8); // 00, for picture start
|
||||
PutBits(&ld2, (pic_start_code >> 8) & 0xff, 8); // For any extra information (like in mpeg4p2, the pic_start_code)
|
||||
//14 + 4 = 18
|
||||
}
|
||||
FlushBits(&ld2);
|
||||
return (ld2.Ptr - data);
|
||||
}
|
263
libeplayer3-arm/output/writer/sh4/vc1.c
Normal file
263
libeplayer3-arm/output/writer/sh4/vc1.c
Normal file
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/stm_ioctls.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
#define WMV3_PRIVATE_DATA_LENGTH 4
|
||||
|
||||
#define METADATA_STRUCT_A_START 12
|
||||
#define METADATA_STRUCT_B_START 24
|
||||
#define METADATA_STRUCT_B_FRAMERATE_START 32
|
||||
#define METADATA_STRUCT_C_START 8
|
||||
|
||||
|
||||
#define VC1_SEQUENCE_LAYER_METADATA_START_CODE 0x80
|
||||
#define VC1_FRAME_START_CODE 0x0d
|
||||
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define VC1_DEBUG
|
||||
#else
|
||||
#define VC1_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef VC1_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define vc1_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define vc1_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef VC1_SILENT
|
||||
#define vc1_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define vc1_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
static const unsigned char SequenceLayerStartCode[] = {0x00, 0x00, 0x01, VC1_SEQUENCE_LAYER_METADATA_START_CODE};
|
||||
|
||||
|
||||
static const unsigned char Metadata[] =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0xc5,
|
||||
0x04, 0x00, 0x00, 0x00,
|
||||
0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile*/
|
||||
0x00, 0x00, 0x00, 0x00, /* Struct A */
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x0c, 0x00, 0x00, 0x00,
|
||||
0x60, 0x00, 0x00, 0x00, /* Struct B */
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
static int initialHeader = 1;
|
||||
static unsigned char FrameHeaderSeen = 0;
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
static int reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
FrameHeaderSeen = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
int len = 0;
|
||||
vc1_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
vc1_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
vc1_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
vc1_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
vc1_printf(10, "VideoPts %lld\n", call->Pts);
|
||||
vc1_printf(10, "Got Private Size %d\n", call->private_size);
|
||||
if (initialHeader)
|
||||
{
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
unsigned char PesPayload[128];
|
||||
unsigned char *PesPtr;
|
||||
unsigned int crazyFramerate = 0;
|
||||
struct iovec iov[2];
|
||||
vc1_printf(10, "Framerate: %u\n", call->FrameRate);
|
||||
vc1_printf(10, "biWidth: %d\n", call->Width);
|
||||
vc1_printf(10, "biHeight: %d\n", call->Height);
|
||||
crazyFramerate = ((10000000.0 / call->FrameRate) * 1000.0);
|
||||
vc1_printf(10, "crazyFramerate: %u\n", crazyFramerate);
|
||||
memset(PesPayload, 0, sizeof(PesPayload));
|
||||
PesPtr = PesPayload;
|
||||
memcpy(PesPtr, SequenceLayerStartCode, sizeof(SequenceLayerStartCode));
|
||||
PesPtr += sizeof(SequenceLayerStartCode);
|
||||
memcpy(PesPtr, Metadata, sizeof(Metadata));
|
||||
PesPtr += METADATA_STRUCT_C_START;
|
||||
PesPtr += WMV3_PRIVATE_DATA_LENGTH;
|
||||
/* Metadata Header Struct A */
|
||||
*PesPtr++ = (call->Height >> 0) & 0xff;
|
||||
*PesPtr++ = (call->Height >> 8) & 0xff;
|
||||
*PesPtr++ = (call->Height >> 16) & 0xff;
|
||||
*PesPtr++ = call->Height >> 24;
|
||||
*PesPtr++ = (call->Width >> 0) & 0xff;
|
||||
*PesPtr++ = (call->Width >> 8) & 0xff;
|
||||
*PesPtr++ = (call->Width >> 16) & 0xff;
|
||||
*PesPtr++ = call->Width >> 24;
|
||||
PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */
|
||||
*PesPtr++ = (crazyFramerate >> 0) & 0xff;
|
||||
*PesPtr++ = (crazyFramerate >> 8) & 0xff;
|
||||
*PesPtr++ = (crazyFramerate >> 16) & 0xff;
|
||||
*PesPtr++ = crazyFramerate >> 24;
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[1].iov_base = 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);
|
||||
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 */
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[1].iov_base = call->private_data;
|
||||
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);
|
||||
len = writev(call->fd, iov, 2);
|
||||
initialHeader = 0;
|
||||
}
|
||||
if (call->len > 0 && call->data)
|
||||
{
|
||||
uint32_t Position = 0;
|
||||
uint8_t insertSampleHeader = 1;
|
||||
while (Position < call->len)
|
||||
{
|
||||
int32_t PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ?
|
||||
(call->len - Position) : MAX_PES_PACKET_SIZE;
|
||||
int32_t Remaining = call->len - Position - PacketLength;
|
||||
vc1_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", PacketLength, Remaining, Position);
|
||||
uint8_t PesHeader[PES_MAX_HEADER_SIZE];
|
||||
int32_t HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, call->Pts, 0);
|
||||
if (insertSampleHeader)
|
||||
{
|
||||
const uint8_t Vc1FrameStartCode[] = {0, 0, 1, VC1_FRAME_START_CODE};
|
||||
if (!FrameHeaderSeen && (call->len > 3) && (memcmp(call->data, Vc1FrameStartCode, 4) == 0))
|
||||
{
|
||||
FrameHeaderSeen = 1;
|
||||
}
|
||||
if (!FrameHeaderSeen)
|
||||
{
|
||||
memcpy(&PesHeader[HeaderLength], Vc1FrameStartCode, sizeof(Vc1FrameStartCode));
|
||||
HeaderLength += sizeof(Vc1FrameStartCode);
|
||||
}
|
||||
insertSampleHeader = 0;
|
||||
}
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = HeaderLength;
|
||||
iov[1].iov_base = call->data + Position;
|
||||
iov[1].iov_len = PacketLength;
|
||||
ssize_t l = writev(call->fd, iov, 2);
|
||||
if (l < 0)
|
||||
{
|
||||
len = l;
|
||||
break;
|
||||
}
|
||||
len += l;
|
||||
Position += PacketLength;
|
||||
call->Pts = INVALID_PTS_VALUE;
|
||||
}
|
||||
}
|
||||
vc1_printf(10, "< %d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps =
|
||||
{
|
||||
"vc1",
|
||||
eVideo,
|
||||
"V_VC1",
|
||||
VIDEO_ENCODING_VC1,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoVC1 =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps
|
||||
};
|
||||
|
146
libeplayer3-arm/output/writer/sh4/vorbis.c
Normal file
146
libeplayer3-arm/output/writer/sh4/vorbis.c
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "stm_ioctls.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define VORBIS_DEBUG
|
||||
#else
|
||||
#define VORBIS_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef VORBIS_DEBUG
|
||||
|
||||
static short debug_level = 1;
|
||||
|
||||
#define vorbis_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define vorbis_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef VORBIS_SILENT
|
||||
#define vorbis_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define vorbis_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int reset()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
vorbis_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
vorbis_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
vorbis_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
vorbis_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
vorbis_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
int HeaderLength = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
|
||||
unsigned char *PacketStart = malloc(call->len + HeaderLength);
|
||||
memcpy(PacketStart, PesHeader, HeaderLength);
|
||||
memcpy(PacketStart + HeaderLength, call->data, call->len);
|
||||
int len = write(call->fd, PacketStart, call->len + HeaderLength);
|
||||
free(PacketStart);
|
||||
vorbis_printf(10, "vorbis_Write-< len=%d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps_vorbis =
|
||||
{
|
||||
"vorbis",
|
||||
eAudio,
|
||||
"A_VORBIS",
|
||||
AUDIO_ENCODING_VORBIS,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioVORBIS =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps_vorbis
|
||||
};
|
191
libeplayer3-arm/output/writer/sh4/wma.c
Normal file
191
libeplayer3-arm/output/writer/sh4/wma.c
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/stm_ioctls.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define WMA_DEBUG
|
||||
#else
|
||||
#define WMA_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef WMA_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define wma_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define wma_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef WMA_SILENT
|
||||
#define wma_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define wma_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
static int initialHeader = 1;
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
|
||||
static int reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
int len = 0;
|
||||
wma_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
wma_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
wma_printf(10, "AudioPts %lld\n", call->Pts);
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
wma_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
wma_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
if (initialHeader)
|
||||
{
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
if ((call->private_size <= 0) || (call->private_data == NULL))
|
||||
{
|
||||
wma_err("private NULL.\n");
|
||||
return -1;
|
||||
}
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = InsertPesHeader(PesHeader, call->private_size, MPEG_AUDIO_PES_START_CODE, 0, 0);
|
||||
iov[1].iov_base = call->private_data;
|
||||
iov[1].iov_len = call->private_size;
|
||||
len = writev(call->fd, iov, 2);
|
||||
initialHeader = 0;
|
||||
}
|
||||
if (len > -1 && call->len > 0 && call->data)
|
||||
{
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
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_len = call->len;
|
||||
ssize_t l = writev(call->fd, iov, 2);
|
||||
len = (l > -1) ? len + l : l;
|
||||
}
|
||||
wma_printf(10, "wma < %d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t capsWMAPRO =
|
||||
{
|
||||
"wma/pro",
|
||||
eAudio,
|
||||
"A_WMA/PRO",
|
||||
AUDIO_ENCODING_WMA,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioWMAPRO =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&capsWMAPRO
|
||||
};
|
||||
|
||||
|
||||
static WriterCaps_t capsWMA =
|
||||
{
|
||||
"wma",
|
||||
eAudio,
|
||||
"A_WMA",
|
||||
AUDIO_ENCODING_WMA,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterAudioWMA =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&capsWMA
|
||||
};
|
254
libeplayer3-arm/output/writer/sh4/wmv.c
Normal file
254
libeplayer3-arm/output/writer/sh4/wmv.c
Normal file
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010 based on linuxdvb.c code from libeplayer2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
#include <linux/dvb/stm_ioctls.h>
|
||||
#include <memory.h>
|
||||
#include <asm/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "output.h"
|
||||
#include "debug.h"
|
||||
#include "misc.h"
|
||||
#include "pes.h"
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
#define WMV3_PRIVATE_DATA_LENGTH 4
|
||||
|
||||
#define METADATA_STRUCT_A_START 12
|
||||
#define METADATA_STRUCT_B_START 24
|
||||
#define METADATA_STRUCT_B_FRAMERATE_START 32
|
||||
#define METADATA_STRUCT_C_START 8
|
||||
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define WMV_DEBUG
|
||||
#else
|
||||
#define WMV_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef WMV_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define wmv_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define wmv_printf(level, fmt, x...)
|
||||
#endif
|
||||
|
||||
#ifndef WMV_SILENT
|
||||
#define wmv_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
|
||||
#else
|
||||
#define wmv_err(fmt, x...)
|
||||
#endif
|
||||
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char privateData[WMV3_PRIVATE_DATA_LENGTH];
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int framerate;
|
||||
} awmv_t;
|
||||
|
||||
static const unsigned char Metadata[] =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0xc5,
|
||||
0x04, 0x00, 0x00, 0x00,
|
||||
0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile*/
|
||||
0x00, 0x00, 0x00, 0x00, /* Struct A */
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x0c, 0x00, 0x00, 0x00,
|
||||
0x60, 0x00, 0x00, 0x00, /* Struct B */
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
static int initialHeader = 1;
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* MISC Functions */
|
||||
/* ***************************** */
|
||||
static int reset()
|
||||
{
|
||||
initialHeader = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int writeData(void *_call)
|
||||
{
|
||||
WriterAVCallData_t *call = (WriterAVCallData_t *) _call;
|
||||
awmv_t private_data;
|
||||
int len = 0;
|
||||
wmv_printf(10, "\n");
|
||||
if (call == NULL)
|
||||
{
|
||||
wmv_err("call data is NULL...\n");
|
||||
return 0;
|
||||
}
|
||||
if ((call->data == NULL) || (call->len <= 0))
|
||||
{
|
||||
wmv_err("parsing NULL Data. ignoring...\n");
|
||||
return 0;
|
||||
}
|
||||
if (call->fd < 0)
|
||||
{
|
||||
wmv_err("file pointer < 0. ignoring ...\n");
|
||||
return 0;
|
||||
}
|
||||
wmv_printf(10, "VideoPts %lld\n", call->Pts);
|
||||
wmv_printf(10, "Got Private Size %d\n", call->private_size);
|
||||
memcpy(private_data.privateData, call->private_data,
|
||||
call->private_size > WMV3_PRIVATE_DATA_LENGTH ? WMV3_PRIVATE_DATA_LENGTH : call->private_size);
|
||||
private_data.width = call->Width;
|
||||
private_data.height = call->Height;
|
||||
private_data.framerate = call->FrameRate;
|
||||
#define PES_MIN_HEADER_SIZE 9
|
||||
if (initialHeader)
|
||||
{
|
||||
unsigned char PesPacket[PES_MIN_HEADER_SIZE + 128];
|
||||
unsigned char *PesPtr;
|
||||
unsigned int MetadataLength;
|
||||
unsigned int crazyFramerate = 0;
|
||||
wmv_printf(10, "Framerate: %u\n", private_data.framerate);
|
||||
wmv_printf(10, "biWidth: %d\n", private_data.width);
|
||||
wmv_printf(10, "biHeight: %d\n", private_data.height);
|
||||
crazyFramerate = ((10000000.0 / private_data.framerate) * 1000.0);
|
||||
wmv_printf(10, "crazyFramerate: %u\n", crazyFramerate);
|
||||
PesPtr = &PesPacket[PES_MIN_HEADER_SIZE];
|
||||
memcpy(PesPtr, Metadata, sizeof(Metadata));
|
||||
PesPtr += METADATA_STRUCT_C_START;
|
||||
memcpy(PesPtr, private_data.privateData, WMV3_PRIVATE_DATA_LENGTH);
|
||||
PesPtr += WMV3_PRIVATE_DATA_LENGTH;
|
||||
/* Metadata Header Struct A */
|
||||
*PesPtr++ = (private_data.height >> 0) & 0xff;
|
||||
*PesPtr++ = (private_data.height >> 8) & 0xff;
|
||||
*PesPtr++ = (private_data.height >> 16) & 0xff;
|
||||
*PesPtr++ = private_data.height >> 24;
|
||||
*PesPtr++ = (private_data.width >> 0) & 0xff;
|
||||
*PesPtr++ = (private_data.width >> 8) & 0xff;
|
||||
*PesPtr++ = (private_data.width >> 16) & 0xff;
|
||||
*PesPtr++ = private_data.width >> 24;
|
||||
PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */
|
||||
*PesPtr++ = (crazyFramerate >> 0) & 0xff;
|
||||
*PesPtr++ = (crazyFramerate >> 8) & 0xff;
|
||||
*PesPtr++ = (crazyFramerate >> 16) & 0xff;
|
||||
*PesPtr++ = crazyFramerate >> 24;
|
||||
MetadataLength = PesPtr - &PesPacket[PES_MIN_HEADER_SIZE];
|
||||
int HeaderLength = InsertPesHeader(PesPacket, MetadataLength, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
|
||||
len = write(call->fd, PesPacket, HeaderLength + MetadataLength);
|
||||
initialHeader = 0;
|
||||
}
|
||||
if (call->len > 0 && call->data)
|
||||
{
|
||||
unsigned int Position = 0;
|
||||
unsigned char insertSampleHeader = 1;
|
||||
while (Position < call->len)
|
||||
{
|
||||
int PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ?
|
||||
(call->len - Position) : MAX_PES_PACKET_SIZE;
|
||||
int Remaining = call->len - Position - PacketLength;
|
||||
wmv_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", PacketLength, Remaining, Position);
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
memset(PesHeader, '0', PES_MAX_HEADER_SIZE);
|
||||
int HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, call->Pts, 0);
|
||||
unsigned char *PacketStart;
|
||||
if (insertSampleHeader)
|
||||
{
|
||||
unsigned int PesLength;
|
||||
unsigned int PrivateHeaderLength;
|
||||
PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength],
|
||||
call->len);
|
||||
/* Update PesLength */
|
||||
PesLength = PesHeader[PES_LENGTH_BYTE_0] +
|
||||
(PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength;
|
||||
PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff;
|
||||
PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff;
|
||||
PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength;
|
||||
PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT;
|
||||
HeaderLength += PrivateHeaderLength;
|
||||
insertSampleHeader = 0;
|
||||
}
|
||||
PacketStart = malloc(call->len + HeaderLength);
|
||||
memcpy(PacketStart, PesHeader, HeaderLength);
|
||||
memcpy(PacketStart + HeaderLength, call->data + Position, PacketLength);
|
||||
len = write(call->fd, PacketStart, PacketLength + HeaderLength);
|
||||
free(PacketStart);
|
||||
Position += PacketLength;
|
||||
call->Pts = INVALID_PTS_VALUE;
|
||||
}
|
||||
}
|
||||
wmv_printf(10, "< %d\n", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
/* Writer Definition */
|
||||
/* ***************************** */
|
||||
|
||||
static WriterCaps_t caps =
|
||||
{
|
||||
"wmv",
|
||||
eVideo,
|
||||
"V_WMV",
|
||||
VIDEO_ENCODING_WMV,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoWMV =
|
||||
{
|
||||
&reset,
|
||||
&writeData,
|
||||
NULL,
|
||||
&caps
|
||||
};
|
144
libeplayer3-arm/output/writer/sh4/writer.c
Normal file
144
libeplayer3-arm/output/writer/sh4/writer.c
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* linuxdvb output/writer handling.
|
||||
*
|
||||
* konfetti 2010
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/* ***************************** */
|
||||
/* Includes */
|
||||
/* ***************************** */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "writer.h"
|
||||
|
||||
/* ***************************** */
|
||||
/* Makros/Constants */
|
||||
/* ***************************** */
|
||||
|
||||
#ifdef SAM_WITH_DEBUG
|
||||
#define WRITER_DEBUG
|
||||
#else
|
||||
#define WRITER_SILENT
|
||||
#endif
|
||||
|
||||
#ifdef WRITER_DEBUG
|
||||
|
||||
static short debug_level = 0;
|
||||
|
||||
#define writer_printf(level, x...) do { \
|
||||
if (debug_level >= level) printf(x); } while (0)
|
||||
#else
|
||||
#define writer_printf(level, x...)
|
||||
#endif
|
||||
|
||||
#ifndef WRITER_SILENT
|
||||
#define writer_err(x...) do { printf(x); } while (0)
|
||||
#else
|
||||
#define writer_err(x...)
|
||||
#endif
|
||||
|
||||
/* ***************************** */
|
||||
/* Types */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Varaibles */
|
||||
/* ***************************** */
|
||||
|
||||
static Writer_t *AvailableWriter[] =
|
||||
{
|
||||
&WriterAudioIPCM,
|
||||
&WriterAudioPCM,
|
||||
&WriterAudioMP3,
|
||||
&WriterAudioMPEGL3,
|
||||
&WriterAudioAC3,
|
||||
&WriterAudioAAC,
|
||||
&WriterAudioDTS,
|
||||
&WriterAudioWMA,
|
||||
&WriterAudioVORBIS,
|
||||
|
||||
&WriterVideoMPEG2,
|
||||
&WriterVideoMPEGH264,
|
||||
&WriterVideoH264,
|
||||
&WriterVideoDIVX,
|
||||
&WriterVideoFOURCC,
|
||||
&WriterVideoMSCOMP,
|
||||
&WriterVideoWMV,
|
||||
&WriterVideoH263,
|
||||
&WriterVideoFLV,
|
||||
&WriterVideoVC1,
|
||||
NULL
|
||||
};
|
||||
|
||||
// &WriterAudioFLAC,
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
|
||||
/* ***************************** */
|
||||
/* Functions */
|
||||
/* ***************************** */
|
||||
|
||||
Writer_t *getWriter(char *encoding)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; AvailableWriter[i] != NULL; i++)
|
||||
{
|
||||
if (strcmp(AvailableWriter[i]->caps->textEncoding, encoding) == 0)
|
||||
{
|
||||
writer_printf(50, "%s: found writer \"%s\" for \"%s\"\n", __func__, AvailableWriter[i]->caps->name, encoding);
|
||||
return AvailableWriter[i];
|
||||
}
|
||||
}
|
||||
writer_printf(1, "%s: no writer found for \"%s\"\n", __func__, encoding);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Writer_t *getDefaultVideoWriter()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; AvailableWriter[i] != NULL; i++)
|
||||
{
|
||||
if (strcmp(AvailableWriter[i]->caps->textEncoding, "V_MPEG2") == 0)
|
||||
{
|
||||
writer_printf(50, "%s: found writer \"%s\"\n", __func__, AvailableWriter[i]->caps->name);
|
||||
return AvailableWriter[i];
|
||||
}
|
||||
}
|
||||
writer_printf(1, "%s: no writer found\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Writer_t *getDefaultAudioWriter()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; AvailableWriter[i] != NULL; i++)
|
||||
{
|
||||
if (strcmp(AvailableWriter[i]->caps->textEncoding, "A_MP3") == 0)
|
||||
{
|
||||
writer_printf(50, "%s: found writer \"%s\"\n", __func__, AvailableWriter[i]->caps->name);
|
||||
return AvailableWriter[i];
|
||||
}
|
||||
}
|
||||
writer_printf(1, "%s: no writer found\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
Reference in New Issue
Block a user