long do_rt_sigreturn(CPUState *env) { struct rt_sigframe *frame; sigset_t host_set; /* * Since we stacked the signal on a 64-bit boundary, * then 'sp' should be word aligned here. If it's * not, then the user is trying to mess with us. */ if (env->regs[13] & 7) goto badframe; frame = (struct rt_sigframe *)env->regs[13]; #if 0 if (verify_area(VERIFY_READ, frame, sizeof (*frame))) goto badframe; #endif target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask); sigprocmask(SIG_SETMASK, &host_set, NULL); if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) goto badframe; if (do_sigaltstack(h2g(&frame->uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT) goto badframe; #if 0 /* Send SIGTRAP if we're single-stepping */ if (ptrace_cancel_bpt(current)) send_sig(SIGTRAP, current, 1); #endif return env->regs[0]; badframe: force_sig(SIGSEGV /* , current */); return 0; }


static PCIDevice *find_dev(sPAPREnvironment *spapr, uint64_t buid, uint32_t config_addr) { sPAPRPHBState *sphb = find_phb(spapr, buid); PCIHostState *phb = PCI_HOST_BRIDGE(sphb); int bus_num = (config_addr >> 16) & 0xFF; int devfn = (config_addr >> 8) & 0xFF; if (!phb) { return NULL; } return pci_find_device(phb->bus, bus_num, devfn); }


void *pci_assign_dev_load_option_rom(PCIDevice *dev, struct Object *owner, int *size, unsigned int domain, unsigned int bus, unsigned int slot, unsigned int function) { char name[32], rom_file[64]; FILE *fp; uint8_t val; struct stat st; void *ptr = NULL; /* If loading ROM from file, pci handles it */ if (dev->romfile || !dev->rom_bar) { return NULL; } snprintf(rom_file, sizeof(rom_file), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/rom", domain, bus, slot, function); if (stat(rom_file, &st)) { if (errno != ENOENT) { error_report("pci-assign: Invalid ROM."); } return NULL; } /* Write "1" to the ROM file to enable it */ fp = fopen(rom_file, "r+"); if (fp == NULL) { error_report("pci-assign: Cannot open %s: %s", rom_file, strerror(errno)); return NULL; } val = 1; if (fwrite(&val, 1, 1, fp) != 1) { goto close_rom; } fseek(fp, 0, SEEK_SET); snprintf(name, sizeof(name), "%s.rom", object_get_typename(owner)); memory_region_init_ram(&dev->rom, owner, name, st.st_size, &error_abort); vmstate_register_ram(&dev->rom, &dev->qdev); ptr = memory_region_get_ram_ptr(&dev->rom); memset(ptr, 0xff, st.st_size); if (!fread(ptr, 1, st.st_size, fp)) { error_report("pci-assign: Cannot read from host %s", rom_file); error_printf("Device option ROM contents are probably invalid " "(check dmesg).\nSkip option ROM probe with rombar=0, " "or load from file with romfile=\n"); goto close_rom; } pci_register_bar(dev, PCI_ROM_SLOT, 0, &dev->rom); dev->has_rom = true; *size = st.st_size; close_rom: /* Write "0" to disable ROM */ fseek(fp, 0, SEEK_SET); val = 0; if (!fwrite(&val, 1, 1, fp)) { DEBUG("%s\n", "Failed to disable pci-sysfs rom file"); } fclose(fp); return ptr; }


void cpu_unregister_map_client(void *_client) { MapClient *client = (MapClient *)_client; LIST_REMOVE(client, link); qemu_free(client); }


static inline void gen_intermediate_code_internal(PowerPCCPU *cpu, TranslationBlock *tb, bool search_pc) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; DisasContext ctx, *ctxp = &ctx; opc_handler_t **table, *handler; target_ulong pc_start; uint16_t *gen_opc_end; CPUBreakpoint *bp; int j, lj = -1; int num_insns; int max_insns; pc_start = tb->pc; gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; ctx.nip = pc_start; ctx.tb = tb; ctx.exception = POWERPC_EXCP_NONE; ctx.spr_cb = env->spr_cb; ctx.pr = msr_pr; ctx.hv = !msr_pr && msr_hv; ctx.mem_idx = env->mmu_idx; ctx.insns_flags = env->insns_flags; ctx.insns_flags2 = env->insns_flags2; ctx.access_type = -1; ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0; ctx.default_tcg_memop_mask = ctx.le_mode ? MO_LE : MO_BE; #if defined(TARGET_PPC64) ctx.sf_mode = msr_is_64bit(env, env->msr); ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR); #endif ctx.fpu_enabled = msr_fp; if ((env->flags & POWERPC_FLAG_SPE) && msr_spe) ctx.spe_enabled = msr_spe; else ctx.spe_enabled = 0; if ((env->flags & POWERPC_FLAG_VRE) && msr_vr) ctx.altivec_enabled = msr_vr; else ctx.altivec_enabled = 0; if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) { ctx.vsx_enabled = msr_vsx; } else { ctx.vsx_enabled = 0; } if ((env->flags & POWERPC_FLAG_SE) && msr_se) ctx.singlestep_enabled = CPU_SINGLE_STEP; else ctx.singlestep_enabled = 0; if ((env->flags & POWERPC_FLAG_BE) && msr_be) ctx.singlestep_enabled |= CPU_BRANCH_STEP; if (unlikely(cs->singlestep_enabled)) { ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP; } #if defined (DO_SINGLE_STEP) && 0 /* Single step trace mode */ msr_se = 1; #endif num_insns = 0; max_insns = tb->cflags & CF_COUNT_MASK; if (max_insns == 0) max_insns = CF_COUNT_MASK; gen_tb_start(); tcg_clear_temp_count(); /* Set env in case of segfault during code fetch */ while (ctx.exception == POWERPC_EXCP_NONE && tcg_ctx.gen_opc_ptr < gen_opc_end) { if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) { QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { if (bp->pc == ctx.nip) { gen_debug_exception(ctxp); break; } } } if (unlikely(search_pc)) { j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf; if (lj < j) { lj++; while (lj < j) tcg_ctx.gen_opc_instr_start[lj++] = 0; } tcg_ctx.gen_opc_pc[lj] = ctx.nip; tcg_ctx.gen_opc_instr_start[lj] = 1; tcg_ctx.gen_opc_icount[lj] = num_insns; } LOG_DISAS("----------------\n"); LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n", ctx.nip, ctx.mem_idx, (int)msr_ir); if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) gen_io_start(); if (unlikely(need_byteswap(&ctx))) { ctx.opcode = bswap32(cpu_ldl_code(env, ctx.nip)); } else { ctx.opcode = cpu_ldl_code(env, ctx.nip); } LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n", ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode), ctx.le_mode ? "little" : "big"); if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) { tcg_gen_debug_insn_start(ctx.nip); } ctx.nip += 4; table = env->opcodes; num_insns++; handler = table[opc1(ctx.opcode)]; if (is_indirect_opcode(handler)) { table = ind_table(handler); handler = table[opc2(ctx.opcode)]; if (is_indirect_opcode(handler)) { table = ind_table(handler); handler = table[opc3(ctx.opcode)]; } } /* Is opcode *REALLY* valid ? */ if (unlikely(handler->handler == &gen_invalid)) { if (qemu_log_enabled()) { qemu_log("invalid/unsupported opcode: " "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n", opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir); } } else { uint32_t inval; if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) && Rc(ctx.opcode))) { inval = handler->inval2; } else { inval = handler->inval1; } if (unlikely((ctx.opcode & inval) != 0)) { if (qemu_log_enabled()) { qemu_log("invalid bits: %08x for opcode: " "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n", ctx.opcode & inval, opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode), ctx.opcode, ctx.nip - 4); } gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL); break; } } (*(handler->handler))(&ctx); #if defined(DO_PPC_STATISTICS) handler->count++; #endif /* Check trace mode exceptions */ if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP && (ctx.nip <= 0x100 || ctx.nip > 0xF00) && ctx.exception != POWERPC_SYSCALL && ctx.exception != POWERPC_EXCP_TRAP && ctx.exception != POWERPC_EXCP_BRANCH)) { gen_exception(ctxp, POWERPC_EXCP_TRACE); } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) || (cs->singlestep_enabled) || singlestep || num_insns >= max_insns)) { /* if we reach a page boundary or are single stepping, stop * generation */ break; } if (tcg_check_temp_count()) { fprintf(stderr, "Opcode %02x %02x %02x (%08x) leaked temporaries\n", opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode), ctx.opcode); exit(1); } } if (tb->cflags & CF_LAST_IO) gen_io_end(); if (ctx.exception == POWERPC_EXCP_NONE) { gen_goto_tb(&ctx, 0, ctx.nip); } else if (ctx.exception != POWERPC_EXCP_BRANCH) { if (unlikely(cs->singlestep_enabled)) { gen_debug_exception(ctxp); } /* Generate the return instruction */ tcg_gen_exit_tb(0); } gen_tb_end(tb, num_insns); *tcg_ctx.gen_opc_ptr = INDEX_op_end; if (unlikely(search_pc)) { j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf; lj++; while (lj <= j) tcg_ctx.gen_opc_instr_start[lj++] = 0; } else { tb->size = ctx.nip - pc_start; tb->icount = num_insns; } #if defined(DEBUG_DISAS) if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { int flags; flags = env->bfd_mach; flags |= ctx.le_mode << 16; qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(env, pc_start, ctx.nip - pc_start, flags); qemu_log("\n"); } #endif }


static void dma_aio_cancel(BlockDriverAIOCB *acb) { DMAAIOCB *dbs = container_of(acb, DMAAIOCB, common); if (dbs->acb) { bdrv_aio_cancel(dbs->acb); } }


int32_t idiv32(int32_t *q_ptr, int64_t num, int32_t den) { *q_ptr = num / den; return num % den; }


void qmp_nbd_server_add(const char *device, bool has_writable, bool writable, Error **errp) { BlockDriverState *bs; NBDExport *exp; NBDCloseNotifier *n; if (server_fd == -1) { error_setg(errp, "NBD server not running"); return; } if (nbd_export_find(device)) { error_setg(errp, "NBD server already exporting device '%s'", device); return; } bs = bdrv_find(device); if (!bs) { error_set(errp, QERR_DEVICE_NOT_FOUND, device); return; } if (!bdrv_is_inserted(bs)) { error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device); return; } if (!has_writable) { writable = false; } if (bdrv_is_read_only(bs)) { writable = false; } exp = nbd_export_new(bs, 0, -1, writable ? 0 : NBD_FLAG_READ_ONLY, NULL); nbd_export_set_name(exp, device); n = g_malloc0(sizeof(NBDCloseNotifier)); n->n.notify = nbd_close_notifier; n->exp = exp; bdrv_add_close_notifier(bs, &n->n); QTAILQ_INSERT_TAIL(&close_notifiers, n, next); }


static void xbr3x(AVFrame *input, AVFrame *output, const uint32_t *r2y) { const int nl = output->linesize[0]>>2; const int nl1 = nl + nl; uint32_t pprev; uint32_t pprev2; int x,y; for (y = 0; y < input->height; y++) { uint32_t * E = (uint32_t *)(output->data[0] + y * output->linesize[0] * 3); /* middle. Offset of -8 is given */ uint32_t * sa2 = (uint32_t *)(input->data[0] + y * input->linesize[0] - 8); /* up one */ uint32_t * sa1 = sa2 - (input->linesize[0]>>2); /* up two */ uint32_t * sa0 = sa1 - (input->linesize[0]>>2); /* down one */ uint32_t * sa3 = sa2 + (input->linesize[0]>>2); /* down two */ uint32_t * sa4 = sa3 + (input->linesize[0]>>2); if (y <= 1){ sa0 = sa1; if (y == 0){ sa0 = sa1 = sa2; } } if (y >= input->height - 2){ sa4 = sa3; if (y == input->height - 1){ sa4 = sa3 = sa2; } } pprev = pprev2 = 2; for (x = 0; x < input->width; x++){ uint32_t B1 = sa0[2]; uint32_t PB = sa1[2]; uint32_t PE = sa2[2]; uint32_t PH = sa3[2]; uint32_t H5 = sa4[2]; uint32_t A1 = sa0[pprev]; uint32_t PA = sa1[pprev]; uint32_t PD = sa2[pprev]; uint32_t PG = sa3[pprev]; uint32_t G5 = sa4[pprev]; uint32_t A0 = sa1[pprev2]; uint32_t D0 = sa2[pprev2]; uint32_t G0 = sa3[pprev2]; uint32_t C1 = 0; uint32_t PC = 0; uint32_t PF = 0; uint32_t PI = 0; uint32_t I5 = 0; uint32_t C4 = 0; uint32_t F4 = 0; uint32_t I4 = 0; if (x >= input->width - 2){ if (x == input->width - 1){ C1 = sa0[2]; PC = sa1[2]; PF = sa2[2]; PI = sa3[2]; I5 = sa4[2]; C4 = sa1[2]; F4 = sa2[2]; I4 = sa3[2]; } else { C1 = sa0[3]; PC = sa1[3]; PF = sa2[3]; PI = sa3[3]; I5 = sa4[3]; C4 = sa1[3]; F4 = sa2[3]; I4 = sa3[3]; } } else { C1 = sa0[3]; PC = sa1[3]; PF = sa2[3]; PI = sa3[3]; I5 = sa4[3]; C4 = sa1[4]; F4 = sa2[4]; I4 = sa3[4]; } E[0] = E[1] = E[2] = PE; E[nl] = E[nl+1] = E[nl+2] = PE; // 3, 4, 5 E[nl1] = E[nl1+1] = E[nl1+2] = PE; // 6, 7, 8 FILT3(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, 0, 1, 2, nl, nl+1, nl+2, nl1, nl1+1, nl1+2); FILT3(PE, PC, PF, PB, PI, PA, PH, PD, PG, I4, A1, I5, H5, A0, D0, B1, C1, F4, C4, G5, G0, nl1, nl, 0, nl1+1, nl+1, 1, nl1+2, nl+2, 2); FILT3(PE, PA, PB, PD, PC, PG, PF, PH, PI, C1, G0, C4, F4, G5, H5, D0, A0, B1, A1, I4, I5, nl1+2, nl1+1, nl1, nl+2, nl+1, nl, 2, 1, 0); FILT3(PE, PG, PD, PH, PA, PI, PB, PF, PC, A0, I5, A1, B1, I4, F4, H5, G5, D0, G0, C1, C4, 2, nl+2, nl1+2, 1, nl+1, nl1+1, 0, nl, nl1); sa0 += 1; sa1 += 1; sa2 += 1; sa3 += 1; sa4 += 1; E += 3; if (pprev2){ pprev2--; pprev = 1; } } } }


qio_channel_websock_source_prepare(GSource *source, gint *timeout) { QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source; GIOCondition cond = 0; *timeout = -1; if (wsource->wioc->rawinput.offset) { cond |= G_IO_IN; } if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) { cond |= G_IO_OUT; } return cond & wsource->condition; }


static uint_fast8_t vorbis_floor1_decode(vorbis_context *vc, vorbis_floor_data *vfu, float *vec) { vorbis_floor1 *vf = &vfu->t1; GetBitContext *gb = &vc->gb; uint_fast16_t range_v[4] = { 256, 128, 86, 64 }; uint_fast16_t range = range_v[vf->multiplier-1]; uint_fast16_t floor1_Y[258]; uint_fast16_t floor1_Y_final[258]; int floor1_flag[258]; uint_fast8_t class_; uint_fast8_t cdim; uint_fast8_t cbits; uint_fast8_t csub; uint_fast8_t cval; int_fast16_t book; uint_fast16_t offset; uint_fast16_t i,j; /*u*/int_fast16_t adx, ady, off, predicted; // WTF ? dy/adx = (unsigned)dy/adx ? int_fast16_t dy, err; if (!get_bits1(gb)) // silence return 1; // Read values (or differences) for the floor's points floor1_Y[0] = get_bits(gb, ilog(range - 1)); floor1_Y[1] = get_bits(gb, ilog(range - 1)); AV_DEBUG("floor 0 Y %d floor 1 Y %d \n", floor1_Y[0], floor1_Y[1]); offset = 2; for (i = 0; i < vf->partitions; ++i) { class_ = vf->partition_class[i]; cdim = vf->class_dimensions[class_]; cbits = vf->class_subclasses[class_]; csub = (1 << cbits) - 1; cval = 0; AV_DEBUG("Cbits %d \n", cbits); if (cbits) // this reads all subclasses for this partition's class cval = get_vlc2(gb, vc->codebooks[vf->class_masterbook[class_]].vlc.table, vc->codebooks[vf->class_masterbook[class_]].nb_bits, 3); for (j = 0; j < cdim; ++j) { book = vf->subclass_books[class_][cval & csub]; AV_DEBUG("book %d Cbits %d cval %d bits:%d \n", book, cbits, cval, get_bits_count(gb)); cval = cval >> cbits; if (book > -1) { floor1_Y[offset+j] = get_vlc2(gb, vc->codebooks[book].vlc.table, vc->codebooks[book].nb_bits, 3); } else { floor1_Y[offset+j] = 0; } AV_DEBUG(" floor(%d) = %d \n", vf->list[offset+j].x, floor1_Y[offset+j]); } offset+=cdim; } // Amplitude calculation from the differences floor1_flag[0] = 1; floor1_flag[1] = 1; floor1_Y_final[0] = floor1_Y[0]; floor1_Y_final[1] = floor1_Y[1]; for (i = 2; i < vf->x_list_dim; ++i) { uint_fast16_t val, highroom, lowroom, room; uint_fast16_t high_neigh_offs; uint_fast16_t low_neigh_offs; low_neigh_offs = vf->list[i].low; high_neigh_offs = vf->list[i].high; dy = floor1_Y_final[high_neigh_offs] - floor1_Y_final[low_neigh_offs]; // render_point begin adx = vf->list[high_neigh_offs].x - vf->list[low_neigh_offs].x; ady = FFABS(dy); err = ady * (vf->list[i].x - vf->list[low_neigh_offs].x); off = (int16_t)err / (int16_t)adx; if (dy < 0) { predicted = floor1_Y_final[low_neigh_offs] - off; } else { predicted = floor1_Y_final[low_neigh_offs] + off; } // render_point end val = floor1_Y[i]; highroom = range-predicted; lowroom = predicted; if (highroom < lowroom) { room = highroom * 2; } else { room = lowroom * 2; // SPEC mispelling } if (val) { floor1_flag[low_neigh_offs] = 1; floor1_flag[high_neigh_offs] = 1; floor1_flag[i] = 1; if (val >= room) { if (highroom > lowroom) { floor1_Y_final[i] = val - lowroom + predicted; } else { floor1_Y_final[i] = predicted - val + highroom - 1; } } else { if (val & 1) { floor1_Y_final[i] = predicted - (val + 1) / 2; } else { floor1_Y_final[i] = predicted + val / 2; } } } else { floor1_flag[i] = 0; floor1_Y_final[i] = predicted; } AV_DEBUG(" Decoded floor(%d) = %d / val %d \n", vf->list[i].x, floor1_Y_final[i], val); } // Curve synth - connect the calculated dots and convert from dB scale FIXME optimize ? ff_vorbis_floor1_render_list(vf->list, vf->x_list_dim, floor1_Y_final, floor1_flag, vf->multiplier, vec, vf->list[1].x); AV_DEBUG(" Floor decoded\n"); return 0; }


static void qemu_add_data_dir(const char *path) { int i; if (path == NULL) { return; } if (data_dir_idx == ARRAY_SIZE(data_dir)) { return; } for (i = 0; i < data_dir_idx; i++) { if (strcmp(data_dir[i], path) == 0) { return; /* duplicate */ } } data_dir[data_dir_idx++] = path; }


void *ff_schro_queue_pop(FFSchroQueue *queue) { FFSchroQueueElement *top = queue->p_head; if (top) { void *data = top->data; queue->p_head = queue->p_head->next; --queue->size; av_freep(&top); return data; } return NULL; }


static void virtio_net_vhost_status(VirtIONet *n, uint8_t status) { VirtIODevice *vdev = VIRTIO_DEVICE(n); NetClientState *nc = qemu_get_queue(n->nic); int queues = n->multiqueue ? n->max_queues : 1; if (!get_vhost_net(nc->peer)) { return; } if ((virtio_net_started(n, status) && !nc->peer->link_down) == !!n->vhost_started) { return; } if (!n->vhost_started) { int r, i; if (!vhost_net_query(get_vhost_net(nc->peer), vdev)) { return; } /* Any packets outstanding? Purge them to avoid touching rings * when vhost is running. */ for (i = 0; i < queues; i++) { NetClientState *qnc = qemu_get_subqueue(n->nic, i); /* Purge both directions: TX and RX. */ qemu_net_queue_purge(qnc->peer->incoming_queue, qnc); qemu_net_queue_purge(qnc->incoming_queue, qnc->peer); } n->vhost_started = 1; r = vhost_net_start(vdev, n->nic->ncs, queues); if (r < 0) { error_report("unable to start vhost net: %d: " "falling back on userspace virtio", -r); n->vhost_started = 0; } } else { vhost_net_stop(vdev, n->nic->ncs, queues); n->vhost_started = 0; } }


static int evrc_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; AVFrame *frame = data; EVRCContext *e = avctx->priv_data; int buf_size = avpkt->size; float ilspf[FILTER_ORDER], ilpc[FILTER_ORDER], idelay[NB_SUBFRAMES]; float *samples; int i, j, ret, error_flag = 0; frame->nb_samples = 160; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; samples = (float *)frame->data[0]; if ((e->bitrate = determine_bitrate(avctx, &buf_size, &buf)) == RATE_ERRS) { warn_insufficient_frame_quality(avctx, "bitrate cannot be determined."); goto erasure; } if (e->bitrate <= SILENCE || e->bitrate == RATE_QUARTER) goto erasure; if (e->bitrate == RATE_QUANT && e->last_valid_bitrate == RATE_FULL && !e->prev_error_flag) goto erasure; init_get_bits(&e->gb, buf, 8 * buf_size); memset(&e->frame, 0, sizeof(EVRCAFrame)); unpack_frame(e); if (e->bitrate != RATE_QUANT) { uint8_t *p = (uint8_t *) &e->frame; for (i = 0; i < sizeof(EVRCAFrame); i++) { if (p[i]) break; } if (i == sizeof(EVRCAFrame)) goto erasure; } else if (e->frame.lsp[0] == 0xf && e->frame.lsp[1] == 0xf && e->frame.energy_gain == 0xff) { goto erasure; } if (decode_lspf(e) < 0) goto erasure; if (e->bitrate == RATE_FULL || e->bitrate == RATE_HALF) { /* Pitch delay parameter checking as per TIA/IS-127 5.1.5.1 */ if (e->frame.pitch_delay > MAX_DELAY - MIN_DELAY) goto erasure; e->pitch_delay = e->frame.pitch_delay + MIN_DELAY; /* Delay diff parameter checking as per TIA/IS-127 5.1.5.2 */ if (e->frame.delay_diff) { int p = e->pitch_delay - e->frame.delay_diff + 16; if (p < MIN_DELAY || p > MAX_DELAY) goto erasure; } /* Delay contour reconstruction as per TIA/IS-127 5.2.2.2 */ if (e->frame.delay_diff && e->bitrate == RATE_FULL && e->prev_error_flag) { float delay; memcpy(e->pitch, e->pitch_back, ACB_SIZE * sizeof(float)); delay = e->prev_pitch_delay; e->prev_pitch_delay = delay - e->frame.delay_diff + 16.0; if (fabs(e->pitch_delay - delay) > 15) delay = e->pitch_delay; for (i = 0; i < NB_SUBFRAMES; i++) { int subframe_size = subframe_sizes[i]; interpolate_delay(idelay, delay, e->prev_pitch_delay, i); acb_excitation(e, e->pitch + ACB_SIZE, e->avg_acb_gain, idelay, subframe_size); memcpy(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float)); } } /* Smoothing of the decoded delay as per TIA/IS-127 5.2.2.5 */ if (fabs(e->pitch_delay - e->prev_pitch_delay) > 15) e->prev_pitch_delay = e->pitch_delay; e->avg_acb_gain = e->avg_fcb_gain = 0.0; } else { idelay[0] = idelay[1] = idelay[2] = MIN_DELAY; /* Decode frame energy vectors as per TIA/IS-127 5.7.2 */ for (i = 0; i < NB_SUBFRAMES; i++) e->energy_vector[i] = pow(10, evrc_energy_quant[e->frame.energy_gain][i]); e->prev_energy_gain = e->frame.energy_gain; } for (i = 0; i < NB_SUBFRAMES; i++) { float tmp[SUBFRAME_SIZE + 6] = { 0 }; int subframe_size = subframe_sizes[i]; int pitch_lag; interpolate_lsp(ilspf, e->lspf, e->prev_lspf, i); if (e->bitrate != RATE_QUANT) interpolate_delay(idelay, e->pitch_delay, e->prev_pitch_delay, i); pitch_lag = lrintf((idelay[1] + idelay[0]) / 2.0); decode_predictor_coeffs(ilspf, ilpc); /* Bandwidth expansion as per TIA/IS-127 5.2.3.3 */ if (e->frame.lpc_flag && e->prev_error_flag) bandwidth_expansion(ilpc, ilpc, 0.75); if (e->bitrate != RATE_QUANT) { float acb_sum, f; f = exp((e->bitrate == RATE_HALF ? 0.5 : 0.25) * (e->frame.fcb_gain[i] + 1)); acb_sum = pitch_gain_vq[e->frame.acb_gain[i]]; e->avg_acb_gain += acb_sum / NB_SUBFRAMES; e->avg_fcb_gain += f / NB_SUBFRAMES; acb_excitation(e, e->pitch + ACB_SIZE, acb_sum, idelay, subframe_size); fcb_excitation(e, e->frame.fcb_shape[i], tmp, acb_sum, pitch_lag, subframe_size); /* Total excitation generation as per TIA/IS-127 5.2.3.9 */ for (j = 0; j < subframe_size; j++) e->pitch[ACB_SIZE + j] += f * tmp[j]; e->fade_scale = FFMIN(e->fade_scale + 0.2, 1.0); } else { for (j = 0; j < subframe_size; j++) e->pitch[ACB_SIZE + j] = e->energy_vector[i]; } memcpy(e->pitch, e->pitch + subframe_size, ACB_SIZE * sizeof(float)); synthesis_filter(e->pitch + ACB_SIZE, ilpc, e->synthesis, subframe_size, tmp); postfilter(e, tmp, ilpc, samples, pitch_lag, &postfilter_coeffs[e->bitrate], subframe_size); samples += subframe_size; } if (error_flag) { erasure: error_flag = 1; av_log(avctx, AV_LOG_WARNING, "frame erasure\n"); frame_erasure(e, samples); } memcpy(e->prev_lspf, e->lspf, sizeof(e->prev_lspf)); e->prev_error_flag = error_flag; e->last_valid_bitrate = e->bitrate; if (e->bitrate != RATE_QUANT) e->prev_pitch_delay = e->pitch_delay; samples = (float *)frame->data[0]; for (i = 0; i < 160; i++) samples[i] /= 32768; *got_frame_ptr = 1; return avpkt->size; }


static int _do_rematrixing(AC3DecodeContext *ctx, int start, int end) { float tmp0, tmp1; while (start < end) { tmp0 = ctx->samples[start]; tmp1 = (ctx->samples + 256)[start]; ctx->samples[start] = tmp0 + tmp1; (ctx->samples + 256)[start] = tmp0 - tmp1; start++; } return 0; }


const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys, const uint8_t* frame, unsigned buf_size) { int i; int dsf = (frame[3] & 0x80) >> 7; int stype = frame[80*5 + 48 + 3] & 0x1f; /* 576i50 25Mbps 4:1:1 is a special case */ if (dsf == 1 && stype == 0 && frame[4] & 0x07 /* the APT field */) { return &dv_profiles[2]; } for (i=0; i<FF_ARRAY_ELEMS(dv_profiles); i++) if (dsf == dv_profiles[i].dsf && stype == dv_profiles[i].video_stype) return &dv_profiles[i]; /* check if old sys matches and assumes corrupted input */ if (sys && buf_size == sys->frame_size) return sys; return NULL; }


static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, abi_ulong parent_tidptr, target_ulong newtls, abi_ulong child_tidptr) { int ret; TaskState *ts; uint8_t *new_stack; CPUState *new_env; #if defined(CONFIG_USE_NPTL) unsigned int nptl_flags; sigset_t sigmask; #endif /* Emulate vfork() with fork() */ if (flags & CLONE_VFORK) flags &= ~(CLONE_VFORK | CLONE_VM); if (flags & CLONE_VM) { TaskState *parent_ts = (TaskState *)env->opaque; #if defined(CONFIG_USE_NPTL) new_thread_info info; pthread_attr_t attr; #endif ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE); init_task_state(ts); new_stack = ts->stack; /* we create a new CPU instance. */ new_env = cpu_copy(env); #if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC) cpu_reset(new_env); #endif /* Init regs that differ from the parent. */ cpu_clone_regs(new_env, newsp); new_env->opaque = ts; ts->bprm = parent_ts->bprm; ts->info = parent_ts->info; #if defined(CONFIG_USE_NPTL) nptl_flags = flags; flags &= ~CLONE_NPTL_FLAGS2; if (nptl_flags & CLONE_CHILD_CLEARTID) { ts->child_tidptr = child_tidptr; } if (nptl_flags & CLONE_SETTLS) cpu_set_tls (new_env, newtls); /* Grab a mutex so that thread setup appears atomic. */ pthread_mutex_lock(&clone_lock); memset(&info, 0, sizeof(info)); pthread_mutex_init(&info.mutex, NULL); pthread_mutex_lock(&info.mutex); pthread_cond_init(&info.cond, NULL); info.env = new_env; if (nptl_flags & CLONE_CHILD_SETTID) info.child_tidptr = child_tidptr; if (nptl_flags & CLONE_PARENT_SETTID) info.parent_tidptr = parent_tidptr; ret = pthread_attr_init(&attr); ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE); /* It is not safe to deliver signals until the child has finished initializing, so temporarily block all signals. */ sigfillset(&sigmask); sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask); ret = pthread_create(&info.thread, &attr, clone_func, &info); /* TODO: Free new CPU state if thread creation failed. */ sigprocmask(SIG_SETMASK, &info.sigmask, NULL); pthread_attr_destroy(&attr); if (ret == 0) { /* Wait for the child to initialize. */ pthread_cond_wait(&info.cond, &info.mutex); ret = info.tid; if (flags & CLONE_PARENT_SETTID) put_user_u32(ret, parent_tidptr); } else { ret = -1; } pthread_mutex_unlock(&info.mutex); pthread_cond_destroy(&info.cond); pthread_mutex_destroy(&info.mutex); pthread_mutex_unlock(&clone_lock); #else if (flags & CLONE_NPTL_FLAGS2) return -EINVAL; /* This is probably going to die very quickly, but do it anyway. */ #ifdef __ia64__ ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env); #else ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); #endif #endif } else { /* if no CLONE_VM, we consider it is a fork */ if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) return -EINVAL; fork_start(); ret = fork(); if (ret == 0) { /* Child Process. */ cpu_clone_regs(env, newsp); fork_end(1); #if defined(CONFIG_USE_NPTL) /* There is a race condition here. The parent process could theoretically read the TID in the child process before the child tid is set. This would require using either ptrace (not implemented) or having *_tidptr to point at a shared memory mapping. We can't repeat the spinlock hack used above because the child process gets its own copy of the lock. */ if (flags & CLONE_CHILD_SETTID) put_user_u32(gettid(), child_tidptr); if (flags & CLONE_PARENT_SETTID) put_user_u32(gettid(), parent_tidptr); ts = (TaskState *)env->opaque; if (flags & CLONE_SETTLS) cpu_set_tls (env, newtls); if (flags & CLONE_CHILD_CLEARTID) ts->child_tidptr = child_tidptr; #endif } else { fork_end(0); } } return ret; }


static inline void decode(DisasContext *dc, uint32_t ir) { if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) { tcg_gen_debug_insn_start(dc->pc); } dc->ir = ir; LOG_DIS("%8.8x\t", dc->ir); /* try guessing 'empty' instruction memory, although it may be a valid * instruction sequence (eg. srui r0, r0, 0) */ if (dc->ir) { dc->nr_nops = 0; } else { LOG_DIS("nr_nops=%d\t", dc->nr_nops); dc->nr_nops++; if (dc->nr_nops > 4) { cpu_abort(dc->env, "fetching nop sequence\n"); } } dc->opcode = EXTRACT_FIELD(ir, 26, 31); dc->imm5 = EXTRACT_FIELD(ir, 0, 4); dc->imm16 = EXTRACT_FIELD(ir, 0, 15); dc->imm26 = EXTRACT_FIELD(ir, 0, 25); dc->csr = EXTRACT_FIELD(ir, 21, 25); dc->r0 = EXTRACT_FIELD(ir, 21, 25); dc->r1 = EXTRACT_FIELD(ir, 16, 20); dc->r2 = EXTRACT_FIELD(ir, 11, 15); /* bit 31 seems to indicate insn type. */ if (ir & (1 << 31)) { dc->format = OP_FMT_RR; } else { dc->format = OP_FMT_RI; } assert(ARRAY_SIZE(decinfo) == 64); assert(dc->opcode < 64); decinfo[dc->opcode](dc); }


static int decode_zbuf(AVBPrint *bp, const uint8_t *data, const uint8_t *data_end) { z_stream zstream; unsigned char *buf; unsigned buf_size; int ret; zstream.zalloc = ff_png_zalloc; zstream.zfree = ff_png_zfree; zstream.opaque = NULL; if (inflateInit(&zstream) != Z_OK) return AVERROR_EXTERNAL; zstream.next_in = (unsigned char *)data; zstream.avail_in = data_end - data; av_bprint_init(bp, 0, -1); while (zstream.avail_in > 0) { av_bprint_get_buffer(bp, 1, &buf, &buf_size); if (!buf_size) { ret = AVERROR(ENOMEM); goto fail; } zstream.next_out = buf; zstream.avail_out = buf_size; ret = inflate(&zstream, Z_PARTIAL_FLUSH); if (ret != Z_OK && ret != Z_STREAM_END) { ret = AVERROR_EXTERNAL; goto fail; } bp->len += zstream.next_out - buf; if (ret == Z_STREAM_END) break; } inflateEnd(&zstream); bp->str[bp->len] = 0; return 0; fail: inflateEnd(&zstream); av_bprint_finalize(bp, NULL); return ret; }


static int write_extradata(FFV1Context *f) { RangeCoder *const c = &f->c; uint8_t state[CONTEXT_SIZE]; int i, j, k; uint8_t state2[32][CONTEXT_SIZE]; unsigned v; memset(state2, 128, sizeof(state2)); memset(state, 128, sizeof(state)); f->avctx->extradata_size = 10000 + 4 + (11 * 11 * 5 * 5 * 5 + 11 * 11 * 11) * 32; f->avctx->extradata = av_malloc(f->avctx->extradata_size); ff_init_range_encoder(c, f->avctx->extradata, f->avctx->extradata_size); ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8); put_symbol(c, state, f->version, 0); if (f->version > 2) { if (f->version == 3) f->minor_version = 4; put_symbol(c, state, f->minor_version, 0); } put_symbol(c, state, f->ac, 0); if (f->ac > 1) for (i = 1; i < 256; i++) put_symbol(c, state, f->state_transition[i] - c->one_state[i], 1); put_symbol(c, state, f->colorspace, 0); // YUV cs type put_symbol(c, state, f->bits_per_raw_sample, 0); put_rac(c, state, f->chroma_planes); put_symbol(c, state, f->chroma_h_shift, 0); put_symbol(c, state, f->chroma_v_shift, 0); put_rac(c, state, f->transparency); put_symbol(c, state, f->num_h_slices - 1, 0); put_symbol(c, state, f->num_v_slices - 1, 0); put_symbol(c, state, f->quant_table_count, 0); for (i = 0; i < f->quant_table_count; i++) write_quant_tables(c, f->quant_tables[i]); for (i = 0; i < f->quant_table_count; i++) { for (j = 0; j < f->context_count[i] * CONTEXT_SIZE; j++) if (f->initial_states[i] && f->initial_states[i][0][j] != 128) break; if (j < f->context_count[i] * CONTEXT_SIZE) { put_rac(c, state, 1); for (j = 0; j < f->context_count[i]; j++) for (k = 0; k < CONTEXT_SIZE; k++) { int pred = j ? f->initial_states[i][j - 1][k] : 128; put_symbol(c, state2[k], (int8_t)(f->initial_states[i][j][k] - pred), 1); } } else { put_rac(c, state, 0); } } if (f->version > 2) { put_symbol(c, state, f->ec, 0); put_symbol(c, state, f->intra = (f->avctx->gop_size < 2), 0); } f->avctx->extradata_size = ff_rac_terminate(c); v = av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0, f->avctx->extradata, f->avctx->extradata_size); AV_WL32(f->avctx->extradata + f->avctx->extradata_size, v); f->avctx->extradata_size += 4; return 0; }


int qemu_strtol(const char *nptr, const char **endptr, int base, long *result) { char *p; int err = 0; if (!nptr) { if (endptr) { *endptr = nptr; } err = -EINVAL; } else { errno = 0; *result = strtol(nptr, &p, base); err = check_strtox_error(endptr, p, errno); } return err; }


static void spapr_set_vsmt_mode(sPAPRMachineState *spapr, Error **errp) { Error *local_err = NULL; bool vsmt_user = !!spapr->vsmt; int kvm_smt = kvmppc_smt_threads(); int ret; if (!kvm_enabled() && (smp_threads > 1)) { error_setg(&local_err, "TCG cannot support more than 1 thread/core " "on a pseries machine"); goto out; } if (!is_power_of_2(smp_threads)) { error_setg(&local_err, "Cannot support %d threads/core on a pseries " "machine because it must be a power of 2", smp_threads); goto out; } /* Detemine the VSMT mode to use: */ if (vsmt_user) { if (spapr->vsmt < smp_threads) { error_setg(&local_err, "Cannot support VSMT mode %d" " because it must be >= threads/core (%d)", spapr->vsmt, smp_threads); goto out; } /* In this case, spapr->vsmt has been set by the command line */ } else { /* Choose a VSMT mode that may be higher than necessary but is * likely to be compatible with hosts that don't have VSMT. */ spapr->vsmt = MAX(kvm_smt, smp_threads); } /* KVM: If necessary, set the SMT mode: */ if (kvm_enabled() && (spapr->vsmt != kvm_smt)) { ret = kvmppc_set_smt_threads(spapr->vsmt); if (ret) { /* Looks like KVM isn't able to change VSMT mode */ error_setg(&local_err, "Failed to set KVM's VSMT mode to %d (errno %d)", spapr->vsmt, ret); /* We can live with that if the default one is big enough * for the number of threads, and a submultiple of the one * we want. In this case we'll waste some vcpu ids, but * behaviour will be correct */ if ((kvm_smt >= smp_threads) && ((spapr->vsmt % kvm_smt) == 0)) { warn_report_err(local_err); local_err = NULL; goto out; } else { if (!vsmt_user) { error_append_hint(&local_err, "On PPC, a VM with %d threads/core" " on a host with %d threads/core" " requires the use of VSMT mode %d.\n", smp_threads, kvm_smt, spapr->vsmt); } kvmppc_hint_smt_possible(&local_err); goto out; } } } /* else TCG: nothing to do currently */ out: error_propagate(errp, local_err); }


static void pci_bridge_update_mappings(PCIBridge *br) { /* Make updates atomic to: handle the case of one VCPU updating the bridge * while another accesses an unaffected region. */ memory_region_transaction_begin(); pci_bridge_region_cleanup(br); pci_bridge_region_init(br); memory_region_transaction_commit(); }


static struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta, omap_clk iclk, struct omap_mpu_state_s *mpu) { struct omap_sysctl_s *s = (struct omap_sysctl_s *) g_malloc0(sizeof(struct omap_sysctl_s)); s->mpu = mpu; omap_sysctl_reset(s); memory_region_init_io(&s->iomem, NULL, &omap_sysctl_ops, s, "omap.sysctl", omap_l4_region_size(ta, 0)); omap_l4_attach(ta, 0, &s->iomem); return s; }


static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) { AVStream *st = s->streams[pkt->stream_index]; int size = pkt->size; uint8_t *buf = pkt->data; uint8_t *data = NULL; MpegTSWrite *ts = s->priv_data; MpegTSWriteStream *ts_st = st->priv_data; const int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) * 2; int64_t dts = pkt->dts, pts = pkt->pts; if (ts->reemit_pat_pmt) { av_log(s, AV_LOG_WARNING, "resend_headers option is deprecated, use -mpegts_flags resend_headers\n"); ts->reemit_pat_pmt = 0; ts->flags |= MPEGTS_FLAG_REEMIT_PAT_PMT; } if (ts->flags & MPEGTS_FLAG_REEMIT_PAT_PMT) { ts->pat_packet_count = ts->pat_packet_period - 1; ts->sdt_packet_count = ts->sdt_packet_period - 1; ts->flags &= ~MPEGTS_FLAG_REEMIT_PAT_PMT; } if (ts->copyts < 1) { if (pts != AV_NOPTS_VALUE) pts += delay; if (dts != AV_NOPTS_VALUE) dts += delay; } if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) { av_log(s, AV_LOG_ERROR, "first pts value must be set\n"); return AVERROR_INVALIDDATA; } ts_st->first_pts_check = 0; if (st->codec->codec_id == AV_CODEC_ID_H264) { const uint8_t *p = buf, *buf_end = p + size; uint32_t state = -1; int extradd = (pkt->flags & AV_PKT_FLAG_KEY) ? st->codec->extradata_size : 0; int ret = ff_check_h264_startcode(s, st, pkt); if (ret < 0) return ret; if (extradd && AV_RB24(st->codec->extradata) > 1) extradd = 0; do { p = avpriv_find_start_code(p, buf_end, &state); av_log(s, AV_LOG_TRACE, "nal %d\n", state & 0x1f); if ((state & 0x1f) == 7) extradd = 0; } while (p < buf_end && (state & 0x1f) != 9 && (state & 0x1f) != 5 && (state & 0x1f) != 1); if ((state & 0x1f) != 5) extradd = 0; if ((state & 0x1f) != 9) { // AUD NAL data = av_malloc(pkt->size + 6 + extradd); if (!data) return AVERROR(ENOMEM); memcpy(data + 6, st->codec->extradata, extradd); memcpy(data + 6 + extradd, pkt->data, pkt->size); AV_WB32(data, 0x00000001); data[4] = 0x09; data[5] = 0xf0; // any slice type (0xe) + rbsp stop one bit buf = data; size = pkt->size + 6 + extradd; } } else if (st->codec->codec_id == AV_CODEC_ID_AAC) { if (pkt->size < 2) { av_log(s, AV_LOG_ERROR, "AAC packet too short\n"); return AVERROR_INVALIDDATA; } if ((AV_RB16(pkt->data) & 0xfff0) != 0xfff0) { int ret; AVPacket pkt2; if (!ts_st->amux) { av_log(s, AV_LOG_ERROR, "AAC bitstream not in ADTS format " "and extradata missing\n"); return AVERROR_INVALIDDATA; } av_init_packet(&pkt2); pkt2.data = pkt->data; pkt2.size = pkt->size; av_assert0(pkt->dts != AV_NOPTS_VALUE); pkt2.dts = av_rescale_q(pkt->dts, st->time_base, ts_st->amux->streams[0]->time_base); ret = avio_open_dyn_buf(&ts_st->amux->pb); if (ret < 0) return AVERROR(ENOMEM); ret = av_write_frame(ts_st->amux, &pkt2); if (ret < 0) { ffio_free_dyn_buf(&ts_st->amux->pb); return ret; } size = avio_close_dyn_buf(ts_st->amux->pb, &data); ts_st->amux->pb = NULL; buf = data; } } else if (st->codec->codec_id == AV_CODEC_ID_HEVC) { int ret = check_hevc_startcode(s, st, pkt); if (ret < 0) return ret; } if (pkt->dts != AV_NOPTS_VALUE) { int i; for(i=0; i<s->nb_streams; i++) { AVStream *st2 = s->streams[i]; MpegTSWriteStream *ts_st2 = st2->priv_data; if ( ts_st2->payload_size && (ts_st2->payload_dts == AV_NOPTS_VALUE || dts - ts_st2->payload_dts > delay/2)) { mpegts_write_pes(s, st2, ts_st2->payload, ts_st2->payload_size, ts_st2->payload_pts, ts_st2->payload_dts, ts_st2->payload_flags & AV_PKT_FLAG_KEY); ts_st2->payload_size = 0; } } } if (ts_st->payload_size && (ts_st->payload_size + size > ts->pes_payload_size || (dts != AV_NOPTS_VALUE && ts_st->payload_dts != AV_NOPTS_VALUE && av_compare_ts(dts - ts_st->payload_dts, st->time_base, s->max_delay, AV_TIME_BASE_Q) >= 0))) { mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size, ts_st->payload_pts, ts_st->payload_dts, ts_st->payload_flags & AV_PKT_FLAG_KEY); ts_st->payload_size = 0; } if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO || size > ts->pes_payload_size) { av_assert0(!ts_st->payload_size); // for video and subtitle, write a single pes packet mpegts_write_pes(s, st, buf, size, pts, dts, pkt->flags & AV_PKT_FLAG_KEY); av_free(data); return 0; } if (!ts_st->payload_size) { ts_st->payload_pts = pts; ts_st->payload_dts = dts; ts_st->payload_flags = pkt->flags; } memcpy(ts_st->payload + ts_st->payload_size, buf, size); ts_st->payload_size += size; av_free(data); return 0; }


static int mp3_write_packet(AVFormatContext *s, AVPacket *pkt) { MP3Context *mp3 = s->priv_data; if (pkt->stream_index == mp3->audio_stream_idx) { if (mp3->pics_to_write) { /* buffer audio packets until we get all the pictures */ AVPacketList *pktl = av_mallocz(sizeof(*pktl)); if (!pktl) return AVERROR(ENOMEM); pktl->pkt = *pkt; pktl->pkt.buf = av_buffer_ref(pkt->buf); if (!pktl->pkt.buf) { av_freep(&pktl); return AVERROR(ENOMEM); } if (mp3->queue_end) mp3->queue_end->next = pktl; else mp3->queue = pktl; mp3->queue_end = pktl; } else return mp3_write_audio_packet(s, pkt); } else { int ret; /* warn only once for each stream */ if (s->streams[pkt->stream_index]->nb_frames == 1) { av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d," " ignoring.\n", pkt->stream_index); } if (!mp3->pics_to_write || s->streams[pkt->stream_index]->nb_frames >= 1) return 0; if ((ret = ff_id3v2_write_apic(s, &mp3->id3, pkt)) < 0) return ret; mp3->pics_to_write--; /* flush the buffered audio packets */ if (!mp3->pics_to_write && (ret = mp3_queue_flush(s)) < 0) return ret; } return 0; }


static void ioport_write(void *opaque, target_phys_addr_t addr, uint64_t val, unsigned size) { PCIQXLDevice *d = opaque; uint32_t io_port = addr; qxl_async_io async = QXL_SYNC; uint32_t orig_io_port = io_port; if (d->guest_bug && !io_port == QXL_IO_RESET) { return; if (d->revision <= QXL_REVISION_STABLE_V10 && io_port >= QXL_IO_FLUSH_SURFACES_ASYNC) { qxl_set_guest_bug(d, "unsupported io %d for revision %d\n", io_port, d->revision); return; switch (io_port) { case QXL_IO_RESET: case QXL_IO_SET_MODE: case QXL_IO_MEMSLOT_ADD: case QXL_IO_MEMSLOT_DEL: case QXL_IO_CREATE_PRIMARY: case QXL_IO_UPDATE_IRQ: case QXL_IO_LOG: case QXL_IO_MEMSLOT_ADD_ASYNC: case QXL_IO_CREATE_PRIMARY_ASYNC: default: if (d->mode != QXL_MODE_VGA) { trace_qxl_io_unexpected_vga_mode(d->id, io_port, io_port_to_string(io_port)); /* be nice to buggy guest drivers */ if (io_port >= QXL_IO_UPDATE_AREA_ASYNC && io_port < QXL_IO_RANGE_SIZE) { qxl_send_events(d, QXL_INTERRUPT_IO_CMD); return; /* we change the io_port to avoid ifdeffery in the main switch */ orig_io_port = io_port; switch (io_port) { case QXL_IO_UPDATE_AREA_ASYNC: io_port = QXL_IO_UPDATE_AREA; goto async_common; case QXL_IO_MEMSLOT_ADD_ASYNC: io_port = QXL_IO_MEMSLOT_ADD; goto async_common; case QXL_IO_CREATE_PRIMARY_ASYNC: io_port = QXL_IO_CREATE_PRIMARY; goto async_common; case QXL_IO_DESTROY_PRIMARY_ASYNC: io_port = QXL_IO_DESTROY_PRIMARY; goto async_common; case QXL_IO_DESTROY_SURFACE_ASYNC: io_port = QXL_IO_DESTROY_SURFACE_WAIT; goto async_common; case QXL_IO_DESTROY_ALL_SURFACES_ASYNC: io_port = QXL_IO_DESTROY_ALL_SURFACES; goto async_common; case QXL_IO_FLUSH_SURFACES_ASYNC: case QXL_IO_MONITORS_CONFIG_ASYNC: async_common: async = QXL_ASYNC; qemu_mutex_lock(&d->async_lock); if (d->current_async != QXL_UNDEFINED_IO) { qxl_set_guest_bug(d, "%d async started before last (%d) complete", io_port, d->current_async); qemu_mutex_unlock(&d->async_lock); return; d->current_async = orig_io_port; qemu_mutex_unlock(&d->async_lock); default: trace_qxl_io_write(d->id, qxl_mode_to_string(d->mode), addr, val, size, async); switch (io_port) { case QXL_IO_UPDATE_AREA: { QXLCookie *cookie = NULL; QXLRect update = d->ram->update_area; if (d->ram->update_surface > d->ssd.num_surfaces) { qxl_set_guest_bug(d, "QXL_IO_UPDATE_AREA: invalid surface id %d\n", d->ram->update_surface); return; if (update.left >= update.right || update.top >= update.bottom) { qxl_set_guest_bug(d, "QXL_IO_UPDATE_AREA: invalid area (%ux%u)x(%ux%u)\n", update.left, update.top, update.right, update.bottom); return; if (async == QXL_ASYNC) { cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO, QXL_IO_UPDATE_AREA_ASYNC); cookie->u.area = update; qxl_spice_update_area(d, d->ram->update_surface, cookie ? &cookie->u.area : &update, NULL, 0, 0, async, cookie); case QXL_IO_NOTIFY_CMD: qemu_spice_wakeup(&d->ssd); case QXL_IO_NOTIFY_CURSOR: qemu_spice_wakeup(&d->ssd); case QXL_IO_UPDATE_IRQ: qxl_update_irq(d); case QXL_IO_NOTIFY_OOM: if (!SPICE_RING_IS_EMPTY(&d->ram->release_ring)) { d->oom_running = 1; qxl_spice_oom(d); d->oom_running = 0; case QXL_IO_SET_MODE: qxl_set_mode(d, val, 0); case QXL_IO_LOG: if (d->guestdebug) { fprintf(stderr, "qxl/guest-%d: %" PRId64 ": %s", d->id, qemu_get_clock_ns(vm_clock), d->ram->log_buf); case QXL_IO_RESET: qxl_hard_reset(d, 0); case QXL_IO_MEMSLOT_ADD: if (val >= NUM_MEMSLOTS) { qxl_set_guest_bug(d, "QXL_IO_MEMSLOT_ADD: val out of range"); if (d->guest_slots[val].active) { qxl_set_guest_bug(d, "QXL_IO_MEMSLOT_ADD: memory slot already active"); d->guest_slots[val].slot = d->ram->mem_slot; qxl_add_memslot(d, val, 0, async); case QXL_IO_MEMSLOT_DEL: if (val >= NUM_MEMSLOTS) { qxl_set_guest_bug(d, "QXL_IO_MEMSLOT_DEL: val out of range"); qxl_del_memslot(d, val); case QXL_IO_CREATE_PRIMARY: if (val != 0) { qxl_set_guest_bug(d, "QXL_IO_CREATE_PRIMARY (async=%d): val != 0", async); goto cancel_async; d->guest_primary.surface = d->ram->create_surface; qxl_create_guest_primary(d, 0, async); case QXL_IO_DESTROY_PRIMARY: if (val != 0) { qxl_set_guest_bug(d, "QXL_IO_DESTROY_PRIMARY (async=%d): val != 0", async); goto cancel_async; if (!qxl_destroy_primary(d, async)) { trace_qxl_io_destroy_primary_ignored(d->id, qxl_mode_to_string(d->mode)); goto cancel_async; case QXL_IO_DESTROY_SURFACE_WAIT: if (val >= d->ssd.num_surfaces) { qxl_set_guest_bug(d, "QXL_IO_DESTROY_SURFACE (async=%d):" "%" PRIu64 " >= NUM_SURFACES", async, val); goto cancel_async; qxl_spice_destroy_surface_wait(d, val, async); case QXL_IO_FLUSH_RELEASE: { QXLReleaseRing *ring = &d->ram->release_ring; if (ring->prod - ring->cons + 1 == ring->num_items) { fprintf(stderr, "ERROR: no flush, full release ring [p%d,%dc]\n", ring->prod, ring->cons); qxl_push_free_res(d, 1 /* flush */); case QXL_IO_FLUSH_SURFACES_ASYNC: qxl_spice_flush_surfaces_async(d); case QXL_IO_DESTROY_ALL_SURFACES: d->mode = QXL_MODE_UNDEFINED; qxl_spice_destroy_surfaces(d, async); case QXL_IO_MONITORS_CONFIG_ASYNC: qxl_spice_monitors_config_async(d, 0); default: qxl_set_guest_bug(d, "%s: unexpected ioport=0x%x\n", __func__, io_port); return; cancel_async: if (async) { qxl_send_events(d, QXL_INTERRUPT_IO_CMD); qemu_mutex_lock(&d->async_lock); d->current_async = QXL_UNDEFINED_IO; qemu_mutex_unlock(&d->async_lock);


static int decode_frame_byterun1(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { IffContext *s = avctx->priv_data; const uint8_t *buf = avpkt->data; unsigned buf_size = avpkt->size; const uint8_t *buf_end = buf+buf_size; unsigned y, plane, x; if (avctx->reget_buffer(avctx, &s->frame) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } for(y = 0; y < avctx->height ; y++ ) { uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved memset(row, 0, avctx->pix_fmt == PIX_FMT_PAL8 ? avctx->width : (avctx->width * 4)); for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) { for(x = 0; x < s->planesize && buf < buf_end; ) { int8_t value = *buf++; unsigned length; if (value >= 0) { length = value + 1; memcpy(s->planebuf + x, buf, FFMIN3(length, s->planesize - x, buf_end - buf)); buf += length; } else if (value > -128) { length = -value + 1; memset(s->planebuf + x, *buf++, FFMIN(length, s->planesize - x)); } else { //noop continue; } x += length; } if (avctx->pix_fmt == PIX_FMT_PAL8) { decodeplane8(row, s->planebuf, s->planesize, avctx->bits_per_coded_sample, plane); } else { //PIX_FMT_BGR32 decodeplane32((uint32_t *) row, s->planebuf, s->planesize, avctx->bits_per_coded_sample, plane); } } } else { for(x = 0; x < avctx->width && buf < buf_end; ) { int8_t value = *buf++; unsigned length; if (value >= 0) { length = value + 1; memcpy(row + x, buf, FFMIN3(length, buf_end - buf, avctx->width - x)); buf += length; } else if (value > -128) { length = -value + 1; memset(row + x, *buf++, FFMIN(length, avctx->width - x)); } else { //noop continue; } x += length; } } } *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; return buf_size; }


static void avc_loopfilter_luma_inter_edge_ver_msa(uint8_t *data, uint8_t bs0, uint8_t bs1, uint8_t bs2, uint8_t bs3, uint8_t tc0, uint8_t tc1, uint8_t tc2, uint8_t tc3, uint8_t alpha_in, uint8_t beta_in, uint32_t img_width) { uint8_t *src; v16u8 beta, tmp_vec, bs = { 0 }; v16u8 tc = { 0 }; v16u8 is_less_than, is_less_than_beta; v16u8 p1, p0, q0, q1; v8i16 p0_r, q0_r, p1_r = { 0 }; v8i16 q1_r = { 0 }; v8i16 p0_l, q0_l, p1_l = { 0 }; v8i16 q1_l = { 0 }; v16u8 p3_org, p2_org, p1_org, p0_org, q0_org, q1_org, q2_org, q3_org; v8i16 p2_org_r, p1_org_r, p0_org_r, q0_org_r, q1_org_r, q2_org_r; v8i16 p2_org_l, p1_org_l, p0_org_l, q0_org_l, q1_org_l, q2_org_l; v8i16 tc_r, tc_l; v16i8 zero = { 0 }; v16u8 is_bs_greater_than0; tmp_vec = (v16u8) __msa_fill_b(bs0); bs = (v16u8) __msa_insve_w((v4i32) bs, 0, (v4i32) tmp_vec); tmp_vec = (v16u8) __msa_fill_b(bs1); bs = (v16u8) __msa_insve_w((v4i32) bs, 1, (v4i32) tmp_vec); tmp_vec = (v16u8) __msa_fill_b(bs2); bs = (v16u8) __msa_insve_w((v4i32) bs, 2, (v4i32) tmp_vec); tmp_vec = (v16u8) __msa_fill_b(bs3); bs = (v16u8) __msa_insve_w((v4i32) bs, 3, (v4i32) tmp_vec); if (!__msa_test_bz_v(bs)) { tmp_vec = (v16u8) __msa_fill_b(tc0); tc = (v16u8) __msa_insve_w((v4i32) tc, 0, (v4i32) tmp_vec); tmp_vec = (v16u8) __msa_fill_b(tc1); tc = (v16u8) __msa_insve_w((v4i32) tc, 1, (v4i32) tmp_vec); tmp_vec = (v16u8) __msa_fill_b(tc2); tc = (v16u8) __msa_insve_w((v4i32) tc, 2, (v4i32) tmp_vec); tmp_vec = (v16u8) __msa_fill_b(tc3); tc = (v16u8) __msa_insve_w((v4i32) tc, 3, (v4i32) tmp_vec); is_bs_greater_than0 = (zero < bs); { v16u8 row0, row1, row2, row3, row4, row5, row6, row7; v16u8 row8, row9, row10, row11, row12, row13, row14, row15; src = data; src -= 4; LOAD_8VECS_UB(src, img_width, row0, row1, row2, row3, row4, row5, row6, row7); src += (8 * img_width); LOAD_8VECS_UB(src, img_width, row8, row9, row10, row11, row12, row13, row14, row15); TRANSPOSE16x8_B_UB(row0, row1, row2, row3, row4, row5, row6, row7, row8, row9, row10, row11, row12, row13, row14, row15, p3_org, p2_org, p1_org, p0_org, q0_org, q1_org, q2_org, q3_org); } { v16u8 p0_asub_q0, p1_asub_p0, q1_asub_q0, alpha; v16u8 is_less_than_alpha; p0_asub_q0 = __msa_asub_u_b(p0_org, q0_org); p1_asub_p0 = __msa_asub_u_b(p1_org, p0_org); q1_asub_q0 = __msa_asub_u_b(q1_org, q0_org); alpha = (v16u8) __msa_fill_b(alpha_in); beta = (v16u8) __msa_fill_b(beta_in); is_less_than_alpha = (p0_asub_q0 < alpha); is_less_than_beta = (p1_asub_p0 < beta); is_less_than = is_less_than_beta & is_less_than_alpha; is_less_than_beta = (q1_asub_q0 < beta); is_less_than = is_less_than_beta & is_less_than; is_less_than = is_less_than & is_bs_greater_than0; } if (!__msa_test_bz_v(is_less_than)) { v16i8 negate_tc, sign_negate_tc; v8i16 negate_tc_r, i16_negatetc_l; negate_tc = zero - (v16i8) tc; sign_negate_tc = __msa_clti_s_b(negate_tc, 0); negate_tc_r = (v8i16) __msa_ilvr_b(sign_negate_tc, negate_tc); i16_negatetc_l = (v8i16) __msa_ilvl_b(sign_negate_tc, negate_tc); tc_r = (v8i16) __msa_ilvr_b(zero, (v16i8) tc); tc_l = (v8i16) __msa_ilvl_b(zero, (v16i8) tc); p1_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) p1_org); p0_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) p0_org); q0_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) q0_org); p1_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) p1_org); p0_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) p0_org); q0_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) q0_org); { v16u8 p2_asub_p0; v16u8 is_less_than_beta_r, is_less_than_beta_l; p2_asub_p0 = __msa_asub_u_b(p2_org, p0_org); is_less_than_beta = (p2_asub_p0 < beta); is_less_than_beta = is_less_than_beta & is_less_than; is_less_than_beta_r = (v16u8) __msa_sldi_b((v16i8) is_less_than_beta, zero, 8); if (!__msa_test_bz_v(is_less_than_beta_r)) { p2_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) p2_org); AVC_LOOP_FILTER_P1_OR_Q1(p0_org_r, q0_org_r, p1_org_r, p2_org_r, negate_tc_r, tc_r, p1_r); } is_less_than_beta_l = (v16u8) __msa_sldi_b(zero, (v16i8) is_less_than_beta, 8); if (!__msa_test_bz_v(is_less_than_beta_l)) { p2_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) p2_org); AVC_LOOP_FILTER_P1_OR_Q1(p0_org_l, q0_org_l, p1_org_l, p2_org_l, i16_negatetc_l, tc_l, p1_l); } } if (!__msa_test_bz_v(is_less_than_beta)) { p1 = (v16u8) __msa_pckev_b((v16i8) p1_l, (v16i8) p1_r); p1_org = __msa_bmnz_v(p1_org, p1, is_less_than_beta); is_less_than_beta = __msa_andi_b(is_less_than_beta, 1); tc = tc + is_less_than_beta; } { v16u8 u8_q2asub_q0; v16u8 is_less_than_beta_l, is_less_than_beta_r; u8_q2asub_q0 = __msa_asub_u_b(q2_org, q0_org); is_less_than_beta = (u8_q2asub_q0 < beta); is_less_than_beta = is_less_than_beta & is_less_than; q1_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) q1_org); is_less_than_beta_r = (v16u8) __msa_sldi_b((v16i8) is_less_than_beta, zero, 8); if (!__msa_test_bz_v(is_less_than_beta_r)) { q2_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) q2_org); AVC_LOOP_FILTER_P1_OR_Q1(p0_org_r, q0_org_r, q1_org_r, q2_org_r, negate_tc_r, tc_r, q1_r); } q1_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) q1_org); is_less_than_beta_l = (v16u8) __msa_sldi_b(zero, (v16i8) is_less_than_beta, 8); if (!__msa_test_bz_v(is_less_than_beta_l)) { q2_org_l = (v8i16) __msa_ilvl_b(zero, (v16i8) q2_org); AVC_LOOP_FILTER_P1_OR_Q1(p0_org_l, q0_org_l, q1_org_l, q2_org_l, i16_negatetc_l, tc_l, q1_l); } } if (!__msa_test_bz_v(is_less_than_beta)) { q1 = (v16u8) __msa_pckev_b((v16i8) q1_l, (v16i8) q1_r); q1_org = __msa_bmnz_v(q1_org, q1, is_less_than_beta); is_less_than_beta = __msa_andi_b(is_less_than_beta, 1); tc = tc + is_less_than_beta; } { v8i16 threshold_r, negate_thresh_r; v8i16 threshold_l, negate_thresh_l; v16i8 negate_thresh, sign_negate_thresh; negate_thresh = zero - (v16i8) tc; sign_negate_thresh = __msa_clti_s_b(negate_thresh, 0); threshold_r = (v8i16) __msa_ilvr_b(zero, (v16i8) tc); negate_thresh_r = (v8i16) __msa_ilvr_b(sign_negate_thresh, negate_thresh); AVC_LOOP_FILTER_P0Q0(q0_org_r, p0_org_r, p1_org_r, q1_org_r, negate_thresh_r, threshold_r, p0_r, q0_r); threshold_l = (v8i16) __msa_ilvl_b(zero, (v16i8) tc); negate_thresh_l = (v8i16) __msa_ilvl_b(sign_negate_thresh, negate_thresh); AVC_LOOP_FILTER_P0Q0(q0_org_l, p0_org_l, p1_org_l, q1_org_l, negate_thresh_l, threshold_l, p0_l, q0_l); } p0 = (v16u8) __msa_pckev_b((v16i8) p0_l, (v16i8) p0_r); q0 = (v16u8) __msa_pckev_b((v16i8) q0_l, (v16i8) q0_r); p0_org = __msa_bmnz_v(p0_org, p0, is_less_than); q0_org = __msa_bmnz_v(q0_org, q0, is_less_than); } { v16i8 tmp0, tmp1; v8i16 tmp2, tmp5; v4i32 tmp3, tmp4, tmp6, tmp7; uint32_t out0, out2; uint16_t out1, out3; src = data - 3; tmp0 = __msa_ilvr_b((v16i8) p1_org, (v16i8) p2_org); tmp1 = __msa_ilvr_b((v16i8) q0_org, (v16i8) p0_org); tmp2 = (v8i16) __msa_ilvr_b((v16i8) q2_org, (v16i8) q1_org); tmp3 = (v4i32) __msa_ilvr_h((v8i16) tmp1, (v8i16) tmp0); tmp4 = (v4i32) __msa_ilvl_h((v8i16) tmp1, (v8i16) tmp0); tmp0 = __msa_ilvl_b((v16i8) p1_org, (v16i8) p2_org); tmp1 = __msa_ilvl_b((v16i8) q0_org, (v16i8) p0_org); tmp5 = (v8i16) __msa_ilvl_b((v16i8) q2_org, (v16i8) q1_org); tmp6 = (v4i32) __msa_ilvr_h((v8i16) tmp1, (v8i16) tmp0); tmp7 = (v4i32) __msa_ilvl_h((v8i16) tmp1, (v8i16) tmp0); out0 = __msa_copy_u_w(tmp3, 0); out1 = __msa_copy_u_h(tmp2, 0); out2 = __msa_copy_u_w(tmp3, 1); out3 = __msa_copy_u_h(tmp2, 1); STORE_WORD(src, out0); STORE_HWORD((src + 4), out1); src += img_width; STORE_WORD(src, out2); STORE_HWORD((src + 4), out3); out0 = __msa_copy_u_w(tmp3, 2); out1 = __msa_copy_u_h(tmp2, 2); out2 = __msa_copy_u_w(tmp3, 3); out3 = __msa_copy_u_h(tmp2, 3); src += img_width; STORE_WORD(src, out0); STORE_HWORD((src + 4), out1); src += img_width; STORE_WORD(src, out2); STORE_HWORD((src + 4), out3); out0 = __msa_copy_u_w(tmp4, 0); out1 = __msa_copy_u_h(tmp2, 4); out2 = __msa_copy_u_w(tmp4, 1); out3 = __msa_copy_u_h(tmp2, 5); src += img_width; STORE_WORD(src, out0); STORE_HWORD((src + 4), out1); src += img_width; STORE_WORD(src, out2); STORE_HWORD((src + 4), out3); out0 = __msa_copy_u_w(tmp4, 2); out1 = __msa_copy_u_h(tmp2, 6); out2 = __msa_copy_u_w(tmp4, 3); out3 = __msa_copy_u_h(tmp2, 7); src += img_width; STORE_WORD(src, out0); STORE_HWORD((src + 4), out1); src += img_width; STORE_WORD(src, out2); STORE_HWORD((src + 4), out3); out0 = __msa_copy_u_w(tmp6, 0); out1 = __msa_copy_u_h(tmp5, 0); out2 = __msa_copy_u_w(tmp6, 1); out3 = __msa_copy_u_h(tmp5, 1); src += img_width; STORE_WORD(src, out0); STORE_HWORD((src + 4), out1); src += img_width; STORE_WORD(src, out2); STORE_HWORD((src + 4), out3); out0 = __msa_copy_u_w(tmp6, 2); out1 = __msa_copy_u_h(tmp5, 2); out2 = __msa_copy_u_w(tmp6, 3); out3 = __msa_copy_u_h(tmp5, 3); src += img_width; STORE_WORD(src, out0); STORE_HWORD((src + 4), out1); src += img_width; STORE_WORD(src, out2); STORE_HWORD((src + 4), out3); out0 = __msa_copy_u_w(tmp7, 0); out1 = __msa_copy_u_h(tmp5, 4); out2 = __msa_copy_u_w(tmp7, 1); out3 = __msa_copy_u_h(tmp5, 5); src += img_width; STORE_WORD(src, out0); STORE_HWORD((src + 4), out1); src += img_width; STORE_WORD(src, out2); STORE_HWORD((src + 4), out3); out0 = __msa_copy_u_w(tmp7, 2); out1 = __msa_copy_u_h(tmp5, 6); out2 = __msa_copy_u_w(tmp7, 3); out3 = __msa_copy_u_h(tmp5, 7); src += img_width; STORE_WORD(src, out0); STORE_HWORD((src + 4), out1); src += img_width; STORE_WORD(src, out2); STORE_HWORD((src + 4), out3); } } }


static void dvbsub_parse_region_segment(AVCodecContext *avctx, const uint8_t *buf, int buf_size) { DVBSubContext *ctx = avctx->priv_data; const uint8_t *buf_end = buf + buf_size; int region_id, object_id; DVBSubRegion *region; DVBSubObject *object; DVBSubObjectDisplay *display; int fill; if (buf_size < 10) return; region_id = *buf++; region = get_region(ctx, region_id); if (!region) { region = av_mallocz(sizeof(DVBSubRegion)); region->id = region_id; region->next = ctx->region_list; ctx->region_list = region; } fill = ((*buf++) >> 3) & 1; region->width = AV_RB16(buf); buf += 2; region->height = AV_RB16(buf); buf += 2; if (region->width * region->height != region->buf_size) { av_free(region->pbuf); region->buf_size = region->width * region->height; region->pbuf = av_malloc(region->buf_size); fill = 1; } region->depth = 1 << (((*buf++) >> 2) & 7); if(region->depth<2 || region->depth>8){ av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth); region->depth= 4; } region->clut = *buf++; if (region->depth == 8) region->bgcolor = *buf++; else { buf += 1; if (region->depth == 4) region->bgcolor = (((*buf++) >> 4) & 15); else region->bgcolor = (((*buf++) >> 2) & 3); } av_dlog(avctx, "Region %d, (%dx%d)\n", region_id, region->width, region->height); if (fill) { memset(region->pbuf, region->bgcolor, region->buf_size); av_dlog(avctx, "Fill region (%d)\n", region->bgcolor); } delete_region_display_list(ctx, region); while (buf + 5 < buf_end) { object_id = AV_RB16(buf); buf += 2; object = get_object(ctx, object_id); if (!object) { object = av_mallocz(sizeof(DVBSubObject)); object->id = object_id; object->next = ctx->object_list; ctx->object_list = object; } object->type = (*buf) >> 6; display = av_mallocz(sizeof(DVBSubObjectDisplay)); display->object_id = object_id; display->region_id = region_id; display->x_pos = AV_RB16(buf) & 0xfff; buf += 2; display->y_pos = AV_RB16(buf) & 0xfff; buf += 2; if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) { display->fgcolor = *buf++; display->bgcolor = *buf++; } display->region_list_next = region->display_list; region->display_list = display; display->object_list_next = object->display_list; object->display_list = display; } }


static void sdhci_initfn(Object *obj) { SDHCIState *s = SDHCI(obj); DriveInfo *di; di = drive_get_next(IF_SD); s->card = sd_init(di ? blk_bs(blk_by_legacy_dinfo(di)) : NULL, false); if (s->card == NULL) { exit(1); } s->eject_cb = qemu_allocate_irq(sdhci_insert_eject_cb, s, 0); s->ro_cb = qemu_allocate_irq(sdhci_card_readonly_cb, s, 0); sd_set_cb(s->card, s->ro_cb, s->eject_cb); s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s); s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_do_data_transfer, s); }


static int print_ptr(DeviceState *dev, Property *prop, char *dest, size_t len) { void **ptr = qdev_get_prop_ptr(dev, prop); return snprintf(dest, len, "<%p>", *ptr); }


static ssize_t drop_sync(int fd, size_t size) { ssize_t ret, dropped = size; uint8_t *buffer = g_malloc(MIN(65536, size)); while (size > 0) { ret = read_sync(fd, buffer, MIN(65536, size)); if (ret < 0) { g_free(buffer); return ret; } assert(ret <= size); size -= ret; } g_free(buffer); return dropped; }


static int coroutine_fn iscsi_co_flush(BlockDriverState *bs) { IscsiLun *iscsilun = bs->opaque; struct IscsiTask iTask; if (bs->sg) { return 0; } if (!iscsilun->force_next_flush) { return 0; } iscsilun->force_next_flush = false; iscsi_co_init_iscsitask(iscsilun, &iTask); retry: if (iscsi_synchronizecache10_task(iscsilun->iscsi, iscsilun->lun, 0, 0, 0, 0, iscsi_co_generic_cb, &iTask) == NULL) { return -ENOMEM; } while (!iTask.complete) { iscsi_set_events(iscsilun); qemu_coroutine_yield(); } if (iTask.task != NULL) { scsi_free_scsi_task(iTask.task); iTask.task = NULL; } if (iTask.do_retry) { iTask.complete = 0; goto retry; } if (iTask.status != SCSI_STATUS_GOOD) { return -EIO; } return 0; }


static void mmio_ide_write(void *opaque, target_phys_addr_t addr, uint64_t val, unsigned size) { MMIOState *s = opaque; addr >>= s->shift; if (addr & 7) ide_ioport_write(&s->bus, addr, val); else ide_data_writew(&s->bus, 0, val); }


static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; VmdAudioContext *s = avctx->priv_data; int block_type; unsigned char *output_samples = (unsigned char *)data; if (buf_size < 16) { av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n"); *data_size = 0; return buf_size; } block_type = buf[6]; if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) { av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type); return AVERROR(EINVAL); } buf += 16; buf_size -= 16; if (block_type == BLOCK_TYPE_AUDIO) { /* the chunk contains audio */ *data_size = vmdaudio_loadsound(s, output_samples, buf, 0, buf_size); } else if (block_type == BLOCK_TYPE_INITIAL) { /* initial chunk, may contain audio and silence */ uint32_t flags = AV_RB32(buf); int silent_chunks = av_popcount(flags); buf += 4; buf_size -= 4; if(*data_size < (s->block_align*silent_chunks + buf_size) * 2) return -1; *data_size = vmdaudio_loadsound(s, output_samples, buf, silent_chunks, buf_size); } else if (block_type == BLOCK_TYPE_SILENCE) { /* silent chunk */ *data_size = vmdaudio_loadsound(s, output_samples, buf, 1, 0); } return avpkt->size; }


static int usb_parse(const char *cmdline) { int r; r = usb_device_add(cmdline); if (r < 0) { fprintf(stderr, "qemu: could not add USB device '%s'\n", cmdline); } return r; }


static int count_contiguous_free_clusters(uint64_t nb_clusters, uint64_t *l2_table) { int i; for (i = 0; i < nb_clusters; i++) { int type = qcow2_get_cluster_type(be64_to_cpu(l2_table[i])); if (type != QCOW2_CLUSTER_UNALLOCATED) { break; } } return i; }


void bdrv_set_geometry_hint(BlockDriverState *bs, int cyls, int heads, int secs) { bs->cyls = cyls; bs->heads = heads; bs->secs = secs; }


static BlockDriverState *bdrv_new_open(const char *filename, const char *fmt, int flags) { BlockDriverState *bs; BlockDriver *drv; char password[256]; bs = bdrv_new(""); if (!bs) { error_report("Not enough memory"); goto fail; } if (fmt) { drv = bdrv_find_format(fmt); if (!drv) { error_report("Unknown file format '%s'", fmt); goto fail; } } else { drv = NULL; } if (bdrv_open(bs, filename, flags, drv) < 0) { error_report("Could not open '%s'", filename); goto fail; } if (bdrv_is_encrypted(bs)) { printf("Disk image '%s' is encrypted.\n", filename); if (read_password(password, sizeof(password)) < 0) { error_report("No password given"); goto fail; } if (bdrv_set_key(bs, password) < 0) { error_report("invalid password"); goto fail; } } return bs; fail: if (bs) { bdrv_delete(bs); } return NULL; }


static uint32_t bitband_readl(void *opaque, target_phys_addr_t offset) { uint32_t addr; uint32_t mask; uint32_t v; addr = bitband_addr(opaque, offset) & ~3; mask = (1 << ((offset >> 2) & 31)); mask = tswap32(mask); cpu_physical_memory_read(addr, (uint8_t *)&v, 4); return (v & mask) != 0; }


int64_t qemu_strtosz_MiB(const char *nptr, char **end) { return do_strtosz(nptr, end, 'M', 1024); }


static void to_json(const QObject *obj, QString *str, int pretty, int indent) { switch (qobject_type(obj)) { case QTYPE_QINT: { QInt *val = qobject_to_qint(obj); char buffer[1024]; snprintf(buffer, sizeof(buffer), "%" PRId64, qint_get_int(val)); qstring_append(str, buffer); break; } case QTYPE_QSTRING: { QString *val = qobject_to_qstring(obj); const char *ptr; ptr = qstring_get_str(val); qstring_append(str, "\""); while (*ptr) { if ((ptr[0] & 0xE0) == 0xE0 && (ptr[1] & 0x80) && (ptr[2] & 0x80)) { uint16_t wchar; char escape[7]; wchar = (ptr[0] & 0x0F) << 12; wchar |= (ptr[1] & 0x3F) << 6; wchar |= (ptr[2] & 0x3F); ptr += 2; snprintf(escape, sizeof(escape), "\\u%04X", wchar); qstring_append(str, escape); } else if ((ptr[0] & 0xE0) == 0xC0 && (ptr[1] & 0x80)) { uint16_t wchar; char escape[7]; wchar = (ptr[0] & 0x1F) << 6; wchar |= (ptr[1] & 0x3F); ptr++; snprintf(escape, sizeof(escape), "\\u%04X", wchar); qstring_append(str, escape); } else switch (ptr[0]) { case '\"': qstring_append(str, "\\\""); break; case '\\': qstring_append(str, "\\\\"); break; case '\b': qstring_append(str, "\\b"); break; case '\f': qstring_append(str, "\\f"); break; case '\n': qstring_append(str, "\\n"); break; case '\r': qstring_append(str, "\\r"); break; case '\t': qstring_append(str, "\\t"); break; default: { if (ptr[0] <= 0x1F) { char escape[7]; snprintf(escape, sizeof(escape), "\\u%04X", ptr[0]); qstring_append(str, escape); } else { char buf[2] = { ptr[0], 0 }; qstring_append(str, buf); } break; } } ptr++; } qstring_append(str, "\""); break; } case QTYPE_QDICT: { ToJsonIterState s; QDict *val = qobject_to_qdict(obj); s.count = 0; s.str = str; s.indent = indent + 1; s.pretty = pretty; qstring_append(str, "{"); qdict_iter(val, to_json_dict_iter, &s); if (pretty) { int j; qstring_append(str, "\n"); for (j = 0 ; j < indent ; j++) qstring_append(str, " "); } qstring_append(str, "}"); break; } case QTYPE_QLIST: { ToJsonIterState s; QList *val = qobject_to_qlist(obj); s.count = 0; s.str = str; s.indent = indent + 1; s.pretty = pretty; qstring_append(str, "["); qlist_iter(val, (void *)to_json_list_iter, &s); if (pretty) { int j; qstring_append(str, "\n"); for (j = 0 ; j < indent ; j++) qstring_append(str, " "); } qstring_append(str, "]"); break; } case QTYPE_QFLOAT: { QFloat *val = qobject_to_qfloat(obj); char buffer[1024]; int len; len = snprintf(buffer, sizeof(buffer), "%f", qfloat_get_double(val)); while (len > 0 && buffer[len - 1] == '0') { len--; } if (len && buffer[len - 1] == '.') { buffer[len - 1] = 0; } else { buffer[len] = 0; } qstring_append(str, buffer); break; } case QTYPE_QBOOL: { QBool *val = qobject_to_qbool(obj); if (qbool_get_int(val)) { qstring_append(str, "true"); } else { qstring_append(str, "false"); } break; } case QTYPE_QERROR: /* XXX: should QError be emitted? */ case QTYPE_NONE: break; } }


static int rm_assemble_video_frame(AVFormatContext *s, RMContext *rm, AVPacket *pkt, int len) { ByteIOContext *pb = &s->pb; int hdr, seq, pic_num, len2, pos; int type; int ssize; hdr = get_byte(pb); len--; type = hdr >> 6; switch(type){ case 0: // slice case 2: // last slice seq = get_byte(pb); len--; len2 = get_num(pb, &len); pos = get_num(pb, &len); pic_num = get_byte(pb); len--; rm->remaining_len = len; break; case 1: //whole frame seq = get_byte(pb); len--; if(av_new_packet(pkt, len + 9) < 0) return AVERROR(EIO); pkt->data[0] = 0; AV_WL32(pkt->data + 1, 1); AV_WL32(pkt->data + 5, 0); get_buffer(pb, pkt->data + 9, len); rm->remaining_len = 0; return 0; case 3: //frame as a part of packet len2 = get_num(pb, &len); pos = get_num(pb, &len); pic_num = get_byte(pb); len--; rm->remaining_len = len - len2; if(av_new_packet(pkt, len2 + 9) < 0) return AVERROR(EIO); pkt->data[0] = 0; AV_WL32(pkt->data + 1, 1); AV_WL32(pkt->data + 5, 0); get_buffer(pb, pkt->data + 9, len2); return 0; } //now we have to deal with single slice if((seq & 0x7F) == 1 || rm->curpic_num != pic_num){ rm->slices = ((hdr & 0x3F) << 1) + 1; ssize = len2 + 8*rm->slices + 1; rm->videobuf = av_realloc(rm->videobuf, ssize); rm->videobufsize = ssize; rm->videobufpos = 8*rm->slices + 1; rm->cur_slice = 0; rm->curpic_num = pic_num; rm->pktpos = url_ftell(pb); } if(type == 2){ len = FFMIN(len, pos); pos = len2 - pos; } if(++rm->cur_slice > rm->cur_slice) return 1; AV_WL32(rm->videobuf - 7 + 8*rm->cur_slice, 1); AV_WL32(rm->videobuf - 3 + 8*rm->cur_slice, rm->videobufpos - 8*rm->slices - 1); if(rm->videobufpos + len > rm->videobufsize) return 1; if (get_buffer(pb, rm->videobuf + rm->videobufpos, len) != len) return AVERROR(EIO); rm->videobufpos += len, rm->remaining_len-= len; if(type == 2 || (rm->videobufpos) == rm->videobufsize){ //adjust slice headers memmove(rm->videobuf + 1 + 8*rm->cur_slice, rm->videobuf + 1 + 8*rm->slices, rm->videobufsize - 1 - 8*rm->slices); ssize = rm->videobufsize - 8*(rm->slices - rm->cur_slice); rm->videobuf[0] = rm->cur_slice-1; if(av_new_packet(pkt, ssize) < 0) return AVERROR(ENOMEM); memcpy(pkt->data, rm->videobuf, ssize); pkt->pts = AV_NOPTS_VALUE; pkt->pos = rm->pktpos; return 0; } return 1; }


static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) { if (d->term_got_escape) { d->term_got_escape = 0; if (ch == term_escape_char) goto send_char; switch(ch) { case '?': case 'h': mux_print_help(chr); break; case 'x': { const char *term = "QEMU: Terminated\n\r"; qemu_chr_fe_write(chr, (uint8_t *)term, strlen(term)); exit(0); break; } case 's': blk_commit_all(); break; case 'b': qemu_chr_be_event(chr, CHR_EVENT_BREAK); break; case 'c': /* Switch to the next registered device */ mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT); d->focus++; if (d->focus >= d->mux_cnt) d->focus = 0; mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN); break; case 't': d->timestamps = !d->timestamps; d->timestamps_start = -1; d->linestart = 0; break; } } else if (ch == term_escape_char) { d->term_got_escape = 1; } else { send_char: return 1; } return 0; }


static void win_chr_readfile(CharDriverState *chr) { WinCharState *s = chr->opaque; int ret, err; uint8_t buf[1024]; DWORD size; ZeroMemory(&s->orecv, sizeof(s->orecv)); s->orecv.hEvent = s->hrecv; ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv); if (!ret) { err = GetLastError(); if (err == ERROR_IO_PENDING) { ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE); } } if (size > 0) { qemu_chr_read(chr, buf, size); } }


void mips_r4k_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; const char *cpu_model = machine->cpu_model; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; char *filename; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios; MemoryRegion *iomem = g_new(MemoryRegion, 1); MemoryRegion *isa_io = g_new(MemoryRegion, 1); MemoryRegion *isa_mem = g_new(MemoryRegion, 1); int bios_size; MIPSCPU *cpu; CPUMIPSState *env; ResetData *reset_info; int i; qemu_irq *i8259; ISABus *isa_bus; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; DriveInfo *dinfo; int be; /* init CPUs */ if (cpu_model == NULL) { #ifdef TARGET_MIPS64 cpu_model = "R4000"; #else cpu_model = "24Kf"; #endif } cpu = cpu_mips_init(cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } env = &cpu->env; reset_info = g_malloc0(sizeof(ResetData)); reset_info->cpu = cpu; reset_info->vector = env->active_tc.PC; qemu_register_reset(main_cpu_reset, reset_info); /* allocate RAM */ if (ram_size > (256 << 20)) { fprintf(stderr, "qemu: Too much memory for this machine: %d MB, maximum 256 MB\n", ((unsigned int)ram_size / (1 << 20))); exit(1); } memory_region_allocate_system_memory(ram, NULL, "mips_r4k.ram", ram_size); memory_region_add_subregion(address_space_mem, 0, ram); memory_region_init_io(iomem, NULL, &mips_qemu_ops, NULL, "mips-qemu", 0x10000); memory_region_add_subregion(address_space_mem, 0x1fbf0000, iomem); /* Try to load a BIOS image. If this fails, we continue regardless, but initialize the hardware ourselves. When a kernel gets preloaded we also initialize the hardware, since the BIOS wasn't run. */ if (bios_name == NULL) bios_name = BIOS_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { bios_size = get_image_size(filename); } else { bios_size = -1; } #ifdef TARGET_WORDS_BIGENDIAN be = 1; #else be = 0; #endif if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) { bios = g_new(MemoryRegion, 1); memory_region_init_ram(bios, NULL, "mips_r4k.bios", BIOS_SIZE, &error_fatal); memory_region_set_readonly(bios, true); memory_region_add_subregion(get_system_memory(), 0x1fc00000, bios); load_image_targphys(filename, 0x1fc00000, BIOS_SIZE); } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) { uint32_t mips_rom = 0x00400000; if (!pflash_cfi01_register(0x1fc00000, NULL, "mips_r4k.bios", mips_rom, blk_by_legacy_dinfo(dinfo), sector_len, mips_rom / sector_len, 4, 0, 0, 0, 0, be)) { fprintf(stderr, "qemu: Error registering flash memory.\n"); } } else if (!qtest_enabled()) { /* not fatal */ fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n", bios_name); } g_free(filename); if (kernel_filename) { loaderparams.ram_size = ram_size; loaderparams.kernel_filename = kernel_filename; loaderparams.kernel_cmdline = kernel_cmdline; loaderparams.initrd_filename = initrd_filename; reset_info->vector = load_kernel(); } /* Init CPU internal devices */ cpu_mips_irq_init_cpu(cpu); cpu_mips_clock_init(cpu); /* ISA bus: IO space at 0x14000000, mem space at 0x10000000 */ memory_region_init_alias(isa_io, NULL, "isa-io", get_system_io(), 0, 0x00010000); memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000); memory_region_add_subregion(get_system_memory(), 0x14000000, isa_io); memory_region_add_subregion(get_system_memory(), 0x10000000, isa_mem); isa_bus = isa_bus_new(NULL, isa_mem, get_system_io(), &error_abort); /* The PIC is attached to the MIPS CPU INT0 pin */ i8259 = i8259_init(isa_bus, env->irq[2]); isa_bus_irqs(isa_bus, i8259); rtc_init(isa_bus, 2000, NULL); pit = pit_init(isa_bus, 0x40, 0, NULL); serial_hds_isa_init(isa_bus, 0, MAX_SERIAL_PORTS); isa_vga_init(isa_bus); if (nd_table[0].used) isa_ne2000_init(isa_bus, 0x300, 9, &nd_table[0]); ide_drive_get(hd, ARRAY_SIZE(hd)); for(i = 0; i < MAX_IDE_BUS; i++) isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i], hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); isa_create_simple(isa_bus, "i8042"); }


static int write_note(struct memelfnote *men, int fd) { struct elf_note en; en.n_namesz = men->namesz; en.n_type = men->type; en.n_descsz = men->datasz; bswap_note(&en); if (dump_write(fd, &en, sizeof(en)) != 0) return (-1); if (dump_write(fd, men->name, men->namesz_rounded) != 0) return (-1); if (dump_write(fd, men->data, men->datasz) != 0) return (-1); return (0); }


static int vhost_virtqueue_start(struct vhost_dev *dev, struct VirtIODevice *vdev, struct vhost_virtqueue *vq, unsigned idx) { hwaddr s, l, a; int r; int vhost_vq_index = idx - dev->vq_index; struct vhost_vring_file file = { .index = vhost_vq_index }; struct vhost_vring_state state = { .index = vhost_vq_index }; struct VirtQueue *vvq = virtio_get_queue(vdev, idx); assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs); vq->num = state.num = virtio_queue_get_num(vdev, idx); r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_NUM, &state); if (r) { return -errno; } state.num = virtio_queue_get_last_avail_idx(vdev, idx); r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_BASE, &state); if (r) { return -errno; } if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1) && virtio_legacy_is_cross_endian(vdev)) { r = vhost_virtqueue_set_vring_endian_legacy(dev, virtio_is_big_endian(vdev), vhost_vq_index); if (r) { return -errno; } } s = l = virtio_queue_get_desc_size(vdev, idx); a = virtio_queue_get_desc_addr(vdev, idx); vq->desc = cpu_physical_memory_map(a, &l, 0); if (!vq->desc || l != s) { r = -ENOMEM; goto fail_alloc_desc; } s = l = virtio_queue_get_avail_size(vdev, idx); a = virtio_queue_get_avail_addr(vdev, idx); vq->avail = cpu_physical_memory_map(a, &l, 0); if (!vq->avail || l != s) { r = -ENOMEM; goto fail_alloc_avail; } vq->used_size = s = l = virtio_queue_get_used_size(vdev, idx); vq->used_phys = a = virtio_queue_get_used_addr(vdev, idx); vq->used = cpu_physical_memory_map(a, &l, 1); if (!vq->used || l != s) { r = -ENOMEM; goto fail_alloc_used; } vq->ring_size = s = l = virtio_queue_get_ring_size(vdev, idx); vq->ring_phys = a = virtio_queue_get_ring_addr(vdev, idx); vq->ring = cpu_physical_memory_map(a, &l, 1); if (!vq->ring || l != s) { r = -ENOMEM; goto fail_alloc_ring; } r = vhost_virtqueue_set_addr(dev, vq, vhost_vq_index, dev->log_enabled); if (r < 0) { r = -errno; goto fail_alloc; } file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq)); r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_KICK, &file); if (r) { r = -errno; goto fail_kick; } /* Clear and discard previous events if any. */ event_notifier_test_and_clear(&vq->masked_notifier); return 0; fail_kick: fail_alloc: cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx), 0, 0); fail_alloc_ring: cpu_physical_memory_unmap(vq->used, virtio_queue_get_used_size(vdev, idx), 0, 0); fail_alloc_used: cpu_physical_memory_unmap(vq->avail, virtio_queue_get_avail_size(vdev, idx), 0, 0); fail_alloc_avail: cpu_physical_memory_unmap(vq->desc, virtio_queue_get_desc_size(vdev, idx), 0, 0); fail_alloc_desc: return r; }


void vnc_client_read(void *opaque) { VncState *vs = opaque; long ret; #ifdef CONFIG_VNC_SASL if (vs->sasl.conn && vs->sasl.runSSF) ret = vnc_client_read_sasl(vs); else #endif /* CONFIG_VNC_SASL */ #ifdef CONFIG_VNC_WS if (vs->encode_ws) { ret = vnc_client_read_ws(vs); if (ret == -1) { vnc_disconnect_start(vs); return; } else if (ret == -2) { vnc_client_error(vs); return; } } else #endif /* CONFIG_VNC_WS */ { ret = vnc_client_read_plain(vs); } if (!ret) { if (vs->csock == -1) vnc_disconnect_finish(vs); return; } while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) { size_t len = vs->read_handler_expect; int ret; ret = vs->read_handler(vs, vs->input.buffer, len); if (vs->csock == -1) { vnc_disconnect_finish(vs); return; } if (!ret) { buffer_advance(&vs->input, len); } else { vs->read_handler_expect = ret; } } }


static void update_sono_yuv(AVFrame *sono, const ColorFloat *c, int idx) { int x, fmt = sono->format, w = sono->width; uint8_t *lpy = sono->data[0] + idx * sono->linesize[0]; uint8_t *lpu = sono->data[1] + idx * sono->linesize[1]; uint8_t *lpv = sono->data[2] + idx * sono->linesize[2]; for (x = 0; x < w; x += 2) { *lpy++ = c[x].yuv.y + 0.5f; *lpu++ = c[x].yuv.u + 0.5f; *lpv++ = c[x].yuv.v + 0.5f; *lpy++ = c[x+1].yuv.y + 0.5f; if (fmt == AV_PIX_FMT_YUV444P) { *lpu++ = c[x+1].yuv.u + 0.5f; *lpv++ = c[x+1].yuv.v + 0.5f; } } }


static int find_pte32(CPUPPCState *env, struct mmu_ctx_hash32 *ctx, target_ulong sr, target_ulong eaddr, int rwx) { hwaddr pteg_off, pte_offset; ppc_hash_pte32_t pte; hwaddr hash; uint32_t vsid, pgidx, ptem; int ret; ret = -1; /* No entry found */ vsid = sr & SR32_VSID; ctx->key = (((sr & SR32_KP) && (msr_pr != 0)) || ((sr & SR32_KS) && (msr_pr == 0))) ? 1 : 0; pgidx = (eaddr & ~SEGMENT_MASK_256M) >> TARGET_PAGE_BITS; hash = vsid ^ pgidx; ptem = (vsid << 7) | (pgidx >> 10); /* Page address translation */ LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx " hash " TARGET_FMT_plx "\n", env->htab_base, env->htab_mask, hash); /* Primary PTEG lookup */ LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx " vsid=%" PRIx32 " ptem=%" PRIx32 " hash=" TARGET_FMT_plx "\n", env->htab_base, env->htab_mask, vsid, ptem, hash); pteg_off = get_pteg_offset32(env, hash); pte_offset = ppc_hash32_pteg_search(env, pteg_off, 0, ptem, &pte); if (pte_offset == -1) { /* Secondary PTEG lookup */ LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx " vsid=%" PRIx32 " api=%" PRIx32 " hash=" TARGET_FMT_plx "\n", env->htab_base, env->htab_mask, vsid, ptem, ~hash); pteg_off = get_pteg_offset32(env, ~hash); pte_offset = ppc_hash32_pteg_search(env, pteg_off, 1, ptem, &pte); } if (pte_offset != -1) { ret = pte_check_hash32(ctx, pte.pte0, pte.pte1, rwx); LOG_MMU("found PTE at addr %08" HWADDR_PRIx " prot=%01x ret=%d\n", ctx->raddr, ctx->prot, ret); /* Update page flags */ if (ppc_hash32_pte_update_flags(ctx, &pte.pte1, ret, rwx) == 1) { ppc_hash32_store_hpte1(env, pte_offset, pte.pte1); } } return ret; }


static void csrhci_in_packet_vendor(struct csrhci_s *s, int ocf, uint8_t *data, int len) { int offset; uint8_t *rpkt; switch (ocf) { case OCF_CSR_SEND_FIRMWARE: /* Check if this is the bd_address packet */ if (len >= 18 + 8 && data[12] == 0x01 && data[13] == 0x00) { offset = 18; s->bd_addr.b[0] = data[offset + 7]; /* Beyond cmd packet end(!?) */ s->bd_addr.b[1] = data[offset + 6]; s->bd_addr.b[2] = data[offset + 4]; s->bd_addr.b[3] = data[offset + 0]; s->bd_addr.b[4] = data[offset + 3]; s->bd_addr.b[5] = data[offset + 2]; s->hci->bdaddr_set(s->hci, s->bd_addr.b); fprintf(stderr, "%s: bd_address loaded from firmware: " "%02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__, s->bd_addr.b[0], s->bd_addr.b[1], s->bd_addr.b[2], s->bd_addr.b[3], s->bd_addr.b[4], s->bd_addr.b[5]); } rpkt = csrhci_out_packet_event(s, EVT_VENDOR, 11); /* Status bytes: no error */ rpkt[9] = 0x00; rpkt[10] = 0x00; break; default: fprintf(stderr, "%s: got a bad CMD packet\n", __FUNCTION__); return; } csrhci_fifo_wake(s); }


static void spapr_cpu_core_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); dc->realize = spapr_cpu_core_realize; }


static int vnc_display_listen(VncDisplay *vd, SocketAddressLegacy **saddr, size_t nsaddr, SocketAddressLegacy **wsaddr, size_t nwsaddr, Error **errp) { size_t i; for (i = 0; i < nsaddr; i++) { if (vnc_display_listen_addr(vd, saddr[i], "vnc-listen", &vd->lsock, &vd->lsock_tag, &vd->nlsock, errp) < 0) { return -1; } } for (i = 0; i < nwsaddr; i++) { if (vnc_display_listen_addr(vd, wsaddr[i], "vnc-ws-listen", &vd->lwebsock, &vd->lwebsock_tag, &vd->nlwebsock, errp) < 0) { return -1; } } return 0; }


static int do_create_others(int type, struct iovec *iovec) { dev_t rdev; int retval = 0; int offset = PROXY_HDR_SZ; V9fsString oldpath, path; int mode, uid, gid, cur_uid, cur_gid; v9fs_string_init(&path); v9fs_string_init(&oldpath); cur_uid = geteuid(); cur_gid = getegid(); retval = proxy_unmarshal(iovec, offset, "dd", &uid, &gid); if (retval < 0) { return retval; } offset += retval; retval = setfsugid(uid, gid); if (retval < 0) { retval = -errno; goto err_out; } switch (type) { case T_MKNOD: retval = proxy_unmarshal(iovec, offset, "sdq", &path, &mode, &rdev); if (retval < 0) { goto err_out; } retval = mknod(path.data, mode, rdev); break; case T_MKDIR: retval = proxy_unmarshal(iovec, offset, "sd", &path, &mode); if (retval < 0) { goto err_out; } retval = mkdir(path.data, mode); break; case T_SYMLINK: retval = proxy_unmarshal(iovec, offset, "ss", &oldpath, &path); if (retval < 0) { goto err_out; } retval = symlink(oldpath.data, path.data); break; } if (retval < 0) { retval = -errno; } err_out: v9fs_string_free(&path); v9fs_string_free(&oldpath); setfsugid(cur_uid, cur_gid); return retval; }


void blockdev_auto_del(BlockDriverState *bs) { DriveInfo *dinfo = drive_get_by_blockdev(bs); if (dinfo->auto_del) { drive_uninit(dinfo); } }


void helper_lcall_protected_T0_T1(int shift, int next_eip) { int new_cs, new_eip; uint32_t e1, e2, cpl, dpl, rpl, selector, offset, param_count; uint32_t ss, ss_e1, ss_e2, push_size, sp, type, ss_dpl; uint32_t old_ss, old_esp, val, i, limit; uint8_t *ssp, *old_ssp; new_cs = T0; new_eip = T1; if ((new_cs & 0xfffc) == 0) raise_exception_err(EXCP0D_GPF, 0); if (load_segment(&e1, &e2, new_cs) != 0) raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); cpl = env->hflags & HF_CPL_MASK; if (e2 & DESC_S_MASK) { if (!(e2 & DESC_CS_MASK)) raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); dpl = (e2 >> DESC_DPL_SHIFT) & 3; if (e2 & DESC_CS_MASK) { /* conforming code segment */ if (dpl > cpl) raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); } else { /* non conforming code segment */ rpl = new_cs & 3; if (rpl > cpl) raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); if (dpl != cpl) raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); } if (!(e2 & DESC_P_MASK)) raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc); sp = ESP; if (!(env->segs[R_SS].flags & DESC_B_MASK)) sp &= 0xffff; ssp = env->segs[R_SS].base + sp; if (shift) { ssp -= 4; stl_kernel(ssp, env->segs[R_CS].selector); ssp -= 4; stl_kernel(ssp, next_eip); } else { ssp -= 2; stw_kernel(ssp, env->segs[R_CS].selector); ssp -= 2; stw_kernel(ssp, next_eip); } sp -= (4 << shift); limit = get_seg_limit(e1, e2); if (new_eip > limit) raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); /* from this point, not restartable */ if (!(env->segs[R_SS].flags & DESC_B_MASK)) ESP = (ESP & 0xffff0000) | (sp & 0xffff); else ESP = sp; cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl, get_seg_base(e1, e2), limit, e2); EIP = new_eip; } else { /* check gate type */ type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; switch(type) { case 1: /* available 286 TSS */ case 9: /* available 386 TSS */ case 5: /* task gate */ cpu_abort(env, "task gate not supported"); break; case 4: /* 286 call gate */ case 12: /* 386 call gate */ break; default: raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); break; } shift = type >> 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; rpl = new_cs & 3; if (dpl < cpl || dpl < rpl) raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); /* check valid bit */ if (!(e2 & DESC_P_MASK)) raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc); selector = e1 >> 16; offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff); if ((selector & 0xfffc) == 0) raise_exception_err(EXCP0D_GPF, 0); if (load_segment(&e1, &e2, selector) != 0) raise_exception_err(EXCP0D_GPF, selector & 0xfffc); if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) raise_exception_err(EXCP0D_GPF, selector & 0xfffc); dpl = (e2 >> DESC_DPL_SHIFT) & 3; if (dpl > cpl) raise_exception_err(EXCP0D_GPF, selector & 0xfffc); if (!(e2 & DESC_P_MASK)) raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc); if (!(e2 & DESC_C_MASK) && dpl < cpl) { /* to inner priviledge */ get_ss_esp_from_tss(&ss, &sp, dpl); if ((ss & 0xfffc) == 0) raise_exception_err(EXCP0A_TSS, ss & 0xfffc); if ((ss & 3) != dpl) raise_exception_err(EXCP0A_TSS, ss & 0xfffc); if (load_segment(&ss_e1, &ss_e2, ss) != 0) raise_exception_err(EXCP0A_TSS, ss & 0xfffc); ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3; if (ss_dpl != dpl) raise_exception_err(EXCP0A_TSS, ss & 0xfffc); if (!(ss_e2 & DESC_S_MASK) || (ss_e2 & DESC_CS_MASK) || !(ss_e2 & DESC_W_MASK)) raise_exception_err(EXCP0A_TSS, ss & 0xfffc); if (!(ss_e2 & DESC_P_MASK)) raise_exception_err(EXCP0A_TSS, ss & 0xfffc); param_count = e2 & 0x1f; push_size = ((param_count * 2) + 8) << shift; old_esp = ESP; old_ss = env->segs[R_SS].selector; if (!(env->segs[R_SS].flags & DESC_B_MASK)) old_esp &= 0xffff; old_ssp = env->segs[R_SS].base + old_esp; /* XXX: from this point not restartable */ ss = (ss & ~3) | dpl; cpu_x86_load_seg_cache(env, R_SS, ss, get_seg_base(ss_e1, ss_e2), get_seg_limit(ss_e1, ss_e2), ss_e2); if (!(env->segs[R_SS].flags & DESC_B_MASK)) sp &= 0xffff; ssp = env->segs[R_SS].base + sp; if (shift) { ssp -= 4; stl_kernel(ssp, old_ss); ssp -= 4; stl_kernel(ssp, old_esp); ssp -= 4 * param_count; for(i = 0; i < param_count; i++) { val = ldl_kernel(old_ssp + i * 4); stl_kernel(ssp + i * 4, val); } } else { ssp -= 2; stw_kernel(ssp, old_ss); ssp -= 2; stw_kernel(ssp, old_esp); ssp -= 2 * param_count; for(i = 0; i < param_count; i++) { val = lduw_kernel(old_ssp + i * 2); stw_kernel(ssp + i * 2, val); } } } else { /* to same priviledge */ if (!(env->segs[R_SS].flags & DESC_B_MASK)) sp &= 0xffff; ssp = env->segs[R_SS].base + sp; push_size = (4 << shift); } if (shift) { ssp -= 4; stl_kernel(ssp, env->segs[R_CS].selector); ssp -= 4; stl_kernel(ssp, next_eip); } else { ssp -= 2; stw_kernel(ssp, env->segs[R_CS].selector); ssp -= 2; stw_kernel(ssp, next_eip); } sp -= push_size; selector = (selector & ~3) | dpl; cpu_x86_load_seg_cache(env, R_CS, selector, get_seg_base(e1, e2), get_seg_limit(e1, e2), e2); cpu_x86_set_cpl(env, dpl); /* from this point, not restartable if same priviledge */ if (!(env->segs[R_SS].flags & DESC_B_MASK)) ESP = (ESP & 0xffff0000) | (sp & 0xffff); else ESP = sp; EIP = offset; } }


static void armv7m_nvic_realize(DeviceState *dev, Error **errp) { NVICState *s = NVIC(dev); SysBusDevice *systick_sbd; Error *err = NULL; s->cpu = ARM_CPU(qemu_get_cpu(0)); assert(s->cpu); if (s->num_irq > NVIC_MAX_IRQ) { error_setg(errp, "num-irq %d exceeds NVIC maximum", s->num_irq); return; } qdev_init_gpio_in(dev, set_irq_level, s->num_irq); /* include space for internal exception vectors */ s->num_irq += NVIC_FIRST_IRQ; object_property_set_bool(OBJECT(&s->systick), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); return; } systick_sbd = SYS_BUS_DEVICE(&s->systick); sysbus_connect_irq(systick_sbd, 0, qdev_get_gpio_in_named(dev, "systick-trigger", 0)); /* The NVIC and System Control Space (SCS) starts at 0xe000e000 * and looks like this: * 0x004 - ICTR * 0x010 - 0xff - systick * 0x100..0x7ec - NVIC * 0x7f0..0xcff - Reserved * 0xd00..0xd3c - SCS registers * 0xd40..0xeff - Reserved or Not implemented * 0xf00 - STIR */ memory_region_init(&s->container, OBJECT(s), "nvic", 0x1000); /* The system register region goes at the bottom of the priority * stack as it covers the whole page. */ memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s, "nvic_sysregs", 0x1000); memory_region_add_subregion(&s->container, 0, &s->sysregmem); memory_region_add_subregion_overlap(&s->container, 0x10, sysbus_mmio_get_region(systick_sbd, 0), 1); sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container); }


static int nprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *n_val) { OMAContext *oc = s->priv_data; uint32_t pos, taglen, datalen; struct AVDES av_des; if (!enc_header || !n_val) return -1; pos = OMA_ENC_HEADER_SIZE + oc->k_size; if (!memcmp(&enc_header[pos], "EKB ", 4)) pos += 32; if (AV_RB32(&enc_header[pos]) != oc->rid) av_log(s, AV_LOG_DEBUG, "Mismatching RID\n"); taglen = AV_RB32(&enc_header[pos+32]); datalen = AV_RB32(&enc_header[pos+36]) >> 4; pos += 44 + taglen; av_des_init(&av_des, n_val, 192, 1); while (datalen-- > 0) { av_des_crypt(&av_des, oc->r_val, &enc_header[pos], 2, NULL, 1); kset(s, oc->r_val, NULL, 16); if (!rprobe(s, enc_header, oc->r_val)) return 0; pos += 16; } return -1; }


static gboolean nbd_negotiate_continue(QIOChannel *ioc, GIOCondition condition, void *opaque) { qemu_coroutine_enter(opaque, NULL); return TRUE; }


void object_add(const char *type, const char *id, const QDict *qdict, Visitor *v, Error **errp) { Object *obj; const QDictEntry *e; Error *local_err = NULL; if (!object_class_by_name(type)) { error_setg(errp, "invalid class name"); return; } obj = object_new(type); if (qdict) { for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) { object_property_set(obj, v, e->key, &local_err); if (local_err) { goto out; } } } if (!object_dynamic_cast(obj, TYPE_USER_CREATABLE)) { error_setg(&local_err, "object type '%s' isn't supported by object-add", type); goto out; } user_creatable_complete(obj, &local_err); if (local_err) { goto out; } object_property_add_child(container_get(object_get_root(), "/objects"), id, obj, &local_err); out: if (local_err) { error_propagate(errp, local_err); } object_unref(obj); }


static int create_filtergraph(AVFilterContext *ctx, const AVFrame *in, const AVFrame *out) { ColorSpaceContext *s = ctx->priv; const AVPixFmtDescriptor *in_desc = av_pix_fmt_desc_get(in->format); const AVPixFmtDescriptor *out_desc = av_pix_fmt_desc_get(out->format); int emms = 0, m, n, o, res, fmt_identical, redo_yuv2rgb = 0, redo_rgb2yuv = 0; #define supported_depth(d) ((d) == 8 || (d) == 10 || (d) == 12) #define supported_subsampling(lcw, lch) \ (((lcw) == 0 && (lch) == 0) || ((lcw) == 1 && (lch) == 0) || ((lcw) == 1 && (lch) == 1)) #define supported_format(d) \ ((d) != NULL && (d)->nb_components == 3 && \ !((d)->flags & AV_PIX_FMT_FLAG_RGB) && \ supported_depth((d)->comp[0].depth) && \ supported_subsampling((d)->log2_chroma_w, (d)->log2_chroma_h)) if (!supported_format(in_desc)) { av_log(ctx, AV_LOG_ERROR, "Unsupported input format %d (%s) or bitdepth (%d)\n", in->format, av_get_pix_fmt_name(in->format), in_desc ? in_desc->comp[0].depth : -1); return AVERROR(EINVAL); } if (!supported_format(out_desc)) { av_log(ctx, AV_LOG_ERROR, "Unsupported output format %d (%s) or bitdepth (%d)\n", out->format, av_get_pix_fmt_name(out->format), out_desc ? out_desc->comp[0].depth : -1); return AVERROR(EINVAL); } if (in->color_primaries != s->in_prm) s->in_primaries = NULL; if (out->color_primaries != s->out_prm) s->out_primaries = NULL; if (in->color_trc != s->in_trc) s->in_txchr = NULL; if (out->color_trc != s->out_trc) s->out_txchr = NULL; if (in->colorspace != s->in_csp || in->color_range != s->in_rng) s->in_lumacoef = NULL; if (out->colorspace != s->out_csp || out->color_range != s->out_rng) s->out_lumacoef = NULL; if (!s->out_primaries || !s->in_primaries) { s->in_prm = in->color_primaries; s->in_primaries = get_color_primaries(s->in_prm); if (!s->in_primaries) { av_log(ctx, AV_LOG_ERROR, "Unsupported input primaries %d (%s)\n", s->in_prm, av_color_primaries_name(s->in_prm)); return AVERROR(EINVAL); } s->out_prm = out->color_primaries; s->out_primaries = get_color_primaries(s->out_prm); if (!s->out_primaries) { if (s->out_prm == AVCOL_PRI_UNSPECIFIED) { if (s->user_all == CS_UNSPECIFIED) { av_log(ctx, AV_LOG_ERROR, "Please specify output primaries\n"); } else { av_log(ctx, AV_LOG_ERROR, "Unsupported output color property %d\n", s->user_all); } } else { av_log(ctx, AV_LOG_ERROR, "Unsupported output primaries %d (%s)\n", s->out_prm, av_color_primaries_name(s->out_prm)); } return AVERROR(EINVAL); } s->lrgb2lrgb_passthrough = !memcmp(s->in_primaries, s->out_primaries, sizeof(*s->in_primaries)); if (!s->lrgb2lrgb_passthrough) { double rgb2xyz[3][3], xyz2rgb[3][3], rgb2rgb[3][3]; fill_rgb2xyz_table(s->out_primaries, rgb2xyz); invert_matrix3x3(rgb2xyz, xyz2rgb); fill_rgb2xyz_table(s->in_primaries, rgb2xyz); if (s->out_primaries->wp != s->in_primaries->wp && s->wp_adapt != WP_ADAPT_IDENTITY) { double wpconv[3][3], tmp[3][3]; fill_whitepoint_conv_table(wpconv, s->wp_adapt, s->in_primaries->wp, s->out_primaries->wp); mul3x3(tmp, rgb2xyz, wpconv); mul3x3(rgb2rgb, tmp, xyz2rgb); } else { mul3x3(rgb2rgb, rgb2xyz, xyz2rgb); } for (m = 0; m < 3; m++) for (n = 0; n < 3; n++) { s->lrgb2lrgb_coeffs[m][n][0] = lrint(16384.0 * rgb2rgb[m][n]); for (o = 1; o < 8; o++) s->lrgb2lrgb_coeffs[m][n][o] = s->lrgb2lrgb_coeffs[m][n][0]; } emms = 1; } } if (!s->in_txchr) { av_freep(&s->lin_lut); s->in_trc = in->color_trc; s->in_txchr = get_transfer_characteristics(s->in_trc); if (!s->in_txchr) { av_log(ctx, AV_LOG_ERROR, "Unsupported input transfer characteristics %d (%s)\n", s->in_trc, av_color_transfer_name(s->in_trc)); return AVERROR(EINVAL); } } if (!s->out_txchr) { av_freep(&s->lin_lut); s->out_trc = out->color_trc; s->out_txchr = get_transfer_characteristics(s->out_trc); if (!s->out_txchr) { if (s->out_trc == AVCOL_TRC_UNSPECIFIED) { if (s->user_all == CS_UNSPECIFIED) { av_log(ctx, AV_LOG_ERROR, "Please specify output transfer characteristics\n"); } else { av_log(ctx, AV_LOG_ERROR, "Unsupported output color property %d\n", s->user_all); } } else { av_log(ctx, AV_LOG_ERROR, "Unsupported output transfer characteristics %d (%s)\n", s->out_trc, av_color_transfer_name(s->out_trc)); } return AVERROR(EINVAL); } } s->rgb2rgb_passthrough = s->fast_mode || (s->lrgb2lrgb_passthrough && !memcmp(s->in_txchr, s->out_txchr, sizeof(*s->in_txchr))); if (!s->rgb2rgb_passthrough && !s->lin_lut) { res = fill_gamma_table(s); if (res < 0) return res; emms = 1; } if (!s->in_lumacoef) { s->in_csp = in->colorspace; s->in_rng = in->color_range; s->in_lumacoef = get_luma_coefficients(s->in_csp); if (!s->in_lumacoef) { av_log(ctx, AV_LOG_ERROR, "Unsupported input colorspace %d (%s)\n", s->in_csp, av_color_space_name(s->in_csp)); return AVERROR(EINVAL); } redo_yuv2rgb = 1; } if (!s->out_lumacoef) { s->out_csp = out->colorspace; s->out_rng = out->color_range; s->out_lumacoef = get_luma_coefficients(s->out_csp); if (!s->out_lumacoef) { if (s->out_csp == AVCOL_SPC_UNSPECIFIED) { if (s->user_all == CS_UNSPECIFIED) { av_log(ctx, AV_LOG_ERROR, "Please specify output transfer characteristics\n"); } else { av_log(ctx, AV_LOG_ERROR, "Unsupported output color property %d\n", s->user_all); } } else { av_log(ctx, AV_LOG_ERROR, "Unsupported output transfer characteristics %d (%s)\n", s->out_csp, av_color_space_name(s->out_csp)); } return AVERROR(EINVAL); } redo_rgb2yuv = 1; } fmt_identical = in_desc->log2_chroma_h == out_desc->log2_chroma_h && in_desc->log2_chroma_w == out_desc->log2_chroma_w; s->yuv2yuv_fastmode = s->rgb2rgb_passthrough && fmt_identical; s->yuv2yuv_passthrough = s->yuv2yuv_fastmode && s->in_rng == s->out_rng && !memcmp(s->in_lumacoef, s->out_lumacoef, sizeof(*s->in_lumacoef)); if (!s->yuv2yuv_passthrough) { if (redo_yuv2rgb) { double rgb2yuv[3][3], (*yuv2rgb)[3] = s->yuv2rgb_dbl_coeffs; int off, bits, in_rng; res = get_range_off(&off, &s->in_y_rng, &s->in_uv_rng, s->in_rng, in_desc->comp[0].depth); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "Unsupported input color range %d (%s)\n", s->in_rng, av_color_range_name(s->in_rng)); return res; } for (n = 0; n < 8; n++) s->yuv_offset[0][n] = off; fill_rgb2yuv_table(s->in_lumacoef, rgb2yuv); invert_matrix3x3(rgb2yuv, yuv2rgb); bits = 1 << (in_desc->comp[0].depth - 1); for (n = 0; n < 3; n++) { for (in_rng = s->in_y_rng, m = 0; m < 3; m++, in_rng = s->in_uv_rng) { s->yuv2rgb_coeffs[n][m][0] = lrint(28672 * bits * yuv2rgb[n][m] / in_rng); for (o = 1; o < 8; o++) s->yuv2rgb_coeffs[n][m][o] = s->yuv2rgb_coeffs[n][m][0]; } } av_assert2(s->yuv2rgb_coeffs[0][1][0] == 0); av_assert2(s->yuv2rgb_coeffs[2][2][0] == 0); av_assert2(s->yuv2rgb_coeffs[0][0][0] == s->yuv2rgb_coeffs[1][0][0]); av_assert2(s->yuv2rgb_coeffs[0][0][0] == s->yuv2rgb_coeffs[2][0][0]); s->yuv2rgb = s->dsp.yuv2rgb[(in_desc->comp[0].depth - 8) >> 1] [in_desc->log2_chroma_h + in_desc->log2_chroma_w]; emms = 1; } if (redo_rgb2yuv) { double (*rgb2yuv)[3] = s->rgb2yuv_dbl_coeffs; int off, out_rng, bits; res = get_range_off(&off, &s->out_y_rng, &s->out_uv_rng, s->out_rng, out_desc->comp[0].depth); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "Unsupported output color range %d (%s)\n", s->out_rng, av_color_range_name(s->out_rng)); return res; } for (n = 0; n < 8; n++) s->yuv_offset[1][n] = off; fill_rgb2yuv_table(s->out_lumacoef, rgb2yuv); bits = 1 << (29 - out_desc->comp[0].depth); for (out_rng = s->out_y_rng, n = 0; n < 3; n++, out_rng = s->out_uv_rng) { for (m = 0; m < 3; m++) { s->rgb2yuv_coeffs[n][m][0] = lrint(bits * out_rng * rgb2yuv[n][m] / 28672); for (o = 1; o < 8; o++) s->rgb2yuv_coeffs[n][m][o] = s->rgb2yuv_coeffs[n][m][0]; } } av_assert2(s->rgb2yuv_coeffs[1][2][0] == s->rgb2yuv_coeffs[2][0][0]); s->rgb2yuv = s->dsp.rgb2yuv[(out_desc->comp[0].depth - 8) >> 1] [out_desc->log2_chroma_h + out_desc->log2_chroma_w]; s->rgb2yuv_fsb = s->dsp.rgb2yuv_fsb[(out_desc->comp[0].depth - 8) >> 1] [out_desc->log2_chroma_h + out_desc->log2_chroma_w]; emms = 1; } if (s->yuv2yuv_fastmode && (redo_yuv2rgb || redo_rgb2yuv)) { int idepth = in_desc->comp[0].depth, odepth = out_desc->comp[0].depth; double (*rgb2yuv)[3] = s->rgb2yuv_dbl_coeffs; double (*yuv2rgb)[3] = s->yuv2rgb_dbl_coeffs; double yuv2yuv[3][3]; int in_rng, out_rng; mul3x3(yuv2yuv, yuv2rgb, rgb2yuv); for (out_rng = s->out_y_rng, m = 0; m < 3; m++, out_rng = s->out_uv_rng) { for (in_rng = s->in_y_rng, n = 0; n < 3; n++, in_rng = s->in_uv_rng) { s->yuv2yuv_coeffs[m][n][0] = lrint(16384 * yuv2yuv[m][n] * out_rng * (1 << idepth) / (in_rng * (1 << odepth))); for (o = 1; o < 8; o++) s->yuv2yuv_coeffs[m][n][o] = s->yuv2yuv_coeffs[m][n][0]; } } av_assert2(s->yuv2yuv_coeffs[1][0][0] == 0); av_assert2(s->yuv2yuv_coeffs[2][0][0] == 0); s->yuv2yuv = s->dsp.yuv2yuv[(idepth - 8) >> 1][(odepth - 8) >> 1] [in_desc->log2_chroma_h + in_desc->log2_chroma_w]; } } if (emms) emms_c(); return 0; }


AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff){ AVResampleContext *c= av_mallocz(sizeof(AVResampleContext)); double factor= FFMIN(out_rate * cutoff / in_rate, 1.0); int phase_count= 1<<phase_shift; if (!c) return NULL; c->phase_shift= phase_shift; c->phase_mask= phase_count-1; c->linear= linear; c->filter_length= FFMAX((int)ceil(filter_size/factor), 1); c->filter_bank= av_mallocz(c->filter_length*(phase_count+1)*sizeof(FELEM)); if (!c->filter_bank) goto error; if (build_filter(c->filter_bank, factor, c->filter_length, phase_count, 1<<FILTER_SHIFT, WINDOW_TYPE)) goto error; memcpy(&c->filter_bank[c->filter_length*phase_count+1], c->filter_bank, (c->filter_length-1)*sizeof(FELEM)); c->filter_bank[c->filter_length*phase_count]= c->filter_bank[c->filter_length - 1]; c->src_incr= out_rate; c->ideal_dst_incr= c->dst_incr= in_rate * phase_count; c->index= -phase_count*((c->filter_length-1)/2); return c; error: av_free(c->filter_bank); av_free(c); return NULL; }