现有一项目是关于mpeg2传输流和节目流转换的:
在收到传输流包(Transport package)后转换为PES(Package Elementary Stream)再转换为PS(节目流)。
请问有没有关于这个的开源代码或者别的什么资料,实现起来是不是很复杂。我对mpeg完全是个初哥,下了标准(is138181,is138182)看得很是头晕。
在收到传输流包(Transport package)后转换为PES(Package Elementary Stream)再转换为PS(节目流)。
请问有没有关于这个的开源代码或者别的什么资料,实现起来是不是很复杂。我对mpeg完全是个初哥,下了标准(is138181,is138182)看得很是头晕。
解决方案 »
- 关于VS2008字符串的问题
- GetParent的问题
- 求Advanced C++ Programming Styles and Idioms英文版
- Gmail~Gmail~Gmail~需要Gmail~的进来~8
- 菜鸟的问题!
- 近来在学习STL中,对于VECTOR,LIST,MAP还不是很熟悉,请各位赐教,或者给予相关资料
- 在vc中怎么操作access数据库中的数据啊?
- 菜鸟问题:请问如何在VC中动态创建矩形按钮并且指定他的位置?
- ADO 操作Access 数据库崩溃的问题
- ??类添加的问题!
- 关于ace中ACE_Event_Handler中handle_input的一点疑惑...
- 从COM组件中导出里面的enum类型,应该如何作,谢谢大家……
#ifndef __GST_TS2PS_H__
#define __GST_TS2PS_H__#include <gst/gst.h>
#include <gsttsparse.h>
#include <mpegtools/transform.h>G_BEGIN_DECLS#define DEFAULT_BUFFERSIZE 4096/* #define's don't like whitespacey bits */
#define GST_TYPE_TS2PS \
(gst_ts2ps_get_type())
#define GST_TS2PS(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TS2PS,GstTs2Ps))
#define GST_TS2PS_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TS2PS,GstTs2PsClass))
#define GST_IS_TS2PS(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TS2PS))
#define GST_IS_TS2PS_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TS2PS))typedef struct _GstTs2Ps GstTs2Ps;
typedef struct _GstTs2PsClass GstTs2PsClass;struct _GstTs2Ps
{
GstTsParse ts_parse; /* TODO: parse to pes or ps
PES-only streams currently not supported by the mpegdemuxer
gboolean ps; */ ipack pa;
ipack pv;
uint8_t* ps_buffer;
int ps_off;
gboolean finished; uint8_t* out_buffer;
int buffersize; uint16_t vpid;
uint16_t apid;};struct _GstTs2PsClass
{
GstTsParseClass parent_class;
void (*handle_event) (GstTsParse *object, GstEvent *event);
};
GType gst_ts2ps_get_type (void);
gboolean gst_ts2ps_plugin_init (GstPlugin *plugin);G_END_DECLS#endif /* __GST_TS2PS_H__ */
#include "gstts2ps.h"
#include <gst/gst.h>
#include <errno.h>
#include <string.h>
#include <mpegtools/transform.h>GST_DEBUG_CATEGORY_STATIC (gstts2ps_debug);
#define GST_CAT_DEFAULT (gstts2ps_debug)static GstElementDetails ts2ps_details = {
"TS2PS",
"Filter/TS2PS",
"Mpeg Transport Stream to Program Stream Converter",
"P2P-VCR, C-Lab, University of Paderborn"
};/* Object signals and args */
enum {
LAST_SIGNAL
};/* Arguments */
enum {
ARG_0,
ARG_TS2PS_V_PID,
ARG_TS2PS_A_PID,
ARG_TS2PS_BUFFERSIZE
};
static GstStaticPadTemplate ps_src_factory =
GST_STATIC_PAD_TEMPLATE (
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/mpeg, "
"mpegversion = (int) 2, "
"systemstream = (boolean) TRUE"
)
);
static void gst_ts2ps_base_init (GstTs2PsClass *klass);
static void gst_ts2ps_class_init (GstTs2PsClass *klass);
static void gst_ts2ps_init (GstTs2Ps *object);
static void gst_ts2ps_dispose (GObject *object);
static void gst_ts2ps_finalize (GObject *object);
static void gst_ts2ps_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_ts2ps_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);static GstPadLinkReturn gst_ts2ps_srcconnect_func (GstPad *pad, GstCaps *caps, gboolean newcaps);
//static GstElementStateReturn gst_ts2ps_change_state (GstElement *element);
static void gst_ts2ps_loop (GstElement* element);
GstBuffer * gst_ts2ps_get (GstPad * pad);
static void gst_ts2ps_push (uint8_t *buf, int count, void *p);void gst_ts2ps_parse_payload (GstTsParse *ts_parse, guint8 *data, int length);
static void gst_ts2ps_handle_event (GstTsParse *ts_parse, GstEvent *event);
static GstTsParseClass *parent_class = NULL;/*
******************************
* *
* Private-Methods *
* *
* *
******************************
*//*
******************************
* *
* GObject Related *
* *
* *
******************************
*/
GType
gst_ts2ps_get_type (void)
{
static GType gst_ts2ps_type = 0; if (!gst_ts2ps_type)
{
static const GTypeInfo ts2ps_info =
{
sizeof (GstTs2PsClass),
(GBaseInitFunc) gst_ts2ps_base_init,
NULL,
(GClassInitFunc) gst_ts2ps_class_init,
NULL,
NULL,
sizeof (GstTs2Ps),
0,
(GInstanceInitFunc) gst_ts2ps_init,
};
gst_ts2ps_type = g_type_register_static (GST_TYPE_TSPARSE,
"GstTs2Ps",
&ts2ps_info, 0);
GST_DEBUG_CATEGORY_INIT (gstts2ps_debug, "ts2ps", 0, "Mpeg TS to PS Element"); }
return gst_ts2ps_type;
}/* initialize the plugin's class */
static void
gst_ts2ps_base_init (GstTs2PsClass *klass)
{
GObjectClass *gobject_class;
GstElementClass *element_class = (GstElementClass*) klass; gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&ps_src_factory));
}/* initialize the plugin's class */
static void
gst_ts2ps_class_init (GstTs2PsClass *klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
GstTsParseClass *ts_parse_class; GST_INFO("gst_ts2ps_class_init"); gobject_class = (GObjectClass*) klass;
gstelement_class = (GstElementClass*) klass;
ts_parse_class = (GstTsParseClass*) klass; parent_class = g_type_class_ref (GST_TYPE_TSPARSE); gobject_class->set_property = gst_ts2ps_set_property;
gobject_class->get_property = gst_ts2ps_get_property;
gobject_class->dispose = gst_ts2ps_dispose;
gobject_class->finalize = gst_ts2ps_finalize; g_object_class_install_property (gobject_class, ARG_TS2PS_V_PID,
g_param_spec_int ("vpid",
"vpid",
"Video Program ID",
0, G_MAXINT, 0,
G_PARAM_READWRITE)
); g_object_class_install_property (gobject_class, ARG_TS2PS_A_PID,
g_param_spec_int ("apid",
"apid",
"Audio Program ID",
0, G_MAXINT, 0,
G_PARAM_READWRITE)
); g_object_class_install_property (gobject_class, ARG_TS2PS_BUFFERSIZE,
g_param_spec_int ("buffersize",
"buffersize",
"Buffersize in bytes",
2048, G_MAXINT, DEFAULT_BUFFERSIZE,
G_PARAM_READWRITE)
); ts_parse_class->parse_payload = gst_ts2ps_parse_payload;
ts_parse_class->handle_event = gst_ts2ps_handle_event;
}/* initialize the new element
* instantiate pads and add them to element
* set functions
* initialize structure
*/
static void
gst_ts2ps_init (GstTs2Ps *object)
{
GstTsParse *ts_parse = (GstTsParse*) object;
GST_INFO("gst_ts2ps_init"); object->buffersize = DEFAULT_BUFFERSIZE; /* set to something sane for testing purpose */
//* 3SAT (Germany)
object->apid = 220;
object->vpid = 210;
//*/ object->ps_buffer = g_malloc(object->buffersize);
object->ps_off = 0; init_ipack(&object->pa, 2048, gst_ts2ps_push, 1);
init_ipack(&object->pv, 2048, gst_ts2ps_push, 1); /* Set private data in packet to our object */
object->pa.data = object;
object->pv.data = object;
gst_element_remove_pad (GST_ELEMENT (ts_parse), ts_parse->srcpad);
ts_parse->srcpad = gst_pad_new_from_template(
gst_static_pad_template_get (&ps_src_factory), "src");
gst_element_add_pad (GST_ELEMENT (ts_parse), ts_parse->srcpad);
}
gst_ts2ps_set_property (GObject *_object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
GstTs2Ps *object; g_return_if_fail (GST_IS_TS2PS (_object));
object = GST_TS2PS (_object); switch (prop_id) {
case ARG_TS2PS_V_PID:
object->vpid = g_value_get_int(value);
break;
case ARG_TS2PS_A_PID:
object->apid = g_value_get_int(value);
break;
case ARG_TS2PS_BUFFERSIZE:
object->buffersize = g_value_get_int(value);
g_free(object->ps_buffer);
object->ps_buffer = g_malloc(object->buffersize);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
gst_ts2ps_get_property (GObject *_object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
GstTs2Ps *object; g_return_if_fail (GST_IS_TS2PS (_object));
object = GST_TS2PS (_object); switch (prop_id)
{
case ARG_TS2PS_V_PID:
g_value_set_int(value, object->vpid);
break;
case ARG_TS2PS_A_PID:
g_value_set_int(value, object->apid);
break;
case ARG_TS2PS_BUFFERSIZE:
g_value_set_int(value, object->buffersize);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}static void
gst_ts2ps_dispose (GObject *_object)
{
GstTs2Ps *object; GST_DEBUG("gst_ts2ps_dispose"); g_return_if_fail (GST_IS_TS2PS (_object));
object = GST_TS2PS (_object); G_OBJECT_CLASS (parent_class)->dispose (_object);
}static void
gst_ts2ps_finalize (GObject *_object)
{
GstTs2Ps *object; GST_DEBUG("gst_ts2ps_finalize"); g_return_if_fail (GST_IS_TS2PS (_object));
object = GST_TS2PS (_object); G_OBJECT_CLASS (parent_class)->finalize (_object);
}/*
******************************
* *
* Plugin Realisation *
* *
******************************
*/
/* entry point to initialize the plug-in
* initialize the plug-in itself
* register the element factories and pad templates
* register the features
*/
gboolean
gst_ts2ps_plugin_init (GstPlugin *plugin)
{
return gst_element_register (plugin, "ts2ps", GST_RANK_NONE, GST_TYPE_TS2PS);
}static void
gst_ts2ps_handle_event(GstTsParse *ts_parse, GstEvent *event) {
GstTs2Ps *object = GST_TS2PS(ts_parse);
gint etype; etype = event ? GST_EVENT_TYPE (event) : GST_EVENT_EOS;
switch (etype) {
case GST_EVENT_EOS:
break;
case GST_EVENT_DISCONTINUOUS:
fprintf(stderr, "gst_ts2ps handling discont\n");
if (GST_EVENT_DISCONT_NEW_MEDIA(event)) {
init_ipack(&object->pa, 2048, gst_ts2ps_push, 1);
init_ipack(&object->pv, 2048, gst_ts2ps_push, 1);
}
break;
case GST_EVENT_FLUSH:
break;
}
parent_class->handle_event(object, event);}
/* The output routine for sending a PS */
static void
gst_ts2ps_push(uint8_t *buf, int count, void *p)
{
GstTs2Ps *object = GST_TS2PS(p);
GstBuffer *gst_buf;
GST_DEBUG("%s (..., %d, ...)", __FUNCTION__, count);
/* will we fill the ps_buffer? */
if (object->ps_off+count >= object->buffersize) {
int r = object->ps_off +count - object->buffersize; /* fill buffer, and make a copy */
memcpy(object->ps_buffer + object->ps_off, buf, count-r);
object->out_buffer = g_memdup(object->ps_buffer, object->buffersize); /* take care about the rest */
memcpy(object->ps_buffer, buf+count-r, r);
object->ps_off = r;
/* one buffer finished */
object->finished = TRUE;
}
else {
memcpy(object->ps_buffer + object->ps_off, buf, count);
object->ps_off += count;
} }
void
gst_ts2ps_parse_payload (GstTsParse *ts_parse, guint8 *data, int length)
{
GstTs2Ps *object = GST_TS2PS(ts_parse);
GstBuffer* buf;
ipack* p; GST_DEBUG("Data: 0x%x, Length: %d", data, length); if (ts_parse->transport_error) {
GST_DEBUG("Transport Error");
return;
}
if (ts_parse->pid == object->vpid) {
GST_DEBUG("Video PID");
p = &object->pv;
}
else if (ts_parse->pid == object->apid) {
GST_DEBUG("Audio PID");
p = &object->pa;
}
else {
GST_INFO("Additional PID in TS: %d\n", ts_parse->pid);
return;
}
if (ts_parse->unit_start) {
if (p->plength == MMAX_PLENGTH-6){
p->plength = p->found-6;
p->found = 0;
GST_DEBUG("Unit Start pushing???");
send_ipack(p);
reset_ipack(p);
}
}
instant_repack(data, length, p);
if (object->finished) {
GST_DEBUG ("pushing buffer");
buf = gst_buffer_new();
GST_BUFFER_DATA(buf) = object->out_buffer;
GST_BUFFER_SIZE(buf) = object->buffersize;
GST_BUFFER_TIMESTAMP(buf) = GST_CLOCK_TIME_NONE;
gst_pad_push(ts_parse->srcpad, GST_DATA(buf));
object->finished = FALSE;
}
}