Media add-on for DVB.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20707 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
fbaad6fdb5
commit
b2859abe13
|
@ -0,0 +1,292 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h> // required on BeOS R5
|
||||
#include <OS.h>
|
||||
|
||||
#include "DVBCard.h"
|
||||
|
||||
|
||||
DVBCard::DVBCard(const char *path)
|
||||
: fInitStatus(B_OK)
|
||||
, fDev(-1)
|
||||
{
|
||||
printf("DVBCard opening %s\n", path);
|
||||
|
||||
fDev = open(path, O_RDWR);
|
||||
if (fDev < 0) {
|
||||
printf("DVBCard opening %s failed\n", path);
|
||||
fInitStatus = B_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
dvb_frequency_info_t info;
|
||||
if (do_ioctl(fDev, DVB_GET_FREQUENCY_INFO, &info) < 0) {
|
||||
printf("DVB_GET_FREQUENCY_INFO failed with error %s\n", strerror(errno));
|
||||
// close(fDev);
|
||||
// fDev = -1;
|
||||
// return;
|
||||
}
|
||||
|
||||
fFreqMin = info.frequency_min;
|
||||
fFreqMax = info.frequency_max;
|
||||
fFreqStep = info.frequency_step;
|
||||
|
||||
fCaptureActive = false;
|
||||
}
|
||||
|
||||
|
||||
DVBCard::~DVBCard()
|
||||
{
|
||||
if (fDev > 0)
|
||||
close(fDev);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DVBCard::InitCheck()
|
||||
{
|
||||
return fInitStatus;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DVBCard::GetCardType(dvb_type_t *type)
|
||||
{
|
||||
dvb_interface_info_t info;
|
||||
|
||||
if (do_ioctl(fDev, DVB_GET_INTERFACE_INFO, &info) < 0) {
|
||||
printf("DVB_GET_INTERFACE_INFO failed with error %s\n", strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (info.version < 1) {
|
||||
printf("DVBCard::GetCardInfo wrong API version\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
*type = info.type;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DVBCard::GetCardInfo(char *_name, int max_name_len, char *_info, int max_info_len)
|
||||
{
|
||||
dvb_interface_info_t info;
|
||||
|
||||
if (do_ioctl(fDev, DVB_GET_INTERFACE_INFO, &info) < 0) {
|
||||
printf("DVB_GET_INTERFACE_INFO failed with error %s\n", strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
|
||||
// strlcpy(_name, info.name, max_name_len);
|
||||
// strlcpy(_info, info.info, max_info_len);
|
||||
strcpy(_name, info.name);
|
||||
strcpy(_info, info.info);
|
||||
|
||||
if (info.version < 1) {
|
||||
printf("DVBCard::GetCardInfo wrong API version\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DVBCard::SetTuningParameter(const dvb_tuning_parameters_t& param)
|
||||
{
|
||||
if (fDev < 0)
|
||||
return B_NO_INIT;
|
||||
|
||||
printf("DVBCard::SetTuningParameter:\n");
|
||||
/*
|
||||
printf("frequency %Ld\n", param.frequency);
|
||||
printf("inversion %d\n", param.inversion);
|
||||
printf("bandwidth %d\n", param.bandwidth);
|
||||
printf("modulation %d\n", param.modulation);
|
||||
printf("hierarchy %d\n", param.hierarchy);
|
||||
printf("code_rate_hp %d\n", param.code_rate_hp);
|
||||
printf("code_rate_lp %d\n", param.code_rate_lp);
|
||||
printf("transmission_mode %d\n", param.transmission_mode);
|
||||
printf("guard_interval %d\n", param.guard_interval);
|
||||
printf("symbolrate %d\n", param.symbolrate);
|
||||
printf("polarity %d\n", param.polarity);
|
||||
printf("agc_inversion %d\n", param.agc_inversion);
|
||||
*/
|
||||
params = param;// XXX temporary!
|
||||
|
||||
// if (do_ioctl(fDev, DVB_SET_TUNING_PARAMETERS, const_cast<void *>(¶m)) < 0) {
|
||||
// if (do_ioctl(fDev, DVB_SET_TUNING_PARAMETERS, (void *)(¶m)) < 0) {
|
||||
if (ioctl(fDev, DVB_SET_TUNING_PARAMETERS, (void *)(¶m)) < 0) {
|
||||
printf("DVB_SET_TUNING_PARAMETERS failed with error %s\n", strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
|
||||
dvb_status_t status;
|
||||
|
||||
bigtime_t start = system_time();
|
||||
bool has_lock = false;
|
||||
bool has_signal = false;
|
||||
bool has_carrier = false;
|
||||
do {
|
||||
if (do_ioctl(fDev, DVB_GET_STATUS, &status) < 0) {
|
||||
printf("DVB_GET_STATUS failed with error %s\n", strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
if (!has_signal && status & DVB_STATUS_SIGNAL) {
|
||||
has_signal = true;
|
||||
printf("got signal after %.6f\n", (system_time() - start) / 1e6);
|
||||
}
|
||||
if (!has_carrier && status & DVB_STATUS_CARRIER) {
|
||||
has_carrier = true;
|
||||
printf("got carrier after %.6f\n", (system_time() - start) / 1e6);
|
||||
}
|
||||
if (!has_lock && status & DVB_STATUS_LOCK) {
|
||||
has_lock = true;
|
||||
printf("got lock after %.6f\n", (system_time() - start) / 1e6);
|
||||
}
|
||||
|
||||
if ((status & (DVB_STATUS_SIGNAL|DVB_STATUS_CARRIER|DVB_STATUS_LOCK)) == (DVB_STATUS_SIGNAL|DVB_STATUS_CARRIER|DVB_STATUS_LOCK))
|
||||
break;
|
||||
snooze(25000);
|
||||
} while ((system_time() - start) < 5000000);
|
||||
|
||||
|
||||
if ((status & (DVB_STATUS_SIGNAL|DVB_STATUS_CARRIER|DVB_STATUS_LOCK)) != (DVB_STATUS_SIGNAL|DVB_STATUS_CARRIER|DVB_STATUS_LOCK)) {
|
||||
printf("DVB tuning failed! need these status flags: DVB_STATUS_SIGNAL, DVB_STATUS_CARRIER, DVB_STATUS_LOCK\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DVBCard::GetTuningParameter(dvb_tuning_parameters_t *param)
|
||||
{
|
||||
// XXX get from CARD
|
||||
*param = params;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DVBCard::GetSignalInfo(uint32 *ss, uint32 *ber, uint32 *snr)
|
||||
{
|
||||
if (do_ioctl(fDev, DVB_GET_SS, ss) < 0) {
|
||||
printf("DVB_GET_SS failed with error %s\n", strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
if (do_ioctl(fDev, DVB_GET_BER, ber) < 0) {
|
||||
printf("DVB_GET_BER failed with error %s\n", strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
if (do_ioctl(fDev, DVB_GET_SNR, snr) < 0) {
|
||||
printf("DVB_GET_SNR failed with error %s\n", strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
|
||||
printf("ss %08lx, ber %08lx, snr %08lx\n", *ss, *ber, *snr);
|
||||
printf("ss %lu%%, ber %lu%%, snr %lu%%\n", *ss / (0xffffffff / 100), *ber / (0xffffffff / 100), *snr / (0xffffffff / 100));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DVBCard::CaptureStart()
|
||||
{
|
||||
printf("DVBCard::CaptureStart\n");
|
||||
|
||||
if (fCaptureActive) {
|
||||
printf("CaptureStart already called, doing nothing\n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
if (do_ioctl(fDev, DVB_START_CAPTURE, 0) < 0) {
|
||||
printf("DVB_START_CAPTURE failed with error %s\n", strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
|
||||
fCaptureActive = true;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DVBCard::CaptureStop()
|
||||
{
|
||||
printf("DVBCard::CaptureStop\n");
|
||||
|
||||
if (!fCaptureActive) {
|
||||
printf("CaptureStop already called, doing nothing\n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
if (do_ioctl(fDev, DVB_STOP_CAPTURE, 0) < 0) {
|
||||
printf("DVB_STOP_CAPTURE failed with error %s\n", strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
|
||||
fCaptureActive = false;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DVBCard::Capture(void **data, size_t *size, bigtime_t *end_time)
|
||||
{
|
||||
dvb_capture_t cap;
|
||||
|
||||
if (ioctl(fDev, DVB_CAPTURE, &cap) < 0)
|
||||
return errno;
|
||||
|
||||
*data = cap.data;
|
||||
*size = cap.size;
|
||||
*end_time = cap.end_time;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
DVBCard::do_ioctl(int fDev, ulong op, void *arg)
|
||||
{
|
||||
int res = 0; // silence stupid compiler warning
|
||||
int i;
|
||||
for (i = 0; i < 20; i++) {
|
||||
res = ioctl(fDev, op, arg);
|
||||
if (res >= 0)
|
||||
break;
|
||||
}
|
||||
if (i != 0) printf("ioctl %lx repeated %d times\n", op, i);
|
||||
return res;
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __DVB_CARD_H
|
||||
#define __DVB_CARD_H
|
||||
|
||||
#include "../drivers/cx23882/dvb.h"
|
||||
|
||||
class DVBCard
|
||||
{
|
||||
public:
|
||||
DVBCard(const char *path);
|
||||
~DVBCard();
|
||||
|
||||
status_t InitCheck();
|
||||
|
||||
status_t GetCardType(dvb_type_t *type);
|
||||
status_t GetCardInfo(char *name, int max_name_len, char *info, int max_info_len);
|
||||
status_t GetSignalInfo(uint32 *ss, uint32 *ber, uint32 *snr);
|
||||
|
||||
status_t SetTuningParameter(const dvb_tuning_parameters_t& param);
|
||||
status_t GetTuningParameter(dvb_tuning_parameters_t *param);
|
||||
|
||||
status_t CaptureStart();
|
||||
status_t CaptureStop();
|
||||
status_t Capture(void **data, size_t *size, bigtime_t *end_time);
|
||||
|
||||
private:
|
||||
|
||||
int do_ioctl(int fDev, ulong op, void *arg);
|
||||
|
||||
status_t fInitStatus;
|
||||
int fDev;
|
||||
|
||||
int64 fFreqMin;
|
||||
int64 fFreqMax;
|
||||
int64 fFreqStep;
|
||||
|
||||
bool fCaptureActive;
|
||||
|
||||
dvb_tuning_parameters_t params; // XXX temporary cache
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "DVBMediaAddon.h"
|
||||
#include "DVBCard.h"
|
||||
#include "DVBMediaNode.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <Alert.h>
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <Path.h>
|
||||
|
||||
struct device_info
|
||||
{
|
||||
DVBCard * card;
|
||||
char name[200];
|
||||
char info[200];
|
||||
media_format formats[5];
|
||||
flavor_info flavor;
|
||||
bool active; // workaround for zeta
|
||||
};
|
||||
|
||||
|
||||
extern "C" BMediaAddOn *
|
||||
make_media_addon(image_id id)
|
||||
{
|
||||
return new DVBMediaAddon(id);
|
||||
}
|
||||
|
||||
|
||||
DVBMediaAddon::DVBMediaAddon(image_id id)
|
||||
: BMediaAddOn(id)
|
||||
{
|
||||
ScanFolder("/dev/dvb");
|
||||
}
|
||||
|
||||
|
||||
DVBMediaAddon::~DVBMediaAddon()
|
||||
{
|
||||
FreeDeviceList();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DVBMediaAddon::InitCheck(const char ** out_failure_text)
|
||||
{
|
||||
if (!fDeviceList.CountItems()) {
|
||||
*out_failure_text = "No supported device found";
|
||||
return B_ERROR;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
DVBMediaAddon::CountFlavors()
|
||||
{
|
||||
return fDeviceList.CountItems();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DVBMediaAddon::GetFlavorAt(int32 n, const flavor_info ** out_info)
|
||||
{
|
||||
device_info *dev = (device_info *)fDeviceList.ItemAt(n);
|
||||
if (!dev)
|
||||
return B_ERROR;
|
||||
*out_info = &dev->flavor;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
BMediaNode *
|
||||
DVBMediaAddon::InstantiateNodeFor(const flavor_info * info, BMessage * config, status_t * out_error)
|
||||
{
|
||||
printf("DVB: DVBMediaAddon::InstantiateNodeFor\n");
|
||||
|
||||
device_info *dev = (device_info *)fDeviceList.ItemAt(info->internal_id);
|
||||
if (!dev || dev->flavor.internal_id != info->internal_id) {
|
||||
*out_error = B_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
*out_error = B_OK;
|
||||
|
||||
// workaround for Zeta
|
||||
if (dev->active) {
|
||||
printf("DVB: max instances violation!!!\n");
|
||||
*out_error = B_ERROR;
|
||||
return NULL;
|
||||
} else {
|
||||
dev->active = true;
|
||||
}
|
||||
|
||||
return new DVBMediaNode(this, dev->name, dev->flavor.internal_id, dev->card, &dev->active);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DVBMediaAddon::WantsAutoStart()
|
||||
{
|
||||
#if BUILD_FOR_HAIKU
|
||||
printf("DVB: DVBMediaAddon::WantsAutoStart - NO\n");
|
||||
return false;
|
||||
#else
|
||||
printf("DVB: DVBMediaAddon::WantsAutoStart - YES\n");
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DVBMediaAddon::AutoStart(int index, BMediaNode **outNode, int32 *outInternalID, bool *outHasMore)
|
||||
{
|
||||
printf("DVB: DVBMediaAddon::AutoStart, index %d\n", index);
|
||||
|
||||
#if BUILD_FOR_HAIKU
|
||||
return B_ERROR;
|
||||
#else
|
||||
|
||||
device_info *dev = (device_info *)fDeviceList.ItemAt(index);
|
||||
if (!dev) {
|
||||
printf("DVB: DVBMediaAddon::AutoStart, bad index\n");
|
||||
return B_BAD_INDEX;
|
||||
}
|
||||
|
||||
*outHasMore = fDeviceList.ItemAt(index + 1) ? true : false;
|
||||
|
||||
// workaround for Zeta
|
||||
if (dev->active) {
|
||||
printf("DVB: max instances violation!!!\n");
|
||||
*outInternalID = -1;
|
||||
*outNode = NULL;
|
||||
return B_MEDIA_ADDON_FAILED;
|
||||
}
|
||||
|
||||
dev->active = true;
|
||||
|
||||
*outInternalID = dev->flavor.internal_id;
|
||||
*outNode = new DVBMediaNode(this, dev->name, dev->flavor.internal_id, dev->card, &dev->active);
|
||||
|
||||
printf("DVB: DVBMediaAddon::AutoStart, success\n");
|
||||
|
||||
return B_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DVBMediaAddon::ScanFolder(const char *path)
|
||||
{
|
||||
BDirectory dir(path);
|
||||
if (dir.InitCheck() != B_OK)
|
||||
return;
|
||||
|
||||
BEntry ent;
|
||||
|
||||
while (dir.GetNextEntry(&ent) == B_OK) {
|
||||
BPath path(&ent);
|
||||
if (ent.IsDirectory()) {
|
||||
ScanFolder(path.Path());
|
||||
} else {
|
||||
DVBCard *card = new DVBCard(path.Path());
|
||||
if (card->InitCheck() == B_OK)
|
||||
AddDevice(card, path.Path());
|
||||
else
|
||||
delete card;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DVBMediaAddon::AddDevice(DVBCard *card, const char *path)
|
||||
{
|
||||
dvb_type_t type;
|
||||
char name[250];
|
||||
char info[1000];
|
||||
const char *dvbtype;
|
||||
const char *dvbnumber;
|
||||
|
||||
// get card name, info and type
|
||||
if (B_OK != card->GetCardType(&type)) {
|
||||
printf("DVBMediaAddon::AddDevice: getting DVB card type failed\n");
|
||||
return;
|
||||
}
|
||||
if (B_OK != card->GetCardInfo(name, sizeof(name), info, sizeof(info))) {
|
||||
printf("DVBMediaAddon::AddDevice: getting DVB card info failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// get type
|
||||
switch (type) {
|
||||
case DVB_TYPE_DVB_C: dvbtype = "C"; break;
|
||||
case DVB_TYPE_DVB_H: dvbtype = "H"; break;
|
||||
case DVB_TYPE_DVB_S: dvbtype = "S"; break;
|
||||
case DVB_TYPE_DVB_T: dvbtype = "T"; break;
|
||||
default:
|
||||
printf("DVBMediaAddon::AddDevice: unsupported DVB type %d\n", type);
|
||||
return;
|
||||
}
|
||||
|
||||
// get interface number
|
||||
const char *p = strrchr(path, '/');
|
||||
dvbnumber = p ? p + 1 : "";
|
||||
|
||||
// create device_info
|
||||
device_info *dev = new device_info;
|
||||
fDeviceList.AddItem(dev);
|
||||
|
||||
dev->card = card;
|
||||
|
||||
dev->active = false; // workaround for Zeta
|
||||
|
||||
// setup name and info, it's important that name starts with "DVB"
|
||||
// snprintf(dev->name, sizeof(dev->name), "DVB-%s %s (%s)", dvbtype, dvbnumber, name);
|
||||
// strlcpy(dev->info, info, sizeof(dev->info));
|
||||
sprintf(dev->name, "DVB-%s %s %s", dvbtype, name, dvbnumber);
|
||||
strcpy(dev->info, info);
|
||||
|
||||
// setup supported formats (the lazy way)
|
||||
memset(dev->formats, 0, sizeof(dev->formats));
|
||||
dev->formats[0].type = B_MEDIA_RAW_VIDEO;
|
||||
dev->formats[1].type = B_MEDIA_RAW_AUDIO;
|
||||
dev->formats[2].type = B_MEDIA_ENCODED_VIDEO;
|
||||
dev->formats[3].type = B_MEDIA_ENCODED_AUDIO;
|
||||
dev->formats[4].type = B_MEDIA_MULTISTREAM;
|
||||
|
||||
// setup flavor info
|
||||
dev->flavor.name = dev->name;
|
||||
dev->flavor.info = dev->info;
|
||||
dev->flavor.kinds = B_BUFFER_PRODUCER | B_CONTROLLABLE | B_PHYSICAL_INPUT;
|
||||
dev->flavor.flavor_flags = B_FLAVOR_IS_GLOBAL;
|
||||
dev->flavor.internal_id = fDeviceList.CountItems() - 1;
|
||||
dev->flavor.possible_count = 1;
|
||||
dev->flavor.in_format_count = 0;
|
||||
dev->flavor.in_format_flags = 0;
|
||||
dev->flavor.in_formats = 0;
|
||||
dev->flavor.out_format_count = 5;
|
||||
dev->flavor.out_format_flags = 0;
|
||||
dev->flavor.out_formats = dev->formats;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DVBMediaAddon::FreeDeviceList()
|
||||
{
|
||||
device_info *dev;
|
||||
while ((dev = (device_info *)fDeviceList.RemoveItem((int32)0))) {
|
||||
delete dev->card;
|
||||
delete dev;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _DVB_MEDIA_ADDON_H_
|
||||
#define _DVB_MEDIA_ADDON_H_
|
||||
|
||||
#include <MediaAddOn.h>
|
||||
|
||||
class DVBCard;
|
||||
|
||||
class DVBMediaAddon : public BMediaAddOn
|
||||
{
|
||||
public:
|
||||
DVBMediaAddon(image_id id);
|
||||
~DVBMediaAddon();
|
||||
|
||||
status_t InitCheck(const char **out_failure_text);
|
||||
|
||||
int32 CountFlavors();
|
||||
|
||||
status_t GetFlavorAt(int32 n, const flavor_info **out_info);
|
||||
|
||||
BMediaNode *InstantiateNodeFor(const flavor_info *info, BMessage *config, status_t *out_error);
|
||||
|
||||
bool WantsAutoStart();
|
||||
status_t AutoStart(int index, BMediaNode **outNode, int32 *outInternalID, bool *outHasMore);
|
||||
|
||||
protected:
|
||||
void ScanFolder(const char *path);
|
||||
|
||||
void AddDevice(DVBCard *card, const char *path);
|
||||
void FreeDeviceList();
|
||||
|
||||
protected:
|
||||
BList fDeviceList;
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __DVB_MEDIA_NODE_H
|
||||
#define __DVB_MEDIA_NODE_H
|
||||
|
||||
#include <kernel/OS.h>
|
||||
#include <media/BufferProducer.h>
|
||||
#include <media/Controllable.h>
|
||||
#include <media/MediaDefs.h>
|
||||
#include <media/MediaEventLooper.h>
|
||||
#include <media/MediaNode.h>
|
||||
#include <support/Locker.h>
|
||||
|
||||
#include "ts_demux.h"
|
||||
#include "DVBCard.h"
|
||||
#include "StringList.h"
|
||||
#include "DecoderInterface.h"
|
||||
|
||||
class BDiscreteParameter;
|
||||
class PacketQueue;
|
||||
class DVBCard;
|
||||
|
||||
class DVBMediaNode :
|
||||
public virtual BBufferProducer,
|
||||
public virtual BControllable,
|
||||
public virtual BMediaEventLooper
|
||||
{
|
||||
public:
|
||||
DVBMediaNode(BMediaAddOn *addon,
|
||||
const char *name, int32 internal_id, DVBCard *card, bool *active); // bool *active is a workaround for Zeta
|
||||
virtual ~DVBMediaNode();
|
||||
|
||||
virtual status_t InitCheck() const { return fInitStatus; }
|
||||
|
||||
/* BMediaNode */
|
||||
public:
|
||||
virtual BMediaAddOn *AddOn(int32 * internal_id) const;
|
||||
virtual status_t HandleMessage(int32 message, const void *data,
|
||||
size_t size);
|
||||
protected:
|
||||
virtual void Preroll();
|
||||
virtual void SetTimeSource(BTimeSource * time_source);
|
||||
virtual void SetRunMode(run_mode mode);
|
||||
|
||||
/* BMediaEventLooper */
|
||||
protected:
|
||||
virtual void NodeRegistered();
|
||||
virtual void Stop(bigtime_t performance_time, bool immediate);
|
||||
|
||||
virtual void HandleEvent(const media_timed_event *event,
|
||||
bigtime_t lateness, bool realTimeEvent = false);
|
||||
|
||||
/* BBufferProducer */
|
||||
protected:
|
||||
virtual status_t FormatSuggestionRequested(media_type type, int32 quality,
|
||||
media_format * format);
|
||||
virtual status_t FormatProposal(const media_source &source,
|
||||
media_format *format);
|
||||
virtual status_t FormatChangeRequested(const media_source &source,
|
||||
const media_destination &destination,
|
||||
media_format *io_format, int32 *_deprecated_);
|
||||
virtual status_t GetNextOutput(int32 * cookie, media_output * out_output);
|
||||
virtual status_t DisposeOutputCookie(int32 cookie);
|
||||
virtual status_t SetBufferGroup(const media_source &for_source,
|
||||
BBufferGroup * group);
|
||||
virtual status_t VideoClippingChanged(const media_source &for_source,
|
||||
int16 num_shorts, int16 *clip_data,
|
||||
const media_video_display_info &display,
|
||||
int32 * _deprecated_);
|
||||
virtual status_t GetLatency(bigtime_t * out_latency);
|
||||
virtual status_t PrepareToConnect(const media_source &what,
|
||||
const media_destination &where,
|
||||
media_format *format,
|
||||
media_source *out_source, char *out_name);
|
||||
virtual void Connect(status_t error, const media_source &source,
|
||||
const media_destination &destination,
|
||||
const media_format & format, char *io_name);
|
||||
virtual void Disconnect(const media_source & what,
|
||||
const media_destination & where);
|
||||
virtual void LateNoticeReceived(const media_source & what,
|
||||
bigtime_t how_much, bigtime_t performance_time);
|
||||
virtual void EnableOutput(const media_source & what, bool enabled,
|
||||
int32 * _deprecated_);
|
||||
virtual status_t SetPlayRate(int32 numer,int32 denom);
|
||||
virtual void AdditionalBufferRequested(const media_source & source,
|
||||
media_buffer_id prev_buffer, bigtime_t prev_time,
|
||||
const media_seek_tag * prev_tag);
|
||||
virtual void LatencyChanged(const media_source & source,
|
||||
const media_destination & destination,
|
||||
bigtime_t new_latency, uint32 flags);
|
||||
|
||||
/* BControllable */
|
||||
protected:
|
||||
virtual status_t GetParameterValue(int32 id, bigtime_t *last_change,
|
||||
void *value, size_t *size);
|
||||
virtual void SetParameterValue(int32 id, bigtime_t when,
|
||||
const void *value, size_t size);
|
||||
|
||||
/* state */
|
||||
private:
|
||||
void HandleStart(bigtime_t performance_time);
|
||||
void HandleStop();
|
||||
void HandleTimeWarp(bigtime_t performance_time);
|
||||
void HandleSeek(bigtime_t performance_time);
|
||||
|
||||
void InitDefaultFormats();
|
||||
void SpecializeFormatRawVideo(media_raw_video_format *format);
|
||||
void SpecializeFormatRawAudio(media_multi_audio_format *format);
|
||||
void SpecializeFormatEncVideo(media_encoded_video_format *format);
|
||||
void SpecializeFormatEncAudio(media_encoded_audio_format *format);
|
||||
void SpecializeFormatTS(media_multistream_format *format);
|
||||
|
||||
bool VerifyFormatRawVideo(const media_raw_video_format &format);
|
||||
bool VerifyFormatRawAudio(const media_multi_audio_format &format);
|
||||
|
||||
status_t GetStreamFormat(PacketQueue *queue, media_format *format);
|
||||
|
||||
status_t SetOutput(const media_source &source, const media_destination &destination, const media_format &format);
|
||||
status_t ResetOutput(const media_source &source);
|
||||
const char * SourceDefaultName(const media_source &source);
|
||||
|
||||
BParameterWeb * CreateParameterWeb();
|
||||
void SetAboutInfo(BParameterGroup *about);
|
||||
|
||||
|
||||
void RefreshParameterWeb();
|
||||
|
||||
void LoadSettings();
|
||||
|
||||
void LoadAddons();
|
||||
void UnloadAddons();
|
||||
image_id LoadAddon(const char *path, const char *name, void **ptr);
|
||||
|
||||
void AddStateItems(BDiscreteParameter *param);
|
||||
void AddRegionItems(BDiscreteParameter *param);
|
||||
void AddChannelItems(BDiscreteParameter *param);
|
||||
void AddAudioItems(BDiscreteParameter *param);
|
||||
|
||||
void RefreshStateList();
|
||||
void RefreshRegionList();
|
||||
void RefreshChannelList();
|
||||
void RefreshAudioList();
|
||||
|
||||
status_t StartCapture();
|
||||
status_t StopCapture();
|
||||
status_t StartCaptureThreads();
|
||||
status_t StopCaptureThreads();
|
||||
status_t Tune();
|
||||
|
||||
status_t ExtractTuningParams(const char *description, int audio_pid_index,
|
||||
dvb_tuning_parameters_t *param,
|
||||
int *video_pid, int *audio_pid, int *pcr_pid);
|
||||
|
||||
static int32 _card_reader_thread_(void *arg);
|
||||
static int32 _mpeg_demux_thread_(void *arg);
|
||||
static int32 _enc_audio_thread_(void *arg);
|
||||
static int32 _enc_video_thread_(void *arg);
|
||||
static int32 _mpeg_ts_thread_(void *arg);
|
||||
static int32 _raw_audio_thread_(void *arg);
|
||||
static int32 _raw_video_thread_(void *arg);
|
||||
|
||||
void card_reader_thread();
|
||||
void mpeg_demux_thread();
|
||||
void enc_audio_thread();
|
||||
void enc_video_thread();
|
||||
void mpeg_ts_thread();
|
||||
void raw_audio_thread();
|
||||
void raw_video_thread();
|
||||
|
||||
status_t GetNextVideoChunk(const void **chunkData, size_t *chunkLen, media_header *mh);
|
||||
status_t GetNextAudioChunk(const void **chunkData, size_t *chunkLen, media_header *mh);
|
||||
|
||||
static status_t _GetNextVideoChunk(const void **chunkData, size_t *chunkLen, media_header *mh, void *cookie);
|
||||
static status_t _GetNextAudioChunk(const void **chunkData, size_t *chunkLen, media_header *mh, void *cookie);
|
||||
|
||||
status_t fInitStatus;
|
||||
|
||||
int32 fInternalID;
|
||||
BMediaAddOn *fAddOn;
|
||||
|
||||
bool fStopDisabled;
|
||||
|
||||
bool fOutputEnabledRawVideo;
|
||||
bool fOutputEnabledRawAudio;
|
||||
bool fOutputEnabledEncVideo;
|
||||
bool fOutputEnabledEncAudio;
|
||||
bool fOutputEnabledTS;
|
||||
|
||||
media_output fOutputRawVideo;
|
||||
media_output fOutputRawAudio;
|
||||
media_output fOutputEncVideo;
|
||||
media_output fOutputEncAudio;
|
||||
media_output fOutputTS;
|
||||
|
||||
media_format fDefaultFormatRawVideo;
|
||||
media_format fDefaultFormatRawAudio;
|
||||
media_format fDefaultFormatEncVideo;
|
||||
media_format fDefaultFormatEncAudio;
|
||||
media_format fDefaultFormatTS;
|
||||
|
||||
media_format fRequiredFormatRawVideo;
|
||||
media_format fRequiredFormatRawAudio;
|
||||
media_format fRequiredFormatEncVideo;
|
||||
media_format fRequiredFormatEncAudio;
|
||||
media_format fRequiredFormatTS;
|
||||
|
||||
PacketQueue * fCardDataQueue; // holds MPEG TS data read from the card
|
||||
PacketQueue * fRawVideoQueue; // holds encoded PES frames for video decoding
|
||||
PacketQueue * fRawAudioQueue; // holds encoded PES frames for audio decoding
|
||||
PacketQueue * fEncVideoQueue; // holds encoded PES frames for enc video out
|
||||
PacketQueue * fEncAudioQueue; // holds encoded PES frames for enc audio out
|
||||
PacketQueue * fMpegTsQueue; // holds encoded PES frames for MPEG TS out
|
||||
|
||||
DVBCard * fCard;
|
||||
|
||||
bool fCaptureThreadsActive;
|
||||
|
||||
thread_id fThreadIdCardReader;
|
||||
thread_id fThreadIdMpegDemux;
|
||||
thread_id fThreadIdRawAudio;
|
||||
thread_id fThreadIdRawVideo;
|
||||
thread_id fThreadIdEncAudio;
|
||||
thread_id fThreadIdEncVideo;
|
||||
thread_id fThreadIdMpegTS;
|
||||
|
||||
volatile bool fTerminateThreads;
|
||||
|
||||
TSDemux * fDemux;
|
||||
|
||||
BBufferGroup * fBufferGroupRawVideo;
|
||||
BBufferGroup * fBufferGroupRawAudio;
|
||||
|
||||
BParameterWeb * fWeb;
|
||||
|
||||
dvb_tuning_parameters_t fTuningParam;
|
||||
dvb_type_t fInterfaceType;
|
||||
|
||||
int fAudioPid;
|
||||
int fVideoPid;
|
||||
int fPcrPid;
|
||||
|
||||
bool fTuningSuccess;
|
||||
bool fCaptureActive;
|
||||
|
||||
sem_id fVideoDelaySem;
|
||||
sem_id fAudioDelaySem;
|
||||
|
||||
int fSelectedState;
|
||||
int fSelectedRegion;
|
||||
int fSelectedChannel;
|
||||
int fSelectedAudio;
|
||||
|
||||
StringList * fStateList;
|
||||
StringList * fRegionList;
|
||||
StringList * fChannelList;
|
||||
StringList * fAudioList;
|
||||
|
||||
DecoderInterface * fVideoDecoder;
|
||||
DecoderInterface * fAudioDecoder;
|
||||
|
||||
Packet * fCurrentVideoPacket;
|
||||
Packet * fCurrentAudioPacket;
|
||||
|
||||
image_id fMpeg2VideoDecoderImage;
|
||||
image_id fMpeg2AudioDecoderImage;
|
||||
image_id fAC3DecoderImage;
|
||||
image_id fDeinterlaceFilterImage;
|
||||
|
||||
DecoderInterface * (*instantiate_mpeg2_video_decoder)(get_next_chunk_func, void *, const char *);
|
||||
DecoderInterface * (*instantiate_mpeg2_audio_decoder)(get_next_chunk_func, void *, const char *);
|
||||
DecoderInterface * (*instantiate_ac3_audio_decoder)(get_next_chunk_func, void *, const char *);
|
||||
DecoderInterface * (*instantiate_deinterlace_filter)(get_next_chunk_func, void *, const char *);
|
||||
|
||||
BLocker lock;
|
||||
|
||||
bool * fActive; // workaround for Zeta
|
||||
|
||||
// used only for debugging:
|
||||
int fVideoFile;
|
||||
int fAudioFile;
|
||||
int fRawAudioFile;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <media/MediaFormats.h>
|
||||
#include <stdio.h>
|
||||
#include "MediaFormat.h"
|
||||
|
||||
void
|
||||
PrintFormat(const media_output &output)
|
||||
{
|
||||
PrintFormat(output.format);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PrintFormat(const media_format &format)
|
||||
{
|
||||
char s[200];
|
||||
string_for_format(format, s, sizeof(s));
|
||||
printf("%s\n", s);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GetHeaderFormat(media_format *out_format, const void *header, size_t size, int stream_id)
|
||||
{
|
||||
|
||||
const uint8 *d = (const uint8 *)header;
|
||||
printf("GetHeaderFormat: stream_id %02x\n", stream_id);
|
||||
printf("frame header: "
|
||||
"%02x %02x %02x %02x %02x %02x %02x %02x "
|
||||
"%02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
|
||||
d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
|
||||
|
||||
if (d[0] == 0xff && d[1] == 0xfc) {
|
||||
|
||||
printf("GetHeaderFormat: assuming mepeg audio\n");
|
||||
|
||||
status_t err;
|
||||
|
||||
media_format_description desc;
|
||||
desc.family = B_MPEG_FORMAT_FAMILY;
|
||||
desc.u.mpeg.id = B_MPEG_1_AUDIO_LAYER_3;
|
||||
|
||||
BMediaFormats formats;
|
||||
media_format format;
|
||||
|
||||
err = formats.InitCheck();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = formats.GetFormatFor(desc, out_format);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
out_format->u.encoded_audio.output.frame_rate = 48000;
|
||||
out_format->u.encoded_audio.output.channel_count = 2;
|
||||
out_format->u.encoded_audio.output.buffer_size = 1024;
|
||||
|
||||
printf("GetHeaderFormat: ");
|
||||
PrintFormat(*out_format);
|
||||
} else {
|
||||
|
||||
printf("GetHeaderFormat: assuming mepeg video\n");
|
||||
|
||||
status_t err;
|
||||
|
||||
media_format_description desc;
|
||||
desc.family = B_MPEG_FORMAT_FAMILY;
|
||||
desc.u.mpeg.id = B_MPEG_1_VIDEO;
|
||||
|
||||
BMediaFormats formats;
|
||||
media_format format;
|
||||
|
||||
err = formats.InitCheck();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = formats.GetFormatFor(desc, out_format);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __MEDIA_FORMAT_H
|
||||
#define __MEDIA_FORMAT_H
|
||||
|
||||
class media_output;
|
||||
class media_format;
|
||||
|
||||
void PrintFormat(const media_output &output);
|
||||
void PrintFormat(const media_format &format);
|
||||
|
||||
status_t GetHeaderFormat(media_format *out_format, const void *header, size_t size, int stream_id);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "packet.h"
|
||||
|
||||
#define PACKET
|
||||
#ifdef PACKET
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...)
|
||||
#endif
|
||||
|
||||
|
||||
Packet::Packet(size_t init_size)
|
||||
: fBuffer(malloc(init_size))
|
||||
, fBufferSize(0)
|
||||
, fBufferSizeMax(init_size)
|
||||
, fTimeStamp(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Packet::Packet(const Packet &clone)
|
||||
{
|
||||
fBufferSize = clone.Size();
|
||||
fBufferSizeMax = fBufferSize;
|
||||
fBuffer = malloc(fBufferSize);
|
||||
fTimeStamp = clone.TimeStamp();
|
||||
memcpy(fBuffer, clone.Data(), fBufferSize);
|
||||
}
|
||||
|
||||
|
||||
Packet::Packet(const void *data, size_t size, bigtime_t time_stamp)
|
||||
: fBuffer(malloc(size))
|
||||
, fBufferSize(size)
|
||||
, fBufferSizeMax(size)
|
||||
, fTimeStamp(time_stamp)
|
||||
{
|
||||
memcpy(fBuffer, data, size);
|
||||
}
|
||||
|
||||
|
||||
Packet::~Packet()
|
||||
{
|
||||
free(fBuffer);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Packet::AddData(const void *data, size_t size)
|
||||
{
|
||||
if (fBufferSize + size > fBufferSizeMax) {
|
||||
fBufferSizeMax = (fBufferSize + size + 8191) & ~8191;
|
||||
fBuffer = realloc(fBuffer, fBufferSizeMax);
|
||||
}
|
||||
|
||||
memcpy((char *)fBuffer + fBufferSize, data, size);
|
||||
fBufferSize += size;
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __PACKET_H
|
||||
#define __PACKET_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
class Packet
|
||||
{
|
||||
public:
|
||||
Packet(size_t init_size = 8192);
|
||||
Packet(const Packet &clone);
|
||||
Packet(const void *data, size_t size, bigtime_t time_stamp = 0);
|
||||
~Packet();
|
||||
|
||||
void AddData(const void *data, size_t size);
|
||||
|
||||
void MakeEmpty();
|
||||
|
||||
const uint8 * Data() const;
|
||||
size_t Size() const;
|
||||
|
||||
void SetTimeStamp(bigtime_t time_stamp);
|
||||
bigtime_t TimeStamp() const;
|
||||
|
||||
|
||||
private:
|
||||
// not implemented
|
||||
Packet & operator= (const Packet &clone);
|
||||
|
||||
private:
|
||||
void * fBuffer;
|
||||
size_t fBufferSize;
|
||||
size_t fBufferSizeMax;
|
||||
bigtime_t fTimeStamp;
|
||||
};
|
||||
|
||||
|
||||
inline const uint8 *
|
||||
Packet::Data() const
|
||||
{
|
||||
return (uint8 *)fBuffer;
|
||||
}
|
||||
|
||||
|
||||
inline size_t
|
||||
Packet::Size() const
|
||||
{
|
||||
return fBufferSize;
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
Packet::SetTimeStamp(bigtime_t time_stamp)
|
||||
{
|
||||
fTimeStamp = time_stamp;
|
||||
}
|
||||
|
||||
|
||||
inline bigtime_t
|
||||
Packet::TimeStamp() const
|
||||
{
|
||||
return fTimeStamp;
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
Packet::MakeEmpty()
|
||||
{
|
||||
fBufferSize = 0;
|
||||
fTimeStamp = 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <OS.h>
|
||||
|
||||
#include "Packet.h"
|
||||
#include "PacketQueue.h"
|
||||
|
||||
#define TRACE_PACKET_QUEUE
|
||||
#ifdef TRACE_PACKET_QUEUE
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...)
|
||||
#endif
|
||||
|
||||
|
||||
PacketQueue::PacketQueue(int max_packets)
|
||||
: fQueue(new Packet* [max_packets])
|
||||
, fSem(create_sem(0, "packet queue sem"))
|
||||
, fTerminate(false)
|
||||
, fWriteIndex(0)
|
||||
, fReadIndex(0)
|
||||
, fMaxPackets(max_packets)
|
||||
, fPacketCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PacketQueue::~PacketQueue()
|
||||
{
|
||||
Empty();
|
||||
delete_sem(fSem);
|
||||
delete [] fQueue;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PacketQueue::Empty()
|
||||
{
|
||||
while (fPacketCount--) {
|
||||
delete fQueue[fReadIndex];
|
||||
fReadIndex = (fReadIndex + 1) % fMaxPackets;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PacketQueue::Insert(Packet *packet)
|
||||
{
|
||||
if (fTerminate) {
|
||||
return B_NOT_ALLOWED;
|
||||
}
|
||||
if (atomic_add(&fPacketCount, 1) == fMaxPackets) {
|
||||
atomic_add(&fPacketCount, -1);
|
||||
return B_WOULD_BLOCK;
|
||||
}
|
||||
fQueue[fWriteIndex] = packet;
|
||||
fWriteIndex = (fWriteIndex + 1) % fMaxPackets;
|
||||
release_sem(fSem);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PacketQueue::Remove(Packet **packet)
|
||||
{
|
||||
if (fTerminate) {
|
||||
return B_NOT_ALLOWED;
|
||||
}
|
||||
if (acquire_sem(fSem) != B_OK)
|
||||
return B_ERROR;
|
||||
if (fTerminate) {
|
||||
return B_NOT_ALLOWED;
|
||||
}
|
||||
*packet = fQueue[fReadIndex];
|
||||
atomic_add(&fPacketCount, -1);
|
||||
fReadIndex = (fReadIndex + 1) % fMaxPackets;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PacketQueue::Flush(bigtime_t timeout)
|
||||
{
|
||||
if (fTerminate) {
|
||||
return;
|
||||
}
|
||||
|
||||
timeout += system_time();
|
||||
|
||||
while (acquire_sem_etc(fSem, 1, B_ABSOLUTE_TIMEOUT, timeout) == B_OK) {
|
||||
if (fTerminate) {
|
||||
return;
|
||||
}
|
||||
Packet *packet = fQueue[fReadIndex];
|
||||
atomic_add(&fPacketCount, -1);
|
||||
fReadIndex = (fReadIndex + 1) % fMaxPackets;
|
||||
delete packet;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// peeks into queue and delivers a copy
|
||||
status_t
|
||||
PacketQueue::Peek(Packet **packet)
|
||||
{
|
||||
if (fTerminate) {
|
||||
return B_NOT_ALLOWED;
|
||||
}
|
||||
if (acquire_sem(fSem) != B_OK)
|
||||
return B_ERROR;
|
||||
if (fTerminate) {
|
||||
return B_NOT_ALLOWED;
|
||||
}
|
||||
*packet = new Packet(*fQueue[fReadIndex]);
|
||||
release_sem(fSem);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PacketQueue::Terminate()
|
||||
{
|
||||
fTerminate = true;
|
||||
release_sem(fSem);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PacketQueue::Restart()
|
||||
{
|
||||
Empty();
|
||||
|
||||
delete_sem(fSem);
|
||||
fSem = create_sem(0, "packet queue sem");
|
||||
fTerminate = false;
|
||||
fWriteIndex = 0;
|
||||
fReadIndex = 0;
|
||||
fPacketCount = 0;
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __PACKET_QUEUE_H
|
||||
#define __PACKET_QUEUE_H
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
class Packet;
|
||||
|
||||
class PacketQueue
|
||||
{
|
||||
public:
|
||||
PacketQueue(int max_packets = 5);
|
||||
~PacketQueue();
|
||||
|
||||
status_t Insert(Packet *packet);
|
||||
status_t Remove(Packet **packet);
|
||||
|
||||
// peeks into queue and delivers a copy
|
||||
status_t Peek(Packet **packet);
|
||||
|
||||
void Flush(bigtime_t timeout);
|
||||
|
||||
void Terminate();
|
||||
void Restart();
|
||||
|
||||
private:
|
||||
void Empty();
|
||||
|
||||
// not implemented
|
||||
PacketQueue(const PacketQueue & clone);
|
||||
PacketQueue & operator=(PacketQueue & clone);
|
||||
|
||||
private:
|
||||
|
||||
Packet **fQueue;
|
||||
sem_id fSem;
|
||||
volatile bool fTerminate;
|
||||
|
||||
int fWriteIndex;
|
||||
int fReadIndex;
|
||||
int fMaxPackets;
|
||||
int32 fPacketCount;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __STRING_LIST_H
|
||||
#define __STRING_LIST_H
|
||||
|
||||
#include <List.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
class StringList
|
||||
{
|
||||
public:
|
||||
StringList();
|
||||
~StringList();
|
||||
|
||||
// AddItem makes a copy of the data
|
||||
void AddItem(const char *string);
|
||||
|
||||
// either the String or NULL
|
||||
const char *ItemAt(int index) const;
|
||||
|
||||
void MakeEmpty();
|
||||
|
||||
private:
|
||||
BList list;
|
||||
};
|
||||
|
||||
|
||||
inline
|
||||
StringList::StringList()
|
||||
: list()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
StringList::~StringList()
|
||||
{
|
||||
MakeEmpty();
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
StringList::AddItem(const char *string)
|
||||
{
|
||||
list.AddItem(strdup(string));
|
||||
}
|
||||
|
||||
|
||||
inline const char *
|
||||
StringList::ItemAt(int index) const
|
||||
{
|
||||
return (const char *)list.ItemAt(index);
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
StringList::MakeEmpty()
|
||||
{
|
||||
int i = list.CountItems();
|
||||
while (--i > -1)
|
||||
free(list.RemoveItem(i));
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,448 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ts_demux.h"
|
||||
#include "packet.h"
|
||||
#include "packet_queue.h"
|
||||
|
||||
#define TRACE_TS_DEMUX
|
||||
#ifdef TRACE_TS_DEMUX
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...)
|
||||
#endif
|
||||
|
||||
#define CLOCK_TO_USEC(clck) (bigtime_t((clck) + 13) / 27)
|
||||
#define USEC_TO_CLOCK(usec) (bigtime_t((usec) * 27))
|
||||
|
||||
|
||||
TransportStreamDemux::TransportStreamDemux(
|
||||
PacketQueue *vid_queue, PacketQueue *aud_queue,
|
||||
PacketQueue *vid_queue2, PacketQueue *aud_queue2,
|
||||
PacketQueue *mpeg_ts_queue)
|
||||
: fCount(0)
|
||||
, fSystemTime(0)
|
||||
, fPerformanceTime(0)
|
||||
, fLastEndTime(0)
|
||||
, fVidPid(-1)
|
||||
, fAudPid(-1)
|
||||
, fPcrPid(-1)
|
||||
, fVidQueue(vid_queue)
|
||||
, fVidQueue2(vid_queue2)
|
||||
, fAudQueue(aud_queue)
|
||||
, fAudQueue2(aud_queue2)
|
||||
, fMpegTsQueue(mpeg_ts_queue)
|
||||
, fVidPacket(new Packet)
|
||||
, fAudPacket(new Packet)
|
||||
, fVidPacketValid(false)
|
||||
, fAudPacketValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TransportStreamDemux::~TransportStreamDemux()
|
||||
{
|
||||
delete fVidPacket;
|
||||
delete fAudPacket;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TransportStreamDemux::SetPIDs(int vid_pid, int aud_pid, int pcr_pid)
|
||||
{
|
||||
fVidPacket->MakeEmpty();
|
||||
fAudPacket->MakeEmpty();
|
||||
fVidPacketValid = false;
|
||||
fAudPacketValid = false;
|
||||
fVidPid = vid_pid;
|
||||
fAudPid = aud_pid;
|
||||
fPcrPid = pcr_pid;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TransportStreamDemux::ProcessPacket(const mpeg_ts_packet *pkt, bigtime_t start_time)
|
||||
{
|
||||
fCount++;
|
||||
|
||||
// printf("ProcessPacket %Ld\n", fCount);
|
||||
|
||||
if (pkt->SyncByte() != 0x47) {
|
||||
// fCountInvalid++;
|
||||
printf("packet %Ld sync byte error "
|
||||
"%02x %02x %02x %02x %02x %02x %02x %02x "
|
||||
"%02x %02x %02x %02x %02x %02x %02x %02x\n", fCount,
|
||||
pkt->header[0], pkt->header[1], pkt->header[2], pkt->header[3],
|
||||
pkt->data[0], pkt->data[1], pkt->data[2], pkt->data[3],
|
||||
pkt->data[4], pkt->data[5], pkt->data[6], pkt->data[7],
|
||||
pkt->data[8], pkt->data[9], pkt->data[10], pkt->data[11]);
|
||||
return;
|
||||
}
|
||||
|
||||
// if (pkt->TransportError()) {
|
||||
// fCountInvalid++;
|
||||
// printf("invalid packet %Ld (transport_error_indicator)\n", fCount);
|
||||
// return;
|
||||
// }
|
||||
|
||||
int pid = pkt->PID();
|
||||
|
||||
if (pid == 0) {
|
||||
ProcessPAT(pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pid == fPcrPid) {
|
||||
ProcessPCR(pkt, start_time);
|
||||
}
|
||||
|
||||
if (pid == fAudPid) {
|
||||
ProcessAUD(pkt);
|
||||
}
|
||||
|
||||
if (pid == fVidPid) {
|
||||
ProcessVID(pkt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TransportStreamDemux::ProcessPAT(const mpeg_ts_packet *pkt)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TransportStreamDemux::ProcessPCR(const mpeg_ts_packet *pkt, bigtime_t start_time)
|
||||
{
|
||||
if (!(pkt->AdaptationFieldControl() & 0x2)) // adaptation field present?
|
||||
return;
|
||||
if (pkt->data[0] < 7) // long enough?
|
||||
return;
|
||||
if (!(pkt->data[1] & 0x10)) // PCR present?
|
||||
return;
|
||||
int64 pcr;
|
||||
pcr = (uint64(pkt->data[2]) << 25)
|
||||
| (uint32(pkt->data[3]) << 17)
|
||||
| (uint32(pkt->data[4]) << 9)
|
||||
| (uint32(pkt->data[5]) << 1)
|
||||
| (pkt->data[6] >> 7);
|
||||
pcr *= 300;
|
||||
pcr += (pkt->data[6] & 1) | pkt->data[7];
|
||||
// printf(" pcr = %Ld\n", pcr);
|
||||
|
||||
// bigtime_t now = system_time();
|
||||
// printf("system_time %.3f, PCR-time %.3f, delta %.06f, PCR %Ld\n", now / 1e6, CLOCK_TO_USEC(pcr) / 1e6, (CLOCK_TO_USEC(pcr) - now) / 1e6, pcr);
|
||||
|
||||
// atomic_set64(&fCurrentTime, CLOCK_TO_USEC(pcr));
|
||||
|
||||
fTimeSourceLocker.Lock();
|
||||
fSystemTime = start_time;
|
||||
fPerformanceTime = CLOCK_TO_USEC(pcr);
|
||||
fTimeSourceLocker.Unlock();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TransportStreamDemux::ProcessAUD(const mpeg_ts_packet *pkt)
|
||||
{
|
||||
// flush old packet
|
||||
if (pkt->PayloadUnitStart()) {
|
||||
if (fAudPacketValid) {
|
||||
Packet *clone = new Packet(*fAudPacket);
|
||||
status_t err = fAudQueue->Insert(fAudPacket);
|
||||
if (err != B_OK) {
|
||||
delete fAudPacket;
|
||||
if (err == B_WOULD_BLOCK) {
|
||||
printf("fAudQueue->Insert failed (would block)\n");
|
||||
}
|
||||
}
|
||||
err = fAudQueue2->Insert(clone);
|
||||
if (err != B_OK) {
|
||||
delete clone;
|
||||
if (err == B_WOULD_BLOCK) {
|
||||
printf("fAudQueue2->Insert failed (would block)\n");
|
||||
}
|
||||
}
|
||||
fAudPacket = new Packet;
|
||||
} else {
|
||||
fAudPacket->MakeEmpty();
|
||||
fAudPacketValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
int skip;
|
||||
switch (pkt->AdaptationFieldControl()) {
|
||||
case 0: // illegal
|
||||
skip = 184;
|
||||
break;
|
||||
case 1: // payload only
|
||||
skip = 0;
|
||||
break;
|
||||
case 2: // adaptation field only
|
||||
skip = 184;
|
||||
break;
|
||||
case 3: // adaptation field followed by payload
|
||||
skip = pkt->data[0] + 1;
|
||||
if (skip > 184)
|
||||
skip = 184;
|
||||
break;
|
||||
default:
|
||||
skip = 0; // stupid compiler, impossible case
|
||||
}
|
||||
|
||||
const uint8 *data = pkt->data + skip;
|
||||
int size = 184 - skip;
|
||||
|
||||
// if (skip != 0)
|
||||
// printf("aud skip %d\n", skip);
|
||||
|
||||
if (pkt->PayloadUnitStart()) {
|
||||
|
||||
if (pkt->TransportError()) {
|
||||
printf("error in audio packet %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3]);
|
||||
fAudPacketValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (data[0] || data[1] || data[2] != 0x01 || data[3] <= 0xbf || data[3] >= 0xf0) {
|
||||
printf("invalid audio packet %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3]);
|
||||
fAudPacketValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (data[7] & 0x80) { // PTS
|
||||
int64 pts;
|
||||
int64 dts;
|
||||
|
||||
pts = (uint64((data[9] >> 1) & 0x7) << 30)
|
||||
| (data[10] << 22) | ((data[11] >> 1) << 15)
|
||||
| (data[12] << 7) | (data[13] >> 1);
|
||||
pts *= 300;
|
||||
|
||||
// printf("vid pts = %Ld\n", pts);
|
||||
|
||||
if (data[7] & 0x40) { // DTS
|
||||
|
||||
dts = (uint64((data[14] >> 1) & 0x7) << 30)
|
||||
| (data[15] << 22) | ((data[16] >> 1) << 15)
|
||||
| (data[17] << 7) | (data[18] >> 1);
|
||||
dts *= 300;
|
||||
|
||||
// printf("aud dts = %Ld\n", dts);
|
||||
} else {
|
||||
dts = pts;
|
||||
}
|
||||
|
||||
fAudPacket->SetTimeStamp(CLOCK_TO_USEC(dts));
|
||||
}
|
||||
|
||||
|
||||
// printf("aud %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
// data[0], data[1], data[2], data[3], data[4],
|
||||
// data[5], data[6], data[7], data[8], data[9]);
|
||||
}
|
||||
|
||||
fAudPacket->AddData(data, size);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TransportStreamDemux::ProcessVID(const mpeg_ts_packet *pkt)
|
||||
{
|
||||
// flush old packet
|
||||
// if (pkt->PayloadUnitStart() || pkt->TransportError()) {
|
||||
if (pkt->PayloadUnitStart()) {
|
||||
if (fVidPacketValid) {
|
||||
Packet *clone = new Packet(*fVidPacket);
|
||||
status_t err = fVidQueue->Insert(fVidPacket);
|
||||
if (err != B_OK) {
|
||||
delete fVidPacket;
|
||||
if (err == B_WOULD_BLOCK) {
|
||||
printf("fVidQueue->Insert failed (would block)\n");
|
||||
}
|
||||
}
|
||||
err = fVidQueue2->Insert(clone);
|
||||
if (err != B_OK) {
|
||||
delete clone;
|
||||
if (err == B_WOULD_BLOCK) {
|
||||
printf("fVidQueue2->Insert failed (would block)\n");
|
||||
}
|
||||
}
|
||||
fVidPacket = new Packet;
|
||||
} else {
|
||||
fVidPacket->MakeEmpty();
|
||||
fVidPacketValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if (pkt->TransportError()) {
|
||||
// printf("transport error\n");
|
||||
// fVidPacketValid = false;
|
||||
// return;
|
||||
// }
|
||||
|
||||
int skip;
|
||||
switch (pkt->AdaptationFieldControl()) {
|
||||
case 0: // illegal
|
||||
skip = 184;
|
||||
break;
|
||||
case 1: // payload only
|
||||
skip = 0;
|
||||
break;
|
||||
case 2: // adaptation field only
|
||||
skip = 184;
|
||||
break;
|
||||
case 3: // adaptation field followed by payload
|
||||
skip = pkt->data[0] + 1;
|
||||
if (skip > 184)
|
||||
skip = 184;
|
||||
break;
|
||||
default:
|
||||
skip = 0; // stupid compiler, impossible case
|
||||
}
|
||||
|
||||
const uint8 *data = pkt->data + skip;
|
||||
int size = 184 - skip;
|
||||
|
||||
// if (skip != 0)
|
||||
// printf("vid skip %d\n", skip);
|
||||
|
||||
if (pkt->PayloadUnitStart()) {
|
||||
|
||||
if (pkt->TransportError()) {
|
||||
printf("error in video packet %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3]);
|
||||
fVidPacketValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (data[0] || data[1] || data[2] != 0x01 || data[3] <= 0xbf || data[3] >= 0xf0) {
|
||||
printf("invalid video packet %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3]);
|
||||
fVidPacketValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (data[7] & 0x80) { // PTS
|
||||
int64 pts;
|
||||
int64 dts;
|
||||
|
||||
pts = (uint64((data[9] >> 1) & 0x7) << 30)
|
||||
| (data[10] << 22) | ((data[11] >> 1) << 15)
|
||||
| (data[12] << 7) | (data[13] >> 1);
|
||||
pts *= 300;
|
||||
|
||||
// printf("vid pts = %Ld\n", pts);
|
||||
|
||||
if (data[7] & 0x40) { // DTS
|
||||
|
||||
dts = (uint64((data[14] >> 1) & 0x7) << 30)
|
||||
| (data[15] << 22) | ((data[16] >> 1) << 15)
|
||||
| (data[17] << 7) | (data[18] >> 1);
|
||||
dts *= 300;
|
||||
|
||||
// printf("vid dts = %Ld\n", dts);
|
||||
// printf("dts = %Ld, pts = %Ld, delta %Ld ### dts = %Ld, pts = %Ld, delta %Ld\n",
|
||||
// dts, pts, pts - dts, CLOCK_TO_USEC(dts), CLOCK_TO_USEC(pts), CLOCK_TO_USEC(pts - dts));
|
||||
} else {
|
||||
dts = pts;
|
||||
}
|
||||
|
||||
// printf("clocks: dts = %14Ld, pts = %14Ld, delta %8Ld ### usec: dts = %14Ld, pts = %14Ld, delta %8Ld\n",
|
||||
// dts, pts, pts - dts, CLOCK_TO_USEC(dts), CLOCK_TO_USEC(pts), CLOCK_TO_USEC(pts - dts));
|
||||
|
||||
fVidPacket->SetTimeStamp(CLOCK_TO_USEC(dts));
|
||||
}
|
||||
|
||||
// printf("vid %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
// data[0], data[1], data[2], data[3], data[4],
|
||||
// data[5], data[6], data[7], data[8], data[9]);
|
||||
}
|
||||
|
||||
fVidPacket->AddData(data, size);
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
TransportStreamDemux::ProcessData(const void *data, int size, bigtime_t start_time, bigtime_t delta)
|
||||
{
|
||||
const uint8 *d = (const uint8 *)data;
|
||||
if (d[0] != 0x47 && size > 376 && d[188] != 0x47 && d[376] != 0x47) {
|
||||
printf("TransportStreamDemux::ProcessData: input sync error: "
|
||||
"%02x %02x %02x %02x %02x %02x %02x %02x "
|
||||
"%02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
|
||||
d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
|
||||
return;
|
||||
}
|
||||
|
||||
const mpeg_ts_packet *pkt = (const mpeg_ts_packet *)data;
|
||||
int count = size / 188;
|
||||
for (int i = 0; i < count; i++) {
|
||||
ProcessPacket(pkt++, start_time + (i * delta) / count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TransportStreamDemux::AddData(Packet *packet)
|
||||
{
|
||||
bigtime_t end_time = packet->TimeStamp();
|
||||
|
||||
if (fLastEndTime == 0) {
|
||||
#define DEFAULT_DELTA 36270
|
||||
// need something at the start, 36270 usec is the packet length
|
||||
// in Germany, and should be ok for other countries, too
|
||||
fLastEndTime = end_time - DEFAULT_DELTA;
|
||||
}
|
||||
|
||||
bigtime_t delta = end_time - fLastEndTime;
|
||||
|
||||
// sanity check
|
||||
if (delta > (3 * DEFAULT_DELTA)) {
|
||||
printf("TransportStreamDemux::ProcessData: delta %.6f is too large\n", delta / 1E6);
|
||||
fLastEndTime = end_time - DEFAULT_DELTA;
|
||||
delta = DEFAULT_DELTA;
|
||||
}
|
||||
|
||||
ProcessData(packet->Data(), packet->Size(), fLastEndTime, delta);
|
||||
|
||||
packet->SetTimeStamp(fLastEndTime);
|
||||
|
||||
fLastEndTime = end_time;
|
||||
|
||||
status_t err = fMpegTsQueue->Insert(packet);
|
||||
if (err != B_OK) {
|
||||
delete packet;
|
||||
if (err == B_WOULD_BLOCK) {
|
||||
printf("fMpegTsQueue->Insert failed (would block)\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __TRANSPORT_STREAM_DEMUX_H
|
||||
#define __TRANSPORT_STREAM_DEMUX_H
|
||||
|
||||
#include <Locker.h>
|
||||
#include "mpeg_ts_packet.h"
|
||||
|
||||
class PacketQueue;
|
||||
class Packet;
|
||||
|
||||
class TransportStreamDemux
|
||||
{
|
||||
public:
|
||||
TransportStreamDemux(
|
||||
PacketQueue *vid_queue, PacketQueue *aud_queue,
|
||||
PacketQueue *vid_queue2, PacketQueue *aud_queue2,
|
||||
PacketQueue *mpeg_ts_queue);
|
||||
virtual ~TransportStreamDemux();
|
||||
|
||||
void SetPIDs(int vid_pid, int aud_pid, int pcr_pid);
|
||||
|
||||
void AddData(Packet *packet);
|
||||
|
||||
void TimesourceInfo(bigtime_t *perf_time, bigtime_t *sys_time);
|
||||
|
||||
private:
|
||||
void ProcessData(const void *data, int size, bigtime_t start_time, bigtime_t delta);
|
||||
void ProcessPacket(const mpeg_ts_packet *pkt, bigtime_t start_time);
|
||||
|
||||
protected:
|
||||
virtual void ProcessPCR(const mpeg_ts_packet *pkt, bigtime_t start_time);
|
||||
virtual void ProcessPAT(const mpeg_ts_packet *pkt);
|
||||
virtual void ProcessAUD(const mpeg_ts_packet *pkt);
|
||||
virtual void ProcessVID(const mpeg_ts_packet *pkt);
|
||||
|
||||
private:
|
||||
int64 fCount;
|
||||
bigtime_t fSystemTime;
|
||||
bigtime_t fPerformanceTime;
|
||||
bigtime_t fLastEndTime;
|
||||
int fVidPid;
|
||||
int fAudPid;
|
||||
int fPcrPid;
|
||||
PacketQueue * fVidQueue;
|
||||
PacketQueue * fVidQueue2;
|
||||
PacketQueue * fAudQueue;
|
||||
PacketQueue * fAudQueue2;
|
||||
PacketQueue * fMpegTsQueue;
|
||||
Packet * fVidPacket;
|
||||
Packet * fAudPacket;
|
||||
bool fVidPacketValid;
|
||||
bool fAudPacketValid;
|
||||
BLocker fTimeSourceLocker;
|
||||
};
|
||||
|
||||
|
||||
inline void
|
||||
TransportStreamDemux::TimesourceInfo(bigtime_t *perf_time, bigtime_t *sys_time)
|
||||
{
|
||||
fTimeSourceLocker.Lock();
|
||||
*perf_time = fPerformanceTime;
|
||||
*sys_time = fSystemTime;
|
||||
fTimeSourceLocker.Unlock();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _DVB_MEDIA_ADDON_CONFIG_H_
|
||||
#define _DVB_MEDIA_ADDON_CONFIG_H_
|
||||
|
||||
#include "revision.h"
|
||||
|
||||
#define VERSION "1.0"
|
||||
#define BUILD __DATE__ " "__TIME__
|
||||
|
||||
#define BUILD_FOR_HAIKU 1
|
||||
|
||||
#endif
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __MEDIA_HEADER_EX_H_
|
||||
#define __MEDIA_HEADER_EX_H_
|
||||
|
||||
#include <MediaDefs.h>
|
||||
|
||||
struct media_audio_header_ex {
|
||||
int32 _reserved_[13];
|
||||
float frame_rate; // NEW!
|
||||
uint32 channel_count; // NEW!
|
||||
} _PACKED;
|
||||
|
||||
|
||||
struct media_video_header_ex {
|
||||
uint32 _reserved_[8];
|
||||
uint32 display_line_width; // NEW!
|
||||
uint32 display_line_count; // NEW!
|
||||
uint32 bytes_per_row; // NEW!
|
||||
uint16 pixel_width_aspect; // NEW!
|
||||
uint16 pixel_height_aspect; // NEW!
|
||||
float field_gamma;
|
||||
uint32 field_sequence;
|
||||
uint16 field_number;
|
||||
uint16 pulldown_number;
|
||||
uint16 first_active_line;
|
||||
uint16 line_count;
|
||||
} _PACKED;
|
||||
|
||||
|
||||
struct media_header_ex {
|
||||
media_type type;
|
||||
media_buffer_id buffer;
|
||||
int32 destination;
|
||||
media_node_id time_source;
|
||||
uint32 _reserved1_;
|
||||
uint32 size_used;
|
||||
bigtime_t start_time;
|
||||
area_id owner;
|
||||
type_code user_data_type;
|
||||
uchar user_data[64];
|
||||
uint32 _reserved2_[2];
|
||||
off_t file_pos;
|
||||
size_t orig_size;
|
||||
uint32 data_offset;
|
||||
union {
|
||||
media_audio_header_ex raw_audio;
|
||||
media_video_header_ex raw_video;
|
||||
media_multistream_header multistream;
|
||||
media_encoded_audio_header encoded_audio;
|
||||
media_encoded_video_header encoded_video;
|
||||
char _reserved_[64];
|
||||
} u;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _MPEG_TS_PACKET_H
|
||||
#define _MPEG_TS_PACKET_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
class mpeg_ts_packet
|
||||
{
|
||||
public:
|
||||
int SyncByte() const;
|
||||
int TransportError() const;
|
||||
int PayloadUnitStart() const;
|
||||
int PID() const;
|
||||
int AdaptationFieldControl() const;
|
||||
int ContinuityCounter() const;
|
||||
|
||||
public:
|
||||
uint8 header[4];
|
||||
uint8 data[184];
|
||||
} _PACKED;
|
||||
|
||||
|
||||
inline int mpeg_ts_packet::SyncByte() const
|
||||
{
|
||||
return header[0];
|
||||
}
|
||||
|
||||
inline int mpeg_ts_packet::TransportError() const
|
||||
{
|
||||
return header[1] & 0x80;
|
||||
}
|
||||
|
||||
inline int mpeg_ts_packet::PayloadUnitStart() const
|
||||
{
|
||||
return header[1] & 0x40;
|
||||
}
|
||||
|
||||
inline int mpeg_ts_packet::PID() const
|
||||
{
|
||||
return ((header[1] << 8) | header[2]) & 0x1fff;
|
||||
}
|
||||
|
||||
inline int mpeg_ts_packet::AdaptationFieldControl() const
|
||||
{
|
||||
return (header[3] >> 4) & 0x3;
|
||||
}
|
||||
|
||||
inline int mpeg_ts_packet::ContinuityCounter() const
|
||||
{
|
||||
return header[3] & 0x0f;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "pes.h"
|
||||
|
||||
|
||||
status_t
|
||||
pes_extract(const uint8 *pes_data, size_t pes_size, const uint8 **data, size_t *size)
|
||||
{
|
||||
if (pes_size <= 9)
|
||||
return B_ERROR;
|
||||
|
||||
if (pes_data[0] || pes_data[1] || pes_data[2] != 1)
|
||||
return B_ERROR;
|
||||
|
||||
size_t header_size = 9 + pes_data[8];
|
||||
|
||||
if (pes_size <= header_size)
|
||||
return B_ERROR;
|
||||
|
||||
// printf("header size %d\n", header_size);
|
||||
|
||||
pes_data += header_size;
|
||||
pes_size -= header_size;
|
||||
|
||||
*data = pes_data;
|
||||
*size = pes_size;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
pes_stream_id(const uint8 *pes_data, size_t pes_size, int *stream_id)
|
||||
{
|
||||
if (pes_size <= 9)
|
||||
return B_ERROR;
|
||||
|
||||
if (pes_data[0] || pes_data[1] || pes_data[2] != 1)
|
||||
return B_ERROR;
|
||||
|
||||
*stream_id = pes_data[3];
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __PES_H
|
||||
#define __PES_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
status_t pes_extract(const uint8 *pes_data, size_t pes_size, const uint8 **data, size_t *size);
|
||||
|
||||
status_t pes_stream_id(const uint8 *pes_data, size_t pes_size, int *stream_id);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue