static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) { unsigned int i; x86_def_t *def; char *s = g_strdup(cpu_model); char *featurestr, *name = strtok(s, ","); /* Features to be added*/ uint32_t plus_features = 0, plus_ext_features = 0; uint32_t plus_ext2_features = 0, plus_ext3_features = 0; uint32_t plus_kvm_features = 0, plus_svm_features = 0; /* Features to be removed */ uint32_t minus_features = 0, minus_ext_features = 0; uint32_t minus_ext2_features = 0, minus_ext3_features = 0; uint32_t minus_kvm_features = 0, minus_svm_features = 0; uint32_t numvalue; for (def = x86_defs; def; def = def->next) if (!strcmp(name, def->name)) break; if (kvm_enabled() && strcmp(name, "host") == 0) { cpu_x86_fill_host(x86_cpu_def); } else if (!def) { goto error; } else { memcpy(x86_cpu_def, def, sizeof(*def)); } plus_kvm_features = ~0; /* not supported bits will be filtered out later */ add_flagname_to_bitmaps("hypervisor", &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features, &plus_kvm_features, &plus_svm_features); featurestr = strtok(NULL, ","); while (featurestr) { char *val; if (featurestr[0] == '+') { add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features, &plus_kvm_features, &plus_svm_features); } else if (featurestr[0] == '-') { add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features, &minus_kvm_features, &minus_svm_features); } else if ((val = strchr(featurestr, '='))) { *val = 0; val++; if (!strcmp(featurestr, "family")) { char *err; numvalue = strtoul(val, &err, 0); if (!*val || *err) { fprintf(stderr, "bad numerical value %s\n", val); goto error; } x86_cpu_def->family = numvalue; } else if (!strcmp(featurestr, "model")) { char *err; numvalue = strtoul(val, &err, 0); if (!*val || *err || numvalue > 0xff) { fprintf(stderr, "bad numerical value %s\n", val); goto error; } x86_cpu_def->model = numvalue; } else if (!strcmp(featurestr, "stepping")) { char *err; numvalue = strtoul(val, &err, 0); if (!*val || *err || numvalue > 0xf) { fprintf(stderr, "bad numerical value %s\n", val); goto error; } x86_cpu_def->stepping = numvalue ; } else if (!strcmp(featurestr, "level")) { char *err; numvalue = strtoul(val, &err, 0); if (!*val || *err) { fprintf(stderr, "bad numerical value %s\n", val); goto error; } x86_cpu_def->level = numvalue; } else if (!strcmp(featurestr, "xlevel")) { char *err; numvalue = strtoul(val, &err, 0); if (!*val || *err) { fprintf(stderr, "bad numerical value %s\n", val); goto error; } if (numvalue < 0x80000000) { numvalue += 0x80000000; } x86_cpu_def->xlevel = numvalue; } else if (!strcmp(featurestr, "vendor")) { if (strlen(val) != 12) { fprintf(stderr, "vendor string must be 12 chars long\n"); goto error; } x86_cpu_def->vendor1 = 0; x86_cpu_def->vendor2 = 0; x86_cpu_def->vendor3 = 0; for(i = 0; i < 4; i++) { x86_cpu_def->vendor1 |= ((uint8_t)val[i ]) << (8 * i); x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i); x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i); } x86_cpu_def->vendor_override = 1; } else if (!strcmp(featurestr, "model_id")) { pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id), val); } else if (!strcmp(featurestr, "tsc_freq")) { int64_t tsc_freq; char *err; tsc_freq = strtosz_suffix_unit(val, &err, STRTOSZ_DEFSUFFIX_B, 1000); if (!*val || *err) { fprintf(stderr, "bad numerical value %s\n", val); goto error; } x86_cpu_def->tsc_khz = tsc_freq / 1000; } else { fprintf(stderr, "unrecognized feature %s\n", featurestr); goto error; } } else if (!strcmp(featurestr, "check")) { check_cpuid = 1; } else if (!strcmp(featurestr, "enforce")) { check_cpuid = enforce_cpuid = 1; } else { fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr); goto error; } featurestr = strtok(NULL, ","); } x86_cpu_def->features |= plus_features; x86_cpu_def->ext_features |= plus_ext_features; x86_cpu_def->ext2_features |= plus_ext2_features; x86_cpu_def->ext3_features |= plus_ext3_features; x86_cpu_def->kvm_features |= plus_kvm_features; x86_cpu_def->svm_features |= plus_svm_features; x86_cpu_def->features &= ~minus_features; x86_cpu_def->ext_features &= ~minus_ext_features; x86_cpu_def->ext2_features &= ~minus_ext2_features; x86_cpu_def->ext3_features &= ~minus_ext3_features; x86_cpu_def->kvm_features &= ~minus_kvm_features; x86_cpu_def->svm_features &= ~minus_svm_features; if (check_cpuid) { if (check_features_against_host(x86_cpu_def) && enforce_cpuid) goto error; } g_free(s); return 0; error: g_free(s); return -1; }


static int virtio_gpu_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info) { VirtIOGPU *g = opaque; if (idx > g->conf.max_outputs) { return -1; } g->req_state[idx].x = info->xoff; g->req_state[idx].y = info->yoff; g->req_state[idx].width = info->width; g->req_state[idx].height = info->height; if (info->width && info->height) { g->enabled_output_bitmask |= (1 << idx); } else { g->enabled_output_bitmask &= ~(1 << idx); } /* send event to guest */ virtio_gpu_notify_event(g, VIRTIO_GPU_EVENT_DISPLAY); return 0; }


void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { sPAPRCPUCore *core = SPAPR_CPU_CORE(OBJECT(dev)); PowerPCCPU *cpu = POWERPC_CPU(core->threads); int id = ppc_get_vcpu_dt_id(cpu); sPAPRDRConnector *drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, id); sPAPRDRConnectorClass *drck; Error *local_err = NULL; g_assert(drc); drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); drck->detach(drc, dev, spapr_core_release, NULL, &local_err); if (local_err) { error_propagate(errp, local_err); return; } spapr_hotplug_req_remove_by_index(drc); }


static void qobject_input_check_struct(Visitor *v, Error **errp) { QObjectInputVisitor *qiv = to_qiv(v); StackObject *tos = QSLIST_FIRST(&qiv->stack); assert(tos && !tos->entry); if (qiv->strict) { GHashTable *const top_ht = tos->h; if (top_ht) { GHashTableIter iter; const char *key; g_hash_table_iter_init(&iter, top_ht); if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) { error_setg(errp, "Parameter '%s' is unexpected", key); } } } }


static int mpeg_decode_slice(MpegEncContext *s, int mb_y, const uint8_t **buf, int buf_size) { AVCodecContext *avctx = s->avctx; const int field_pic = s->picture_structure != PICT_FRAME; int ret; s->resync_mb_x = s->resync_mb_y = -1; assert(mb_y < s->mb_height); init_get_bits(&s->gb, *buf, buf_size * 8); ff_mpeg1_clean_buffers(s); s->interlaced_dct = 0; s->qscale = get_qscale(s); if (s->qscale == 0) { av_log(s->avctx, AV_LOG_ERROR, "qscale == 0\n"); return AVERROR_INVALIDDATA; } /* extra slice info */ while (get_bits1(&s->gb) != 0) skip_bits(&s->gb, 8); s->mb_x = 0; if (mb_y == 0 && s->codec_tag == AV_RL32("SLIF")) { skip_bits1(&s->gb); } else { while (get_bits_left(&s->gb) > 0) { int code = get_vlc2(&s->gb, ff_mbincr_vlc.table, MBINCR_VLC_BITS, 2); if (code < 0) { av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n"); return AVERROR_INVALIDDATA; } if (code >= 33) { if (code == 33) s->mb_x += 33; /* otherwise, stuffing, nothing to do */ } else { s->mb_x += code; break; } } } if (s->mb_x >= (unsigned) s->mb_width) { av_log(s->avctx, AV_LOG_ERROR, "initial skip overflow\n"); return AVERROR_INVALIDDATA; } if (avctx->hwaccel) { const uint8_t *buf_end, *buf_start = *buf - 4; /* include start_code */ int start_code = -1; buf_end = avpriv_find_start_code(buf_start + 2, *buf + buf_size, &start_code); if (buf_end < *buf + buf_size) buf_end -= 4; s->mb_y = mb_y; if (avctx->hwaccel->decode_slice(avctx, buf_start, buf_end - buf_start) < 0) return DECODE_SLICE_ERROR; *buf = buf_end; return DECODE_SLICE_OK; } s->resync_mb_x = s->mb_x; s->resync_mb_y = s->mb_y = mb_y; s->mb_skip_run = 0; ff_init_block_index(s); if (s->mb_y == 0 && s->mb_x == 0 && (s->first_field || s->picture_structure == PICT_FRAME)) { if (s->avctx->debug & FF_DEBUG_PICT_INFO) { av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%2d%2d%2d%2d %s %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n", s->qscale, s->mpeg_f_code[0][0], s->mpeg_f_code[0][1], s->mpeg_f_code[1][0], s->mpeg_f_code[1][1], s->pict_type == AV_PICTURE_TYPE_I ? "I" : (s->pict_type == AV_PICTURE_TYPE_P ? "P" : (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")), s->progressive_sequence ? "ps" : "", s->progressive_frame ? "pf" : "", s->alternate_scan ? "alt" : "", s->top_field_first ? "top" : "", s->intra_dc_precision, s->picture_structure, s->frame_pred_frame_dct, s->concealment_motion_vectors, s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" : ""); } } for (;;) { #if FF_API_XVMC FF_DISABLE_DEPRECATION_WARNINGS // If 1, we memcpy blocks in xvmcvideo. if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) ff_xvmc_init_block(s); // set s->block FF_ENABLE_DEPRECATION_WARNINGS #endif /* FF_API_XVMC */ if ((ret = mpeg_decode_mb(s, s->block)) < 0) return ret; // Note motion_val is normally NULL unless we want to extract the MVs. if (s->current_picture.motion_val[0] && !s->encoding) { const int wrap = s->b8_stride; int xy = s->mb_x * 2 + s->mb_y * 2 * wrap; int b8_xy = 4 * (s->mb_x + s->mb_y * s->mb_stride); int motion_x, motion_y, dir, i; for (i = 0; i < 2; i++) { for (dir = 0; dir < 2; dir++) { if (s->mb_intra || (dir == 1 && s->pict_type != AV_PICTURE_TYPE_B)) { motion_x = motion_y = 0; } else if (s->mv_type == MV_TYPE_16X16 || (s->mv_type == MV_TYPE_FIELD && field_pic)) { motion_x = s->mv[dir][0][0]; motion_y = s->mv[dir][0][1]; } else { /* if ((s->mv_type == MV_TYPE_FIELD) || (s->mv_type == MV_TYPE_16X8)) */ motion_x = s->mv[dir][i][0]; motion_y = s->mv[dir][i][1]; } s->current_picture.motion_val[dir][xy][0] = motion_x; s->current_picture.motion_val[dir][xy][1] = motion_y; s->current_picture.motion_val[dir][xy + 1][0] = motion_x; s->current_picture.motion_val[dir][xy + 1][1] = motion_y; s->current_picture.ref_index [dir][b8_xy] = s->current_picture.ref_index [dir][b8_xy + 1] = s->field_select[dir][i]; assert(s->field_select[dir][i] == 0 || s->field_select[dir][i] == 1); } xy += wrap; b8_xy += 2; } } s->dest[0] += 16; s->dest[1] += 16 >> s->chroma_x_shift; s->dest[2] += 16 >> s->chroma_x_shift; ff_mpv_decode_mb(s, s->block); if (++s->mb_x >= s->mb_width) { const int mb_size = 16; ff_mpeg_draw_horiz_band(s, mb_size * (s->mb_y >> field_pic), mb_size); ff_mpv_report_decode_progress(s); s->mb_x = 0; s->mb_y += 1 << field_pic; if (s->mb_y >= s->mb_height) { int left = get_bits_left(&s->gb); int is_d10 = s->chroma_format == 2 && s->pict_type == AV_PICTURE_TYPE_I && avctx->profile == 0 && avctx->level == 5 && s->intra_dc_precision == 2 && s->q_scale_type == 1 && s->alternate_scan == 0 && s->progressive_frame == 0 /* vbv_delay == 0xBBB || 0xE10 */; if (left < 0 || (left && show_bits(&s->gb, FFMIN(left, 23)) && !is_d10) || ((avctx->err_recognition & AV_EF_BUFFER) && left > 8)) { av_log(avctx, AV_LOG_ERROR, "end mismatch left=%d %0X\n", left, show_bits(&s->gb, FFMIN(left, 23))); return AVERROR_INVALIDDATA; } else goto eos; } ff_init_block_index(s); } /* skip mb handling */ if (s->mb_skip_run == -1) { /* read increment again */ s->mb_skip_run = 0; for (;;) { int code = get_vlc2(&s->gb, ff_mbincr_vlc.table, MBINCR_VLC_BITS, 2); if (code < 0) { av_log(s->avctx, AV_LOG_ERROR, "mb incr damaged\n"); return AVERROR_INVALIDDATA; } if (code >= 33) { if (code == 33) { s->mb_skip_run += 33; } else if (code == 35) { if (s->mb_skip_run != 0 || show_bits(&s->gb, 15) != 0) { av_log(s->avctx, AV_LOG_ERROR, "slice mismatch\n"); return AVERROR_INVALIDDATA; } goto eos; /* end of slice */ } /* otherwise, stuffing, nothing to do */ } else { s->mb_skip_run += code; break; } } if (s->mb_skip_run) { int i; if (s->pict_type == AV_PICTURE_TYPE_I) { av_log(s->avctx, AV_LOG_ERROR, "skipped MB in I-frame at %d %d\n", s->mb_x, s->mb_y); return AVERROR_INVALIDDATA; } /* skip mb */ s->mb_intra = 0; for (i = 0; i < 12; i++) s->block_last_index[i] = -1; if (s->picture_structure == PICT_FRAME) s->mv_type = MV_TYPE_16X16; else s->mv_type = MV_TYPE_FIELD; if (s->pict_type == AV_PICTURE_TYPE_P) { /* if P type, zero motion vector is implied */ s->mv_dir = MV_DIR_FORWARD; s->mv[0][0][0] = s->mv[0][0][1] = 0; s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0; s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0; s->field_select[0][0] = (s->picture_structure - 1) & 1; } else { /* if B type, reuse previous vectors and directions */ s->mv[0][0][0] = s->last_mv[0][0][0]; s->mv[0][0][1] = s->last_mv[0][0][1]; s->mv[1][0][0] = s->last_mv[1][0][0]; s->mv[1][0][1] = s->last_mv[1][0][1]; } } } } eos: // end of slice *buf += (get_bits_count(&s->gb) - 1) / 8; ff_dlog(s, "y %d %d %d %d\n", s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y); return 0; }


create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern) { size_t *sizes = calloc(nr_iov, sizeof(size_t)); size_t count = 0; void *buf, *p; int i; for (i = 0; i < nr_iov; i++) { char *arg = argv[i]; long long len; len = cvtnum(arg); if (len < 0) { printf("non-numeric length argument -- %s\n", arg); return NULL; } /* should be SIZE_T_MAX, but that doesn't exist */ if (len > UINT_MAX) { printf("too large length argument -- %s\n", arg); return NULL; } if (len & 0x1ff) { printf("length argument %lld is not sector aligned\n", len); return NULL; } sizes[i] = len; count += len; } qemu_iovec_init(qiov, nr_iov); buf = p = qemu_io_alloc(count, pattern); for (i = 0; i < nr_iov; i++) { qemu_iovec_add(qiov, p, sizes[i]); p += sizes[i]; } free(sizes); return buf; }


static int vid_probe(AVProbeData *p) { // little-endian VID tag, file starts with "VID\0" if (AV_RL32(p->buf) != MKTAG('V', 'I', 'D', 0)) return 0; return AVPROBE_SCORE_MAX; }


void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) { int i; for (i = 0; ; i++) { (*cpu_fprintf)(f, "PowerPC %-16s PVR %08x\n", ppc_defs[i].name, ppc_defs[i].pvr); if (strcmp(ppc_defs[i].name, "default") == 0) break; } }


void object_delete(Object *obj) { object_unparent(obj); g_assert(obj->ref == 1); object_unref(obj); g_free(obj); }


static int mpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) { Mpeg1Context *s = avctx->priv_data; uint8_t *buf_end, *buf_ptr; int ret, start_code, input_size; AVFrame *picture = data; MpegEncContext *s2 = &s->mpeg_enc_ctx; dprintf("fill_buffer\n"); *data_size = 0; /* special case for last picture */ if (buf_size == 0) { if (s2->picture_number > 0) { *picture= *(AVFrame*)&s2->next_picture; *data_size = sizeof(AVFrame); } return 0; } if(s2->flags&CODEC_FLAG_TRUNCATED){ int next; next= mpeg1_find_frame_end(s2, buf, buf_size); if( ff_combine_frame(s2, next, &buf, &buf_size) < 0 ) return buf_size; } buf_ptr = buf; buf_end = buf + buf_size; #if 0 if (s->repeat_field % 2 == 1) { s->repeat_field++; //fprintf(stderr,"\nRepeating last frame: %d -> %d! pict: %d %d", avctx->frame_number-1, avctx->frame_number, // s2->picture_number, s->repeat_field); if (avctx->flags & CODEC_FLAG_REPEAT_FIELD) { *data_size = sizeof(AVPicture); goto the_end; } } #endif for(;;) { /* find start next code */ start_code = find_start_code(&buf_ptr, buf_end); if (start_code < 0){ printf("missing end of picture\n"); return FFMAX(1, buf_ptr - buf - s2->parse_context.last_index); } /* prepare data for next start code */ input_size = buf_end - buf_ptr; switch(start_code) { case SEQ_START_CODE: mpeg1_decode_sequence(avctx, buf_ptr, input_size); break; case PICTURE_START_CODE: /* we have a complete image : we try to decompress it */ mpeg1_decode_picture(avctx, buf_ptr, input_size); break; case EXT_START_CODE: mpeg_decode_extension(avctx, buf_ptr, input_size); break; case USER_START_CODE: mpeg_decode_user_data(avctx, buf_ptr, input_size); break; default: if (start_code >= SLICE_MIN_START_CODE && start_code <= SLICE_MAX_START_CODE) { /* skip b frames if we dont have reference frames */ if(s2->last_picture_ptr==NULL && s2->pict_type==B_TYPE) break; /* skip b frames if we are in a hurry */ if(avctx->hurry_up && s2->pict_type==B_TYPE) break; /* skip everything if we are in a hurry>=5 */ if(avctx->hurry_up>=5) break; if (!s->mpeg_enc_ctx_allocated) break; ret = mpeg_decode_slice(avctx, picture, start_code, &buf_ptr, input_size); if (ret == DECODE_SLICE_EOP) { if(s2->last_picture_ptr) //FIXME merge with the stuff in mpeg_decode_slice *data_size = sizeof(AVPicture); return FFMAX(1, buf_ptr - buf - s2->parse_context.last_index); }else if(ret < 0){ if(ret == DECODE_SLICE_ERROR) ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x, s2->mb_y, AC_ERROR|DC_ERROR|MV_ERROR); fprintf(stderr,"Error while decoding slice\n"); if(ret==DECODE_SLICE_FATAL_ERROR) return -1; } } break; } } }


static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun, int evpd, int pc) { int full_size; struct scsi_task *task = NULL; task = iscsi_inquiry_sync(iscsi, lun, evpd, pc, 64); if (task == NULL || task->status != SCSI_STATUS_GOOD) { goto fail; } full_size = scsi_datain_getfullsize(task); if (full_size > task->datain.size) { scsi_free_scsi_task(task); /* we need more data for the full list */ task = iscsi_inquiry_sync(iscsi, lun, evpd, pc, full_size); if (task == NULL || task->status != SCSI_STATUS_GOOD) { goto fail; } } return task; fail: error_report("iSCSI: Inquiry command failed : %s", iscsi_get_error(iscsi)); if (task) { scsi_free_scsi_task(task); return NULL; } return NULL; }


static target_ulong h_add_logical_lan_buffer(CPUPPCState *env, sPAPREnvironment *spapr, target_ulong opcode, target_ulong *args) { target_ulong reg = args[0]; target_ulong buf = args[1]; VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg); VIOsPAPRVLANDevice *dev = (VIOsPAPRVLANDevice *)sdev; vlan_bd_t bd; dprintf("H_ADD_LOGICAL_LAN_BUFFER(0x" TARGET_FMT_lx ", 0x" TARGET_FMT_lx ")\n", reg, buf); if (!sdev) { hcall_dprintf("Bad device\n"); return H_PARAMETER; } if ((check_bd(dev, buf, 4) < 0) || (VLAN_BD_LEN(buf) < 16)) { hcall_dprintf("Bad buffer enqueued\n"); return H_PARAMETER; } if (!dev->isopen || dev->rx_bufs >= VLAN_MAX_BUFS) { return H_RESOURCE; } do { dev->add_buf_ptr += 8; if (dev->add_buf_ptr >= SPAPR_VIO_TCE_PAGE_SIZE) { dev->add_buf_ptr = VLAN_RX_BDS_OFF; } bd = ldq_tce(sdev, dev->buf_list + dev->add_buf_ptr); } while (bd & VLAN_BD_VALID); stq_tce(sdev, dev->buf_list + dev->add_buf_ptr, buf); dev->rx_bufs++; dprintf("h_add_logical_lan_buffer(): Added buf ptr=%d rx_bufs=%d" " bd=0x%016llx\n", dev->add_buf_ptr, dev->rx_bufs, (unsigned long long)buf); return H_SUCCESS; }


static uint32_t unassigned_mem_readw(void *opaque, target_phys_addr_t addr) { #ifdef DEBUG_UNASSIGNED printf("Unassigned mem read " TARGET_FMT_plx "\n", addr); #endif #if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) do_unassigned_access(addr, 0, 0, 0, 2); #endif return 0; }


static int pcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { int n, c, sample_size, v, ret; const short *samples; unsigned char *dst; const uint8_t *samples_uint8_t; const int16_t *samples_int16_t; const int32_t *samples_int32_t; const int64_t *samples_int64_t; const uint16_t *samples_uint16_t; const uint32_t *samples_uint32_t; sample_size = av_get_bits_per_sample(avctx->codec->id) / 8; n = frame->nb_samples * avctx->channels; samples = (const short *)frame->data[0]; if ((ret = ff_alloc_packet2(avctx, avpkt, n * sample_size))) return ret; dst = avpkt->data; switch (avctx->codec->id) { case AV_CODEC_ID_PCM_U32LE: ENCODE(uint32_t, le32, samples, dst, n, 0, 0x80000000) break; case AV_CODEC_ID_PCM_U32BE: ENCODE(uint32_t, be32, samples, dst, n, 0, 0x80000000) break; case AV_CODEC_ID_PCM_S24LE: ENCODE(int32_t, le24, samples, dst, n, 8, 0) break; case AV_CODEC_ID_PCM_S24LE_PLANAR: ENCODE_PLANAR(int32_t, le24, dst, n, 8, 0) break; case AV_CODEC_ID_PCM_S24BE: ENCODE(int32_t, be24, samples, dst, n, 8, 0) break; case AV_CODEC_ID_PCM_U24LE: ENCODE(uint32_t, le24, samples, dst, n, 8, 0x800000) break; case AV_CODEC_ID_PCM_U24BE: ENCODE(uint32_t, be24, samples, dst, n, 8, 0x800000) break; case AV_CODEC_ID_PCM_S24DAUD: for (; n > 0; n--) { uint32_t tmp = ff_reverse[(*samples >> 8) & 0xff] + (ff_reverse[*samples & 0xff] << 8); tmp <<= 4; // sync flags would go here bytestream_put_be24(&dst, tmp); samples++; } break; case AV_CODEC_ID_PCM_U16LE: ENCODE(uint16_t, le16, samples, dst, n, 0, 0x8000) break; case AV_CODEC_ID_PCM_U16BE: ENCODE(uint16_t, be16, samples, dst, n, 0, 0x8000) break; case AV_CODEC_ID_PCM_S8: ENCODE(uint8_t, byte, samples, dst, n, 0, -128) break; case AV_CODEC_ID_PCM_S8_PLANAR: ENCODE_PLANAR(uint8_t, byte, dst, n, 0, -128) break; #if HAVE_BIGENDIAN case AV_CODEC_ID_PCM_F64LE: ENCODE(int64_t, le64, samples, dst, n, 0, 0) break; case AV_CODEC_ID_PCM_S32LE: case AV_CODEC_ID_PCM_F32LE: ENCODE(int32_t, le32, samples, dst, n, 0, 0) break; case AV_CODEC_ID_PCM_S32LE_PLANAR: ENCODE_PLANAR(int32_t, le32, dst, n, 0, 0) break; case AV_CODEC_ID_PCM_S16LE: ENCODE(int16_t, le16, samples, dst, n, 0, 0) break; case AV_CODEC_ID_PCM_S16LE_PLANAR: ENCODE_PLANAR(int16_t, le16, dst, n, 0, 0) break; case AV_CODEC_ID_PCM_F64BE: case AV_CODEC_ID_PCM_F32BE: case AV_CODEC_ID_PCM_S32BE: case AV_CODEC_ID_PCM_S16BE: #else case AV_CODEC_ID_PCM_F64BE: ENCODE(int64_t, be64, samples, dst, n, 0, 0) break; case AV_CODEC_ID_PCM_F32BE: case AV_CODEC_ID_PCM_S32BE: ENCODE(int32_t, be32, samples, dst, n, 0, 0) break; case AV_CODEC_ID_PCM_S16BE: ENCODE(int16_t, be16, samples, dst, n, 0, 0) break; case AV_CODEC_ID_PCM_S16BE_PLANAR: ENCODE_PLANAR(int16_t, be16, dst, n, 0, 0) break; case AV_CODEC_ID_PCM_F64LE: case AV_CODEC_ID_PCM_F32LE: case AV_CODEC_ID_PCM_S32LE: case AV_CODEC_ID_PCM_S16LE: #endif /* HAVE_BIGENDIAN */ case AV_CODEC_ID_PCM_U8: memcpy(dst, samples, n * sample_size); break; #if HAVE_BIGENDIAN case AV_CODEC_ID_PCM_S16BE_PLANAR: #else case AV_CODEC_ID_PCM_S16LE_PLANAR: case AV_CODEC_ID_PCM_S32LE_PLANAR: #endif /* HAVE_BIGENDIAN */ n /= avctx->channels; for (c = 0; c < avctx->channels; c++) { const uint8_t *src = frame->extended_data[c]; bytestream_put_buffer(&dst, src, n * sample_size); } break; case AV_CODEC_ID_PCM_ALAW: for (; n > 0; n--) { v = *samples++; *dst++ = linear_to_alaw[(v + 32768) >> 2]; } break; case AV_CODEC_ID_PCM_MULAW: for (; n > 0; n--) { v = *samples++; *dst++ = linear_to_ulaw[(v + 32768) >> 2]; } break; default: return -1; } *got_packet_ptr = 1; return 0; }


static int RENAME(epzs_motion_search)(MpegEncContext * s, int *mx_ptr, int *my_ptr, int P[10][2], int pred_x, int pred_y, uint8_t *src_data[3], uint8_t *ref_data[3], int stride, int uvstride, int16_t (*last_mv)[2], int ref_mv_scale, uint8_t * const mv_penalty) { int best[2]={0, 0}; int d, dmin; const int shift= 1+s->quarter_sample; uint32_t *map= s->me.map; int map_generation; const int penalty_factor= s->me.penalty_factor; const int size=0; const int h=16; const int ref_mv_stride= s->mb_stride; //pass as arg FIXME const int ref_mv_xy= s->mb_x + s->mb_y*ref_mv_stride; //add to last_mv beforepassing FIXME me_cmp_func cmp, chroma_cmp; LOAD_COMMON cmp= s->dsp.me_cmp[size]; chroma_cmp= s->dsp.me_cmp[size+1]; map_generation= update_map_generation(s); CMP(dmin, 0, 0, size); map[0]= map_generation; score_map[0]= dmin; /* first line */ if (s->first_slice_line) { CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) }else{ if(dmin<256 && ( P_LEFT[0] |P_LEFT[1] |P_TOP[0] |P_TOP[1] |P_TOPRIGHT[0]|P_TOPRIGHT[1])==0){ *mx_ptr= 0; *my_ptr= 0; s->me.skip=1; return dmin; } CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift) if(dmin>256*2){ CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) CHECK_MV(P_LEFT[0] >>shift, P_LEFT[1] >>shift) CHECK_MV(P_TOP[0] >>shift, P_TOP[1] >>shift) CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift) } } if(dmin>256*4){ if(s->me.pre_pass){ CHECK_CLIPED_MV((last_mv[ref_mv_xy-1][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy-1][1]*ref_mv_scale + (1<<15))>>16) if(!s->first_slice_line) CHECK_CLIPED_MV((last_mv[ref_mv_xy-ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy-ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) }else{ CHECK_CLIPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16) if(s->end_mb_y == s->mb_height || s->mb_y+1<s->end_mb_y) //FIXME replace at least with last_slice_line CHECK_CLIPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) } } if(s->avctx->last_predictor_count){ const int count= s->avctx->last_predictor_count; const int xstart= FFMAX(0, s->mb_x - count); const int ystart= FFMAX(0, s->mb_y - count); const int xend= FFMIN(s->mb_width , s->mb_x + count + 1); const int yend= FFMIN(s->mb_height, s->mb_y + count + 1); int mb_y; for(mb_y=ystart; mb_y<yend; mb_y++){ int mb_x; for(mb_x=xstart; mb_x<xend; mb_x++){ const int xy= mb_x + 1 + (mb_y + 1)*ref_mv_stride; int mx= (last_mv[xy][0]*ref_mv_scale + (1<<15))>>16; int my= (last_mv[xy][1]*ref_mv_scale + (1<<15))>>16; if(mx>xmax || mx<xmin || my>ymax || my<ymin) continue; CHECK_MV(mx,my) } } } //check(best[0],best[1],0, b0) if(s->me.dia_size==-1) dmin= RENAME(funny_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty); else if(s->me.dia_size<-1) dmin= RENAME(sab_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty); else if(s->me.dia_size<2) dmin= RENAME(small_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty); else dmin= RENAME(var_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty); //check(best[0],best[1],0, b1) *mx_ptr= best[0]; *my_ptr= best[1]; // printf("%d %d %d \n", best[0], best[1], dmin); return dmin; }


static void megasas_complete_frame(MegasasState *s, uint64_t context) { PCIDevice *pci_dev = PCI_DEVICE(s); int tail, queue_offset; /* Decrement busy count */ s->busy--; if (s->reply_queue_pa) { /* * Put command on the reply queue. * Context is opaque, but emulation is running in * little endian. So convert it. */ tail = s->reply_queue_head; if (megasas_use_queue64(s)) { queue_offset = tail * sizeof(uint64_t); stq_le_phys(&address_space_memory, s->reply_queue_pa + queue_offset, context); } else { queue_offset = tail * sizeof(uint32_t); stl_le_phys(&address_space_memory, s->reply_queue_pa + queue_offset, context); } s->reply_queue_head = megasas_next_index(s, tail, s->fw_cmds); s->reply_queue_tail = ldl_le_phys(&address_space_memory, s->consumer_pa); trace_megasas_qf_complete(context, s->reply_queue_head, s->reply_queue_tail, s->busy, s->doorbell); } if (megasas_intr_enabled(s)) { /* Notify HBA */ s->doorbell++; if (s->doorbell == 1) { if (msix_enabled(pci_dev)) { trace_megasas_msix_raise(0); msix_notify(pci_dev, 0); } else if (msi_enabled(pci_dev)) { trace_megasas_msi_raise(0); msi_notify(pci_dev, 0); } else { trace_megasas_irq_raise(); pci_irq_assert(pci_dev); } } } else { trace_megasas_qf_complete_noirq(context); } }


static int decode_residual_block(AVSContext *h, GetBitContext *gb, const dec_2dvlc_t *r, int esc_golomb_order, int qp, uint8_t *dst, int stride) { int i, level_code, esc_code, level, run, mask; DCTELEM level_buf[64]; uint8_t run_buf[64]; DCTELEM *block = h->block; for(i=0;i<65;i++) { level_code = get_ue_code(gb,r->golomb_order); if(level_code >= ESCAPE_CODE) { run = ((level_code - ESCAPE_CODE) >> 1) + 1; esc_code = get_ue_code(gb,esc_golomb_order); level = esc_code + (run > r->max_run ? 1 : r->level_add[run]); while(level > r->inc_limit) r++; mask = -(level_code & 1); level = (level^mask) - mask; } else { level = r->rltab[level_code][0]; if(!level) //end of block signal break; run = r->rltab[level_code][1]; r += r->rltab[level_code][2]; } level_buf[i] = level; run_buf[i] = run; } if(dequant(h,level_buf, run_buf, block, ff_cavs_dequant_mul[qp], ff_cavs_dequant_shift[qp], i)) return -1; h->s.dsp.cavs_idct8_add(dst,block,stride); return 0; }


int ff_thread_decode_frame(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, AVPacket *avpkt) { FrameThreadContext *fctx = avctx->internal->thread_ctx; int finished = fctx->next_finished; PerThreadContext *p; int err; /* release the async lock, permitting blocked hwaccel threads to * go forward while we are in this function */ async_unlock(fctx); /* * Submit a packet to the next decoding thread. */ p = &fctx->threads[fctx->next_decoding]; err = update_context_from_user(p->avctx, avctx); if (err) goto finish; err = submit_packet(p, avpkt); if (err) goto finish; /* * If we're still receiving the initial packets, don't return a frame. */ if (fctx->next_decoding > (avctx->thread_count-1-(avctx->codec_id == AV_CODEC_ID_FFV1))) fctx->delaying = 0; if (fctx->delaying) { *got_picture_ptr=0; if (avpkt->size) { err = avpkt->size; goto finish; } } /* * Return the next available frame from the oldest thread. * If we're at the end of the stream, then we have to skip threads that * didn't output a frame, because we don't want to accidentally signal * EOF (avpkt->size == 0 && *got_picture_ptr == 0). */ do { p = &fctx->threads[finished++]; if (atomic_load(&p->state) != STATE_INPUT_READY) { pthread_mutex_lock(&p->progress_mutex); while (atomic_load_explicit(&p->state, memory_order_relaxed) != STATE_INPUT_READY) pthread_cond_wait(&p->output_cond, &p->progress_mutex); pthread_mutex_unlock(&p->progress_mutex); } av_frame_move_ref(picture, p->frame); *got_picture_ptr = p->got_frame; picture->pkt_dts = p->avpkt.dts; if (p->result < 0) err = p->result; /* * A later call with avkpt->size == 0 may loop over all threads, * including this one, searching for a frame to return before being * stopped by the "finished != fctx->next_finished" condition. * Make sure we don't mistakenly return the same frame again. */ p->got_frame = 0; if (finished >= avctx->thread_count) finished = 0; } while (!avpkt->size && !*got_picture_ptr && finished != fctx->next_finished); update_context_from_thread(avctx, p->avctx, 1); if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0; fctx->next_finished = finished; /* return the size of the consumed packet if no error occurred */ if (err >= 0) err = avpkt->size; finish: async_lock(fctx); return err; }


static void gen_tlbld_6xx(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); #else if (unlikely(ctx->pr)) { gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; } gen_helper_6xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]); #endif }


static int ehci_process_itd(EHCIState *ehci, EHCIitd *itd) { USBDevice *dev; USBEndpoint *ep; int ret; uint32_t i, len, pid, dir, devaddr, endp; uint32_t pg, off, ptr1, ptr2, max, mult; dir =(itd->bufptr[1] & ITD_BUFPTR_DIRECTION); devaddr = get_field(itd->bufptr[0], ITD_BUFPTR_DEVADDR); endp = get_field(itd->bufptr[0], ITD_BUFPTR_EP); max = get_field(itd->bufptr[1], ITD_BUFPTR_MAXPKT); mult = get_field(itd->bufptr[2], ITD_BUFPTR_MULT); for(i = 0; i < 8; i++) { if (itd->transact[i] & ITD_XACT_ACTIVE) { pg = get_field(itd->transact[i], ITD_XACT_PGSEL); off = itd->transact[i] & ITD_XACT_OFFSET_MASK; ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK); ptr2 = (itd->bufptr[pg+1] & ITD_BUFPTR_MASK); len = get_field(itd->transact[i], ITD_XACT_LENGTH); if (len > max * mult) { len = max * mult; } if (len > BUFF_SIZE) { return USB_RET_PROCERR; } pci_dma_sglist_init(&ehci->isgl, &ehci->dev, 2); if (off + len > 4096) { /* transfer crosses page border */ uint32_t len2 = off + len - 4096; uint32_t len1 = len - len2; qemu_sglist_add(&ehci->isgl, ptr1 + off, len1); qemu_sglist_add(&ehci->isgl, ptr2, len2); } else { qemu_sglist_add(&ehci->isgl, ptr1 + off, len); } pid = dir ? USB_TOKEN_IN : USB_TOKEN_OUT; dev = ehci_find_device(ehci, devaddr); ep = usb_ep_get(dev, pid, endp); usb_packet_setup(&ehci->ipacket, pid, ep); usb_packet_map(&ehci->ipacket, &ehci->isgl); ret = usb_handle_packet(dev, &ehci->ipacket); usb_packet_unmap(&ehci->ipacket); qemu_sglist_destroy(&ehci->isgl); #if 0 /* In isoch, there is no facility to indicate a NAK so let's * instead just complete a zero-byte transaction. Setting * DBERR seems too draconian. */ if (ret == USB_RET_NAK) { if (ehci->isoch_pause > 0) { DPRINTF("ISOCH: received a NAK but paused so returning\n"); ehci->isoch_pause--; return 0; } else if (ehci->isoch_pause == -1) { DPRINTF("ISOCH: recv NAK & isoch pause inactive, setting\n"); // Pause frindex for up to 50 msec waiting for data from // remote ehci->isoch_pause = 50; return 0; } else { DPRINTF("ISOCH: isoch pause timeout! return 0\n"); ret = 0; } } else { DPRINTF("ISOCH: received ACK, clearing pause\n"); ehci->isoch_pause = -1; } #else if (ret == USB_RET_NAK) { ret = 0; } #endif if (ret >= 0) { if (!dir) { /* OUT */ set_field(&itd->transact[i], len - ret, ITD_XACT_LENGTH); } else { /* IN */ set_field(&itd->transact[i], ret, ITD_XACT_LENGTH); } if (itd->transact[i] & ITD_XACT_IOC) { ehci_record_interrupt(ehci, USBSTS_INT); } } itd->transact[i] &= ~ITD_XACT_ACTIVE; } } return 0; }


static int swf_probe(AVProbeData *p) { /* check file header */ if (p->buf_size <= 16) return 0; if ((p->buf[0] == 'F' || p->buf[0] == 'C') && p->buf[1] == 'W' && p->buf[2] == 'S') return AVPROBE_SCORE_MAX; else return 0; }


static int16_t *precalc_coefs(double dist25, int depth) { int i; double gamma, simil, C; int16_t *ct = av_malloc((512<<LUT_BITS)*sizeof(int16_t)); if (!ct) return NULL; gamma = log(0.25) / log(1.0 - FFMIN(dist25,252.0)/255.0 - 0.00001); for (i = -255<<LUT_BITS; i <= 255<<LUT_BITS; i++) { double f = ((i<<(9-LUT_BITS)) + (1<<(8-LUT_BITS)) - 1) / 512.0; // midpoint of the bin simil = 1.0 - FFABS(f) / 255.0; C = pow(simil, gamma) * 256.0 * f; ct[(256<<LUT_BITS)+i] = lrint(C); } ct[0] = !!dist25; return ct; }


static void avc_biwgt_4x2_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, int32_t log2_denom, int32_t src_weight, int32_t dst_weight, int32_t offset_in) { uint32_t load0, load1, out0, out1; v16i8 src_wgt, dst_wgt, wgt; v16i8 src0, src1, dst0, dst1; v8i16 temp0, temp1, denom, offset, add_val; int32_t val = 128 * (src_weight + dst_weight); offset_in = ((offset_in + 1) | 1) << log2_denom; src_wgt = __msa_fill_b(src_weight); dst_wgt = __msa_fill_b(dst_weight); offset = __msa_fill_h(offset_in); denom = __msa_fill_h(log2_denom + 1); add_val = __msa_fill_h(val); offset += add_val; wgt = __msa_ilvev_b(dst_wgt, src_wgt); load0 = LOAD_WORD(src); src += src_stride; load1 = LOAD_WORD(src); src0 = (v16i8) __msa_fill_w(load0); src1 = (v16i8) __msa_fill_w(load1); load0 = LOAD_WORD(dst); load1 = LOAD_WORD(dst + dst_stride); dst0 = (v16i8) __msa_fill_w(load0); dst1 = (v16i8) __msa_fill_w(load1); XORI_B_4VECS_SB(src0, src1, dst0, dst1, src0, src1, dst0, dst1, 128); ILVR_B_2VECS_SH(src0, src1, dst0, dst1, temp0, temp1); temp0 = __msa_dpadd_s_h(offset, wgt, (v16i8) temp0); temp1 = __msa_dpadd_s_h(offset, wgt, (v16i8) temp1); temp0 >>= denom; temp1 >>= denom; temp0 = CLIP_UNSIGNED_CHAR_H(temp0); temp1 = CLIP_UNSIGNED_CHAR_H(temp1); dst0 = __msa_pckev_b((v16i8) temp0, (v16i8) temp0); dst1 = __msa_pckev_b((v16i8) temp1, (v16i8) temp1); out0 = __msa_copy_u_w((v4i32) dst0, 0); out1 = __msa_copy_u_w((v4i32) dst1, 0); STORE_WORD(dst, out0); dst += dst_stride; STORE_WORD(dst, out1); }


static int asf_read_value(AVFormatContext *s, uint8_t *name, uint16_t name_len, uint16_t val_len, int type, AVDictionary **met) { int ret; uint8_t *value; uint16_t buflen = 2 * val_len + 1; AVIOContext *pb = s->pb; value = av_malloc(buflen); if (!value) return AVERROR(ENOMEM); if (type == ASF_UNICODE) { // get_asf_string reads UTF-16 and converts it to UTF-8 which needs longer buffer if ((ret = get_asf_string(pb, val_len, value, buflen)) < 0) goto failed; if (av_dict_set(met, name, value, 0) < 0) av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n"); } else { char buf[256]; if (val_len > sizeof(buf)) { ret = AVERROR_INVALIDDATA; goto failed; } if ((ret = avio_read(pb, value, val_len)) < 0) goto failed; if (ret < 2 * val_len) value[ret] = '\0'; else value[2 * val_len - 1] = '\0'; snprintf(buf, sizeof(buf), "%s", value); if (av_dict_set(met, name, buf, 0) < 0) av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n"); } av_freep(&value); return 0; failed: av_freep(&value); return ret; }


static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix) { /* TODO: additional checks possible. */ BDRVVdiState *s = (BDRVVdiState *)bs->opaque; uint32_t blocks_allocated = 0; uint32_t block; uint32_t *bmap; logout("\n"); if (fix) { return -ENOTSUP; } bmap = g_try_malloc(s->header.blocks_in_image * sizeof(uint32_t)); if (s->header.blocks_in_image && bmap == NULL) { res->check_errors++; return -ENOMEM; } memset(bmap, 0xff, s->header.blocks_in_image * sizeof(uint32_t)); /* Check block map and value of blocks_allocated. */ for (block = 0; block < s->header.blocks_in_image; block++) { uint32_t bmap_entry = le32_to_cpu(s->bmap[block]); if (VDI_IS_ALLOCATED(bmap_entry)) { if (bmap_entry < s->header.blocks_in_image) { blocks_allocated++; if (!VDI_IS_ALLOCATED(bmap[bmap_entry])) { bmap[bmap_entry] = bmap_entry; } else { fprintf(stderr, "ERROR: block index %" PRIu32 " also used by %" PRIu32 "\n", bmap[bmap_entry], bmap_entry); res->corruptions++; } } else { fprintf(stderr, "ERROR: block index %" PRIu32 " too large, is %" PRIu32 "\n", block, bmap_entry); res->corruptions++; } } } if (blocks_allocated != s->header.blocks_allocated) { fprintf(stderr, "ERROR: allocated blocks mismatch, is %" PRIu32 ", should be %" PRIu32 "\n", blocks_allocated, s->header.blocks_allocated); res->corruptions++; } g_free(bmap); return 0; }


static void uart_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { LM32UartState *s = opaque; unsigned char ch = value; trace_lm32_uart_memory_write(addr, value); addr >>= 2; switch (addr) { case R_RXTX: if (s->chr) { qemu_chr_fe_write_all(s->chr, &ch, 1); } break; case R_IER: case R_LCR: case R_MCR: case R_DIV: s->regs[addr] = value; break; case R_IIR: case R_LSR: case R_MSR: error_report("lm32_uart: write access to read only register 0x" TARGET_FMT_plx, addr << 2); break; default: error_report("lm32_uart: write access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } uart_update_irq(s); }


static void test_opts_parse_size(void) { Error *err = NULL; QemuOpts *opts; /* Lower limit zero */ opts = qemu_opts_parse(&opts_list_02, "size1=0", false, &error_abort); g_assert_cmpuint(opts_count(opts), ==, 1); g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 0); /* Note: precision is 53 bits since we're parsing with strtod() */ /* Around limit of precision: 2^53-1, 2^53, 2^54 */ opts = qemu_opts_parse(&opts_list_02, "size1=9007199254740991," "size2=9007199254740992," "size3=9007199254740993", false, &error_abort); g_assert_cmpuint(opts_count(opts), ==, 3); g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1), ==, 0x1fffffffffffff); g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1), ==, 0x20000000000000); g_assert_cmphex(qemu_opt_get_size(opts, "size3", 1), ==, 0x20000000000000); /* Close to signed upper limit 0x7ffffffffffffc00 (53 msbs set) */ opts = qemu_opts_parse(&opts_list_02, "size1=9223372036854774784," /* 7ffffffffffffc00 */ "size2=9223372036854775295", /* 7ffffffffffffdff */ false, &error_abort); g_assert_cmpuint(opts_count(opts), ==, 2); g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1), ==, 0x7ffffffffffffc00); g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1), ==, 0x7ffffffffffffc00); /* Close to actual upper limit 0xfffffffffffff800 (53 msbs set) */ opts = qemu_opts_parse(&opts_list_02, "size1=18446744073709549568," /* fffffffffffff800 */ "size2=18446744073709550591", /* fffffffffffffbff */ false, &error_abort); g_assert_cmpuint(opts_count(opts), ==, 2); g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1), ==, 0xfffffffffffff800); g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1), ==, 0xfffffffffffff800); /* Beyond limits */ opts = qemu_opts_parse(&opts_list_02, "size1=-1", false, &err); error_free_or_abort(&err); g_assert(!opts); opts = qemu_opts_parse(&opts_list_02, "size1=18446744073709550592", /* fffffffffffffc00 */ false, &error_abort); /* BUG: should reject */ g_assert_cmpuint(opts_count(opts), ==, 1); g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 0); /* Suffixes */ opts = qemu_opts_parse(&opts_list_02, "size1=8b,size2=1.5k,size3=2M", false, &error_abort); g_assert_cmpuint(opts_count(opts), ==, 3); g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, 8); g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), ==, 1536); g_assert_cmphex(qemu_opt_get_size(opts, "size3", 0), ==, 2 * M_BYTE); opts = qemu_opts_parse(&opts_list_02, "size1=0.1G,size2=16777215T", false, &error_abort); g_assert_cmpuint(opts_count(opts), ==, 2); g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, G_BYTE / 10); g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), ==, 16777215 * T_BYTE); /* Beyond limit with suffix */ opts = qemu_opts_parse(&opts_list_02, "size1=16777216T", false, &error_abort); /* BUG: should reject */ g_assert_cmpuint(opts_count(opts), ==, 1); g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 0); /* Trailing crap */ opts = qemu_opts_parse(&opts_list_02, "size1=16E", false, &err); error_free_or_abort(&err); g_assert(!opts); opts = qemu_opts_parse(&opts_list_02, "size1=16Gi", false, &error_abort); /* BUG: should reject */ g_assert_cmpuint(opts_count(opts), ==, 1); g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 16 * G_BYTE); qemu_opts_reset(&opts_list_02); }


static int usbredir_post_load(void *priv, int version_id) { USBRedirDevice *dev = priv; switch (dev->device_info.speed) { case usb_redir_speed_low: dev->dev.speed = USB_SPEED_LOW; break; case usb_redir_speed_full: dev->dev.speed = USB_SPEED_FULL; break; case usb_redir_speed_high: dev->dev.speed = USB_SPEED_HIGH; break; case usb_redir_speed_super: dev->dev.speed = USB_SPEED_SUPER; break; default: dev->dev.speed = USB_SPEED_FULL; dev->dev.speedmask = (1 << dev->dev.speed); usbredir_setup_usb_eps(dev); usbredir_check_bulk_receiving(dev);


static void smc_decode_stream(SmcContext *s) { int width = s->avctx->width; int height = s->avctx->height; int stride = s->frame.linesize[0]; int i; int stream_ptr = 0; int chunk_size; unsigned char opcode; int n_blocks; unsigned int color_flags; unsigned int color_flags_a; unsigned int color_flags_b; unsigned int flag_mask; unsigned char *pixels = s->frame.data[0]; int image_size = height * s->frame.linesize[0]; int row_ptr = 0; int pixel_ptr = 0; int pixel_x, pixel_y; int row_inc = stride - 4; int block_ptr; int prev_block_ptr; int prev_block_ptr1, prev_block_ptr2; int prev_block_flag; int total_blocks; int color_table_index; /* indexes to color pair, quad, or octet tables */ int pixel; int color_pair_index = 0; int color_quad_index = 0; int color_octet_index = 0; /* make the palette available */ memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE); chunk_size = AV_RB32(&s->buf[stream_ptr]) & 0x00FFFFFF; stream_ptr += 4; if (chunk_size != s->size) av_log(s->avctx, AV_LOG_INFO, "warning: MOV chunk size != encoded chunk size (%d != %d); using MOV chunk size\n", chunk_size, s->size); chunk_size = s->size; total_blocks = ((s->avctx->width + 3) / 4) * ((s->avctx->height + 3) / 4); /* traverse through the blocks */ while (total_blocks) { /* sanity checks */ /* make sure stream ptr hasn't gone out of bounds */ if (stream_ptr > chunk_size) { av_log(s->avctx, AV_LOG_INFO, "SMC decoder just went out of bounds (stream ptr = %d, chunk size = %d)\n", stream_ptr, chunk_size); return; } /* make sure the row pointer hasn't gone wild */ if (row_ptr >= image_size) { av_log(s->avctx, AV_LOG_INFO, "SMC decoder just went out of bounds (row ptr = %d, height = %d)\n", row_ptr, image_size); return; } opcode = s->buf[stream_ptr++]; switch (opcode & 0xF0) { /* skip n blocks */ case 0x00: case 0x10: n_blocks = GET_BLOCK_COUNT(); while (n_blocks--) { ADVANCE_BLOCK(); } break; /* repeat last block n times */ case 0x20: case 0x30: n_blocks = GET_BLOCK_COUNT(); /* sanity check */ if ((row_ptr == 0) && (pixel_ptr == 0)) { av_log(s->avctx, AV_LOG_INFO, "encountered repeat block opcode (%02X) but no blocks rendered yet\n", opcode & 0xF0); break; } /* figure out where the previous block started */ if (pixel_ptr == 0) prev_block_ptr1 = (row_ptr - s->avctx->width * 4) + s->avctx->width - 4; else prev_block_ptr1 = row_ptr + pixel_ptr - 4; while (n_blocks--) { block_ptr = row_ptr + pixel_ptr; prev_block_ptr = prev_block_ptr1; for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++) { pixels[block_ptr++] = pixels[prev_block_ptr++]; } block_ptr += row_inc; prev_block_ptr += row_inc; } ADVANCE_BLOCK(); } break; /* repeat previous pair of blocks n times */ case 0x40: case 0x50: n_blocks = GET_BLOCK_COUNT(); n_blocks *= 2; /* sanity check */ if ((row_ptr == 0) && (pixel_ptr < 2 * 4)) { av_log(s->avctx, AV_LOG_INFO, "encountered repeat block opcode (%02X) but not enough blocks rendered yet\n", opcode & 0xF0); break; } /* figure out where the previous 2 blocks started */ if (pixel_ptr == 0) prev_block_ptr1 = (row_ptr - s->avctx->width * 4) + s->avctx->width - 4 * 2; else if (pixel_ptr == 4) prev_block_ptr1 = (row_ptr - s->avctx->width * 4) + row_inc; else prev_block_ptr1 = row_ptr + pixel_ptr - 4 * 2; if (pixel_ptr == 0) prev_block_ptr2 = (row_ptr - s->avctx->width * 4) + row_inc; else prev_block_ptr2 = row_ptr + pixel_ptr - 4; prev_block_flag = 0; while (n_blocks--) { block_ptr = row_ptr + pixel_ptr; if (prev_block_flag) prev_block_ptr = prev_block_ptr2; else prev_block_ptr = prev_block_ptr1; prev_block_flag = !prev_block_flag; for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++) { pixels[block_ptr++] = pixels[prev_block_ptr++]; } block_ptr += row_inc; prev_block_ptr += row_inc; } ADVANCE_BLOCK(); } break; /* 1-color block encoding */ case 0x60: case 0x70: n_blocks = GET_BLOCK_COUNT(); pixel = s->buf[stream_ptr++]; while (n_blocks--) { block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++) { pixels[block_ptr++] = pixel; } block_ptr += row_inc; } ADVANCE_BLOCK(); } break; /* 2-color block encoding */ case 0x80: case 0x90: n_blocks = (opcode & 0x0F) + 1; /* figure out which color pair to use to paint the 2-color block */ if ((opcode & 0xF0) == 0x80) { /* fetch the next 2 colors from bytestream and store in next * available entry in the color pair table */ for (i = 0; i < CPAIR; i++) { pixel = s->buf[stream_ptr++]; color_table_index = CPAIR * color_pair_index + i; s->color_pairs[color_table_index] = pixel; } /* this is the base index to use for this block */ color_table_index = CPAIR * color_pair_index; color_pair_index++; /* wraparound */ if (color_pair_index == COLORS_PER_TABLE) color_pair_index = 0; } else color_table_index = CPAIR * s->buf[stream_ptr++]; while (n_blocks--) { color_flags = AV_RB16(&s->buf[stream_ptr]); stream_ptr += 2; flag_mask = 0x8000; block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++) { if (color_flags & flag_mask) pixel = color_table_index + 1; else pixel = color_table_index; flag_mask >>= 1; pixels[block_ptr++] = s->color_pairs[pixel]; } block_ptr += row_inc; } ADVANCE_BLOCK(); } break; /* 4-color block encoding */ case 0xA0: case 0xB0: n_blocks = (opcode & 0x0F) + 1; /* figure out which color quad to use to paint the 4-color block */ if ((opcode & 0xF0) == 0xA0) { /* fetch the next 4 colors from bytestream and store in next * available entry in the color quad table */ for (i = 0; i < CQUAD; i++) { pixel = s->buf[stream_ptr++]; color_table_index = CQUAD * color_quad_index + i; s->color_quads[color_table_index] = pixel; } /* this is the base index to use for this block */ color_table_index = CQUAD * color_quad_index; color_quad_index++; /* wraparound */ if (color_quad_index == COLORS_PER_TABLE) color_quad_index = 0; } else color_table_index = CQUAD * s->buf[stream_ptr++]; while (n_blocks--) { color_flags = AV_RB32(&s->buf[stream_ptr]); stream_ptr += 4; /* flag mask actually acts as a bit shift count here */ flag_mask = 30; block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++) { pixel = color_table_index + ((color_flags >> flag_mask) & 0x03); flag_mask -= 2; pixels[block_ptr++] = s->color_quads[pixel]; } block_ptr += row_inc; } ADVANCE_BLOCK(); } break; /* 8-color block encoding */ case 0xC0: case 0xD0: n_blocks = (opcode & 0x0F) + 1; /* figure out which color octet to use to paint the 8-color block */ if ((opcode & 0xF0) == 0xC0) { /* fetch the next 8 colors from bytestream and store in next * available entry in the color octet table */ for (i = 0; i < COCTET; i++) { pixel = s->buf[stream_ptr++]; color_table_index = COCTET * color_octet_index + i; s->color_octets[color_table_index] = pixel; } /* this is the base index to use for this block */ color_table_index = COCTET * color_octet_index; color_octet_index++; /* wraparound */ if (color_octet_index == COLORS_PER_TABLE) color_octet_index = 0; } else color_table_index = COCTET * s->buf[stream_ptr++]; while (n_blocks--) { /* For this input of 6 hex bytes: 01 23 45 67 89 AB Mangle it to this output: flags_a = xx012456, flags_b = xx89A37B */ /* build the color flags */ color_flags_a = ((AV_RB16(s->buf + stream_ptr ) & 0xFFF0) << 8) | (AV_RB16(s->buf + stream_ptr + 2) >> 4); color_flags_b = ((AV_RB16(s->buf + stream_ptr + 4) & 0xFFF0) << 8) | ((s->buf[stream_ptr + 1] & 0x0F) << 8) | ((s->buf[stream_ptr + 3] & 0x0F) << 4) | (s->buf[stream_ptr + 5] & 0x0F); stream_ptr += 6; color_flags = color_flags_a; /* flag mask actually acts as a bit shift count here */ flag_mask = 21; block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { /* reload flags at third row (iteration pixel_y == 2) */ if (pixel_y == 2) { color_flags = color_flags_b; flag_mask = 21; } for (pixel_x = 0; pixel_x < 4; pixel_x++) { pixel = color_table_index + ((color_flags >> flag_mask) & 0x07); flag_mask -= 3; pixels[block_ptr++] = s->color_octets[pixel]; } block_ptr += row_inc; } ADVANCE_BLOCK(); } break; /* 16-color block encoding (every pixel is a different color) */ case 0xE0: n_blocks = (opcode & 0x0F) + 1; while (n_blocks--) { block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++) { pixels[block_ptr++] = s->buf[stream_ptr++]; } block_ptr += row_inc; } ADVANCE_BLOCK(); } break; case 0xF0: av_log(s->avctx, AV_LOG_INFO, "0xF0 opcode seen in SMC chunk (contact the developers)\n"); break; } } }


static void vhost_scsi_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); dc->exit = vhost_scsi_exit; dc->props = vhost_scsi_properties; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); vdc->init = vhost_scsi_init; vdc->get_features = vhost_scsi_get_features; vdc->set_config = vhost_scsi_set_config; vdc->set_status = vhost_scsi_set_status; }


ivshmem_client_parse_args(IvshmemClientArgs *args, int argc, char *argv[]) { int c; while ((c = getopt(argc, argv, "h" /* help */ "v" /* verbose */ "S:" /* unix_sock_path */ )) != -1) { switch (c) { case 'h': /* help */ ivshmem_client_usage(argv[0], 0); break; case 'v': /* verbose */ args->verbose = 1; break; case 'S': /* unix_sock_path */ args->unix_sock_path = strdup(optarg); break; default: ivshmem_client_usage(argv[0], 1); break; } } }


static int estimate_sid_gain(G723_1_Context *p) { int i, shift, seg, seg2, t, val, val_add, x, y; shift = 16 - p->cur_gain * 2; if (shift > 0) t = p->sid_gain << shift; else t = p->sid_gain >> -shift; x = av_clipl_int32(t * (int64_t)cng_filt[0] >> 16); if (x >= cng_bseg[2]) return 0x3F; if (x >= cng_bseg[1]) { shift = 4; seg = 3; } else { shift = 3; seg = (x >= cng_bseg[0]); } seg2 = FFMIN(seg, 3); val = 1 << shift; val_add = val >> 1; for (i = 0; i < shift; i++) { t = seg * 32 + (val << seg2); t *= t; if (x >= t) val += val_add; else val -= val_add; val_add >>= 1; } t = seg * 32 + (val << seg2); y = t * t - x; if (y <= 0) { t = seg * 32 + (val + 1 << seg2); t = t * t - x; val = (seg2 - 1 << 4) + val; if (t >= y) val++; } else { t = seg * 32 + (val - 1 << seg2); t = t * t - x; val = (seg2 - 1 << 4) + val; if (t >= y) val--; } return val; }


static int decode_exp_vlc(WMACodecContext *s, int ch) { int last_exp, n, code; const uint16_t *ptr; float v, max_scale; uint32_t *q, *q_end, iv; const float *ptab = pow_tab + 60; const uint32_t *iptab = (const uint32_t*)ptab; ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; q = (uint32_t *)s->exponents[ch]; q_end = q + s->block_len; max_scale = 0; if (s->version == 1) { last_exp = get_bits(&s->gb, 5) + 10; v = ptab[last_exp]; iv = iptab[last_exp]; max_scale = v; n = *ptr++; switch (n & 3) do { case 0: *q++ = iv; case 3: *q++ = iv; case 2: *q++ = iv; case 1: *q++ = iv; } while ((n -= 4) > 0); }else last_exp = 36; while (q < q_end) { code = get_vlc2(&s->gb, s->exp_vlc.table, EXPVLCBITS, EXPMAX); if (code < 0){ av_log(s->avctx, AV_LOG_ERROR, "Exponent vlc invalid\n"); return -1; } /* NOTE: this offset is the same as MPEG4 AAC ! */ last_exp += code - 60; if ((unsigned)last_exp + 60 > FF_ARRAY_ELEMS(pow_tab)) { av_log(s->avctx, AV_LOG_ERROR, "Exponent out of range: %d\n", last_exp); return -1; } v = ptab[last_exp]; iv = iptab[last_exp]; if (v > max_scale) max_scale = v; n = *ptr++; switch (n & 3) do { case 0: *q++ = iv; case 3: *q++ = iv; case 2: *q++ = iv; case 1: *q++ = iv; } while ((n -= 4) > 0); } s->max_exponent[ch] = max_scale; return 0; }


static int decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { BC_STATUS ret; BC_DTS_STATUS decoder_status; CopyRet rec_ret; CHDContext *priv = avctx->priv_data; HANDLE dev = priv->dev; int len = avpkt->size; uint8_t pic_type = 0; av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: decode_frame\n"); if (len) { int32_t tx_free = (int32_t)DtsTxFreeSize(dev); if (priv->parser) { uint8_t *pout; int psize = len; H264Context *h = priv->parser->priv_data; while (psize) ret = av_parser_parse2(priv->parser, avctx, &pout, &psize, avpkt->data, len, avctx->pkt->pts, avctx->pkt->dts, len - psize); av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: parser picture type %d\n", h->s.picture_structure); pic_type = h->s.picture_structure; } if (len < tx_free - 1024) { /* * Despite being notionally opaque, either libcrystalhd or * the hardware itself will mangle pts values that are too * small or too large. The docs claim it should be in units * of 100ns. Given that we're nominally dealing with a black * box on both sides, any transform we do has no guarantee of * avoiding mangling so we need to build a mapping to values * we know will not be mangled. */ uint64_t pts = opaque_list_push(priv, avctx->pkt->pts, pic_type); if (!pts) { return AVERROR(ENOMEM); } av_log(priv->avctx, AV_LOG_VERBOSE, "input \"pts\": %"PRIu64"\n", pts); ret = DtsProcInput(dev, avpkt->data, len, pts, 0); if (ret == BC_STS_BUSY) { av_log(avctx, AV_LOG_WARNING, "CrystalHD: ProcInput returned busy\n"); usleep(BASE_WAIT); return AVERROR(EBUSY); } else if (ret != BC_STS_SUCCESS) { av_log(avctx, AV_LOG_ERROR, "CrystalHD: ProcInput failed: %u\n", ret); return -1; } avctx->has_b_frames++; } else { av_log(avctx, AV_LOG_WARNING, "CrystalHD: Input buffer full\n"); len = 0; // We didn't consume any bytes. } } else { av_log(avctx, AV_LOG_INFO, "CrystalHD: No more input data\n"); } if (priv->skip_next_output) { av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Skipping next output.\n"); priv->skip_next_output = 0; avctx->has_b_frames--; return len; } ret = DtsGetDriverStatus(dev, &decoder_status); if (ret != BC_STS_SUCCESS) { av_log(avctx, AV_LOG_ERROR, "CrystalHD: GetDriverStatus failed\n"); return -1; } /* * No frames ready. Don't try to extract. * * Empirical testing shows that ReadyListCount can be a damn lie, * and ProcOut still fails when count > 0. The same testing showed * that two more iterations were needed before ProcOutput would * succeed. */ if (priv->output_ready < 2) { if (decoder_status.ReadyListCount != 0) priv->output_ready++; usleep(BASE_WAIT); av_log(avctx, AV_LOG_INFO, "CrystalHD: Filling pipeline.\n"); return len; } else if (decoder_status.ReadyListCount == 0) { /* * After the pipeline is established, if we encounter a lack of frames * that probably means we're not giving the hardware enough time to * decode them, so start increasing the wait time at the end of a * decode call. */ usleep(BASE_WAIT); priv->decode_wait += WAIT_UNIT; av_log(avctx, AV_LOG_INFO, "CrystalHD: No frames ready. Returning\n"); return len; } do { rec_ret = receive_frame(avctx, data, data_size, 0); if (rec_ret == RET_OK && *data_size == 0) { /* * This case is for when the encoded fields are stored * separately and we get a separate avpkt for each one. To keep * the pipeline stable, we should return nothing and wait for * the next time round to grab the second field. * H.264 PAFF is an example of this. */ av_log(avctx, AV_LOG_VERBOSE, "Returning after first field.\n"); avctx->has_b_frames--; } else if (rec_ret == RET_COPY_NEXT_FIELD) { /* * This case is for when the encoded fields are stored in a * single avpkt but the hardware returns then separately. Unless * we grab the second field before returning, we'll slip another * frame in the pipeline and if that happens a lot, we're sunk. * So we have to get that second field now. * Interlaced mpeg2 and vc1 are examples of this. */ av_log(avctx, AV_LOG_VERBOSE, "Trying to get second field.\n"); while (1) { usleep(priv->decode_wait); ret = DtsGetDriverStatus(dev, &decoder_status); if (ret == BC_STS_SUCCESS && decoder_status.ReadyListCount > 0) { rec_ret = receive_frame(avctx, data, data_size, 1); if ((rec_ret == RET_OK && *data_size > 0) || rec_ret == RET_ERROR) break; } } av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Got second field.\n"); } else if (rec_ret == RET_SKIP_NEXT_COPY) { /* * Two input packets got turned into a field pair. Gawd. */ av_log(avctx, AV_LOG_VERBOSE, "Don't output on next decode call.\n"); priv->skip_next_output = 1; } /* * If rec_ret == RET_COPY_AGAIN, that means that either we just handled * a FMT_CHANGE event and need to go around again for the actual frame, * we got a busy status and need to try again, or we're dealing with * packed b-frames, where the hardware strangely returns the packed * p-frame twice. We choose to keep the second copy as it carries the * valid pts. */ } while (rec_ret == RET_COPY_AGAIN); usleep(priv->decode_wait); return len; }


static int au_read_packet(AVFormatContext *s, AVPacket *pkt) { int ret; ret= av_get_packet(s->pb, pkt, BLOCK_SIZE * s->streams[0]->codec->channels * av_get_bits_per_sample(s->streams[0]->codec->codec_id) >> 3); if (ret < 0) return ret; pkt->stream_index = 0; /* note: we need to modify the packet size here to handle the last packet */ pkt->size = ret; return 0; }


static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track) { int tag = track->enc->codec_tag; if (track->mode == MODE_MP4 || track->mode == MODE_PSP) { if (!codec_get_tag(ff_mp4_obj_type, track->enc->codec_id)) return 0; if (track->enc->codec_id == CODEC_ID_H264) tag = MKTAG('a','v','c','1'); else if (track->enc->codec_id == CODEC_ID_AC3) tag = MKTAG('a','c','-','3'); else if (track->enc->codec_id == CODEC_ID_DIRAC) tag = MKTAG('d','r','a','c'); else if (track->enc->codec_id == CODEC_ID_MOV_TEXT) tag = MKTAG('t','x','3','g'); else if (track->enc->codec_type == CODEC_TYPE_VIDEO) tag = MKTAG('m','p','4','v'); else if (track->enc->codec_type == CODEC_TYPE_AUDIO) tag = MKTAG('m','p','4','a'); } else if (track->mode == MODE_IPOD) { if (track->enc->codec_type == CODEC_TYPE_SUBTITLE && (tag == MKTAG('t','x','3','g') || tag == MKTAG('t','e','x','t'))) track->tag = tag; // keep original tag else tag = codec_get_tag(codec_ipod_tags, track->enc->codec_id); if (!match_ext(s->filename, "m4a") && !match_ext(s->filename, "m4v")) av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v " "Quicktime/Ipod might not play the file\n"); } else if (track->mode & MODE_3GP) { tag = codec_get_tag(codec_3gp_tags, track->enc->codec_id); } else if (!tag || (track->enc->strict_std_compliance >= FF_COMPLIANCE_NORMAL && (tag == MKTAG('d','v','c','p') || track->enc->codec_id == CODEC_ID_RAWVIDEO))) { if (track->enc->codec_id == CODEC_ID_DVVIDEO) { if (track->enc->height == 480) /* NTSC */ if (track->enc->pix_fmt == PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n'); else tag = MKTAG('d','v','c',' '); else if (track->enc->pix_fmt == PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p'); else if (track->enc->pix_fmt == PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p'); else tag = MKTAG('d','v','p','p'); } else if (track->enc->codec_id == CODEC_ID_RAWVIDEO) { tag = codec_get_tag(mov_pix_fmt_tags, track->enc->pix_fmt); if (!tag) // restore tag tag = track->enc->codec_tag; } else { if (track->enc->codec_type == CODEC_TYPE_VIDEO) { tag = codec_get_tag(codec_movvideo_tags, track->enc->codec_id); if (!tag) { // if no mac fcc found, try with Microsoft tags tag = codec_get_tag(codec_bmp_tags, track->enc->codec_id); if (tag) av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, " "the file may be unplayable!\n"); } } else if (track->enc->codec_type == CODEC_TYPE_AUDIO) { tag = codec_get_tag(codec_movaudio_tags, track->enc->codec_id); if (!tag) { // if no mac fcc found, try with Microsoft tags int ms_tag = codec_get_tag(codec_wav_tags, track->enc->codec_id); if (ms_tag) { tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff)); av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, " "the file may be unplayable!\n"); } } } else if (track->enc->codec_type == CODEC_TYPE_SUBTITLE) { tag = codec_get_tag(ff_codec_movsubtitle_tags, track->enc->codec_id); } } } return tag; }


static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx) { NvencContext *ctx = avctx->priv_data; if (avctx->bit_rate > 0) { ctx->encode_config.rcParams.averageBitRate = avctx->bit_rate; } else if (ctx->encode_config.rcParams.averageBitRate > 0) { ctx->encode_config.rcParams.maxBitRate = ctx->encode_config.rcParams.averageBitRate; } if (avctx->rc_max_rate > 0) ctx->encode_config.rcParams.maxBitRate = avctx->rc_max_rate; if (ctx->rc < 0) { if (ctx->flags & NVENC_ONE_PASS) ctx->twopass = 0; if (ctx->flags & NVENC_TWO_PASSES) ctx->twopass = 1; if (ctx->twopass < 0) ctx->twopass = (ctx->flags & NVENC_LOWLATENCY) != 0; if (ctx->cbr) { if (ctx->twopass) { ctx->rc = NV_ENC_PARAMS_RC_2_PASS_QUALITY; } else { ctx->rc = NV_ENC_PARAMS_RC_CBR; } } else if (avctx->global_quality > 0) { ctx->rc = NV_ENC_PARAMS_RC_CONSTQP; } else if (ctx->twopass) { ctx->rc = NV_ENC_PARAMS_RC_2_PASS_VBR; } else if (avctx->qmin >= 0 && avctx->qmax >= 0) { ctx->rc = NV_ENC_PARAMS_RC_VBR_MINQP; } } if (ctx->flags & NVENC_LOSSLESS) { set_lossless(avctx); } else if (ctx->rc >= 0) { nvenc_override_rate_control(avctx); } else { ctx->encode_config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_VBR; set_vbr(avctx); } if (avctx->rc_buffer_size > 0) { ctx->encode_config.rcParams.vbvBufferSize = avctx->rc_buffer_size; } else if (ctx->encode_config.rcParams.averageBitRate > 0) { ctx->encode_config.rcParams.vbvBufferSize = 2 * ctx->encode_config.rcParams.averageBitRate; } if (ctx->aq) { ctx->encode_config.rcParams.enableAQ = 1; ctx->encode_config.rcParams.aqStrength = ctx->aq_strength; av_log(avctx, AV_LOG_VERBOSE, "AQ enabled.\n"); } if (ctx->temporal_aq) { ctx->encode_config.rcParams.enableTemporalAQ = 1; av_log(avctx, AV_LOG_VERBOSE, "Temporal AQ enabled.\n"); } if (ctx->rc_lookahead) { int lkd_bound = FFMIN(ctx->nb_surfaces, ctx->async_depth) - ctx->encode_config.frameIntervalP - 4; if (lkd_bound < 0) { av_log(avctx, AV_LOG_WARNING, "Lookahead not enabled. Increase buffer delay (-delay).\n"); } else { ctx->encode_config.rcParams.enableLookahead = 1; ctx->encode_config.rcParams.lookaheadDepth = av_clip(ctx->rc_lookahead, 0, lkd_bound); ctx->encode_config.rcParams.disableIadapt = ctx->no_scenecut; ctx->encode_config.rcParams.disableBadapt = !ctx->b_adapt; av_log(avctx, AV_LOG_VERBOSE, "Lookahead enabled: depth %d, scenecut %s, B-adapt %s.\n", ctx->encode_config.rcParams.lookaheadDepth, ctx->encode_config.rcParams.disableIadapt ? "disabled" : "enabled", ctx->encode_config.rcParams.disableBadapt ? "disabled" : "enabled"); } } if (ctx->strict_gop) { ctx->encode_config.rcParams.strictGOPTarget = 1; av_log(avctx, AV_LOG_VERBOSE, "Strict GOP target enabled.\n"); } if (ctx->nonref_p) ctx->encode_config.rcParams.enableNonRefP = 1; if (ctx->zerolatency) ctx->encode_config.rcParams.zeroReorderDelay = 1; if (ctx->quality) ctx->encode_config.rcParams.targetQuality = ctx->quality; }


int ff_rv34_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) { RV34DecContext *r = avctx->priv_data; MpegEncContext *s = &r->s; AVFrame *pict = data; SliceInfo si; int i; int slice_count; uint8_t *slices_hdr = NULL; int last = 0; /* no supplementary picture */ if (buf_size == 0) { /* special case for last picture */ if (s->low_delay==0 && s->next_picture_ptr) { *pict= *(AVFrame*)s->next_picture_ptr; s->next_picture_ptr= NULL; *data_size = sizeof(AVFrame); } return 0; } if(!avctx->slice_count){ slice_count = (*buf++) + 1; slices_hdr = buf + 4; buf += 8 * slice_count; }else slice_count = avctx->slice_count; for(i=0; i<slice_count; i++){ int offset= get_slice_offset(avctx, slices_hdr, i); int size; if(i+1 == slice_count) size= buf_size - offset; else size= get_slice_offset(avctx, slices_hdr, i+1) - offset; r->si.end = s->mb_width * s->mb_height; if(i+1 < slice_count){ init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, i+1), (buf_size-get_slice_offset(avctx, slices_hdr, i+1))*8); if(r->parse_slice_header(r, &r->s.gb, &si) < 0){ if(i+2 < slice_count) size = get_slice_offset(avctx, slices_hdr, i+2) - offset; else size = buf_size - offset; }else r->si.end = si.start; } last = rv34_decode_slice(r, r->si.end, buf + offset, size); s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start; if(last) break; } if(last){ if(r->loop_filter) r->loop_filter(r); ff_er_frame_end(s); MPV_frame_end(s); if (s->pict_type == FF_B_TYPE || s->low_delay) { *pict= *(AVFrame*)s->current_picture_ptr; } else if (s->last_picture_ptr != NULL) { *pict= *(AVFrame*)s->last_picture_ptr; } if(s->last_picture_ptr || s->low_delay){ *data_size = sizeof(AVFrame); ff_print_debug_info(s, pict); } s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...) } return buf_size; }


static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh) { int x, y, Y, U, V, A; uint8_t *lum, *cb, *cr; int dstx, dsty, dstw, dsth; const AVPicture *src = &rect->pict; dstw = av_clip(rect->w, 0, imgw); dsth = av_clip(rect->h, 0, imgh); dstx = av_clip(rect->x, 0, imgw - dstw); dsty = av_clip(rect->y, 0, imgh - dsth); lum = dst->data[0] + dstx + dsty * dst->linesize[0]; cb = dst->data[1] + dstx/2 + (dsty >> 1) * dst->linesize[1]; cr = dst->data[2] + dstx/2 + (dsty >> 1) * dst->linesize[2]; for (y = 0; y<dsth; y++) { for (x = 0; x<dstw; x++) { Y = src->data[0][x + y*src->linesize[0]]; A = src->data[3][x + y*src->linesize[3]]; lum[0] = ALPHA_BLEND(A, lum[0], Y, 0); lum++; } lum += dst->linesize[0] - dstw; } for (y = 0; y<dsth/2; y++) { for (x = 0; x<dstw/2; x++) { U = src->data[1][x + y*src->linesize[1]]; V = src->data[2][x + y*src->linesize[2]]; A = src->data[3][2*x + 2*y *src->linesize[3]] + src->data[3][2*x + 1 + 2*y *src->linesize[3]] + src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]] + src->data[3][2*x + (2*y+1)*src->linesize[3]]; cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0); cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0); cb++; cr++; } cb += dst->linesize[1] - dstw/2; cr += dst->linesize[2] - dstw/2; } }


int avio_read_partial(AVIOContext *s, unsigned char *buf, int size) { int len; if (size < 0) return -1; if (s->read_packet && s->write_flag) { len = s->read_packet(s->opaque, buf, size); if (len > 0) s->pos += len; return len; } len = s->buf_end - s->buf_ptr; if (len == 0) { /* Reset the buf_end pointer to the start of the buffer, to make sure * the fill_buffer call tries to read as much data as fits into the * full buffer, instead of just what space is left after buf_end. * This avoids returning partial packets at the end of the buffer, * for packet based inputs. */ s->buf_end = s->buf_ptr = s->buffer; fill_buffer(s); len = s->buf_end - s->buf_ptr; } if (len > size) len = size; memcpy(buf, s->buf_ptr, len); s->buf_ptr += len; if (!len) { if (s->error) return s->error; if (avio_feof(s)) return AVERROR_EOF; } return len; }


static int sp5x_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) { #if 0 MJpegDecodeContext *s = avctx->priv_data; #endif const int qscale = 5; uint8_t *buf_ptr, *buf_end, *recoded; int i = 0, j = 0; /* no supplementary picture */ if (buf_size == 0) return 0; if (!avctx->width || !avctx->height) return -1; buf_ptr = buf; buf_end = buf + buf_size; #if 1 recoded = av_mallocz(buf_size + 1024); if (!recoded) return -1; /* SOI */ recoded[j++] = 0xFF; recoded[j++] = 0xD8; memcpy(recoded+j, &sp5x_data_dqt[0], sizeof(sp5x_data_dqt)); memcpy(recoded+j+5, &sp5x_quant_table[qscale * 2], 64); memcpy(recoded+j+70, &sp5x_quant_table[(qscale * 2) + 1], 64); j += sizeof(sp5x_data_dqt); memcpy(recoded+j, &sp5x_data_dht[0], sizeof(sp5x_data_dht)); j += sizeof(sp5x_data_dht); memcpy(recoded+j, &sp5x_data_sof[0], sizeof(sp5x_data_sof)); recoded[j+5] = (avctx->coded_height >> 8) & 0xFF; recoded[j+6] = avctx->coded_height & 0xFF; recoded[j+7] = (avctx->coded_width >> 8) & 0xFF; recoded[j+8] = avctx->coded_width & 0xFF; j += sizeof(sp5x_data_sof); memcpy(recoded+j, &sp5x_data_sos[0], sizeof(sp5x_data_sos)); j += sizeof(sp5x_data_sos); for (i = 14; i < buf_size && j < buf_size+1024-2; i++) { recoded[j++] = buf[i]; if (buf[i] == 0xff) recoded[j++] = 0; } /* EOI */ recoded[j++] = 0xFF; recoded[j++] = 0xD9; i = mjpeg_decode_frame(avctx, data, data_size, recoded, j); av_free(recoded); #else /* SOF */ s->bits = 8; s->width = avctx->coded_width; s->height = avctx->coded_height; s->nb_components = 3; s->component_id[0] = 0; s->h_count[0] = 2; s->v_count[0] = 2; s->quant_index[0] = 0; s->component_id[1] = 1; s->h_count[1] = 1; s->v_count[1] = 1; s->quant_index[1] = 1; s->component_id[2] = 2; s->h_count[2] = 1; s->v_count[2] = 1; s->quant_index[2] = 1; s->h_max = 2; s->v_max = 2; s->qscale_table = av_mallocz((s->width+15)/16); avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV420P : PIX_FMT_YUVJ420; s->interlaced = 0; s->picture.reference = 0; if (avctx->get_buffer(avctx, &s->picture) < 0) { fprintf(stderr, "get_buffer() failed\n"); return -1; } s->picture.pict_type = I_TYPE; s->picture.key_frame = 1; for (i = 0; i < 3; i++) s->linesize[i] = s->picture.linesize[i] << s->interlaced; /* DQT */ for (i = 0; i < 64; i++) { j = s->scantable.permutated[i]; s->quant_matrixes[0][j] = sp5x_quant_table[(qscale * 2) + i]; } s->qscale[0] = FFMAX( s->quant_matrixes[0][s->scantable.permutated[1]], s->quant_matrixes[0][s->scantable.permutated[8]]) >> 1; for (i = 0; i < 64; i++) { j = s->scantable.permutated[i]; s->quant_matrixes[1][j] = sp5x_quant_table[(qscale * 2) + 1 + i]; } s->qscale[1] = FFMAX( s->quant_matrixes[1][s->scantable.permutated[1]], s->quant_matrixes[1][s->scantable.permutated[8]]) >> 1; /* DHT */ /* SOS */ s->comp_index[0] = 0; s->nb_blocks[0] = s->h_count[0] * s->v_count[0]; s->h_scount[0] = s->h_count[0]; s->v_scount[0] = s->v_count[0]; s->dc_index[0] = 0; s->ac_index[0] = 0; s->comp_index[1] = 1; s->nb_blocks[1] = s->h_count[1] * s->v_count[1]; s->h_scount[1] = s->h_count[1]; s->v_scount[1] = s->v_count[1]; s->dc_index[1] = 1; s->ac_index[1] = 1; s->comp_index[2] = 2; s->nb_blocks[2] = s->h_count[2] * s->v_count[2]; s->h_scount[2] = s->h_count[2]; s->v_scount[2] = s->v_count[2]; s->dc_index[2] = 1; s->ac_index[2] = 1; for (i = 0; i < 3; i++) s->last_dc[i] = 1024; s->mb_width = (s->width * s->h_max * 8 -1) / (s->h_max * 8); s->mb_height = (s->height * s->v_max * 8 -1) / (s->v_max * 8); init_get_bits(&s->gb, buf+14, (buf_size-14)*8); return mjpeg_decode_scan(s); #endif return i; }


float32 helper_fdtos(CPUSPARCState *env, float64 src) { float32 ret; clear_float_exceptions(env); ret = float64_to_float32(src, &env->fp_status); check_ieee_exceptions(env); return ret; }


static void icp_control_init(target_phys_addr_t base) { MemoryRegion *io; io = (MemoryRegion *)g_malloc0(sizeof(MemoryRegion)); memory_region_init_io(io, &icp_control_ops, NULL, "control", 0x00800000); memory_region_add_subregion(get_system_memory(), base, io); /* ??? Save/restore. */ }


gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb, bool search_pc) { CPUState *cs = CPU(cpu); DisasContext ctx; target_ulong pc_start; uint16_t *gen_opc_end; CPUBreakpoint *bp; int j, lj = -1; CPUMoxieState *env = &cpu->env; int num_insns; pc_start = tb->pc; gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; ctx.pc = pc_start; ctx.saved_pc = -1; ctx.tb = tb; ctx.memidx = 0; ctx.singlestep_enabled = 0; ctx.bstate = BS_NONE; num_insns = 0; gen_tb_start(); do { if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) { QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { if (ctx.pc == bp->pc) { tcg_gen_movi_i32(cpu_pc, ctx.pc); gen_helper_debug(cpu_env); ctx.bstate = BS_EXCP; goto done_generating; } } } if (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.pc; tcg_ctx.gen_opc_instr_start[lj] = 1; tcg_ctx.gen_opc_icount[lj] = num_insns; } ctx.opcode = cpu_lduw_code(env, ctx.pc); ctx.pc += decode_opc(cpu, &ctx); num_insns++; if (cs->singlestep_enabled) { break; } if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) { break; } } while (ctx.bstate == BS_NONE && tcg_ctx.gen_opc_ptr < gen_opc_end); if (cs->singlestep_enabled) { tcg_gen_movi_tl(cpu_pc, ctx.pc); gen_helper_debug(cpu_env); } else { switch (ctx.bstate) { case BS_STOP: case BS_NONE: gen_goto_tb(env, &ctx, 0, ctx.pc); break; case BS_EXCP: tcg_gen_exit_tb(0); break; case BS_BRANCH: default: break; } } done_generating: gen_tb_end(tb, num_insns); *tcg_ctx.gen_opc_ptr = INDEX_op_end; if (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.pc - pc_start; tb->icount = num_insns; } }


USBBus *usb_bus_find(int busnr) { USBBus *bus; if (-1 == busnr) return TAILQ_FIRST(&busses); TAILQ_FOREACH(bus, &busses, next) { if (bus->busnr == busnr) return bus; } return NULL; }


vreader_copy_list(VReaderList *list) { VReaderList *new_list = NULL; VReaderListEntry *current_entry = NULL; new_list = vreader_list_new(); if (new_list == NULL) { return NULL; } for (current_entry = vreader_list_get_first(list); current_entry; current_entry = vreader_list_get_next(current_entry)) { VReader *reader = vreader_list_get_reader(current_entry); VReaderListEntry *new_entry = vreader_list_entry_new(reader); vreader_free(reader); vreader_queue(new_list, new_entry); } return new_list; }


static int cow_find_streak(const uint8_t *bitmap, int value, int start, int nb_sectors) { int streak_value = value ? 0xFF : 0; int last = MIN(start + nb_sectors, BITS_PER_BITMAP_SECTOR); int bitnum = start; while (bitnum < last) { if ((bitnum & 7) == 0 && bitmap[bitnum / 8] == streak_value) { bitnum += 8; continue; } if (cow_test_bit(bitnum, bitmap) == value) { bitnum++; continue; } break; } return MIN(bitnum, last) - start; }


static int raw_read_options(QDict *options, BlockDriverState *bs, BDRVRawState *s, Error **errp) { Error *local_err = NULL; QemuOpts *opts = NULL; int64_t real_size = 0; int ret; real_size = bdrv_getlength(bs->file->bs); if (real_size < 0) { error_setg_errno(errp, -real_size, "Could not get image size"); return real_size; } opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort); qemu_opts_absorb_qdict(opts, options, &local_err); if (local_err) { error_propagate(errp, local_err); ret = -EINVAL; goto end; } s->offset = qemu_opt_get_size(opts, "offset", 0); if (s->offset > real_size) { error_setg(errp, "Offset (%" PRIu64 ") cannot be greater than " "size of the containing file (%" PRId64 ")", s->offset, real_size); ret = -EINVAL; goto end; } if (qemu_opt_find(opts, "size") != NULL) { s->size = qemu_opt_get_size(opts, "size", 0); s->has_size = true; } else { s->has_size = false; s->size = real_size - s->offset; } /* Check size and offset */ if ((real_size - s->offset) < s->size) { error_setg(errp, "The sum of offset (%" PRIu64 ") and size " "(%" PRIu64 ") has to be smaller or equal to the " " actual size of the containing file (%" PRId64 ")", s->offset, s->size, real_size); ret = -EINVAL; goto end; } /* Make sure size is multiple of BDRV_SECTOR_SIZE to prevent rounding * up and leaking out of the specified area. */ if (s->has_size && !QEMU_IS_ALIGNED(s->size, BDRV_SECTOR_SIZE)) { error_setg(errp, "Specified size is not multiple of %llu", BDRV_SECTOR_SIZE); ret = -EINVAL; goto end; } ret = 0; end: qemu_opts_del(opts); return ret; }


static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst, long dstWidth, const uint8_t *src, int srcW, int xInc) { #if ARCH_X86 #if COMPILE_TEMPLATE_MMX2 int32_t *filterPos = c->hLumFilterPos; int16_t *filter = c->hLumFilter; int canMMX2BeUsed = c->canMMX2BeUsed; void *mmx2FilterCode= c->lumMmx2FilterCode; int i; #if defined(PIC) DECLARE_ALIGNED(8, uint64_t, ebxsave); #endif if (canMMX2BeUsed) { __asm__ volatile( #if defined(PIC) "mov %%"REG_b", %5 \n\t" #endif "pxor %%mm7, %%mm7 \n\t" "mov %0, %%"REG_c" \n\t" "mov %1, %%"REG_D" \n\t" "mov %2, %%"REG_d" \n\t" "mov %3, %%"REG_b" \n\t" "xor %%"REG_a", %%"REG_a" \n\t" // i PREFETCH" (%%"REG_c") \n\t" PREFETCH" 32(%%"REG_c") \n\t" PREFETCH" 64(%%"REG_c") \n\t" #if ARCH_X86_64 #define CALL_MMX2_FILTER_CODE \ "movl (%%"REG_b"), %%esi \n\t"\ "call *%4 \n\t"\ "movl (%%"REG_b", %%"REG_a"), %%esi \n\t"\ "add %%"REG_S", %%"REG_c" \n\t"\ "add %%"REG_a", %%"REG_D" \n\t"\ "xor %%"REG_a", %%"REG_a" \n\t"\ #else #define CALL_MMX2_FILTER_CODE \ "movl (%%"REG_b"), %%esi \n\t"\ "call *%4 \n\t"\ "addl (%%"REG_b", %%"REG_a"), %%"REG_c" \n\t"\ "add %%"REG_a", %%"REG_D" \n\t"\ "xor %%"REG_a", %%"REG_a" \n\t"\ #endif /* ARCH_X86_64 */ CALL_MMX2_FILTER_CODE CALL_MMX2_FILTER_CODE CALL_MMX2_FILTER_CODE CALL_MMX2_FILTER_CODE CALL_MMX2_FILTER_CODE CALL_MMX2_FILTER_CODE CALL_MMX2_FILTER_CODE CALL_MMX2_FILTER_CODE #if defined(PIC) "mov %5, %%"REG_b" \n\t" #endif :: "m" (src), "m" (dst), "m" (filter), "m" (filterPos), "m" (mmx2FilterCode) #if defined(PIC) ,"m" (ebxsave) #endif : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D #if !defined(PIC) ,"%"REG_b #endif ); for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) dst[i] = src[srcW-1]*128; } else { #endif /* COMPILE_TEMPLATE_MMX2 */ x86_reg xInc_shr16 = xInc >> 16; uint16_t xInc_mask = xInc & 0xffff; x86_reg dstWidth_reg = dstWidth; //NO MMX just normal asm ... __asm__ volatile( "xor %%"REG_a", %%"REG_a" \n\t" // i "xor %%"REG_d", %%"REG_d" \n\t" // xx "xorl %%ecx, %%ecx \n\t" // xalpha ".p2align 4 \n\t" "1: \n\t" "movzbl (%0, %%"REG_d"), %%edi \n\t" //src[xx] "movzbl 1(%0, %%"REG_d"), %%esi \n\t" //src[xx+1] FAST_BILINEAR_X86 "movw %%si, (%%"REG_D", %%"REG_a", 2) \n\t" "addw %4, %%cx \n\t" //xalpha += xInc&0xFFFF "adc %3, %%"REG_d" \n\t" //xx+= xInc>>16 + carry "movzbl (%0, %%"REG_d"), %%edi \n\t" //src[xx] "movzbl 1(%0, %%"REG_d"), %%esi \n\t" //src[xx+1] FAST_BILINEAR_X86 "movw %%si, 2(%%"REG_D", %%"REG_a", 2) \n\t" "addw %4, %%cx \n\t" //xalpha += xInc&0xFFFF "adc %3, %%"REG_d" \n\t" //xx+= xInc>>16 + carry "add $2, %%"REG_a" \n\t" "cmp %2, %%"REG_a" \n\t" " jb 1b \n\t" :: "r" (src), "m" (dst), "m" (dstWidth_reg), "m" (xInc_shr16), "m" (xInc_mask) : "%"REG_a, "%"REG_d, "%ecx", "%"REG_D, "%esi" ); #if COMPILE_TEMPLATE_MMX2 } //if MMX2 can't be used #endif #else int i; unsigned int xpos=0; for (i=0;i<dstWidth;i++) { register unsigned int xx=xpos>>16; register unsigned int xalpha=(xpos&0xFFFF)>>9; dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha; xpos+=xInc; } #endif /* ARCH_X86 */ }


bool memory_region_is_skip_dump(MemoryRegion *mr) { return mr->skip_dump; }


static ssize_t nbd_send_reply(int csock, struct nbd_reply *reply) { uint8_t buf[4 + 4 + 8]; /* Reply [ 0 .. 3] magic (NBD_REPLY_MAGIC) [ 4 .. 7] error (0 == no error) [ 7 .. 15] handle */ cpu_to_be32w((uint32_t*)buf, NBD_REPLY_MAGIC); cpu_to_be32w((uint32_t*)(buf + 4), reply->error); cpu_to_be64w((uint64_t*)(buf + 8), reply->handle); TRACE("Sending response to client"); if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) { LOG("writing to socket failed"); errno = EINVAL; return -1; } return 0; }


static void switch_tss(CPUX86State *env, int tss_selector, uint32_t e1, uint32_t e2, int source, uint32_t next_eip) { int tss_limit, tss_limit_max, type, old_tss_limit_max, old_type, v1, v2, i; target_ulong tss_base; uint32_t new_regs[8], new_segs[6]; uint32_t new_eflags, new_eip, new_cr3, new_ldt, new_trap; uint32_t old_eflags, eflags_mask; SegmentCache *dt; int index; target_ulong ptr; type = (e2 >> DESC_TYPE_SHIFT) & 0xf; LOG_PCALL("switch_tss: sel=0x%04x type=%d src=%d\n", tss_selector, type, source); /* if task gate, we read the TSS segment and we load it */ if (type == 5) { if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, tss_selector & 0xfffc); } tss_selector = e1 >> 16; if (tss_selector & 4) { raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc); } if (load_segment(env, &e1, &e2, tss_selector) != 0) { raise_exception_err(env, EXCP0D_GPF, tss_selector & 0xfffc); } if (e2 & DESC_S_MASK) { raise_exception_err(env, EXCP0D_GPF, tss_selector & 0xfffc); } type = (e2 >> DESC_TYPE_SHIFT) & 0xf; if ((type & 7) != 1) { raise_exception_err(env, EXCP0D_GPF, tss_selector & 0xfffc); } } if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, tss_selector & 0xfffc); } if (type & 8) { tss_limit_max = 103; } else { tss_limit_max = 43; } tss_limit = get_seg_limit(e1, e2); tss_base = get_seg_base(e1, e2); if ((tss_selector & 4) != 0 || tss_limit < tss_limit_max) { raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc); } old_type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf; if (old_type & 8) { old_tss_limit_max = 103; } else { old_tss_limit_max = 43; } /* read all the registers from the new TSS */ if (type & 8) { /* 32 bit */ new_cr3 = cpu_ldl_kernel(env, tss_base + 0x1c); new_eip = cpu_ldl_kernel(env, tss_base + 0x20); new_eflags = cpu_ldl_kernel(env, tss_base + 0x24); for (i = 0; i < 8; i++) { new_regs[i] = cpu_ldl_kernel(env, tss_base + (0x28 + i * 4)); } for (i = 0; i < 6; i++) { new_segs[i] = cpu_lduw_kernel(env, tss_base + (0x48 + i * 4)); } new_ldt = cpu_lduw_kernel(env, tss_base + 0x60); new_trap = cpu_ldl_kernel(env, tss_base + 0x64); } else { /* 16 bit */ new_cr3 = 0; new_eip = cpu_lduw_kernel(env, tss_base + 0x0e); new_eflags = cpu_lduw_kernel(env, tss_base + 0x10); for (i = 0; i < 8; i++) { new_regs[i] = cpu_lduw_kernel(env, tss_base + (0x12 + i * 2)) | 0xffff0000; } for (i = 0; i < 4; i++) { new_segs[i] = cpu_lduw_kernel(env, tss_base + (0x22 + i * 4)); } new_ldt = cpu_lduw_kernel(env, tss_base + 0x2a); new_segs[R_FS] = 0; new_segs[R_GS] = 0; new_trap = 0; } /* XXX: avoid a compiler warning, see http://support.amd.com/us/Processor_TechDocs/24593.pdf chapters 12.2.5 and 13.2.4 on how to implement TSS Trap bit */ (void)new_trap; /* NOTE: we must avoid memory exceptions during the task switch, so we make dummy accesses before */ /* XXX: it can still fail in some cases, so a bigger hack is necessary to valid the TLB after having done the accesses */ v1 = cpu_ldub_kernel(env, env->tr.base); v2 = cpu_ldub_kernel(env, env->tr.base + old_tss_limit_max); cpu_stb_kernel(env, env->tr.base, v1); cpu_stb_kernel(env, env->tr.base + old_tss_limit_max, v2); /* clear busy bit (it is restartable) */ if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_IRET) { target_ulong ptr; uint32_t e2; ptr = env->gdt.base + (env->tr.selector & ~7); e2 = cpu_ldl_kernel(env, ptr + 4); e2 &= ~DESC_TSS_BUSY_MASK; cpu_stl_kernel(env, ptr + 4, e2); } old_eflags = cpu_compute_eflags(env); if (source == SWITCH_TSS_IRET) { old_eflags &= ~NT_MASK; } /* save the current state in the old TSS */ if (type & 8) { /* 32 bit */ cpu_stl_kernel(env, env->tr.base + 0x20, next_eip); cpu_stl_kernel(env, env->tr.base + 0x24, old_eflags); cpu_stl_kernel(env, env->tr.base + (0x28 + 0 * 4), env->regs[R_EAX]); cpu_stl_kernel(env, env->tr.base + (0x28 + 1 * 4), env->regs[R_ECX]); cpu_stl_kernel(env, env->tr.base + (0x28 + 2 * 4), env->regs[R_EDX]); cpu_stl_kernel(env, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]); cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), env->regs[R_ESP]); cpu_stl_kernel(env, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP]); cpu_stl_kernel(env, env->tr.base + (0x28 + 6 * 4), env->regs[R_ESI]); cpu_stl_kernel(env, env->tr.base + (0x28 + 7 * 4), env->regs[R_EDI]); for (i = 0; i < 6; i++) { cpu_stw_kernel(env, env->tr.base + (0x48 + i * 4), env->segs[i].selector); } } else { /* 16 bit */ cpu_stw_kernel(env, env->tr.base + 0x0e, next_eip); cpu_stw_kernel(env, env->tr.base + 0x10, old_eflags); cpu_stw_kernel(env, env->tr.base + (0x12 + 0 * 2), env->regs[R_EAX]); cpu_stw_kernel(env, env->tr.base + (0x12 + 1 * 2), env->regs[R_ECX]); cpu_stw_kernel(env, env->tr.base + (0x12 + 2 * 2), env->regs[R_EDX]); cpu_stw_kernel(env, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]); cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), env->regs[R_ESP]); cpu_stw_kernel(env, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP]); cpu_stw_kernel(env, env->tr.base + (0x12 + 6 * 2), env->regs[R_ESI]); cpu_stw_kernel(env, env->tr.base + (0x12 + 7 * 2), env->regs[R_EDI]); for (i = 0; i < 4; i++) { cpu_stw_kernel(env, env->tr.base + (0x22 + i * 4), env->segs[i].selector); } } /* now if an exception occurs, it will occurs in the next task context */ if (source == SWITCH_TSS_CALL) { cpu_stw_kernel(env, tss_base, env->tr.selector); new_eflags |= NT_MASK; } /* set busy bit */ if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_CALL) { target_ulong ptr; uint32_t e2; ptr = env->gdt.base + (tss_selector & ~7); e2 = cpu_ldl_kernel(env, ptr + 4); e2 |= DESC_TSS_BUSY_MASK; cpu_stl_kernel(env, ptr + 4, e2); } /* set the new CPU state */ /* from this point, any exception which occurs can give problems */ env->cr[0] |= CR0_TS_MASK; env->hflags |= HF_TS_MASK; env->tr.selector = tss_selector; env->tr.base = tss_base; env->tr.limit = tss_limit; env->tr.flags = e2 & ~DESC_TSS_BUSY_MASK; if ((type & 8) && (env->cr[0] & CR0_PG_MASK)) { cpu_x86_update_cr3(env, new_cr3); } /* load all registers without an exception, then reload them with possible exception */ env->eip = new_eip; eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK; if (!(type & 8)) { eflags_mask &= 0xffff; } cpu_load_eflags(env, new_eflags, eflags_mask); /* XXX: what to do in 16 bit case? */ env->regs[R_EAX] = new_regs[0]; env->regs[R_ECX] = new_regs[1]; env->regs[R_EDX] = new_regs[2]; env->regs[R_EBX] = new_regs[3]; env->regs[R_ESP] = new_regs[4]; env->regs[R_EBP] = new_regs[5]; env->regs[R_ESI] = new_regs[6]; env->regs[R_EDI] = new_regs[7]; if (new_eflags & VM_MASK) { for (i = 0; i < 6; i++) { load_seg_vm(env, i, new_segs[i]); } /* in vm86, CPL is always 3 */ cpu_x86_set_cpl(env, 3); } else { /* CPL is set the RPL of CS */ cpu_x86_set_cpl(env, new_segs[R_CS] & 3); /* first just selectors as the rest may trigger exceptions */ for (i = 0; i < 6; i++) { cpu_x86_load_seg_cache(env, i, new_segs[i], 0, 0, 0); } } env->ldt.selector = new_ldt & ~4; env->ldt.base = 0; env->ldt.limit = 0; env->ldt.flags = 0; /* load the LDT */ if (new_ldt & 4) { raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc); } if ((new_ldt & 0xfffc) != 0) { dt = &env->gdt; index = new_ldt & ~7; if ((index + 7) > dt->limit) { raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc); } ptr = dt->base + index; e1 = cpu_ldl_kernel(env, ptr); e2 = cpu_ldl_kernel(env, ptr + 4); if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) { raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc); } if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc); } load_seg_cache_raw_dt(&env->ldt, e1, e2); } /* load the segments */ if (!(new_eflags & VM_MASK)) { tss_load_seg(env, R_CS, new_segs[R_CS]); tss_load_seg(env, R_SS, new_segs[R_SS]); tss_load_seg(env, R_ES, new_segs[R_ES]); tss_load_seg(env, R_DS, new_segs[R_DS]); tss_load_seg(env, R_FS, new_segs[R_FS]); tss_load_seg(env, R_GS, new_segs[R_GS]); } /* check that env->eip is in the CS segment limits */ if (new_eip > env->segs[R_CS].limit) { /* XXX: different exception if CALL? */ raise_exception_err(env, EXCP0D_GPF, 0); } #ifndef CONFIG_USER_ONLY /* reset local breakpoints */ if (env->dr[7] & DR7_LOCAL_BP_MASK) { for (i = 0; i < DR7_MAX_BP; i++) { if (hw_local_breakpoint_enabled(env->dr[7], i) && !hw_global_breakpoint_enabled(env->dr[7], i)) { hw_breakpoint_remove(env, i); } } env->dr[7] &= ~DR7_LOCAL_BP_MASK; } #endif }


void kvmppc_read_hptes(ppc_hash_pte64_t *hptes, hwaddr ptex, int n) { int fd, rc; int i; fd = kvmppc_get_htab_fd(false, ptex, &error_abort); i = 0; while (i < n) { struct kvm_get_htab_header *hdr; int m = n < HPTES_PER_GROUP ? n : HPTES_PER_GROUP; char buf[sizeof(*hdr) + m * HASH_PTE_SIZE_64]; rc = read(fd, buf, sizeof(buf)); if (rc < 0) { hw_error("kvmppc_read_hptes: Unable to read HPTEs"); } hdr = (struct kvm_get_htab_header *)buf; while ((i < n) && ((char *)hdr < (buf + rc))) { int invalid = hdr->n_invalid; if (hdr->index != (ptex + i)) { hw_error("kvmppc_read_hptes: Unexpected HPTE index %"PRIu32 " != (%"HWADDR_PRIu" + %d", hdr->index, ptex, i); } memcpy(hptes + i, hdr + 1, HASH_PTE_SIZE_64 * hdr->n_valid); i += hdr->n_valid; if ((n - i) < invalid) { invalid = n - i; } memset(hptes + i, 0, invalid * HASH_PTE_SIZE_64); i += hdr->n_invalid; hdr = (struct kvm_get_htab_header *) ((char *)(hdr + 1) + HASH_PTE_SIZE_64 * hdr->n_valid); } } close(fd); }


void qmp_output_visitor_cleanup(QmpOutputVisitor *v) { QStackEntry *e, *tmp; QTAILQ_FOREACH_SAFE(e, &v->stack, node, tmp) { QTAILQ_REMOVE(&v->stack, e, node); g_free(e); } qobject_decref(v->root); g_free(v); }


static int check_host_key(BDRVSSHState *s, const char *host, int port, const char *host_key_check) { /* host_key_check=no */ if (strcmp(host_key_check, "no") == 0) { return 0; } /* host_key_check=md5:xx:yy:zz:... */ if (strncmp(host_key_check, "md5:", 4) == 0) { return check_host_key_hash(s, &host_key_check[4], LIBSSH2_HOSTKEY_HASH_MD5, 16); } /* host_key_check=sha1:xx:yy:zz:... */ if (strncmp(host_key_check, "sha1:", 5) == 0) { return check_host_key_hash(s, &host_key_check[5], LIBSSH2_HOSTKEY_HASH_SHA1, 20); } /* host_key_check=yes */ if (strcmp(host_key_check, "yes") == 0) { return check_host_key_knownhosts(s, host, port); } error_report("unknown host_key_check setting (%s)", host_key_check); return -EINVAL; }


void memory_region_notify_iommu(MemoryRegion *mr, IOMMUTLBEntry entry) { IOMMUNotifier *iommu_notifier; IOMMUNotifierFlag request_flags; assert(memory_region_is_iommu(mr)); if (entry.perm & IOMMU_RW) { request_flags = IOMMU_NOTIFIER_MAP; } else { request_flags = IOMMU_NOTIFIER_UNMAP; } IOMMU_NOTIFIER_FOREACH(iommu_notifier, mr) { /* * Skip the notification if the notification does not overlap * with registered range. */ if (iommu_notifier->start > entry.iova + entry.addr_mask + 1 || iommu_notifier->end < entry.iova) { continue; } if (iommu_notifier->notifier_flags & request_flags) { iommu_notifier->notify(iommu_notifier, &entry); } } }


static IOWatchPoll *io_watch_poll_from_source(GSource *source) { IOWatchPoll *i; QTAILQ_FOREACH(i, &io_watch_poll_list, node) { if (i->src == source) { return i; } } return NULL; }


void memory_region_init_io(MemoryRegion *mr, Object *owner, const MemoryRegionOps *ops, void *opaque, const char *name, uint64_t size) { memory_region_init(mr, owner, name, size); mr->ops = ops; mr->opaque = opaque; mr->terminates = true; mr->ram_addr = ~(ram_addr_t)0; }


static void filter_mb( H264Context *h, int mb_x, int mb_y ) { MpegEncContext * const s = &h->s; const int mb_xy= mb_x + mb_y*s->mb_stride; uint8_t *img_y = s->current_picture.data[0] + (mb_y * 16* s->linesize ) + mb_x * 16; uint8_t *img_cb = s->current_picture.data[1] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; uint8_t *img_cr = s->current_picture.data[2] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; int linesize, uvlinesize; int dir; #if 0 /* FIXME what's that ? */ if( !s->decode ) return; #endif /* FIXME Implement deblocking filter for field MB */ if( h->sps.mb_aff ) { return; } linesize = s->linesize; uvlinesize = s->uvlinesize; /* dir : 0 -> vertical edge, 1 -> horizontal edge */ for( dir = 0; dir < 2; dir++ ) { int start = 0; int edge; /* test picture boundary */ if( ( dir == 0 && mb_x == 0 ) || ( dir == 1 && mb_y == 0 ) ) { start = 1; } /* FIXME test slice boundary */ if( h->disable_deblocking_filter_idc == 2 ) { } /* Calculate bS */ for( edge = start; edge < 4; edge++ ) { /* mbn_xy: neighbour macroblock (how that works for field ?) */ int mbn_xy = edge > 0 ? mb_xy : ( dir == 0 ? mb_xy -1 : mb_xy - s->mb_stride ); int bS[4]; int qp; if( IS_INTRA( s->current_picture.mb_type[mb_xy] ) || IS_INTRA( s->current_picture.mb_type[mbn_xy] ) ) { bS[0] = bS[1] = bS[2] = bS[3] = ( edge == 0 ? 4 : 3 ); } else { int i; for( i = 0; i < 4; i++ ) { static const uint8_t block_idx_xy[4][4] = { { 0, 2, 8, 10}, { 1, 3, 9, 11}, { 4, 6, 12, 14}, { 5, 7, 13, 15} }; int x = dir == 0 ? edge : i; int y = dir == 0 ? i : edge; int xn = (x - (dir == 0 ? 1 : 0 ))&0x03; int yn = (y - (dir == 0 ? 0 : 1 ))&0x03; if( h->non_zero_count[mb_xy][block_idx_xy[x][y]] != 0 || h->non_zero_count[mbn_xy][block_idx_xy[xn][yn]] != 0 ) { bS[i] = 2; } else if( h->slice_type == P_TYPE ) { const int b8_xy = h->mb2b8_xy[mb_xy]+(y>>1)*h->b8_stride+(x>>1); const int b8n_xy= h->mb2b8_xy[mbn_xy]+(yn>>1)*h->b8_stride+(xn>>1); const int b_xy = h->mb2b_xy[mb_xy]+y*h->b_stride+x; const int bn_xy = h->mb2b_xy[mbn_xy]+yn*h->b_stride+xn; if( s->current_picture.ref_index[0][b8_xy] != s->current_picture.ref_index[0][b8n_xy] || ABS( s->current_picture.motion_val[0][b_xy][0] - s->current_picture.motion_val[0][bn_xy][0] ) >= 4 || ABS( s->current_picture.motion_val[0][b_xy][1] - s->current_picture.motion_val[0][bn_xy][1] ) >= 4 ) bS[i] = 1; else bS[i] = 0; } else { /* FIXME Add support for B frame */ return; } } } /* Filter edge */ qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbn_xy] + 1 ) >> 1; if( dir == 0 ) { filter_mb_edgev( h, &img_y[4*edge], linesize, bS, qp ); if( (edge&1) == 0 ) { int chroma_qp = ( get_chroma_qp( h, s->current_picture.qscale_table[mb_xy] ) + get_chroma_qp( h, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1; filter_mb_edgecv( h, &img_cb[2*edge], uvlinesize, bS, chroma_qp ); filter_mb_edgecv( h, &img_cr[2*edge], uvlinesize, bS, chroma_qp ); } } else { filter_mb_edgeh( h, &img_y[4*edge*linesize], linesize, bS, qp ); if( (edge&1) == 0 ) { int chroma_qp = ( get_chroma_qp( h, s->current_picture.qscale_table[mb_xy] ) + get_chroma_qp( h, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1; filter_mb_edgech( h, &img_cb[2*edge*uvlinesize], uvlinesize, bS, chroma_qp ); filter_mb_edgech( h, &img_cr[2*edge*uvlinesize], uvlinesize, bS, chroma_qp ); } } } } }


void mpeg_motion_internal(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int field_based, int bottom_field, int field_select, uint8_t **ref_picture, op_pixels_func (*pix_op)[4], int motion_x, int motion_y, int h, int is_mpeg12, int mb_y) { uint8_t *ptr_y, *ptr_cb, *ptr_cr; int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos; ptrdiff_t uvlinesize, linesize; #if 0 if (s->quarter_sample) { motion_x >>= 1; motion_y >>= 1; } #endif v_edge_pos = s->v_edge_pos >> field_based; linesize = s->current_picture.f.linesize[0] << field_based; uvlinesize = s->current_picture.f.linesize[1] << field_based; dxy = ((motion_y & 1) << 1) | (motion_x & 1); src_x = s->mb_x * 16 + (motion_x >> 1); src_y = (mb_y << (4 - field_based)) + (motion_y >> 1); if (!is_mpeg12 && s->out_format == FMT_H263) { if ((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based) { mx = (motion_x >> 1) | (motion_x & 1); my = motion_y >> 1; uvdxy = ((my & 1) << 1) | (mx & 1); uvsrc_x = s->mb_x * 8 + (mx >> 1); uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1); } else { uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1); uvsrc_x = src_x >> 1; uvsrc_y = src_y >> 1; } // Even chroma mv's are full pel in H261 } else if (!is_mpeg12 && s->out_format == FMT_H261) { mx = motion_x / 4; my = motion_y / 4; uvdxy = 0; uvsrc_x = s->mb_x * 8 + mx; uvsrc_y = mb_y * 8 + my; } else { if (s->chroma_y_shift) { mx = motion_x / 2; my = motion_y / 2; uvdxy = ((my & 1) << 1) | (mx & 1); uvsrc_x = s->mb_x * 8 + (mx >> 1); uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1); } else { if (s->chroma_x_shift) { // Chroma422 mx = motion_x / 2; uvdxy = ((motion_y & 1) << 1) | (mx & 1); uvsrc_x = s->mb_x * 8 + (mx >> 1); uvsrc_y = src_y; } else { // Chroma444 uvdxy = dxy; uvsrc_x = src_x; uvsrc_y = src_y; } } } ptr_y = ref_picture[0] + src_y * linesize + src_x; ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 1) - 16, 0) || (unsigned)src_y > FFMAX(v_edge_pos - (motion_y & 1) - h, 0)) { if (is_mpeg12 || s->codec_id == AV_CODEC_ID_MPEG2VIDEO || s->codec_id == AV_CODEC_ID_MPEG1VIDEO) { av_log(s->avctx, AV_LOG_DEBUG, "MPEG motion vector out of boundary (%d %d)\n", src_x, src_y); return; } s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, s->linesize, 17, 17 + field_based, src_x, src_y << field_based, s->h_edge_pos, s->v_edge_pos); ptr_y = s->edge_emu_buffer; if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) { uint8_t *uvbuf = s->edge_emu_buffer + 18 * s->linesize; s->vdsp.emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize, s->uvlinesize, 9, 9 + field_based, uvsrc_x, uvsrc_y << field_based, s->h_edge_pos >> 1, s->v_edge_pos >> 1); s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize, s->uvlinesize, 9, 9 + field_based, uvsrc_x, uvsrc_y << field_based, s->h_edge_pos >> 1, s->v_edge_pos >> 1); ptr_cb = uvbuf; ptr_cr = uvbuf + 16; } } /* FIXME use this for field pix too instead of the obnoxious hack which * changes picture.data */ if (bottom_field) { dest_y += s->linesize; dest_cb += s->uvlinesize; dest_cr += s->uvlinesize; } if (field_select) { ptr_y += s->linesize; ptr_cb += s->uvlinesize; ptr_cr += s->uvlinesize; } pix_op[0][dxy](dest_y, ptr_y, linesize, h); if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) { pix_op[s->chroma_x_shift][uvdxy] (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift); pix_op[s->chroma_x_shift][uvdxy] (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift); } if (!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) && s->out_format == FMT_H261) { ff_h261_loop_filter(s); } }