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

📄 vldtest.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的外部设备的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Copyright (c) 1995-1999 by TriMedia Technologies. 
 *
 * +------------------------------------------------------------------+
 * | This software is furnished under a license and may only be used  |
 * | and copied in accordance with the terms and conditions of  such  |
 * | a license and with the inclusion of this copyright notice. This  |
 * | software or any other copies of this software may not be provided|
 * | or otherwise made available to any other person.  The ownership  |
 * | and title of this software is not transferred.                   |
 * |                                                                  |
 * | The information in this software is subject  to change without   |
 * | any  prior notice and should not be construed as a commitment by |
 * | TriMedia Technologies.                                           |
 * |                                                                  |
 * | this code and information is provided "as is" without any        |
 * | warranty of any kind, either expressed or implied, including but |
 * | not limited to the implied warranties of merchantability and/or  |
 * | fitness for any particular purpose.                              |
 * +------------------------------------------------------------------+
 *
 *  Module name              : vldtest.c    1.22
 *
 *  Last update              : 17:37:20 - 00/11/09
 *
 *  VLD library test program.
 *
 *  This program parses MPEG-1 and MPEG-2 macroblocks along with other
 *  headers necessary to parse the macroblocks, then compare
 *  the result with the reference result.
 *  It uses interrupt to get more data in, but polls to detect
 *  the completion of parsing each macro block.
 */

#include <stdio.h>
#include <stdarg.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <tmlib/dprintf.h>
#include <tmlib/tmlibc.h>
#include <ops/custom_defs.h>
#include <tm1/tmVLD.h>
#include <tm1/tmInterrupts.h>
#include <tmlib/AppModel.h>

#include <tm1/tmHelp.h>

#define PROGRAM_VERSION     "2.0"

/*
 * Do up to this many frames or SEQ_END_CODE
 */
#define MAX_NUM_FRAMES        10

#define VLD_MAX_MHB           511    /* (2^9)-1 */
#define VLD_MAX_RL            4095    /* (2^12)-1 */

#define MAX_MBS               20
#define MAX_TOKENS_PER_MB     (64*6)


 /* MPEG video start codes */
 
#define PICTURE_START_CODE     0x00000100
#define SLICE_MIN_START_CODE   0x00000101
#define SLICE_MAX_START_CODE   0x000001af
#define USER_START_CODE        0x000001b2
#define SEQ_START_CODE         0x000001b3
#define SEQ_ERROR_CODE         0x000001b4
#define EXT_START_CODE         0x000001b5    /* MPEG2 confirmation code */
#define SEQ_END_CODE           0x000001b7
#define GOP_START_CODE         0x000001b8

/* MPEG extension start code id */
 
#define SEQ_EXT_ID              0x1
#define SEQ_DISPLAY_EXT_ID      0x2
#define SEQ_SCALABLE_EXT_ID     0x5
#define PICT_CODING_EXT_ID      0x8
#define QUANT_MATRIX_EXT_ID     0x3
#define PICT_DISPLAY_EXT_ID     0x7
#define PICT_TEMP_SCAL_EXT_ID   0xa
#define PICT_SPAT_SCAL_EXT_ID   0x9
#define COPYRIGHT_EXT_ID        0x4
 
 
#define ISO_END_CODE            0x1B9
#define PACK_START_CODE         0x1BA
#define SYSTEM_START_CODE       0x1BB
 
#define VIDEO_ELEMENTARY_STREAM 0x1e0
 
/* scalable_mode */
#define SC_NONE 0
#define SC_DP   1
#define SC_SPAT 2
#define SC_SNR  3
#define SC_TEMP 4
 
/* picture coding type */
#define I_TYPE 1
#define P_TYPE 2
#define B_TYPE 3
#define D_TYPE 4
 
/* picture structure */
#define TOP_FIELD     1
#define BOTTOM_FIELD  2
#define FRAME_PICTURE 3
 

/*
 * macroblock types encoded in mbType field of MB header
 */
#define MB_INTRA    1
#define MB_PATTERN  2
#define MB_BACKWARD 4
#define MB_FORWARD  8
#define MB_QUANT    16

/*
 * Number of bytes given to VLD each time
 */
#define READSIZE        64

#define ERROR_IF_NOT_OK(x)                          \
{                                                   \
    tmLibdevErr_t status;                           \
                                                    \
    status = x;                                     \
    if (status != TMLIBDEV_OK)                      \
    {                                               \
    error(#x "failed.  status = 0x%x", status);     \
    }                                               \
}


#ifdef __BIG_ENDIAN__
#define SWAP_INT(a) \
  ((FUNSHIFT3(a, a) & 0xff00ff00) | (FUNSHIFT1(a, a) & 0x00ff00ff))
#else                /* big endian */
#define SWAP_INT(a)    (a)
#endif

/*
 * Never check EMPTY status since it will be serviced by ISR.
 * If EMPTY status is checked, we may actually read it, but ISR will
 * service it and all we can do is to ignore it.   Why bother.
 * Instead, we are checking VldEmpty flag in case ISR was not able
 * to service it.
 */
#define GET_RETURN_VALUE_FROM_HVLD \
    (vldGetSTATUS() & \
     (VLD_STATUS_SUCCESS | VLD_STATUS_STARTCODE | VLD_STATUS_ERROR | \
      VLD_STATUS_MBH_OUT_DONE | VLD_STATUS_RL_OUT_DONE))

/*
 * Input and reference data
 */
#define BUF_SIZE (128*1024)

extern UInt32 in_data[];

/* Video Sequence Header structure */
typedef struct vid_header {
  UInt16   h_size;
  UInt16   v_size;
  UInt8    aspect_ratio;
  UInt8    frame_rate;
  UInt32   bit_rate;
  UInt16   vbv_buf_size;
  UInt8    const_param_flag;
  UInt8    intra_quant_matrix[8][8];
  UInt8    non_intra_quant_matrix[8][8];
} SeqHeader;

/* Sequence extension structure */
typedef struct seq_ext {
  UInt8    ext_id;
  UInt8    profile_level;
  UInt8    progressive_seq_flag;
  UInt8    chroma_format;
  UInt8    h_size_ext;
  UInt8    v_size_ext;
  UInt16   bit_rate_ext;
  UInt8    vbv_buf_size_ext;
  UInt8    low_delay;
  UInt8    frame_rate_ext_n;
  UInt8    frame_rate_ext_d;
} SeqExt;

typedef struct GoP {
  Bool 	drop_flag;                 /* Flag indicating dropped frame. */
  UInt32 tc_hours;                 /* Hour component of time code.   */
  UInt32 tc_minutes;               /* Minute component of time code. */
  UInt32 tc_seconds;               /* Second component of time code. */
  UInt32 tc_pictures;              /* Picture counter of time code.  */
  Bool   closed_gop;               /* Indicates no pred. vectors to
                                            previous group of pictures.    */
  Bool   broken_link;              /* B frame unable to be decoded.  */
  UInt8  *ext_data;                /* Extension data.                */
  UInt8  *user_data;               /* User data.                     */
} GoP;

static SeqHeader  seqhead;
static SeqExt     seqext;
static Int	  stream = 0;

static UInt8 InData[BUF_SIZE];
static UInt8 MbhRef[BUF_SIZE];
static UInt8 TokenRef[BUF_SIZE];
static UInt8 PictTypeChar[] = "UIPBD";

static Int   instance;
static Pointer ReadAddr;
static vldMBHMpeg2_t *Mbh;
static UInt32 *Token;

static Int  ParsedMbs;
static Int  ErrorMbs;
static Int  ParsedFrames;

static Pointer pvidStream;

static void error(char *fmt,...);
static void inputEmptyCallback(Pointer vidStream, Int32 flag);
static void vldIrqHandler(void);
static Int  allocVldOutput(void);
static Int  parseOffUptoPicture(void);
static Int  parseSeqHeader(void);
static Int  parseGOP(GoP *groupict);
static Int  parsePict(vldPictureInfo_t * pictinfo);
static Int  decodeframe(vldPictureInfo_t * pictinfo);
static void *cache_calloc_share(unsigned num, unsigned size, int i);
static void *cache_calloc(unsigned num, unsigned size, int i);
static void reportPictureInfo(vldPictureInfo_t * pictinfo);
static Int  parseSlice(void);
static UInt reportMbh(vldMBHMpeg2_t * mbh);
static Int  compareMbh(Pointer mbh, Pointer * pMbhRef, Int mpeg2Mode);
static Int  compareToken(Pointer token, Pointer * pTokenRef, Int cbp);

#ifdef DEBUG_VLD_PARSE
static void printMBInfo(vldMBHMpeg2_t * mbh, UInt32 * token);
#endif

/* Set up array for fast conversion from zig zag order to row/column
   coordinates.
   */
 
unsigned char zigzag_direct[64] = {
        0,      8,      2,      4,      10,     16,     24,     18,
        12,     6,      1,      14,     20,     26,     32,     40,
        34,     28,     22,     9,      3,      5,      11,     17,
        30,     36,     42,     48,     56,     50,     44,     38,
        25,     19,     13,     7,      15,     21,     27,     33,
        46,     52,     58,     60,     54,     41,     35,     29,
        23,     31,     37,     43,     49,     62,     57,     51,
        45,     39,     47,     53,     59,     61,     55,     63
};

/****************************************************************************
    main()

    VLD library test program.
****************************************************************************/
main()
{
    UInt32      data, *p, i, j, going;
    vldInstanceSetup_t vldCtrl;
    GoP	   	group;
    vldPictureInfo_t pictinfo;
    pvldCapabilities_t pcap;
    Int         inFile;
    Int         refMbhFile;
    Int         refTokenFile;
    Int         res;
    UInt8	*pointers, *pointerd;
    UInt32	tempdata;

    /*
     * =========================================================== Start
     * of initialization
     */
    DPsize(4 * 1024 * 1024);

    ERROR_IF_NOT_OK(vldGetCapabilities(&pcap));

    DP(("\nTrimedia VLD Test Program, V%s\n\n", PROGRAM_VERSION));
    DP(("This program uses VLD library version %d.%d.%d\n",
        pcap->version.majorVersion,
        pcap->version.minorVersion,
        pcap->version.buildVersion));
    DP(("to parse a simple MPEG-1 or MPEG-2 stream.\n"));

    DP(("Running on ")); tmHelpReportSystem(Null);
    printf("Running on "); tmHelpReportSystem(stdout);

    /*
     * Sanity checking for program correctness
     */
    if (TMLIBDEV_OK != 0) {
        error("This program assumes TMLIBDEV_OK == 0");
    }

    /*
     * Get VLD ready by: Open, setup, prime, shift by 0
     */
    ERROR_IF_NOT_OK(vldOpen(&instance));

    vldCtrl.interrupts = VLD_IMASK_DMA_IN_DONE;
    vldCtrl.vldEmptyFunc = (pFnVldEmpty_t) inputEmptyCallback;
    vldCtrl.priority = intPRIO_4;    /* interrupt priority */
    vldCtrl.vldISR = (pFnVldISR_t) vldIrqHandler;

    ERROR_IF_NOT_OK(vldInstanceSetup(instance, &vldCtrl));

    DP(("Setup done \n"));

    #ifdef __LITTLE_ENDIAN__
       /* endian swap if little endian */
        for(i=0; i<(160*4); i++)
        {
            pointerd = (UInt8 *)&in_data[i];
            tempdata = in_data[i];
            pointers = (UInt8 *) &tempdata;
            for(j=0; j<4; j++)
                  *(pointerd+3-j) = *(pointers+j);
        }
        pointers = (UInt8 *) &in_data[0];
        _cache_copyback(in_data, 160*4);
    #endif
 
    /*
     * Get the data ready by reading in from files
     */
    inFile = open("bike.m1v", O_RDONLY | O_BINARY);
    refMbhFile = open("refmbh_bike.bits", O_RDONLY | O_BINARY);
    refTokenFile = open("reftoken_bike.bits", O_RDONLY | O_BINARY);
    if (inFile < 0 || refMbhFile < 0 || refTokenFile < 0) {
        error("opening file failed");
    }
 
    res = read(inFile, InData, BUF_SIZE);
    printf("input data: %d bytes read\n", res);
    DP(("input data: %d bytes read\n", res));
 
    res = read(refMbhFile, MbhRef, BUF_SIZE);
    printf("mbh reference data: %d bytes read\n", res);
    DP(("mbh reference data: %d bytes read\n", res));
 
    res = read(refTokenFile, TokenRef, BUF_SIZE);
    printf("token reference data: %d bytes read\n", res);
    DP(("token reference data: %d bytes read\n", res));
 
    p = (UInt32 *) MbhRef;
    for (i = 0; i < (BUF_SIZE >> 2); i++) {
        p[i] = SWAP_INT(p[i]);
    }
    p = (UInt32 *) TokenRef;
    for (i = 0; i < (BUF_SIZE >> 2); i++) {
        p[i] = SWAP_INT(p[i]);
    }
 
    /*
     * Copyback so that the data is in memory. We are rather loose about
     * the number of copybacks here knowing that we will not use the
     * whole buffer.
     */
    _cache_copyback(InData, BUF_SIZE);

        /* vldInput: setup input address and count */
    while (stream != 1 && stream != 2) {
        printf("MPEG-1 or MPEG-2 bitstream (key in 1 or 2, respectively): ");
        scanf("%d", &stream);
	printf("\n");
    }
    if (stream == 2) 
        ReadAddr = (Pointer) &in_data[0];
    else
	ReadAddr = (Pointer) InData;

    vldInput(instance, ReadAddr, READSIZE);
    printf("vldInput done and data address: 0x%x \n", ReadAddr);
    DP(("Starting address: 0x%x \n", ReadAddr));

    /*
     * Shifting 0 assures alignment
     */
    vldCommand(instance, VLD_COMMAND_SHIFT | 0);

    /*
     * Allocate spaces for VLD output. Mbh:   macro block header Token:
     * run-length tokens
     */
    ERROR_IF_NOT_OK(allocVldOutput());
    DP(("spaces allocated for VLD outut\n"));

    /*
     * default picture info Set it for MPEG-1 since all are written by
     * MPEG-2
     */
    pictinfo.pictureType = 1;
    pictinfo.pictureStruct = 3;
    pictinfo.framePFrameD = 1;
    pictinfo.intraVLC = 0;
    pictinfo.concealMV = 0;
    pictinfo.mpeg2Mode = 0;
    pictinfo.hForwRSize = 15;
    pictinfo.vForwRSize = 15;
    pictinfo.hBackRSize = 0xf;
    pictinfo.vBackRSize = 0xf;

    ERROR_IF_NOT_OK(vldSetPictureInfo(instance, &pictinfo));
    DP(("vldSetPictureInfo done \n"));

    /*
     * End of initialization
     * ===================================================================
     * = Start parsing. 
     */
    /*ERROR_IF_NOT_OK(parseOffUptoPicture());
     */

    ERROR_IF_NOT_OK(vldNextStartCode(instance, &data));

    going = 1;
    ParsedFrames = 0;
    while (going && ParsedFrames < MAX_NUM_FRAMES) {

        vldShowBits(instance, 8, &data);
        data |= 0x100;
        DP(("data for switch: 0x%x \n", data));
        switch (data) {

	case SEQ_END_CODE:
	    DP(("Sequence End \n"));
	    going = 0;
	    break;

        case SEQ_START_CODE:
	    DP(("Sequence start code \n"));
	    ERROR_IF_NOT_OK(parseSeqHeader());
	    break;
	    
        case GOP_START_CODE:
            DP(("Group of picture start code\n"));
            ERROR_IF_NOT_OK(parseGOP(&group));
            break;

        case PICTURE_START_CODE:
            ERROR_IF_NOT_OK(parsePict(&pictinfo));
            printf("Mpeg-%d frame %d: (%c)", pictinfo.mpeg2Mode + 1,
              ParsedFrames, PictTypeChar[pictinfo.pictureType]);
            DP(("Mpeg-%d frame %d: (%c)", pictinfo.mpeg2Mode + 1,
             ParsedFrames, PictTypeChar[pictinfo.pictureType]));
            decodeframe(&pictinfo);
            printf(" %d MBs parsed, %d MBs error\n",
                   ParsedMbs, ErrorMbs);
            DP((" %d MBs parsed, %d MBs error\n",
                ParsedMbs, ErrorMbs));
            ParsedFrames++;
            break;
   	case EXT_START_CODE:
	    vldNextStartCode(instance, &data);
	    break;

        default:
            error("invalid start code");

⌨️ 快捷键说明

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