📄 asffile.c
字号:
if (bitmap_len > ASF_MAX_EXTRA_DATA_SIZE)
{
Asf_fread(stream->m_asf->m_input, video->m_extra_data,
ASF_MAX_EXTRA_DATA_SIZE);
ASF_Skip(stream->m_asf, bitmap_len - ASF_MAX_EXTRA_DATA_SIZE);
}
else
{
Asf_fread(stream->m_asf->m_input, video->m_extra_data,
video->m_extra_len);
}
stream->m_asf->m_read_bytes += video->m_extra_len;
ASF_DEBUG("extra_size %u (len=%lu)\n",
*((guint16 *) video->m_extra_data), video->m_extra_len);
bitmap_len -= video->m_extra_len;
}
if (len != 0)
ASF_Skip(stream->m_asf, len);
return TRUE;
}
static gboolean
ASF_ReadStreamHeader(ASF_DEMUX * asf, guint64 len)
{
ASF_GUID guid;
guint32 type_specific_len, stream_specific_len;
//guint16 stream_no;
ASF_Stream *stream;
guint32 decoded_guid;
if (len < 54)
return FALSE;
stream = MALLOC(sizeof(ASF_Stream));
stream->m_segs_len = 0;
stream->m_begin_segment = 0;
stream->m_frames_ready = 0;
stream->m_need_descramble = FALSE;
len -= 54;
ASF_ReadGUID(asf, &guid);
ASF_DEBUG("Stream type: ");
ASF_DEBUG_PRINT_GUID(guid);
decoded_guid = ASF_DecodeGUID(&guid, NULL);
ASF_DEBUG("\tThis is %lu\n", decoded_guid);
switch (decoded_guid)
{
case ASF_GUID_AUDIO_STREAM:
case ASF_GUID_VIDEO_STREAM:
stream->m_type = decoded_guid;
stream->m_asf = asf;
break;
default:
FREE(stream);
return FALSE;
}
ASF_ReadGUID(asf, &guid);
ASF_DEBUG("Audio conceal ");
ASF_DEBUG_PRINT_GUID(guid);
decoded_guid = ASF_DecodeGUID(&guid, NULL);
if (decoded_guid == ASF_GUID_AUDIO_CONCEAL)
stream->m_need_descramble = TRUE;
ASF_Skip(asf, 8);
type_specific_len = ASF_Read32(asf);
ASF_DEBUG("Type-Specific size %lu\n", type_specific_len);
stream_specific_len = ASF_Read32(asf);
ASF_DEBUG("Stream-Specific size %lu\n", stream_specific_len);
stream->m_stream_id = ASF_Read16(asf);
ASF_DEBUG("Stream no %u\n", stream->m_stream_id);
ASF_Skip(asf, 4);
switch (stream->m_type)
{
case ASF_GUID_AUDIO_STREAM:
if (!ASF_ReadAudioInfo(stream, type_specific_len))
{
FREE(stream);
return FALSE;
}
len -= type_specific_len;
if (asf->m_audio_stream == NULL)
asf->m_audio_stream = stream;
else
FREE(stream);
break;
case ASF_GUID_VIDEO_STREAM:
if (!ASF_ReadVideoInfo(stream, type_specific_len))
{
FREE(stream);
return FALSE;
}
len -= type_specific_len;
if (asf->m_video_stream == NULL)
asf->m_video_stream = stream;
else
FREE(stream);
break;
default:
FREE(stream);
ASF_DEBUG("Unknown GUID stream type");
break;
}
ASF_Skip(asf, len);
return TRUE;
}
static gboolean
ASF_ReadFileProp(ASF_DEMUX * asf, guint64 len)
{
ASF_Skip(asf, len);
return TRUE;
}
static gboolean
ASF_ReadFileHeader(ASF_DEMUX * asf, guint64 len)
{
ASF_GUID guid;
guint64 /*file_size,*/ file_time;
if (len < 80)
return FALSE;
len -= 80;
ASF_ReadGUID(asf, &guid);
ASF_DEBUG("Client GUID: ");
ASF_DEBUG_PRINT_GUID(guid);
asf->m_file_size = ASF_Read64(asf);
ASF_DEBUG("Size %llu\n", asf->m_file_size);
file_time = ASF_Read64(asf);
ASF_DEBUG("Filetime %llu\n", file_time);
asf->m_num_packets = ASF_Read64(asf);
ASF_DEBUG("Num packets %llu\n", asf->m_num_packets);
asf->m_end_position_time = ASF_Read64(asf);
ASF_DEBUG("End time %llu\n", asf->m_end_position_time);
asf->m_time_len = ASF_Read64(asf) / 10000;
ASF_DEBUG("Time length %llu\n", asf->m_time_len);
asf->m_start_position_time = ASF_Read32(asf);
ASF_DEBUG("Start time %llu\n", asf->m_start_position_time);
ASF_Skip(asf, 4);
asf->m_asf_flags = ASF_Read32(asf);
ASF_DEBUG("Flags 0x%08lx\n", asf->m_asf_flags);
asf->m_min_packet_size = ASF_Read32(asf);
ASF_DEBUG("Min packet size %lu\n", asf->m_min_packet_size);
asf->m_max_packet_size = ASF_Read32(asf);
ASF_DEBUG("Max packet size %lu\n", asf->m_max_packet_size);
asf->m_uncompressed_len = ASF_Read32(asf);
ASF_DEBUG("Uncompressed video frame size %lu\n",
asf->m_uncompressed_len);
ASF_Skip(asf, len);
return TRUE;
}
static gboolean
ASF_ReadCodecList(ASF_DEMUX * asf, guint64 len)
{
return 0;
}
static gboolean
ASF_ReadHeader(ASF_DEMUX * asf)
{
ASF_GUID guid;
guint64 len, obj_len;
guint32 num_chunks;
guint32 asf_id;
ASF_ReadGUID(asf, &guid);
if (ASF_DecodeGUID(&guid, NULL) != ASF_GUID_HEADER)
return FALSE;
len = ASF_Read64(asf);
len -= 24;
num_chunks = ASF_Read32(asf);
ASF_Skip(asf, 1);
ASF_Skip(asf, 1);
len -= 6;
while (num_chunks != 0)
{
ASF_ReadGUID(asf, &guid);
obj_len = ASF_Read64(asf);
asf_id = ASF_DecodeGUID(&guid, NULL);
ASF_DEBUG("Got object %lu (len=%llu)\n", asf_id, obj_len);
if (obj_len < 24)
return FALSE;
len -= 24;
obj_len -= 24;
switch (asf_id)
{
case ASF_GUID_FILEHEADER:
if (!ASF_ReadFileHeader(asf, obj_len))
return FALSE;
break;
case ASF_GUID_STREAMH:
if (!ASF_ReadStreamHeader(asf, obj_len))
return FALSE;
break;
case ASF_GUID_INVALID:
ASF_DEBUG("Unknown guid ");
ASF_DEBUG_PRINT_GUID(guid);
default:
ASF_Skip(asf, obj_len);
break;
}
if (obj_len > len)
{
ASF_DEBUG("Invalid file length ! Ignore global length ...\n");
len = 0;
}
else
len -= obj_len;
num_chunks--;
if (asf->m_error)
return FALSE;
//if (asf->m_input->m_stream->m_error != ASF_STREAM_OK)
// return FALSE;
}
if (len != 0)
ASF_Skip(asf, len);
return TRUE;
}
/* ---------------------------------------------------------------------------
* Interface
* ---------------------------------------------------------------------------
*/
static void
ASF_Cleanup(ASF_DEMUX * asf)
{
if (asf->m_video_stream)
FREE(asf->m_video_stream);
if (asf->m_audio_stream)
FREE(asf->m_audio_stream);
if (asf->m_index.m_entry)
FREE(asf->m_index.m_entry);
}
static int
ASF_Open(ASF_DEMUX * asf)
{
ASF_DEBUG("Entering ASF_Open\n");
asf->m_audio_stream = NULL;
asf->m_video_stream = NULL;
asf->m_object_id_bak = -1;
if (!ASF_ReadHeader(asf))
{
ASF_Cleanup(asf);
return NULL;
}
/* Now we look for the data chunk */
while (1)
{
ASF_GUID guid;
ASF_ReadGUID(asf, &guid);
if (ASF_DecodeGUID(&guid, NULL) == ASF_GUID_DATA_CHUNK)
{
asf->m_data_len = ASF_Read64(asf) - 50;
ASF_Skip(asf, 16);
asf->m_num_packets = ASF_Read64(asf);
ASF_DEBUG("Num of packets %llu\n", asf->m_num_packets);
ASF_Skip(asf, 2);
break;
}
else
{
guint64 chunk_len;
ASF_DEBUG("GUID: ");
ASF_DEBUG_PRINT_GUID(guid);
chunk_len = ASF_Read64(asf);
ASF_DEBUG("Chunk len %llu\n", chunk_len);
chunk_len -= 24;
ASF_Skip(asf, chunk_len);
if (asf->m_error)
return 0;
//if (s->m_stream->m_error != ASF_STREAM_OK) {
// ASF_Cleanup (asf);
// FREE (asf);
// return NULL;
//}
}
}
return 1;
}
static void
ASF_Close(ASF_DEMUX *asf)
{
ASF_Cleanup(asf);
}
static __inline guint32 ASF_FilteredRead(ASF_DEMUX *asf, guint8 flag, guint32 *size)
{
guint32 val;
guint32 psize = *size;
switch (flag & 0x03)
{
case 1:
val = ASF_Read8(asf);
psize--;
break;
case 2:
val = ASF_Read16(asf);
psize -= 2;
break;
case 3:
val = ASF_Read32(asf);
psize -= 4;
break;
default:
val = 0;
break;
}
*size = psize;
return val;
}
static gboolean
ASF_STREAM_SeekTo(ASF_Stream * s, guint32 frame_no)
{
return FALSE;
}
static gboolean
ASF_GetNextPacket(ASF_DEMUX * asf)
{
guint8 ecc_flags;
guint32 ret, add_size = 0, size_got, timeout_cnt = 0;
ASF_DEBUG("Readpacket\n");
asf->m_read_bytes = 0;
size_got = (AsfFtell(asf->m_input) - asf->m_seek_pos[0].Offset) % asf->m_max_packet_size;
if (size_got && (size_got < asf->m_max_packet_size))
AsfFseek(asf->m_input, asf->m_max_packet_size - size_got, SEEK_CUR);
/* read ecc flag and check it */
do
{
ecc_flags = ASF_Read8(asf);
// if(asf->m_error)
// return FALSE;
//if((asf->m_error)||((timeout_cnt++ > ASF_ECC_FLAG_TIMEOUT) && (asfPlayState == ASF_STATE_INITIALIZING))) // init 时候做超时处理
if((asf->m_error)||(timeout_cnt++ > ASF_ECC_FLAG_TIMEOUT))
return FALSE;
}
while (!ecc_flags);
if ((ecc_flags & 0xf0) != 0x80)
{
ASF_DEBUG("Error, stream out of sync !\n");
return FALSE;
}
ASF_Skip(asf, (ecc_flags & 0x0f)); /* Flags */
asf->m_video_packet->flags = ASF_Read8(asf);
asf->m_video_packet->segment_id = ASF_Read8(asf);
ASF_DEBUG("flags=%d segment_id=%d\n", asf->m_video_packet->flags, asf->m_video_packet->segment_id);
ret = 0;
asf->m_video_packet->packet_size = ASF_FilteredRead(asf, (asf->m_video_packet->flags >> 5), &ret);
if (ret == 0)
{
ASF_DEBUG("No explicit packet size, using default (%lu)\n", asf->m_max_packet_size);
asf->m_video_packet->packet_size = asf->m_max_packet_size;
}
else
{
if (asf->m_video_packet->packet_size < asf->m_max_packet_size)
add_size = asf->m_max_packet_size - asf->m_video_packet->packet_size;
asf->m_video_packet->packet_size += ret;
}
asf->m_video_packet->packet_size -= 2 + (ecc_flags & 0x0f) + 1;
ASF_DEBUG("Packet size: %lu\n", asf->m_video_packet->packet_size);
asf->m_video_packet->pad_size = ASF_FilteredRead(asf, (asf->m_video_packet->flags >> 3), &asf->m_video_packet->packet_size);
asf->m_video_packet->packet_size -= asf->m_video_packet->pad_size;
if (add_size)
asf->m_video_packet->pad_size += add_size;
asf->m_video_packet->send_time = ASF_Read32(asf);
asf->m_video_packet->duration = ASF_Read16(asf);
asf->m_video_packet->packet_size -= 6;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -