📄 asffile.c
字号:
/********************************************************************************************
Copyright (C), 2007, Fuzhou Rockchip Co.,Ltd.
File:
AsfFile.c
Description:
Asf file demuxer.
Note:
None.
Author:
ljn
$Log: AsfFile.c,v $
Revision 1.6 2008/06/24 02:02:46 HZF
ASF代码优化
Revision 1.5 2008/06/19 04:42:31 Administrator
代码整理!
Revision 1.4 2008/06/17 02:40:52 HZF
增加DRM判断
Revision 1.3 2008/06/02 12:52:31 HZF
对数据有错误的asf文件处理
Revision 1.2 2008/05/30 09:46:51 HZF
wmv死机
Revision 1.1 2008/05/20 12:01:41 HZF
asf文件播放提交
********************************************************************************************/
#define _IN_ASFFILE_H
#include "system.h"
#include "AsfFile.h"
#include <string.h>
#include "WMV3_VOLHeadDec.h"
/* ---------------------------------------------------------------------------
* ASF integer constants
* ---------------------------------------------------------------------------
*/
/* GUID for header chunk */
static const ASF_GUID gs_guid_header_1_0 =
{ 0x75B22630, 0x668E, 0x11CF, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE,
0x6C
};
static const ASF_GUID gs_guid_header_2_0 =
{ 0xD6E229D1, 0x35da, 0x11d1, 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49,
0xbe
};
static const ASF_GUID gs_guid_audio_stream =
{ 0xF8699E40, 0x5B4D, 0x11CF, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44,
0x2B
};
static const ASF_GUID gs_guid_video_stream =
{ 0xBC19EFC0, 0x5B4D, 0x11CF, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44,
0x2B
};
/* GUID indicating that audio error concealment is absent */
static const ASF_GUID gs_guid_audio_conceal_none =
{ 0x49f1a440, 0x4ece, 0x11d0, 0xa3, 0xac, 0x00, 0xa0, 0xc9, 0x03, 0x48,
0xf6
};
/* GUID indicating that interleaved audio error concealment is present */
static const ASF_GUID gs_guid_audio_conceal_interleave =
{ 0xbfc3cd50, 0x618f, 0x11cf, 0x8b, 0xb2, 0x00, 0xaa, 0x00, 0xb4, 0xe2,
0x20
};
/* GUID for data chunk */
static const ASF_GUID gs_guid_data_chunk =
{ 0x75b22636, 0x668e, 0x11cf, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce,
0x6c
};
/* GUID for index chunk */
static const ASF_GUID gs_guid_index_chunk =
{ 0x33000890, 0xe5b1, 0x11cf, 0x89, 0xf4, 0x00, 0xa0, 0xc9, 0x03, 0x49,
0xcb
};
/* GUID for stream header chunk */
static const ASF_GUID gs_guid_stream_header =
{ 0xB7DC0791, 0xA9B7, 0x11CF, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53,
0x65
};
/* File header object */
static const ASF_GUID gs_guid_file_header =
{ 0x8CABDCA1, 0xA947, 0x11CF, 0x8E, 0xE4, 0x00, 0xC0, 0x0C, 0x20, 0x53,
0x65
};
#define ASF_GUID_STRING 0
#define ASF_GUID_HEADER 1
#define ASF_GUID_DATA_CHUNK 2
#define ASF_GUID_INDEX 3
#define ASF_GUID_FILEPROP 4
#define ASF_GUID_STREAMH 5
#define ASF_GUID_DATAUNIT 6
#define ASF_GUID_HEADER_2 7
#define ASF_GUID_FILEHEADER 8
#define ASF_GUID_AUDIO_STREAM 9
#define ASF_GUID_VIDEO_STREAM 10
#define ASF_GUID_AUDIO_CONCEAL 11
#define ASF_GUID_INVALID 256
static ASF_GUID_EX gs_guid_table[] =
{
{&gs_guid_header_1_0, ASF_GUID_HEADER, NULL},
{&gs_guid_header_2_0, ASF_GUID_HEADER_2, NULL},
{&gs_guid_data_chunk, ASF_GUID_DATA_CHUNK, NULL},
{&gs_guid_index_chunk, ASF_GUID_INDEX, NULL},
{&gs_guid_stream_header, ASF_GUID_STREAMH, NULL},
{&gs_guid_file_header, ASF_GUID_FILEHEADER, NULL},
{&gs_guid_audio_stream, ASF_GUID_AUDIO_STREAM, NULL},
{&gs_guid_video_stream, ASF_GUID_VIDEO_STREAM, NULL},
{&gs_guid_audio_conceal_interleave, ASF_GUID_AUDIO_CONCEAL, NULL},
{NULL, 0, NULL}
};
/* ---------------------------------------------------------------------------
* ASF prototypes
* ---------------------------------------------------------------------------
*/
static guint32 ASF_DecodeGUID(ASF_GUID * guid, const gchar ** guid_name);
static gboolean ASF_ReadHeader(ASF_DEMUX * asf);
/* ---------------------------------------------------------------------------
* ASF integer readers
* ---------------------------------------------------------------------------
*/
static __inline int Asf_fread(AsfFILE *pfIn, void *buf, int size)
{
#if 0
int readSize;
if (!size)
return size;
if ((readSize = AsfFread(buf, 1, size, pfIn)) <= 0)
return AsfFread(buf, 1, size, pfIn);
else
return readSize;
#else
return AsfFread(buf, 1, size, pfIn);
#endif
}
static __inline int Asf_fseek(AsfFILE *pfIn, long offset, int fromwhere)
{
return AsfFseek(pfIn, offset, fromwhere);
}
static __inline guint64
ASF_Read64(ASF_DEMUX * asf)
{
guint64 i;
asf->m_read_bytes += 8;
if (Asf_fread(asf->m_input, &i, 8) < 8)
asf->m_error = TRUE;
//if (asf->m_input->m_stream->m_error != ASF_STREAM_OK)
//longjmp (asf->m_jmp_on_error, -1);
return i;
}
static __inline guint32
ASF_Read32(ASF_DEMUX * asf)
{
guint32 i;
asf->m_read_bytes += 4;
if (Asf_fread(asf->m_input, &i, 4) < 4)
asf->m_error = TRUE;
//if (asf->m_input->m_stream->m_error != ASF_STREAM_OK)
//longjmp (asf->m_jmp_on_error, -1);
return i;
}
static __inline guint16
ASF_Read16(ASF_DEMUX * asf)
{
guint16 i;
asf->m_read_bytes += 2;
if (Asf_fread(asf->m_input, &i, 2) < 2)
asf->m_error = TRUE;
//if (asf->m_input->m_stream->m_error != ASF_STREAM_OK)
//longjmp (asf->m_jmp_on_error, -1);
return i;
}
static __inline guint8
ASF_Read8(ASF_DEMUX * asf)
{
guint8 c;
asf->m_read_bytes++;
if (Asf_fread(asf->m_input, &c, 1) < 1)
asf->m_error = TRUE;
//if (asf->m_input->m_stream->m_error != ASF_STREAM_OK)
//longjmp (asf->m_jmp_on_error, -1);
return c;
}
static void
ASF_Skip(ASF_DEMUX * asf, guint64 len)
{
// guint8 buf[1024];
asf->m_read_bytes += len;
while (len != 0)
{
#if 0
guint32 to_read;
to_read = (len > sizeof(buf)) ? sizeof(buf) : len;
Asf_fread(asf->m_input, buf, to_read);
//if (asf->m_input->m_stream->m_error != ASF_STREAM_OK)
// longjmp (asf->m_jmp_on_error, -1);
len -= to_read;
#else
Asf_fseek(asf->m_input, len, SEEK_CUR);
len -= len;
#endif
}
}
static void
ASF_ReadGUID(ASF_DEMUX * asf, ASF_GUID * guid)
{
guid->m_v1 = ASF_Read32(asf);
guid->m_v2 = ASF_Read16(asf);
guid->m_v3 = ASF_Read16(asf);
Asf_fread(asf->m_input, guid->m_v4, 8);
asf->m_read_bytes += 8;
}
/* ---------------------------------------------------------------------------
* ASF GUID translator
* ---------------------------------------------------------------------------
*/
static guint32
ASF_DecodeGUID(ASF_GUID * guid, const gchar ** guid_name)
{
int i;
const ASF_GUID *cur_guid;
for (i = 0; gs_guid_table[i].m_guid != NULL; i++)
{
cur_guid = gs_guid_table[i].m_guid;
if (guid->m_v1 != cur_guid->m_v1 || guid->m_v2 != cur_guid->m_v2
|| cur_guid->m_v3 != cur_guid->m_v3)
continue;
if (memcmp(guid->m_v4, cur_guid->m_v4, 8) != 0)
continue;
if (guid_name != NULL)
*guid_name = gs_guid_table[i].m_name;
return gs_guid_table[i].m_id;
}
return ASF_GUID_INVALID;
}
/* ---------------------------------------------------------------------------
* ASF header parser
* ---------------------------------------------------------------------------
*/
static gboolean
ASF_ReadAudioInfo(ASF_Stream * stream, guint32 len)
{
ASF_PCMData *audio;
#if 0
audio = (ASF_PCMData *) MALLOC(sizeof(ASF_PCMData) - 1 + len - 16);
#else
audio = &(stream->m_type_specific.m_audio);
#endif
stream->m_type_len = sizeof(ASF_PCMData) - 1 + len - 16;
//stream->m_type_specific.m_audio = audio;
audio->m_encoding = ASF_Read16(stream->m_asf);
audio->m_channels = ASF_Read16(stream->m_asf);
audio->m_sample_rate = ASF_Read32(stream->m_asf);
audio->m_bytes_per_sec = ASF_Read32(stream->m_asf);
audio->m_align = ASF_Read16(stream->m_asf);
audio->m_bps = ASF_Read16(stream->m_asf);
ASF_DEBUG(" Audio format %u\n", audio->m_encoding);
ASF_DEBUG(" Number of channels %u\n", audio->m_channels);
ASF_DEBUG(" Sample rate %lu\n", audio->m_sample_rate);
ASF_DEBUG(" Bytes/Sec %lu\n", audio->m_bytes_per_sec);
ASF_DEBUG(" Align %u\n", audio->m_align);
ASF_DEBUG(" BPS %u\n", audio->m_bps);
len -= 16;
if (len != 0)
{
guint16 extra_size;
extra_size = ASF_Read16(stream->m_asf);
len -= 2;
audio->m_extra_len = extra_size;
/*
* [bug fix] some files may have more than 64 bytes in this field.
* skip them or use malloc?
* By ljn, 2008-5-29 11:15:08.
*/
if (extra_size > ASF_MAX_EXTRA_DATA_SIZE)
{
Asf_fread(stream->m_asf->m_input, &audio->m_extra_data[0],
ASF_MAX_EXTRA_DATA_SIZE);
ASF_Skip(stream->m_asf, extra_size - ASF_MAX_EXTRA_DATA_SIZE);
}
else
{
Asf_fread(stream->m_asf->m_input, &audio->m_extra_data[0],
audio->m_extra_len);
}
len -= extra_size;
ASF_DEBUG("extra_size %u (len=%lu)\n",
*((guint16 *) audio->m_extra_data), audio->m_extra_len);
}
if (len != 0)
{
if (stream->m_need_descramble && len >= 5)
{
stream->m_audio_h = ASF_Read8(stream->m_asf);
stream->m_audio_w = ASF_Read16(stream->m_asf);
stream->m_audio_b = ASF_Read16(stream->m_asf);
len -= 5;
}
else
{
stream->m_audio_w = stream->m_audio_h = 1;
stream->m_audio_b = 1;
}
ASF_Skip(stream->m_asf, len);
}
else
{
stream->m_audio_w = 1;
stream->m_audio_h = 1;
stream->m_audio_b = 1;
}
return TRUE;
}
static gboolean
ASF_ReadVideoInfo(ASF_Stream * stream, guint32 len)
{
ASF_VideoData *video;
guint32 w, h, bitmap_len;
w = ASF_Read32(stream->m_asf);
h = ASF_Read32(stream->m_asf);
ASF_Skip(stream->m_asf, 1);
bitmap_len = ASF_Read16(stream->m_asf);
len -= 11;
ASF_DEBUG("len = %lu bitmap_len = %lu\n", len, bitmap_len);
/* We assert that the previous bytes has been read and does not count
* for bitmap_len. bitmap is included in the header. */
//assert (bitmap_len <= (len));
/* Allocate the right size */
#if 0
video = (ASF_VideoData *) MALLOC(sizeof(ASF_VideoData) - 1 + bitmap_len - 40);
#else
video = &(stream->m_type_specific.m_video);
#endif
stream->m_type_len = sizeof(ASF_VideoData) - 1 + bitmap_len - 40;
//stream->m_type_specific.m_video = video;
video->m_width = w;
video->m_height = h;
/* We skip size, width, height */
ASF_Skip(stream->m_asf, 12);
video->m_planes = ASF_Read16(stream->m_asf);
video->m_bit_count = ASF_Read16(stream->m_asf);
video->m_encoding = ASF_Read32(stream->m_asf);
video->m_image_size = ASF_Read32(stream->m_asf);
video->m_xpels_meter = ASF_Read32(stream->m_asf);
video->m_ypels_meter = ASF_Read32(stream->m_asf);
ASF_Skip(stream->m_asf, 8);
len -= bitmap_len;
bitmap_len -= 40;
if (bitmap_len != 0)
{
guint16 sz;
//sz = ASF_Read16 (stream->m_asf);
//ASF_DEBUG ("sz=%u\n", sz);
//bitmap_len -= 2;
video->m_extra_len = bitmap_len;
/*
* [bug fix] some files may have more than 64 bytes in this field.
* skip them or use malloc?
* By ljn, 2008-5-29 11:17:35.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -