⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asffile.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
📖 第 1 页 / 共 4 页
字号:
/********************************************************************************************
 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 + -