예제 #1
0
static void parseArgs( int &argc, char const **argv )
{
        for ( unsigned arg = 1 ; arg < argc ; arg++ ) {
                if ( '-' == *argv[arg] ) {
                        char const *param = argv[arg]+1 ;
                        char const cmdchar = tolower(*param);
                        if ( 'i' == cmdchar ) {
                            inFile = param+1 ;
                            printf( "input file is <%s>\n", inFile );
                        }
                        else if ( 'o' == cmdchar ) {
                                char const second = tolower(param[1]);
                                if ('w' == second) {
                                        outw = strtoul(param+2,0,0);
                                }
                                else if ('h'==second) {
                                        outh = strtoul(param+2,0,0);
                                }
                                else
                                        printf( "unknown output option %c\n",second);
                        }
                        else if ( 'x' == cmdchar ) {
                                x = strtoul(param+1,0,0);
                        }
                        else if ( 'y' == cmdchar ) {
                                y = strtoul(param+1,0,0);
                        }
                        else if (('a' == cmdchar)||('t' == cmdchar)) {
                                alpha  = strtoul(param+1,0,0);
                        }
                        else if ( 'f' == cmdchar ) {
                                unsigned fcc ; 
                                if(supported_fourcc(param+1,fcc)){
                                    format = fcc ;
                                } else {
                                    fprintf(stderr, "Invalid format %s\n", param+1 );
                                    fprintf(stderr, "supported formats include:\n" );
                                    unsigned const *formats ; unsigned num_formats ;
                                    supported_fourcc_formats(formats,num_formats);
                                    while( num_formats-- ){
                                        fprintf(stderr, "\t%s\n", fourcc_str(*formats));
                                        formats++ ;
                                    }
                                    exit(1);
                                }
                        }
                        else
                                printf( "unknown option %s\n", param );

                        // pull from argument list
                        for ( int j = arg+1 ; j < argc ; j++ ) {
                                argv[j-1] = argv[j];
                        }
                        --arg ;
                        --argc ;
                }
        }
}
예제 #2
0
void video_hw_init(void *lcdbase)
{
	int ret;
	unsigned int div = 0, best = 0, pix_clk;
	u32 frac1;
	const unsigned long lcd_clk = 480000000;
	u32 lcd_ctrl = LCD_CTRL_DEFAULT | LCDIF_CTRL_RUN;
	u32 lcd_ctrl1 = LCD_CTRL1_DEFAULT, lcd_ctrl2 = LCD_CTRL2_DEFAULT;
	u32 lcd_vdctrl0 = LCD_VDCTRL0_DEFAULT;
	u32 lcd_vdctrl1 = LCD_VDCTRL1_DEFAULT;
	u32 lcd_vdctrl2 = LCD_VDCTRL2_DEFAULT;
	u32 lcd_vdctrl3 = LCD_VDCTRL3_DEFAULT;
	u32 lcd_vdctrl4 = LCD_VDCTRL4_DEFAULT;
	struct mxs_clkctrl_regs *clk_regs = (void *)MXS_CLKCTRL_BASE;
	char buf1[16], buf2[16];

	/* pixel format in memory */
	switch (color_depth) {
	case 8:
		lcd_ctrl |= LCDIF_CTRL_WORD_LENGTH_8BIT;
		lcd_ctrl1 |= LCDIF_CTRL1_BYTE_PACKING_FORMAT(1);
		break;

	case 16:
		lcd_ctrl |= LCDIF_CTRL_WORD_LENGTH_16BIT;
		lcd_ctrl1 |= LCDIF_CTRL1_BYTE_PACKING_FORMAT(3);
		break;

	case 18:
		lcd_ctrl |= LCDIF_CTRL_WORD_LENGTH_18BIT;
		lcd_ctrl1 |= LCDIF_CTRL1_BYTE_PACKING_FORMAT(7);
		break;

	case 24:
		lcd_ctrl |= LCDIF_CTRL_WORD_LENGTH_24BIT;
		lcd_ctrl1 |= LCDIF_CTRL1_BYTE_PACKING_FORMAT(7);
		break;

	default:
		printf("Invalid bpp: %d\n", color_depth);
		return;
	}

	/* pixel format on the LCD data pins */
	switch (pix_fmt) {
	case PIX_FMT_RGB332:
		lcd_ctrl |= LCDIF_CTRL_LCD_DATABUS_WIDTH_8BIT;
		break;

	case PIX_FMT_RGB565:
		lcd_ctrl |= LCDIF_CTRL_LCD_DATABUS_WIDTH_16BIT;
		break;

	case PIX_FMT_BGR666:
		lcd_ctrl |= 1 << LCDIF_CTRL_INPUT_DATA_SWIZZLE_OFFSET;
		/* fallthru */
	case PIX_FMT_RGB666:
		lcd_ctrl |= LCDIF_CTRL_LCD_DATABUS_WIDTH_18BIT;
		break;

	case PIX_FMT_BGR24:
		lcd_ctrl |= 1 << LCDIF_CTRL_INPUT_DATA_SWIZZLE_OFFSET;
		/* fallthru */
	case PIX_FMT_RGB24:
		lcd_ctrl |= LCDIF_CTRL_LCD_DATABUS_WIDTH_24BIT;
		break;

	default:
		printf("Invalid pixel format: %c%c%c%c\n", fourcc_str(pix_fmt));
		return;
	}

	pix_clk = PICOS2KHZ(mxsfb_var.pixclock);
	debug("designated pix_clk: %sMHz\n", strmhz(buf1, pix_clk * 1000));

	for (frac1 = 18; frac1 < 36; frac1++) {
		static unsigned int err = ~0;
		unsigned long clk = lcd_clk / 1000 * 18 / frac1;
		unsigned int d = (clk + pix_clk - 1) / pix_clk;
		unsigned int diff = abs(clk / d - pix_clk);

		debug("frac1=%u div=%u lcd_clk=%-8sMHz pix_clk=%-8sMHz diff=%u err=%u\n",
			frac1, d, strmhz(buf1, clk * 1000), strmhz(buf2, clk * 1000 / d),
			diff, err);

		if (clk < pix_clk)
			break;
		if (d > 255)
			continue;

		if (diff < err) {
			best = frac1;
			div = d;
			err = diff;
			if (err == 0)
				break;
		}
	}
	if (div == 0) {
		printf("Requested pixel clock %sMHz out of range\n",
			strmhz(buf1, pix_clk * 1000));
		return;
	}

	debug("div=%lu(%u*%u/18) for pixel clock %sMHz with base clock %sMHz\n",
		lcd_clk / pix_clk / 1000, best, div,
		strmhz(buf1, lcd_clk / div * 18 / best),
		strmhz(buf2, lcd_clk));

	frac1 = (readl(&clk_regs->hw_clkctrl_frac1_reg) & ~0xff) | best;
	writel(frac1, &clk_regs->hw_clkctrl_frac1_reg);
	writel(1 << 14, &clk_regs->hw_clkctrl_clkseq_clr);

	/* enable LCD clk and fractional divider */
	writel(div, &clk_regs->hw_clkctrl_lcdif_reg);
	while (readl(&clk_regs->hw_clkctrl_lcdif_reg) & (1 << 29))
		;

	ret = mxs_reset_block(&lcd_regs->hw_lcdif_ctrl_reg);
	if (ret) {
		printf("Failed to reset LCD controller: LCDIF_CTRL: %08x CLKCTRL_LCDIF: %08x\n",
			readl(&lcd_regs->hw_lcdif_ctrl_reg),
			readl(&clk_regs->hw_clkctrl_lcdif_reg));
		return;
	}

	if (mxsfb_var.sync & FB_SYNC_HOR_HIGH_ACT)
		lcd_vdctrl0 |= LCDIF_VDCTRL0_HSYNC_POL;

	if (mxsfb_var.sync & FB_SYNC_VERT_HIGH_ACT)
		lcd_vdctrl0 |= LCDIF_VDCTRL0_HSYNC_POL;

	if (mxsfb_var.sync & FB_SYNC_DATA_ENABLE_HIGH_ACT)
		lcd_vdctrl0 |= LCDIF_VDCTRL0_ENABLE_POL;

	if (mxsfb_var.sync & FB_SYNC_DOTCLK_FALLING_ACT)
		lcd_vdctrl0 |= LCDIF_VDCTRL0_DOTCLK_POL;

	lcd_vdctrl0 |= LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH(mxsfb_var.vsync_len);
	lcd_vdctrl1 |= LCDIF_VDCTRL1_VSYNC_PERIOD(mxsfb_var.vsync_len +
						mxsfb_var.upper_margin +
						mxsfb_var.lower_margin +
						mxsfb_var.yres);
	lcd_vdctrl2 |= LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH(mxsfb_var.hsync_len);
	lcd_vdctrl2 |= LCDIF_VDCTRL2_HSYNC_PERIOD(mxsfb_var.hsync_len +
						mxsfb_var.left_margin +
						mxsfb_var.right_margin +
						mxsfb_var.xres);

	lcd_vdctrl3 |= LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT(mxsfb_var.left_margin +
							mxsfb_var.hsync_len);
	lcd_vdctrl3 |= LCDIF_VDCTRL3_VERTICAL_WAIT_CNT(mxsfb_var.upper_margin +
							mxsfb_var.vsync_len);

	lcd_vdctrl4 |= LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT(mxsfb_var.xres);

	writel((u32)lcdbase, &lcd_regs->hw_lcdif_next_buf_reg);
	writel(LCDIF_TRANSFER_COUNT_H_COUNT(mxsfb_var.xres) |
		LCDIF_TRANSFER_COUNT_V_COUNT(mxsfb_var.yres),
		&lcd_regs->hw_lcdif_transfer_count_reg);

	writel(lcd_vdctrl0, &lcd_regs->hw_lcdif_vdctrl0_reg);
	writel(lcd_vdctrl1, &lcd_regs->hw_lcdif_vdctrl1_reg);
	writel(lcd_vdctrl2, &lcd_regs->hw_lcdif_vdctrl2_reg);
	writel(lcd_vdctrl3, &lcd_regs->hw_lcdif_vdctrl3_reg);
	writel(lcd_vdctrl4, &lcd_regs->hw_lcdif_vdctrl4_reg);

	writel(lcd_ctrl1, &lcd_regs->hw_lcdif_ctrl1_reg);
	writel(lcd_ctrl2, &lcd_regs->hw_lcdif_ctrl2_reg);

	writel(lcd_ctrl, &lcd_regs->hw_lcdif_ctrl_reg);

	debug("mxsfb framebuffer driver initialized\n");
}
bool PrivateDecoderCrystalHD::Init(const QString &decoder,
                                   PlayerFlags flags,
                                   AVCodecContext *avctx)
{
    if ((decoder != "crystalhd") || !(flags & kDecodeAllowEXT) ||
        !avctx || getenv("NO_CRYSTALHD"))
        return false;

    static bool debugged = false;

    uint32_t well_documented = DTS_PLAYBACK_MODE | DTS_LOAD_FILE_PLAY_FW |
                               DTS_SKIP_TX_CHK_CPB |
                               DTS_PLAYBACK_DROP_RPT_MODE |
                               DTS_DFLT_RESOLUTION(vdecRESOLUTION_CUSTOM);
    INIT_ST;
    st = DtsDeviceOpen(&m_device, well_documented);
    CHECK_ST;
    if (!ok)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to open CrystalHD device");
        return false;
    }

    _BC_INFO_CRYSTAL_ info;
    st = DtsCrystalHDVersion(m_device, &info);
    CHECK_ST;
    if (!ok)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to get device info.");
        return false;
    }

    m_device_type = (BC_DEVICE_TYPE)info.device;

    if (!debugged)
    {
        LOG(VB_GENERAL, LOG_INFO, LOC + QString("Device: %1")
                .arg(device_to_string(m_device_type)));
        LOG(VB_GENERAL, LOG_INFO, LOC + QString("Library : %1.%2.%3")
                .arg(info.dilVersion.dilMajor)
                .arg(info.dilVersion.dilMinor)
                .arg(info.dilVersion.version));
        LOG(VB_GENERAL, LOG_INFO, LOC + QString("Driver  : %1.%2.%3")
                .arg(info.drvVersion.drvMajor)
                .arg(info.drvVersion.drvMinor)
                .arg(info.drvVersion.version));
        LOG(VB_GENERAL, LOG_INFO, LOC + QString("Firmware: %1.%2.%3")
                .arg(info.fwVersion.fwMajor)
                .arg(info.fwVersion.fwMinor)
                .arg(info.fwVersion.version));
    }

    if (BC_70012 == m_device_type)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC +
            "BCM70012 device is currently unsupported.");
        return false;
    }

    BC_HW_CAPS hw_caps;
    uint32_t codecs;
    st = DtsGetCapabilities(m_device, &hw_caps);
    CHECK_ST;
    if (!ok)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to get device capabilities");
        return false;
    }

    BC_OUTPUT_FORMAT m_desired_fmt = (m_device_type == BC_70015) ?
                                     OUTPUT_MODE422_YUY2 : OUTPUT_MODE420;
    m_pix_fmt = OUTPUT_MODE_INVALID;
    for (int i = 0; i < hw_caps.ColorCaps.Count; i++)
    {
        if (m_desired_fmt == hw_caps.ColorCaps.OutFmt[i])
            m_pix_fmt = m_desired_fmt;
        if (!debugged)
        {
            LOG(VB_PLAYBACK, LOG_INFO, LOC +
                QString("Supported output format: %1")
                    .arg(bcmpixfmt_to_string(hw_caps.ColorCaps.OutFmt[i])));
        }
    }
    if (m_pix_fmt != m_desired_fmt)
    {
        LOG(VB_PLAYBACK, LOG_ERR, LOC +
            "Failed to find correct output format.");
        return false;
    }
    LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Using: %1")
            .arg(bcmpixfmt_to_string(m_pix_fmt)));

    codecs = hw_caps.DecCaps;
    if (!debugged)
    {
        LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("H.264 support: %1")
                .arg((bool)(codecs & BC_DEC_FLAGS_H264)));
        LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("MPEG2 support: %1")
                .arg((bool)(codecs & BC_DEC_FLAGS_MPEG2)));
        LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("VC1   support: %1")
                .arg((bool)(codecs & BC_DEC_FLAGS_VC1)));
        LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("MPEG4 support: %1")
                .arg((bool)(codecs & BC_DEC_FLAGS_M4P2)));
        debugged = true;
    }

    BC_MEDIA_SUBTYPE sub_type = BC_MSUBTYPE_INVALID;

    switch (avctx->codec_id)
    {
        case AV_CODEC_ID_MPEG4:
            if (codecs & BC_DEC_FLAGS_M4P2)
                sub_type = BC_MSUBTYPE_DIVX;
            break;
        case AV_CODEC_ID_MPEG1VIDEO:
            if (codecs & BC_DEC_FLAGS_MPEG2)
                sub_type = BC_MSUBTYPE_MPEG1VIDEO;
            break;
        case AV_CODEC_ID_MPEG2VIDEO:
            if (codecs & BC_DEC_FLAGS_MPEG2)
                sub_type = BC_MSUBTYPE_MPEG2VIDEO;
            break;
        case AV_CODEC_ID_VC1:
            if (codecs & BC_DEC_FLAGS_VC1)
            {
                if (avctx->codec_tag == MKTAG('W','V','C','1'))
                    sub_type = BC_MSUBTYPE_WVC1;
                else
                    sub_type = BC_MSUBTYPE_VC1;
            }
            break;
        case AV_CODEC_ID_WMV3:
            if (codecs & BC_DEC_FLAGS_VC1)
                sub_type = BC_MSUBTYPE_WMV3;
            break;
        case AV_CODEC_ID_H264:
            if (codecs & BC_DEC_FLAGS_H264)
            {
                if (avctx->extradata[0] == 0x01)
                {
                    if (!CreateFilter(avctx))
                    {
                        LOG(VB_PLAYBACK, LOG_ERR, LOC +
                            "Failed to create stream filter");
                        return false;
                    }
                    sub_type = BC_MSUBTYPE_AVC1;
                }
                else
                    sub_type = BC_MSUBTYPE_H264;
            }
            break;
    }

    if (sub_type == BC_MSUBTYPE_INVALID)
    {
        LOG(VB_PLAYBACK, LOG_ERR, LOC + QString("Codec %1 not supported")
                .arg(ff_codec_id_string(avctx->codec_id)));
        return false;
    }

    int nalsize = 4;
    if (avctx->codec_id == AV_CODEC_ID_H264)
    {
        LOG(VB_PLAYBACK, LOG_INFO, LOC +
            QString("H.264 Profile: %1 RefFrames: %2 Codec tag: %3")
                .arg(avctx->profile).arg(avctx->refs)
                .arg(fourcc_str(avctx->codec_tag)));
        if (avctx->extradata[0] == 1)
        {
            nalsize = (avctx->extradata[4] & 0x03) + 1;
            LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("avcC nal size: %1")
                    .arg(nalsize));
        }
    }

    BC_INPUT_FORMAT fmt;
    memset(&fmt, 0, sizeof(BC_INPUT_FORMAT));
    fmt.OptFlags       = 0x80000000 | vdecFrameRateUnknown;
    fmt.width          = avctx->coded_width;
    fmt.height         = avctx->coded_height;
    fmt.Progressive    = 1;
    fmt.FGTEnable      = 0;
    fmt.MetaDataEnable = 0;
    fmt.metaDataSz     = avctx->extradata_size;
    fmt.pMetaData      = avctx->extradata;
    fmt.startCodeSz    = nalsize;
    fmt.mSubtype       = sub_type;

    st = DtsSetInputFormat(m_device, &fmt);
    CHECK_ST;
    if (!ok)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to set decoder input format");
        return false;
    }

    st = DtsOpenDecoder(m_device, BC_STREAM_TYPE_ES);
    CHECK_ST;
    if (!ok)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to open CrystalHD decoder");
        return false;
    }

    st = DtsSetColorSpace(m_device, m_pix_fmt);
    if (!ok)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to set decoder output format");
        return false;
    }

    st = DtsStartDecoder(m_device);
    if (!ok)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to start decoder");
        return false;
    }

    st = DtsStartCapture(m_device);
    if (!ok)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to start capture");
        return false;
    }

    Reset();

    LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Created decoder %1 %2x%3")
        .arg(ff_codec_id_string(avctx->codec_id))
        .arg(avctx->coded_width).arg(avctx->coded_height));
    return true;
}