flow.c
资源名称:tcpmp.rar [点击查看]
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:11k
源码类别:
Windows CE
开发平台:
C/C++
- /*****************************************************************************
- *
- * This program is free software ; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id: flow.c 543 2006-01-07 22:06:24Z picard $
- *
- * The Core Pocket Media Player
- * Copyright (c) 2004-2005 Gabor Kovacs
- *
- ****************************************************************************/
- #include "common.h"
- static const datatable FlowParams[] =
- {
- { FLOW_BUFFERED,TYPE_BOOL, DF_HIDDEN },
- DATATABLE_END(FLOW_CLASS)
- };
- int FlowEnum(void* p, int* No, datadef* Param)
- {
- return NodeEnumTable(No,Param,FlowParams);
- }
- static const nodedef Flow =
- {
- CF_ABSTRACT,
- FLOW_CLASS,
- NODE_CLASS,
- PRI_DEFAULT,
- };
- static const datatable OutParams[] =
- {
- { OUT_INPUT, TYPE_PACKET, DF_INPUT },
- { OUT_OUTPUT, TYPE_PACKET, DF_OUTPUT|DF_RDONLY },
- { OUT_TOTAL, TYPE_INT, DF_HIDDEN },
- { OUT_DROPPED, TYPE_INT, DF_HIDDEN },
- { OUT_KEEPALIVE,TYPE_BOOL, DF_HIDDEN },
- DATATABLE_END(OUT_CLASS)
- };
- int OutEnum(void* p, int* No, datadef* Param)
- {
- return NodeEnumTable(No,Param,OutParams);
- }
- static const nodedef Out =
- {
- CF_ABSTRACT,
- OUT_CLASS,
- FLOW_CLASS,
- PRI_DEFAULT,
- };
- void Flow_Init()
- {
- NodeRegisterClass(&Flow);
- NodeRegisterClass(&Out);
- }
- void Flow_Done()
- {
- NodeUnRegisterClass(OUT_CLASS);
- NodeUnRegisterClass(FLOW_CLASS);
- }
- void Disconnect(node* Src,int SrcNo,node* Dst,int DstNo)
- {
- ConnectionUpdate(NULL,0,Dst,DstNo);
- ConnectionUpdate(Src,SrcNo,NULL,0);
- }
- int ConnectionUpdate(node* Src,int SrcNo,node* Dst,int DstNo)
- {
- int Result;
- pin Pin;
- packetformat Format;
- packetprocess Process;
- memset(&Format,0,sizeof(Format));
- // first setup connection via Pin, so when PIN_FORMAT is set the nodes can negotiate
- // ConnectionUpdate should not disconnect nodes even is something fails
- if (Dst && Dst->Get(Dst,DstNo,&Pin,sizeof(Pin))==ERR_NONE && (Pin.Node != Src || Pin.No != SrcNo))
- {
- Pin.Node = Src;
- Pin.No = SrcNo;
- Result = Dst->Set(Dst,DstNo,&Pin,sizeof(Pin));
- if (Result != ERR_NONE)
- return Result;
- }
- if (Src && Src->Get(Src,SrcNo,&Pin,sizeof(Pin))==ERR_NONE && (Pin.Node != Dst || Pin.No != DstNo))
- {
- Pin.Node = Dst;
- Pin.No = DstNo;
- Result = Src->Set(Src,SrcNo,&Pin,sizeof(Pin));
- if (Result != ERR_NONE)
- return Result;
- }
- if (Src && Dst)
- {
- Src->Get(Src,SrcNo|PIN_FORMAT,&Format,sizeof(Format));
- Result = Dst->Set(Dst,DstNo|PIN_FORMAT,&Format,sizeof(Format));
- if (Result != ERR_NONE)
- Dst->Set(Dst,DstNo|PIN_FORMAT,NULL,0);
- Dst->Get(Dst,DstNo|PIN_PROCESS,&Process,sizeof(packetprocess));
- Src->Set(Src,SrcNo|PIN_PROCESS,&Process,sizeof(packetprocess));
- if (Result != ERR_NONE)
- return Result;
- }
- else
- if (Dst)
- Dst->Set(Dst,DstNo|PIN_FORMAT,NULL,0);
- return ERR_NONE;
- }
- int DummyProcess(void* p, const packet* Packet, const flowstate* State)
- {
- if (State->CurrTime >= 0 && Packet && Packet->RefTime > State->CurrTime + SHOWAHEAD)
- return ERR_BUFFER_FULL;
- return ERR_NONE;
- }
- static bool_t ContentType(const packetformat* Format,tchar_t* Out,int OutLen)
- {
- tchar_t Id[16];
- switch (Format->Type)
- {
- case PACKET_VIDEO:
- FourCCToString(Id,TSIZEOF(Id),Format->Format.Video.Pixel.FourCC);
- stprintf_s(Out,OutLen,T("vcodec/%s"),Id);
- break;
- case PACKET_AUDIO:
- stprintf_s(Out,OutLen,T("acodec/0x%04x"),Format->Format.Audio.Format);
- break;
- case PACKET_SUBTITLE:
- FourCCToString(Id,TSIZEOF(Id),Format->Format.Subtitle.FourCC);
- stprintf_s(Out,OutLen,T("subtitle/%s"),Id);
- break;
- default:
- return 0;
- }
- return 1;
- }
- void PacketFormatEnumClass(array* List, const packetformat* Format)
- {
- tchar_t s[16];
- if (ContentType(Format,s,TSIZEOF(s)))
- NodeEnumClassEx(List,FLOW_CLASS,s,NULL,NULL,0);
- else
- memset(List,0,sizeof(array));
- }
- bool_t PacketFormatMatch(int Class, const packetformat* Format)
- {
- tchar_t s[16];
- const tchar_t* Supported = LangStr(Class,NODE_CONTENTTYPE);
- assert(Supported[0]!=0);
- if (Supported[0]==0)
- return 0;
- if (!ContentType(Format,s,TSIZEOF(s)))
- return 0;
- return CheckContentType(s,Supported);
- }
- bool_t PacketFormatSimilarAudio(const packetformat* Current, const packetformat* New)
- {
- return Current && Current->Type == PACKET_AUDIO && New && New->Type == PACKET_AUDIO &&
- Current->Format.Audio.Format == New->Format.Audio.Format &&
- Current->Format.Audio.Channels == New->Format.Audio.Channels &&
- Current->Format.Audio.SampleRate == New->Format.Audio.SampleRate;
- }
- bool_t PacketFormatRotatedVideo(const packetformat* Current, const packetformat* New,int Mask)
- {
- if (Current && Current->Type == PACKET_VIDEO && New && New->Type == PACKET_VIDEO &&
- (Current->Format.Video.Direction ^ New->Format.Video.Direction) & Mask)
- {
- video Tmp = New->Format.Video;
- Tmp.Pitch = Current->Format.Video.Pitch;
- if ((Current->Format.Video.Direction ^ Tmp.Direction) & DIR_SWAPXY)
- SwapInt(&Tmp.Width,&Tmp.Height);
- Tmp.Direction = Current->Format.Video.Direction;
- return EqVideo(&Current->Format.Video,&Tmp);
- }
- return 0;
- }
- bool_t EqPacketFormat(const packetformat* a, const packetformat* b)
- {
- if (!a || !b || a->Type != b->Type)
- return 0;
- switch (a->Type)
- {
- case PACKET_VIDEO: return EqVideo(&a->Format.Video,&b->Format.Video);
- case PACKET_AUDIO: return EqAudio(&a->Format.Audio,&b->Format.Audio);
- case PACKET_SUBTITLE: return EqSubtitle(&a->Format.Subtitle,&b->Format.Subtitle);
- }
- return 1;
- }
- int PacketFormatCopy(packetformat* Dst, const packetformat* Src)
- {
- PacketFormatClear(Dst);
- if (Src)
- {
- *Dst = *Src;
- if (Src->ExtraLength >= 0)
- {
- Dst->Extra = NULL;
- Dst->ExtraLength = 0;
- if (Src->ExtraLength && PacketFormatExtra(Dst,Src->ExtraLength))
- memcpy(Dst->Extra,Src->Extra,Dst->ExtraLength);
- if (Src->Type==PACKET_VIDEO && Src->Format.Video.Pixel.Palette == (rgb*)Src->Extra)
- Dst->Format.Video.Pixel.Palette = (rgb*)Dst->Extra;
- }
- }
- return ERR_NONE;
- }
- void PacketFormatCombine(packetformat* Dst, const packetformat* Src)
- {
- if (Dst->Type == Src->Type)
- {
- if (!Dst->ByteRate)
- Dst->ByteRate = Src->ByteRate;
- if (!Dst->PacketRate.Num)
- Dst->PacketRate = Src->PacketRate;
- switch (Dst->Type)
- {
- case PACKET_VIDEO:
- if (!Dst->Format.Video.Width && !Dst->Format.Video.Height)
- {
- Dst->Format.Video.Width = Src->Format.Video.Width;
- Dst->Format.Video.Height = Src->Format.Video.Height;
- Dst->Format.Video.Direction = Src->Format.Video.Direction;
- }
- if (!Dst->Format.Video.Aspect)
- Dst->Format.Video.Aspect = Src->Format.Video.Aspect;
- break;
- case PACKET_AUDIO:
- // force update
- Dst->Format.Audio.Channels = Src->Format.Audio.Channels;
- Dst->Format.Audio.SampleRate = Src->Format.Audio.SampleRate;
- if (!Dst->Format.Audio.Bits)
- {
- Dst->Format.Audio.Bits = Src->Format.Audio.Bits;
- Dst->Format.Audio.FracBits = Src->Format.Audio.FracBits;
- }
- break;
- }
- }
- }
- void PacketFormatClear(packetformat* p)
- {
- if (p->ExtraLength>=0)
- free(p->Extra);
- memset(p,0,sizeof(packetformat));
- }
- bool_t PacketFormatExtra(packetformat* p, int Length)
- {
- if (Length<=0)
- {
- if (p->ExtraLength>=0)
- free(p->Extra);
- p->Extra = NULL;
- p->ExtraLength = 0;
- return 0;
- }
- else
- {
- void* Extra = realloc(p->Extra,Length);
- if (!Extra && Length)
- return 0;
- p->Extra = Extra;
- p->ExtraLength = Length;
- return 1;
- }
- }
- void PacketFormatPCM(packetformat* p, const packetformat* In, int Bits)
- {
- PacketFormatClear(p);
- p->Type = PACKET_AUDIO;
- p->Format.Audio.Format = AUDIOFMT_PCM;
- p->Format.Audio.Bits = Bits;
- p->Format.Audio.SampleRate = In->Format.Audio.SampleRate;
- p->Format.Audio.Channels = In->Format.Audio.Channels;
- if (p->Format.Audio.Channels > 2)
- p->Format.Audio.Channels = 2;
- PacketFormatDefault(p);
- }
- void PacketFormatDefault(packetformat* p)
- {
- switch (p->Type)
- {
- case PACKET_VIDEO:
- if (p->Format.Video.Pixel.FourCC==0) // DIB?
- {
- if (p->Format.Video.Pixel.BitCount <= 8)
- p->Format.Video.Pixel.Flags = PF_PALETTE;
- else
- switch (p->Format.Video.Pixel.BitCount)
- {
- case 16:
- DefaultRGB(&p->Format.Video.Pixel,p->Format.Video.Pixel.BitCount,5,5,5,0,0,0);
- break;
- case 24:
- case 32:
- DefaultRGB(&p->Format.Video.Pixel,p->Format.Video.Pixel.BitCount,8,8,8,0,0,0);
- break;
- }
- p->Format.Video.Direction = DIR_MIRRORUPDOWN;
- }
- else
- if (p->Format.Video.Pixel.FourCC==3)
- {
- p->Format.Video.Pixel.Flags = PF_RGB;
- p->Format.Video.Direction = DIR_MIRRORUPDOWN;
- }
- else
- {
- p->Format.Video.Pixel.Flags = PF_FOURCC;
- p->Format.Video.Pixel.FourCC = UpperFourCC(p->Format.Video.Pixel.FourCC);
- p->Format.Video.Direction = 0;
- }
- DefaultPitch(&p->Format.Video);
- if (p->Format.Video.Height<0)
- {
- p->Format.Video.Height = -p->Format.Video.Height;
- p->Format.Video.Direction ^= DIR_MIRRORUPDOWN;
- }
- break;
- case PACKET_AUDIO:
- // detect fake PCM
- if (p->Format.Audio.Format > 8192 &&
- p->Format.Audio.BlockAlign > 0 &&
- p->ByteRate > 0 &&
- p->Format.Audio.BlockAlign == ((p->Format.Audio.Channels * p->Format.Audio.Bits) >> 3) &&
- p->ByteRate == p->Format.Audio.SampleRate * p->Format.Audio.BlockAlign)
- p->Format.Audio.Format = AUDIOFMT_PCM;
- if (p->Format.Audio.Format == AUDIOFMT_PCM)
- {
- p->Format.Audio.FracBits = p->Format.Audio.Bits - 1;
- if (p->Format.Audio.Bits <= 8)
- p->Format.Audio.Flags |= PCM_UNSIGNED;
- p->Format.Audio.Bits = ALIGN8(p->Format.Audio.Bits);
- p->Format.Audio.BlockAlign = (p->Format.Audio.Channels * p->Format.Audio.Bits) >> 3;
- p->ByteRate = p->Format.Audio.SampleRate * p->Format.Audio.BlockAlign;
- }
- break;
- }
- }
- bool_t PacketFormatName(packetformat* p, tchar_t* Name, int NameLen)
- {
- tchar_t Id[8];
- switch (p->Type)
- {
- case PACKET_SUBTITLE:
- tcscpy_s(Name,NameLen,LangStr(p->Format.Subtitle.FourCC,0x4400));
- if (!Name[0])
- FourCCToString(Name,NameLen,p->Format.Subtitle.FourCC);
- return 1;
- case PACKET_AUDIO:
- if (p->Format.Audio.Format != AUDIOFMT_PCM)
- {
- stprintf_s(Id,TSIZEOF(Id),T("%04X"),p->Format.Audio.Format);
- tcscpy_s(Name,NameLen,LangStr(FOURCC(Id[0],Id[1],Id[2],Id[3]),0x4400));
- if (!Name[0])
- tcscpy_s(Name,NameLen,Id);
- }
- else
- tcscpy_s(Name,NameLen,T("PCM"));
- return 1;
- case PACKET_VIDEO:
- if (Compressed(&p->Format.Video.Pixel))
- {
- tcscpy_s(Name,NameLen,LangStr(p->Format.Video.Pixel.FourCC,0x4400));
- if (!Name[0])
- FourCCToString(Name,NameLen,p->Format.Video.Pixel.FourCC);
- }
- else
- if (AnyYUV(&p->Format.Video.Pixel))
- tcscpy_s(Name,NameLen,T("YUV"));
- else
- stprintf_s(Name,NameLen,T("RGB %d bits"),p->Format.Video.Pixel.BitCount);
- return 1;
- }
- return 0;
- }