📄 asffile.c
字号:
/* get time of this packet. */
/* if(!ASF_GetNextPacket(asf))
asf->m_seek_pos[i].Time = 0;
else
asf->m_seek_pos[i].Time = asf->m_video_packet->send_time;*/
if (!ASF_GetNextPacket(asf))
{
asf->m_seek_pos[i].Time = 0;
return FALSE;
}
else
{
asf->m_seek_pos[i].Time = asf->m_video_packet->send_time;
}
AsfFastFseek(asf->m_input, asf->m_seek_pos[i].Offset, asf->m_seek_pos[i].Clus);
}
ASF_LoadIndex(asf);
asf->m_error = 0;
memset(asf->m_video_packet, 0, sizeof(ASF_Packet));
AsfFastFseek(asf->m_input, asf->m_seek_pos[0].Offset, asf->m_seek_pos[0].Clus);
return TRUE;
}
//unsigned char buf[4096];
//MY_FILE *pfBitStream;
int AsfFileParsing(ASF_DEMUX *asf)
{
tWMVDecInternalMember WMVDec;
//int readSize = 4096;
asf->m_video_packet = &(asf->m_bits_packet);
asf->m_video_seg = &(asf->m_bits_seg);
/* open stream & parse header */
if (!ASF_Open(asf))
return ASF_FILE_FORMAT_ERR;
/*
* check drm
* 2008-6-6 17:13:36. by ljn
*/
if ((asf->m_video_stream->m_stream_id & 0x8000) != 0)
return ASF_FILE_VIDEO_CODEC_ERR;
/* create table for fast seek. */
if (!ASF_CreateSeekTab(asf))
return ASF_FILE_NO_MOVI_CHUNK;
/* check video codec */
switch (asf->m_video_stream->m_type_specific.m_video.m_encoding)
{
case fccWMV3:
//WMVideoDecDecodeSequenceHeader(&WMVDec, asf->m_video_stream->m_type_specific.m_video.m_extra_data);
break;
case fccWMV2:
case fccWMV1:
break;
default:
return ASF_FILE_VIDEO_CODEC_ERR;
}
/* check resolution */
asf->m_height = asf->m_video_stream->m_type_specific.m_video.m_height;
asf->m_width = asf->m_video_stream->m_type_specific.m_video.m_width;
if ((asf->m_width > ASF_MAX_WIDTH) || (asf->m_width*asf->m_height > ASF_MAX_RESOLUTION))
return ASF_FILE_RESOLUTION_ERR;
/* check audio codec */
switch (asf->m_audio_stream->m_type_specific.m_audio.m_encoding)
{
case WAVE_FORAMT_WMA:
break;
default:
return ASF_FILE_AUDIO_CODEC_ERR;
}
#if 0
pfBitStream = AsfFopen("D:\\bits0.dat", "wb");
while (1)
{
AsfVideoGetDataToSDRAM(asf, (char *)buf, &(gulong)readSize); //readSize = ASF_ReadData(asf, buf, 4096, asf->m_video_stream->m_stream_id);
if (readSize)
{
RKFSFileWrite(buf, readSize, pfBitStream);
}
if (readSize != 4096)
{
break;
}
}
AsfFClose(pfBitStream);
return -1;
#endif
return ASF_FILE_PARSING_OK;
}
int AsfVideoGetDataToSDRAM(ASF_DEMUX *asf, char *buffer, gulong *size)
{
int readSize;
if (!asf->m_bits_hdr_flag) /* fill first block specially for rockchip wmv decoder. */
{
readSize = ASF_FillFirstBlock(asf, buffer, *size);
asf->m_bits_hdr_flag = 1;
if (readSize < *size)
{
*size = readSize;
return -1;
}
return 0;
}
readSize = ASF_ReadData(asf, (unsigned char *)buffer, *size, asf->m_video_stream->m_stream_id);
if (readSize < *size)
{
*size = readSize;
return -1;
}
return 0;
}
int AsfFileOpen(ASF_DEMUX *asf, char *path)
{
memset(asf, 0, sizeof(ASF_DEMUX));
asf->m_input = AsfFopen(path, "rb");
if ((int)asf->m_input == -1 || !(int) asf->m_input)
return -1;
return 0;
}
void AsfFileClose(ASF_DEMUX *asf)
{
ASF_Cleanup(asf);
if (asf->m_input)
AsfFClose(asf->m_input);
}
int AsfSeek(ASF_DEMUX *asf, unsigned int msTime)
{
int i, clus_bak, offset_bak, pkt_found, offset, maxTime;
guint16 *entry;
if ((msTime >= asf->m_time_len) || (asf->m_seek_flag))
{
return FALSE;
}
offset_bak = asf->m_input->Offset;
clus_bak = asf->m_input->Clus;
asf->m_video_packet = &(asf->m_seek_packet);
asf->m_video_seg = &(asf->m_seek_seg);
asf->m_video_packet->packet_size = 0;
asf->m_video_packet->pad_size = 0;
memset(&(asf->m_seek_seg), 0, sizeof(ASF_Segment));
if (!asf->m_index_flag)
{
/* find the nearest pos */
for (i = 0; i < (ASF_SEEK_POSITION_NUM - 1); i++)
{
if ((msTime < asf->m_seek_pos[i+1].Time) && (msTime >= asf->m_seek_pos[i].Time))
break;
}
AsfFastFseek(asf->m_input, asf->m_seek_pos[i].Offset, asf->m_seek_pos[i].Clus);
/* find packet */
do
{
ASF_Skip(asf, asf->m_video_packet->packet_size + asf->m_video_packet->pad_size);
if (!ASF_GetNextPacket(asf))
{
pkt_found = FALSE;
goto seekfaild;
}
}
while (asf->m_video_packet->send_time < msTime);
}
else /* have index */
{
maxTime = asf->m_index.m_time_interval * (asf->m_index.m_entries_count - 1);
msTime += asf->m_start_position_time;
if (msTime > maxTime)
msTime = maxTime;
entry = (guint16 *)((guint8 *)(asf->m_index.m_entry)
+ (msTime / asf->m_index.m_time_interval) * SIZEOF_INDEX_ENTRY);
offset = ((guint32)entry[0] | ((guint32)entry[1] << 16)) * asf->m_max_packet_size
+ asf->m_seek_pos[0].Offset;
/* find the nearest pos */
for (i = 0; i < (ASF_SEEK_POSITION_NUM - 1); i++)
{
if ((offset < asf->m_seek_pos[i+1].Offset) && (offset >= asf->m_seek_pos[i].Offset))
break;
}
AsfFastFseek(asf->m_input, asf->m_seek_pos[i].Offset, asf->m_seek_pos[i].Clus);
AsfFseek(asf->m_input, offset - asf->m_seek_pos[i].Offset, SEEK_CUR);
if (!ASF_GetNextPacket(asf))
{
pkt_found = FALSE;
goto seekfaild;
}
}
/* find key frame */
if (!ASF_FindNextKeyFrm(asf))
{
pkt_found = FALSE;
goto seekfaild;
}
asf->m_seek_dest.Offset = asf->m_input->Offset;
asf->m_seek_dest.Clus = asf->m_input->Clus;
asf->m_seek_flag = 1;
pkt_found = TRUE;
seekfaild:
asf->m_input->Offset = offset_bak;
asf->m_input->Clus = clus_bak;
asf->m_video_packet = &(asf->m_bits_packet);
asf->m_video_seg = &(asf->m_bits_seg);
/* clear error */
asf->m_error = FALSE;
return pkt_found;
}
void AsfSeekImmediately(ASF_DEMUX *asf)
{
if (asf->m_seek_flag)
{
//RockSemObtain(&gFatFlashSem );
AsfFastFseek(asf->m_input, asf->m_seek_dest.Offset, asf->m_seek_dest.Clus);
memcpy(&(asf->m_bits_packet), &(asf->m_seek_packet), sizeof(ASF_Packet));
memcpy(&(asf->m_bits_seg), &(asf->m_seek_seg), sizeof(ASF_Segment));
asf->m_seek_flag = 0;
asf->m_bits_hdr_flag = 0;
asf->m_frmhdr_flag = 1;
//RockSemRelease(&gFatFlashSem );
}
}
int AsfSeekAudioPkt(ASF_DEMUX *asf, int *time)
{
int i, clus_bak, offset_bak, offset = 0;
ASF_Packet seek_pkt;
ASF_Segment seek_seg;
int msTime = *time;
if ((msTime >= asf->m_time_len) || (!asf->m_audio_stream))
{
return FALSE;
}
//RockSemObtain(&gFatFlashSem );
offset_bak = asf->m_input->Offset;
clus_bak = asf->m_input->Clus;
asf->m_video_packet = &seek_pkt;
asf->m_video_seg = &seek_seg;
asf->m_video_packet->packet_size = 0;
asf->m_video_packet->pad_size = 0;
memset(&seek_seg, 0, sizeof(ASF_Segment));
/* find the nearest pos */
for (i = 0; i < (ASF_SEEK_POSITION_NUM - 1); i++)
{
if ((msTime < asf->m_seek_pos[i+1].Time) && (msTime >= asf->m_seek_pos[i].Time))
break;
}
AsfFastFseek(asf->m_input, asf->m_seek_pos[i].Offset, asf->m_seek_pos[i].Clus);
//RockSemRelease(&gFatFlashSem );
/* find packet */
do
{
ASF_Skip(asf, asf->m_video_packet->packet_size + asf->m_video_packet->pad_size);
if (!ASF_GetNextPacket(asf))
{
goto seekfaild;
}
}
while (asf->m_video_packet->send_time < msTime);
/* find audio payload */
while (((asf->m_video_seg->m_stream_no & 0x7f) != asf->m_audio_stream->m_stream_id)
|| (asf->m_video_seg->object_start < msTime + asf->m_start_position_time))
{
ASF_Skip(asf, asf->m_video_seg->data_length);
if (!ASF_GetNextSegment(asf))
{
goto seekfaild;
}
}
if (asf->m_input->Offset >= asf->m_seek_pos[0].Offset)
offset = asf->m_input->Offset - ((asf->m_input->Offset - asf->m_seek_pos[0].Offset) % asf->m_max_packet_size);
if (asf->m_video_seg->object_start > asf->m_start_position_time)
*time = asf->m_video_seg->object_start - asf->m_start_position_time;
seekfaild:
asf->m_input->Offset = offset_bak;
asf->m_input->Clus = clus_bak;
asf->m_video_packet = &(asf->m_bits_packet);
asf->m_video_seg = &(asf->m_bits_seg);
return offset;
}
int AsfSynAudio2Video(ASF_DEMUX *asf)
{
return 0;
}
/*
* Add this function for picture-sound synchronization.
* 2008-6-7, by ljn
*/
int AsfSeekNextKeyFrm(ASF_DEMUX *asf)
{
int i, clus_bak, offset_bak, pkt_found, offset, maxTime, msTime;
guint16 *entry;
/* backup file position */
offset_bak = asf->m_input->Offset;
clus_bak = asf->m_input->Clus;
asf->m_video_packet = &(asf->m_seek_packet);
asf->m_video_seg = &(asf->m_seek_seg);
if (asf->m_index_flag)
{
/* reset pkt & seg info */
asf->m_video_packet->packet_size = 0;
asf->m_video_packet->pad_size = 0;
memset(&(asf->m_seek_seg), 0, sizeof(ASF_Segment));
maxTime = asf->m_index.m_time_interval * (asf->m_index.m_entries_count - 1); /* max seek time */
msTime = asf->m_bits_seg.object_start; /* current time */
/* find next seek point */
do
{
msTime += asf->m_index.m_time_interval;
if (msTime > maxTime)
{
pkt_found = FALSE;
goto seekfaild;
}
/* get entry */
entry = (guint16 *)((guint8 *)(asf->m_index.m_entry)
+ (msTime / asf->m_index.m_time_interval) * SIZEOF_INDEX_ENTRY);
/* get offset */
offset = ((guint32)entry[0] | ((guint32)entry[1] << 16)) * asf->m_max_packet_size
+ asf->m_seek_pos[0].Offset;
}
while (offset <= offset_bak);
/* find the nearest pos */
for (i = 0; i < (ASF_SEEK_POSITION_NUM - 1); i++)
{
if ((offset < asf->m_seek_pos[i+1].Offset) && (offset >= asf->m_seek_pos[i].Offset))
break;
}
AsfFastFseek(asf->m_input, asf->m_seek_pos[i].Offset, asf->m_seek_pos[i].Clus);
AsfFseek(asf->m_input, offset - asf->m_seek_pos[i].Offset, SEEK_CUR);
}
else
{
/* no seek table */
memcpy(&(asf->m_seek_packet), &(asf->m_bits_packet), sizeof(ASF_Packet));
memcpy(&(asf->m_seek_seg), &(asf->m_bits_seg), sizeof(ASF_Segment));
}
/* find next pkt */
if (!ASF_GetNextPacket(asf))
{
pkt_found = FALSE;
goto seekfaild;
}
/* find key frame */
if (!ASF_FindNextKeyFrm(asf))
{
pkt_found = FALSE;
goto seekfaild;
}
/* save position */
asf->m_seek_dest.Offset = asf->m_input->Offset;
asf->m_seek_dest.Clus = asf->m_input->Clus;
asf->m_next_seek_point = asf->m_seek_seg.object_start;
pkt_found = TRUE;
seekfaild:
/* resume */
asf->m_input->Offset = offset_bak;
asf->m_input->Clus = clus_bak;
asf->m_video_packet = &(asf->m_bits_packet);
asf->m_video_seg = &(asf->m_bits_seg);
/* clear error */
asf->m_error = FALSE;
return pkt_found;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -