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 ; } } }
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; }