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

📄 asffile.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
📖 第 1 页 / 共 4 页
字号:

    asf->m_video_packet->num_segments = 1;
    if ((asf->m_video_packet->flags & 0x01) != 0)            /* multiple payloads */
    {
        asf->m_video_packet->num_segments = ASF_Read8(asf);
        asf->m_video_packet->seglentype = (asf->m_video_packet->num_segments >> 6);
        asf->m_video_packet->num_segments &= 0x3F;
        asf->m_video_packet->packet_size--;
    }

    ASF_DEBUG("Read %lu bytes - pad_size = %lu\n", asf->m_read_bytes, asf->m_video_packet->pad_size);

    return TRUE;
}

static gboolean
ASF_GetNextSegment(ASF_DEMUX * asf)
{
    guint32 seg_info_len;
    //guint32 frag_dep;
    //ASF_Segment *asf_segment;
    //ASF_Stream *s;
    guint32 ret;

    if (asf->m_video_seg->compressed)
    {
        /* read all compressed payload out. */
        if (asf->m_video_seg->m_length > asf->m_max_packet_size)
            return FALSE;
        if (asf->m_video_seg->m_length > 1)
        {
            asf->m_video_seg->data_length = ASF_Read8(asf);
            if (asf->m_video_seg->m_length > asf->m_video_seg->data_length)
            {
                asf->m_video_seg->object_length = asf->m_video_seg->data_length;
                asf->m_video_seg->m_length -= asf->m_video_seg->data_length + 1;
                asf->m_video_seg->object_start += asf->m_video_seg->time_delta;
                asf->m_video_seg->m_object_id ++;
                ASF_DEBUG("sub_segment_start = %lu\n", asf->m_video_seg->object_start);
                return TRUE;
            }
            else
            {
                ASF_Skip(asf, asf->m_video_seg->m_length);
                asf->m_video_seg->compressed = 0;
            }
        }
        else
        {
            asf->m_video_seg->compressed = 0;
        }
    }

    if (!asf->m_video_packet->num_segments)
    {
        ASF_Skip(asf, asf->m_video_packet->pad_size);
        if (!ASF_GetNextPacket(asf))
            return FALSE;
    }

    /* Contain key frame flag */
    asf->m_video_seg->m_stream_no = ASF_Read8(asf);     // & 0x7F;
    asf->m_video_packet->packet_size--;

    asf->m_video_seg->m_object_id = ASF_FilteredRead(asf, asf->m_video_packet->segment_id >> 4, &asf->m_video_packet->packet_size);
    asf->m_video_seg->m_offset = ASF_FilteredRead(asf, asf->m_video_packet->segment_id >> 2, &asf->m_video_packet->packet_size);

    seg_info_len = ASF_FilteredRead(asf, asf->m_video_packet->segment_id, &asf->m_video_packet->packet_size);
    if (seg_info_len == 0)
        return FALSE;

    if (seg_info_len == 1)
    {
        asf->m_video_seg->compressed = TRUE;
#if 0
        /* Skip PTS */
        ASF_Skip(asf, 1);
#else
        /* read pts */
        asf->m_video_seg->time_delta = ASF_Read8(asf);
        asf->m_video_seg->object_start = asf->m_video_seg->m_offset;
#endif
        ASF_DEBUG("found compressed payload.\n");
    }
    else
    {
        if (seg_info_len >= 8)
        {
            asf->m_video_seg->object_length = ASF_Read32(asf);
            asf->m_video_seg->object_start = ASF_Read32(asf);
            ASF_Skip(asf, seg_info_len - 8);
        }
        else
        {
            /* bad information */
            printf("Bad Segment Info Length (<= 8)\n");
            asf->m_video_seg->object_length = 0;
            asf->m_video_seg->object_start = 0;
            ASF_Skip(asf, seg_info_len);
        }
        asf->m_video_packet->packet_size -= seg_info_len;
    }

    /* Object length */
    ASF_DEBUG("object_length = %lu; packet_size = %lu\n", asf->m_video_seg->object_length, asf->m_video_packet->packet_size);
    /* Object start time, millisecond */
    ASF_DEBUG("object_start = %lu\n", asf->m_video_seg->object_start);

    if ((asf->m_video_packet->flags & 0x01) != 0)
    {
        /* multiple payloads */
        ret = 0;
        asf->m_video_seg->m_length = ASF_FilteredRead(asf, asf->m_video_packet->seglentype, &ret);
        if (ret == 0)
            asf->m_video_seg->m_length = asf->m_video_packet->packet_size;
        else
            asf->m_video_packet->packet_size += ret;
    }
    else
    {
        /* single payload */
        asf->m_video_seg->m_length = asf->m_video_packet->packet_size;
    }

    ASF_DEBUG("Data length = %lu\n", asf->m_video_seg->m_length);

    asf->m_video_packet->packet_size -= asf->m_video_seg->m_length;

    if (asf->m_video_seg->compressed)
    {
        /* compressed payload */
        asf->m_video_seg->data_length = ASF_Read8(asf);
        asf->m_video_seg->object_length = asf->m_video_seg->data_length;
        asf->m_video_seg->m_length -= asf->m_video_seg->data_length + 1;
    }
    else
    {
        /* noncompressed payload */
        asf->m_video_seg->data_length = asf->m_video_seg->m_length;
        asf->m_video_seg->m_length = 0;
    }
    asf->m_video_packet->num_segments--;

    return TRUE;

}

static __inline void ASF_FillFrmHdr(ASF_DEMUX *asf, unsigned char *buf)
{
    *buf++ = 'W';
    *buf++ = 'M';
    *buf++ = 'V';
    *buf++ = 'V';
#if 0
    *(guint32 *)buf = asf->m_video_seg->object_length;   /* frame size */
    buf += 4;
    *(guint32 *)buf = asf->m_video_seg->object_start;    /* time stamp */
#else
    *buf++ = (asf->m_video_seg->object_length & 0xff);
    *buf++ = ((asf->m_video_seg->object_length >> 8) & 0xff);
    *buf++ = ((asf->m_video_seg->object_length >> 16) & 0xff);
    *buf++ = (asf->m_video_seg->object_length >> 24);
    *buf++ = (asf->m_video_seg->object_start & 0xff);
    *buf++ = ((asf->m_video_seg->object_start >> 8) & 0xff);
    *buf++ = ((asf->m_video_seg->object_start >> 16) & 0xff);
    *buf++ = (asf->m_video_seg->object_start >> 24);
#endif
    asf->m_time_stamp_bak = asf->m_video_seg->object_start;
    ASF_DEBUG(" *** Frame: %d,  length: %d,  time stamp: %d \n",
              asf->m_video_seg->m_object_id, asf->m_video_seg->object_length,
              asf->m_video_seg->object_start);
    asf->m_object_id_bak = asf->m_video_seg->m_object_id;
}

static int ASF_FindNextKeyFrm(ASF_DEMUX *asf)
{
    while ((!(asf->m_video_seg->m_stream_no & 0x80)) || ((asf->m_video_seg->m_offset) && (!asf->m_video_seg->compressed))
            || ((asf->m_video_seg->m_stream_no & 0x7f) != asf->m_video_stream->m_stream_id))
    {
        ASF_Skip(asf, asf->m_video_seg->data_length);
        if (!ASF_GetNextSegment(asf))
        {
            return 0;
        }
    }

    return 1;
}

int ASF_ReadData(ASF_DEMUX *asf, unsigned char *buf, gint32 size, guint16 m_stream_id)
{
    guint32 getBytes = 0, readSize;

    while (size)
    {
        while ((!asf->m_video_seg->data_length))
        {
            if ((!ASF_GetNextSegment(asf)) || (asf->m_error))
                return getBytes;
            if ((asf->m_video_seg->m_stream_no & 0x7f) != m_stream_id/*asf->m_video_stream->m_stream_id*/)
            {
                /* skip data of other stream */
                ASF_Skip(asf, asf->m_video_seg->data_length);
                asf->m_video_seg->data_length = 0;
            }
            else if (asf->m_video_seg->m_object_id != asf->m_object_id_bak)    /* new frame */
            {
                /* fill frame header, if it is a new frame. */
                if (getBytes&0x1)
                {
                    buf[getBytes] = 0;   /* use this to keep frame header word align. */
                    getBytes++;
                    size--;
                }

                if (asf->m_ffd_flag)
                {
                    if ((!(asf->m_video_seg->m_stream_no & 0x80))
                            || ((asf->m_video_seg->object_start - asf->m_time_stamp_bak) < asf->m_ffd_interval))
                    {
                        ASF_Skip(asf, asf->m_video_seg->data_length);
                        asf->m_video_seg->data_length = 0;
                        continue;
                    }
                    //asf->m_ffd_flag = 0;
                }

                if (asf->m_seek_flag)
                {
                    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;
                }

                if (((asf->m_video_seg->m_offset) && (!asf->m_video_seg->compressed)) ||    /* skip bad frame */
                        ((asf->m_object_id_bak == -1) && !(asf->m_video_seg->m_stream_no & 0x80)))  /* first frame is not key frame */
                {
                    ASF_Skip(asf, asf->m_video_seg->data_length);
                    asf->m_video_seg->data_length = 0;
                }
                else
                {
                    /* fill frame header for new frame. */
                    if (size < ASF_FRAME_HEADER_SIZE)
                    {
                        /* if (remain size to get < size of frame header), fill zero */
                        memset(&buf[getBytes], 0, size);
                        getBytes += size;
                        asf->m_frmhdr_flag = 1;     /* set this to fill frame header in next block */
                        return getBytes;
                    }
                    ASF_FillFrmHdr(asf, &buf[getBytes]);
                    size -= ASF_FRAME_HEADER_SIZE;
                    getBytes += ASF_FRAME_HEADER_SIZE;
                }
            }
        }

        if (asf->m_frmhdr_flag)  /* need fill frame header */
        {
            ASF_FillFrmHdr(asf, &buf[getBytes]);
            size -= ASF_FRAME_HEADER_SIZE;
            getBytes += ASF_FRAME_HEADER_SIZE;
            asf->m_frmhdr_flag = 0;
        }

        if (size <= asf->m_video_seg->data_length)
        {
            asf->m_read_bytes += size;
            readSize = Asf_fread(asf->m_input, &buf[getBytes], size);
            size -= readSize;
            getBytes += readSize;
            asf->m_video_seg->data_length -= readSize;

            return getBytes;
        }
        else
        {
            asf->m_read_bytes += asf->m_video_seg->data_length;
            readSize = Asf_fread(asf->m_input, &buf[getBytes], asf->m_video_seg->data_length);
            size -= readSize;
            getBytes += readSize;

            if (readSize < asf->m_video_seg->data_length)
                return getBytes;

            asf->m_video_seg->data_length = 0;
        }
    }

    return getBytes;
}

static __inline int ASF_FillFirstBlock(ASF_DEMUX *asf, char *buffer, gulong size)
{
    int readSize;
    tWMVDecInternalMember WMVDec;

    if (size < sizeof(tWMVDecShareMember))
        return -1;

    *(short *)buffer = (short)asf->m_video_stream->m_type_specific.m_video.m_width;     /* width */
    buffer += 2;
    *(short *)buffer = (short)asf->m_video_stream->m_type_specific.m_video.m_height;    /* height */
    buffer += 2;

    switch (asf->m_video_stream->m_type_specific.m_video.m_encoding)
    {
        case fccWMV3:
            /* fill wmv3 bit stream header */
            WMVideoDecDecodeSequenceHeader(&WMVDec, asf->m_video_stream->m_type_specific.m_video.m_extra_data, 1);
            memcpy(buffer, &WMVDec, sizeof(tWMVDecShareMember));
            buffer += sizeof(tWMVDecShareMember);
            break;
        case fccWMV2:
            WMVideoDecDecodeSequenceHeader(&WMVDec, asf->m_video_stream->m_type_specific.m_video.m_extra_data, 0);
            *((short *)buffer)++ = 2;   /* CODEC WMV2 */
            *((short *)buffer)++ = WMVDec.m_iFrameRate;
            *((short *)buffer)++ = WMVDec.m_iBitRate;
            *((short *)buffer)++ = WMVDec.m_bRndCtrlOn;
            *((short *)buffer)++ = WMVDec.m_bMixedPel;
            *((short *)buffer)++ = WMVDec.m_bLoopFilter;
            *((short *)buffer)++ = WMVDec.m_bXformSwitch;
            *((short *)buffer)++ = WMVDec.m_bXintra8Switch;
            *((short *)buffer)++ = WMVDec.m_bFrmHybridMVOn;
            *((short *)buffer)++ = WMVDec.m_bDCTTable_MB_ENABLED;
            *((short *)buffer)++ = WMVDec.m_iSliceCode;
            memset(buffer, 0, sizeof(tWMVDecShareMember) - 22);
            buffer += sizeof(tWMVDecShareMember) - 22;
            break;
        case fccWMV1:
        default:
            memset(buffer, 0, sizeof(tWMVDecShareMember));
            buffer += sizeof(tWMVDecShareMember);
            break;
    }

    readSize = ASF_ReadData(asf, (unsigned char *)buffer, size
                            - sizeof(tWMVDecShareMember) - 4, asf->m_video_stream->m_stream_id);
    return (readSize + sizeof(tWMVDecShareMember) + 4);

    return 0;
}

static int ASF_LoadIndex(ASF_DEMUX *asf)
{
    guint64 chunk_len;

    Asf_fseek(asf->m_input, 0, SEEK_SET);

    /* Look for the index chunk */
    while (1)
    {
        ASF_GUID guid;

        ASF_ReadGUID(asf, &guid);
        if (ASF_DecodeGUID(&guid, NULL) == ASF_GUID_INDEX)
        {
            chunk_len = ASF_Read64(asf) - 56;
            ASF_Skip(asf, 16);
            asf->m_index.m_time_interval = (guint32)(ASF_Read64(asf) / 10000);
            asf->m_index.m_max_pkt_count = ASF_Read32(asf);
            asf->m_index.m_entries_count = ASF_Read32(asf);
            ASF_DEBUG("Num of entries %d, time interval %llu\n", asf->m_index.m_entries_count,
                      asf->m_index.m_time_interval);
            if ((asf->m_index.m_entries_count < 10) || (!asf->m_index.m_time_interval))
                return 0;

            asf->m_index.m_entry =
                (ASF_Index_Entry *)MALLOC(asf->m_index.m_entries_count * sizeof(ASF_Index_Entry));
            if (asf->m_index.m_entry)
            {
                Asf_fread(asf->m_input, asf->m_index.m_entry,
                          asf->m_index.m_entries_count * SIZEOF_INDEX_ENTRY /*sizeof(ASF_Index_Entry)*/);
                asf->m_index_flag = TRUE;
            }
            break;
        }
        else
        {
            ASF_DEBUG("GUID: ");
            ASF_DEBUG_PRINT_GUID(guid);
            chunk_len = ASF_Read64(asf);
            ASF_DEBUG("Chunk len %llu\n", chunk_len);
            chunk_len -= 24;

            /*
             *  Check chunk length.
             *  Funny I found this bug, when coding function 'AsfSeekNextKeyFrm' :)
             *  2008-6-7, by ljn
             */
            if ((chunk_len >= asf->m_input->FileSize) || (chunk_len < 0))
                return 0;
            ASF_Skip(asf, chunk_len);
            if (asf->m_error)
            {
                //AsfFastFseek(asf->m_input, asf->m_seek_pos[0].Offset, asf->m_seek_pos[0].Clus);
                return 0;
            }
        }
    }

    //AsfFastFseek(asf->m_input, asf->m_seek_pos[0].Offset, asf->m_seek_pos[0].Clus);
    return 1;
}

static int ASF_CreateSeekTab(ASF_DEMUX *asf)
{
    int pkt_interval, i, byte_interval;

    pkt_interval = (asf->m_num_packets) / ASF_SEEK_POSITION_NUM;
    byte_interval = pkt_interval * asf->m_max_packet_size;

    asf->m_seek_pos[0].Offset = asf->m_input->Offset;
    asf->m_seek_pos[0].Clus = asf->m_input->Clus;
    asf->m_seek_pos[0].Time = 0;

    for (i = 1; i < ASF_SEEK_POSITION_NUM; i++)
    {
        /* get next position */
        if (byte_interval)
        {
            AsfFseek(asf->m_input, byte_interval, SEEK_CUR);
        }
        asf->m_seek_pos[i].Offset = asf->m_input->Offset;
        asf->m_seek_pos[i].Clus = asf->m_input->Clus;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -