#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include "asfdemux.h"
static _ERROR_CORRECTION ERR_CORR;
static PayLoadParsingInfo PayHead;
static PayLoadFlag Pay_Load_Flag;
static PayLoadStat Pay_Load_Stat;
static int Demux_Mulpay_Head(unsigned char *buf,unsigned int len);
static int Demux_Mulpay_Payload(unsigned char * buf,unsigned int len);
static int GetReplicatedData(unsigned char *data,int len);
static int WriteFile(unsigned char *buf , unsigned int len,int flag);
int asfdemux(unsigned char *buf,unsigned int len)
{
int i = 0;
int ErrorCLen = 0;
if(len == 0)
{
return -1;
}
memset(&ERR_CORR,0,sizeof(ERR_CORR));
ERR_CORR.Error_Correction_Data_Length = buf[0] & 0x0f;
ERR_CORR.Opaque_Data_Present = (buf[0] >> 4) & 0x01;
ERR_CORR.Error_Corrcection_Length_Type = (buf[0] >> 5) & 0x03;
ERR_CORR.Error_Corrcection_Present = (buf[0] >> 7) & 0x01;
if(ERR_CORR.Error_Corrcection_Length_Type == 0x00 && ERR_CORR.Error_Correction_Data_Length != 0)
{
ErrorCLen = ERR_CORR.Error_Correction_Data_Length;
i = ErrorCLen + 1;
}
PayHead._LenTypeFlag.MulPayPres = (buf[i]) & 0x01 ;
PayHead._LenTypeFlag.SequeType = (buf[i]>>1) & 0x03;
PayHead._LenTypeFlag.PaddingLenType = (buf[i]>>3) & 0x03;
PayHead._LenTypeFlag.PackLenType = (buf[i]>>5) & 0x03;
PayHead._LenTypeFlag.ErrorCorrectionPresent = (buf[i]>>7) &0x01;
i++;
PayHead.PropertyFlag.ReplicatedDataLenType = buf[i] & 0x03;
PayHead.PropertyFlag.OffsetIntoObjLenType = (buf[i] >> 2) &0x03;
PayHead.PropertyFlag.MediaObjNumLenType = (buf[i] >> 4) & 0x03;
PayHead.PropertyFlag.StreamNumLenType = (buf[i] >> 6) & 0x03;
i++;
if(PayHead._LenTypeFlag.PackLenType == 0)
{
PayHead.PacketLength = 0;
}
if(PayHead._LenTypeFlag.PackLenType == 0x01)
{
PayHead.PacketLength = buf[i];
i++;
}
if(PayHead._LenTypeFlag.PackLenType == 0x02)
{
PayHead.PacketLength = buf[i] < 8 | buf[i+1];
i+=2;
}
if(PayHead._LenTypeFlag.PackLenType == 0x03)
{
PayHead.PacketLength = (buf[i] < 8 | buf[i+1]) < 16 | ((buf[i+2] < 8) | buf[i+3]);
i+= 4;
}
// PayHead.Sequence
if(PayHead._LenTypeFlag.SequeType == 0)
{
PayHead.Sequence = 0;
}
if(PayHead._LenTypeFlag.SequeType == 0x01)
{
PayHead.Sequence = buf[i];
i++;
}
if(PayHead._LenTypeFlag.SequeType == 0x02)
{
PayHead.Sequence = buf[i] < 8 | buf[i+1];
i+=2;
}
if(PayHead._LenTypeFlag.SequeType == 0x03)
{
PayHead.Sequence = (buf[i] < 8 | buf[i+1]) < 16 | ((buf[i+2] < 8) | buf[i+3]);
i+= 4;
}
// PayHead.PaddingLength
if(PayHead._LenTypeFlag.PaddingLenType== 0)
{
PayHead.PaddingLength = 0;
}
if(PayHead._LenTypeFlag.PaddingLenType == 0x01)
{
PayHead.PaddingLength = buf[i];
i++;
}
if(PayHead._LenTypeFlag.PaddingLenType == 0x02)
{
PayHead.PaddingLength = buf[i] < 8 | buf[i+1];
i+=2;
}
if(PayHead._LenTypeFlag.PaddingLenType == 0x03)
{
PayHead.PaddingLength = (buf[i] < 8 | buf[i+1]) < 16 | ((buf[i+2] < 8) | buf[i+3]);
i+= 4;
}
PayHead.SendTime = (buf[i] < 8 | buf[i+1]) < 16 | ((buf[i+2] < 8) | buf[i+3]);
i+=4;
PayHead.Duration = buf[i] < 8 | buf[i+1];
i+=2;
if(len i)
{
return -1;
}
if(PayHead._LenTypeFlag.MulPayPres == 0x01)
{
Demux_Mulpay_Head(buf + i ,len - i);
}
else
{
//todo ;
}
return 0;
}
static int Demux_Mulpay_Head(unsigned char *buf,unsigned int len)
{
int i = 0;
int ret = 0;
if(len == 0)
{
return -1;
}
Pay_Load_Flag.NumOfPayloads = buf[i] & 0x03f;
Pay_Load_Flag.PayloadLenType = (buf[i] >> 6) &0x03;
i++;
while(Pay_Load_Flag.NumOfPayloads >= 0 && i len)
{
ret = Demux_Mulpay_Payload(buf+i,len - i);
if(ret 0)
{
return -1;
}
else
{
i+=ret;
}
Pay_Load_Flag.NumOfPayloads--;
}
return 0;
}
static int Demux_Mulpay_Payload(unsigned char * buf,unsigned int len)
{
int i = 0;
if(len == 0)
{
return -1;
}
Pay_Load_Stat.StreamNum.KeyFrameBit = (buf[i] >> 7) & 0x01;
Pay_Load_Stat.StreamNum.StreamN = buf[i] & 0x7f;
i++;
/*
Media Object Number BYTE, WORD or DWORD 0, 8, 16, 32
Offset Into Media Object BYTE, WORD or DWORD 0, 8, 16, 32
Replicated Data Length
*/
if(PayHead.PropertyFlag.MediaObjNumLenType== 0)
{
Pay_Load_Stat.MediaObjectNum= 0;
}
if(PayHead.PropertyFlag.MediaObjNumLenType == 0x01)
{
Pay_Load_Stat.MediaObjectNum = buf[i];
i++;
}
if(PayHead.PropertyFlag.MediaObjNumLenType == 0x02)
{
Pay_Load_Stat.MediaObjectNum = buf[i] < 8 | buf[i+1];
i+=2;
}
if(PayHead.PropertyFlag.MediaObjNumLenType == 0x03)
{
Pay_Load_Stat.MediaObjectNum = (buf[i] < 8 | buf[i+1]) < 16 | ((buf[i+2] < 8) | buf[i+3]);
i+= 4;
}
//Offset
if(PayHead.PropertyFlag.OffsetIntoObjLenType == 0)
{
Pay_Load_Stat.OffsetIntoObject = 0;
}
if(PayHead.PropertyFlag.OffsetIntoObjLenType == 0x01)
{
Pay_Load_Stat.OffsetIntoObject = buf[i];
i++;
}
if(PayHead.PropertyFlag.OffsetIntoObjLenType == 0x02)
{
Pay_Load_Stat.OffsetIntoObject = buf[i] < 8 | buf[i+1];
i+=2;
}
if(PayHead.PropertyFlag.OffsetIntoObjLenType == 0x03)
{
Pay_Load_Stat.OffsetIntoObject = (buf[i] < 8 | buf[i+1]) < 16 | ((buf[i+2] < 8) | buf[i+3]);
i+= 4;
}
//Replicated
if(PayHead.PropertyFlag.ReplicatedDataLenType == 0)
{
Pay_Load_Stat.ReplicatedDataLen = 0;
}
if(PayHead.PropertyFlag.ReplicatedDataLenType == 0x01)
{
Pay_Load_Stat.ReplicatedDataLen = buf[i];
i++;
}
if(PayHead.PropertyFlag.ReplicatedDataLenType == 0x02)
{
Pay_Load_Stat.ReplicatedDataLen = buf[i] < 8 | buf[i+1];
i+=2;
}
if(PayHead.PropertyFlag.ReplicatedDataLenType == 0x03)
{
Pay_Load_Stat.ReplicatedDataLen = (buf[i] < 8 | buf[i+1]) < 16 | ((buf[i+2] < 8) | buf[i+3]);
i+= 4;
}
if(Pay_Load_Stat.ReplicatedDataLen >= 8)
{
GetReplicatedData(buf +i,Pay_Load_Stat.ReplicatedDataLen);
i+= Pay_Load_Stat.ReplicatedDataLen;
}
else
{
i+=Pay_Load_Stat.ReplicatedDataLen;
printf("error Pay_Load_Stat.ReplicatedDataLen 8\n");
}
//Payload Length
if(Pay_Load_Flag.PayloadLenType == 0x01)
{
Pay_Load_Stat.PayLoadLen = buf[i];
i++;
}
if(Pay_Load_Flag.PayloadLenType == 0x02)
{
Pay_Load_Stat.PayLoadLen = buf[i] < 8 | buf[i+1];
i+=2;
}
if(Pay_Load_Flag.PayloadLenType == 0x03)
{
Pay_Load_Stat.PayLoadLen = (buf[i] < 8 | buf[i+1]) < 16 | ((buf[i+2] < 8) | buf[i+3]);
i+= 4;
}
WriteFile(buf + i,Pay_Load_Stat.PayLoadLen,0);
return i+Pay_Load_Stat.PayLoadLen;
}
static int GetReplicatedData(unsigned char *data,int len)
{
if(len >= 8)
{
memcpy(&Pay_Load_Stat.ReplicatedData.MediaObjectSize,data,4*sizeof(char));
memcpy(&Pay_Load_Stat.ReplicatedData.PresTime,&data[4],4*sizeof(char));
/* printf("PayStat->ReplicatedData:\n\t\tMediaObjectSize:%d\tPresTime:%d\n",
PayStat.ReplicatedData.MediaObjectSize,
PayStat.ReplicatedData.PresTime);
*/
}
return len;
}
static int WriteFile(unsigned char *buf , unsigned int len,int flag)
{
FILE *fp = NULL;
static int temp = 0;
char filename[50] = {0};
int ret = 0;
sprintf(filename,FILENAMEFMT,temp++);
fp = fopen(filename,"wb");
if(fp == NULL)
{
printf("error open file\n");
return -1;
}
ret = fwrite(buf,len,1,fp);
fclose(fp);
return ret;
}