void rtsp_close_streams(AVFormatContext *s) { RTSPState *rt = s->priv_data; int i; RTSPStream *rtsp_st; for (i = 0; i < rt->nb_rtsp_streams; i++) { rtsp_st = rt->rtsp_streams[i]; if (rtsp_st) { if (rtsp_st->transport_priv) { if (s->oformat) { AVFormatContext *rtpctx = rtsp_st->transport_priv; av_write_trailer(rtpctx); url_fclose(rtpctx->pb); av_free(rtpctx->streams[0]); av_free(rtpctx); } else if (rt->transport == RTSP_TRANSPORT_RDT) ff_rdt_parse_close(rtsp_st->transport_priv); else rtp_parse_close(rtsp_st->transport_priv); } if (rtsp_st->rtp_handle) url_close(rtsp_st->rtp_handle); if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context) rtsp_st->dynamic_handler->close( rtsp_st->dynamic_protocol_context); } } av_free(rt->rtsp_streams); if (rt->asf_ctx) { av_close_input_stream (rt->asf_ctx); rt->asf_ctx = NULL; } av_freep(&rt->auth_b64); }


void replay_save_instructions(void) { if (replay_file && replay_mode == REPLAY_MODE_RECORD) { replay_mutex_lock(); int diff = (int)(replay_get_current_step() - replay_state.current_step); if (diff > 0) { replay_put_event(EVENT_INSTRUCTION); replay_put_dword(diff); replay_state.current_step += diff; } replay_mutex_unlock(); } }


int load_vmstate(const char *name) { BlockDriverState *bs, *bs1; QEMUSnapshotInfo sn; QEMUFile *f; int ret; /* Verify if there is a device that doesn't support snapshots and is writable */ bs = NULL; while ((bs = bdrv_next(bs))) { if (bdrv_is_removable(bs) || bdrv_is_read_only(bs)) { continue; } if (!bdrv_can_snapshot(bs)) { error_report("Device '%s' is writable but does not support snapshots.", bdrv_get_device_name(bs)); return -ENOTSUP; } } bs = bdrv_snapshots(); if (!bs) { error_report("No block device supports snapshots"); return -EINVAL; } /* Flush all IO requests so they don't interfere with the new state. */ qemu_aio_flush(); bs1 = NULL; while ((bs1 = bdrv_next(bs1))) { if (bdrv_can_snapshot(bs1)) { ret = bdrv_snapshot_goto(bs1, name); if (ret < 0) { switch(ret) { case -ENOTSUP: error_report("%sSnapshots not supported on device '%s'", bs != bs1 ? "Warning: " : "", bdrv_get_device_name(bs1)); break; case -ENOENT: error_report("%sCould not find snapshot '%s' on device '%s'", bs != bs1 ? "Warning: " : "", name, bdrv_get_device_name(bs1)); break; default: error_report("%sError %d while activating snapshot on '%s'", bs != bs1 ? "Warning: " : "", ret, bdrv_get_device_name(bs1)); break; } /* fatal on snapshot block device */ if (bs == bs1) return 0; } } } /* Don't even try to load empty VM states */ ret = bdrv_snapshot_find(bs, &sn, name); if ((ret >= 0) && (sn.vm_state_size == 0)) return -EINVAL; /* restore the VM state */ f = qemu_fopen_bdrv(bs, 0); if (!f) { error_report("Could not open VM state file"); return -EINVAL; } ret = qemu_loadvm_state(f); qemu_fclose(f); if (ret < 0) { error_report("Error %d while loading VM state", ret); return ret; } return 0; }


static int flv_write_header(AVFormatContext *s) { AVIOContext *pb = s->pb; FLVContext *flv = s->priv_data; AVCodecContext *audio_enc = NULL, *video_enc = NULL, *data_enc = NULL; int i, metadata_count = 0; double framerate = 0.0; int64_t metadata_size_pos, data_size, metadata_count_pos; AVDictionaryEntry *tag = NULL; for (i = 0; i < s->nb_streams; i++) { AVCodecContext *enc = s->streams[i]->codec; FLVStreamContext *sc; switch (enc->codec_type) { case AVMEDIA_TYPE_VIDEO: if (s->streams[i]->r_frame_rate.den && s->streams[i]->r_frame_rate.num) { framerate = av_q2d(s->streams[i]->r_frame_rate); } else { framerate = 1 / av_q2d(s->streams[i]->codec->time_base); } video_enc = enc; if (enc->codec_tag == 0) { av_log(s, AV_LOG_ERROR, "video codec not compatible with flv\n"); return -1; } break; case AVMEDIA_TYPE_AUDIO: audio_enc = enc; if (get_audio_flags(s, enc) < 0) return AVERROR_INVALIDDATA; break; case AVMEDIA_TYPE_DATA: if (enc->codec_id != CODEC_ID_TEXT) { av_log(s, AV_LOG_ERROR, "codec not compatible with flv\n"); return AVERROR_INVALIDDATA; } data_enc = enc; break; default: av_log(s, AV_LOG_ERROR, "codec not compatible with flv\n"); return -1; } avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */ sc = av_mallocz(sizeof(FLVStreamContext)); if (!sc) return AVERROR(ENOMEM); s->streams[i]->priv_data = sc; sc->last_ts = -1; } flv->delay = AV_NOPTS_VALUE; avio_write(pb, "FLV", 3); avio_w8(pb, 1); avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!audio_enc + FLV_HEADER_FLAG_HASVIDEO * !!video_enc); avio_wb32(pb, 9); avio_wb32(pb, 0); for (i = 0; i < s->nb_streams; i++) if (s->streams[i]->codec->codec_tag == 5) { avio_w8(pb, 8); // message type avio_wb24(pb, 0); // include flags avio_wb24(pb, 0); // time stamp avio_wb32(pb, 0); // reserved avio_wb32(pb, 11); // size flv->reserved = 5; } /* write meta_tag */ avio_w8(pb, 18); // tag type META metadata_size_pos = avio_tell(pb); avio_wb24(pb, 0); // size of data part (sum of all parts below) avio_wb24(pb, 0); // timestamp avio_wb32(pb, 0); // reserved /* now data of data_size size */ /* first event name as a string */ avio_w8(pb, AMF_DATA_TYPE_STRING); put_amf_string(pb, "onMetaData"); // 12 bytes /* mixed array (hash) with size and string/type/data tuples */ avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY); metadata_count_pos = avio_tell(pb); metadata_count = 5 * !!video_enc + 5 * !!audio_enc + 1 * !!data_enc + 2; // +2 for duration and file size avio_wb32(pb, metadata_count); put_amf_string(pb, "duration"); flv->duration_offset= avio_tell(pb); // fill in the guessed duration, it'll be corrected later if incorrect put_amf_double(pb, s->duration / AV_TIME_BASE); if (video_enc) { put_amf_string(pb, "width"); put_amf_double(pb, video_enc->width); put_amf_string(pb, "height"); put_amf_double(pb, video_enc->height); put_amf_string(pb, "videodatarate"); put_amf_double(pb, video_enc->bit_rate / 1024.0); put_amf_string(pb, "framerate"); put_amf_double(pb, framerate); put_amf_string(pb, "videocodecid"); put_amf_double(pb, video_enc->codec_tag); } if (audio_enc) { put_amf_string(pb, "audiodatarate"); put_amf_double(pb, audio_enc->bit_rate / 1024.0); put_amf_string(pb, "audiosamplerate"); put_amf_double(pb, audio_enc->sample_rate); put_amf_string(pb, "audiosamplesize"); put_amf_double(pb, audio_enc->codec_id == CODEC_ID_PCM_U8 ? 8 : 16); put_amf_string(pb, "stereo"); put_amf_bool(pb, audio_enc->channels == 2); put_amf_string(pb, "audiocodecid"); put_amf_double(pb, audio_enc->codec_tag); } if (data_enc) { put_amf_string(pb, "datastream"); put_amf_double(pb, 0.0); } while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { put_amf_string(pb, tag->key); avio_w8(pb, AMF_DATA_TYPE_STRING); put_amf_string(pb, tag->value); metadata_count++; } put_amf_string(pb, "filesize"); flv->filesize_offset = avio_tell(pb); put_amf_double(pb, 0); // delayed write put_amf_string(pb, ""); avio_w8(pb, AMF_END_OF_OBJECT); /* write total size of tag */ data_size = avio_tell(pb) - metadata_size_pos - 10; avio_seek(pb, metadata_count_pos, SEEK_SET); avio_wb32(pb, metadata_count); avio_seek(pb, metadata_size_pos, SEEK_SET); avio_wb24(pb, data_size); avio_skip(pb, data_size + 10 - 3); avio_wb32(pb, data_size + 11); for (i = 0; i < s->nb_streams; i++) { AVCodecContext *enc = s->streams[i]->codec; if (enc->codec_id == CODEC_ID_AAC || enc->codec_id == CODEC_ID_H264) { int64_t pos; avio_w8(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ? FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO); avio_wb24(pb, 0); // size patched later avio_wb24(pb, 0); // ts avio_w8(pb, 0); // ts ext avio_wb24(pb, 0); // streamid pos = avio_tell(pb); if (enc->codec_id == CODEC_ID_AAC) { avio_w8(pb, get_audio_flags(s, enc)); avio_w8(pb, 0); // AAC sequence header avio_write(pb, enc->extradata, enc->extradata_size); } else { avio_w8(pb, enc->codec_tag | FLV_FRAME_KEY); // flags avio_w8(pb, 0); // AVC sequence header avio_wb24(pb, 0); // composition time ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size); } data_size = avio_tell(pb) - pos; avio_seek(pb, -data_size - 10, SEEK_CUR); avio_wb24(pb, data_size); avio_skip(pb, data_size + 10 - 3); avio_wb32(pb, data_size + 11); // previous tag size } } return 0; }


void ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in) { char *param, buffer[128], tmp[128]; int len, tag_close, sptr = 1, line_start = 1, an = 0, end = 0; SrtStack stack[16]; stack[0].tag[0] = 0; strcpy(stack[0].param[PARAM_SIZE], "{\\fs}"); strcpy(stack[0].param[PARAM_COLOR], "{\\c}"); strcpy(stack[0].param[PARAM_FACE], "{\\fn}"); for (; !end && *in; in++) { switch (*in) { case '\r': break; case '\n': if (line_start) { end = 1; break; } rstrip_spaces_buf(dst); av_bprintf(dst, "\\N"); line_start = 1; break; case ' ': if (!line_start) av_bprint_chars(dst, *in, 1); break; case '{': /* skip all {\xxx} substrings except for {\an%d} and all microdvd like styles such as {Y:xxx} */ len = 0; an += sscanf(in, "{\\an%*1u}%n", &len) >= 0 && len > 0; if ((an != 1 && (len = 0, sscanf(in, "{\\%*[^}]}%n", &len) >= 0 && len > 0)) || (len = 0, sscanf(in, "{%*1[CcFfoPSsYy]:%*[^}]}%n", &len) >= 0 && len > 0)) { in += len - 1; } else av_bprint_chars(dst, *in, 1); break; case '<': tag_close = in[1] == '/'; len = 0; if (sscanf(in+tag_close+1, "%127[^>]>%n", buffer, &len) >= 1 && len > 0) { const char *tagname = buffer; while (*tagname == ' ') tagname++; if ((param = strchr(tagname, ' '))) *param++ = 0; if ((!tag_close && sptr < FF_ARRAY_ELEMS(stack)) || ( tag_close && sptr > 0 && !strcmp(stack[sptr-1].tag, tagname))) { int i, j, unknown = 0; in += len + tag_close; if (!tag_close) memset(stack+sptr, 0, sizeof(*stack)); if (!strcmp(tagname, "font")) { if (tag_close) { for (i=PARAM_NUMBER-1; i>=0; i--) if (stack[sptr-1].param[i][0]) for (j=sptr-2; j>=0; j--) if (stack[j].param[i][0]) { av_bprintf(dst, "%s", stack[j].param[i]); break; } } else { while (param) { if (!strncmp(param, "size=", 5)) { unsigned font_size; param += 5 + (param[5] == '"'); if (sscanf(param, "%u", &font_size) == 1) { snprintf(stack[sptr].param[PARAM_SIZE], sizeof(stack[0].param[PARAM_SIZE]), "{\\fs%u}", font_size); } } else if (!strncmp(param, "color=", 6)) { param += 6 + (param[6] == '"'); snprintf(stack[sptr].param[PARAM_COLOR], sizeof(stack[0].param[PARAM_COLOR]), "{\\c&H%X&}", html_color_parse(log_ctx, param)); } else if (!strncmp(param, "face=", 5)) { param += 5 + (param[5] == '"'); len = strcspn(param, param[-1] == '"' ? "\"" :" "); av_strlcpy(tmp, param, FFMIN(sizeof(tmp), len+1)); param += len; snprintf(stack[sptr].param[PARAM_FACE], sizeof(stack[0].param[PARAM_FACE]), "{\\fn%s}", tmp); } if ((param = strchr(param, ' '))) param++; } for (i=0; i<PARAM_NUMBER; i++) if (stack[sptr].param[i][0]) av_bprintf(dst, "%s", stack[sptr].param[i]); } } else if (tagname[0] && !tagname[1] && strspn(tagname, "bisu") == 1) { av_bprintf(dst, "{\\%c%d}", tagname[0], !tag_close); } else { unknown = 1; snprintf(tmp, sizeof(tmp), "</%s>", tagname); } if (tag_close) { sptr--; } else if (unknown && !strstr(in, tmp)) { in -= len + tag_close; av_bprint_chars(dst, *in, 1); } else av_strlcpy(stack[sptr++].tag, tagname, sizeof(stack[0].tag)); break; } } default: av_bprint_chars(dst, *in, 1); break; } if (*in != ' ' && *in != '\r' && *in != '\n') line_start = 0; } while (dst->len >= 2 && !strncmp(&dst->str[dst->len - 2], "\\N", 2)) dst->len -= 2; dst->str[dst->len] = 0; rstrip_spaces_buf(dst); }


static void qpa_fini_in (HWVoiceIn *hw) { void *ret; PAVoiceIn *pa = (PAVoiceIn *) hw; audio_pt_lock (&pa->pt, AUDIO_FUNC); pa->done = 1; audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC); audio_pt_join (&pa->pt, &ret, AUDIO_FUNC); if (pa->s) { pa_simple_free (pa->s); pa->s = NULL; } audio_pt_fini (&pa->pt, AUDIO_FUNC); g_free (pa->pcm_buf); pa->pcm_buf = NULL; }


static void onenand_reset(OneNANDState *s, int cold) { memset(&s->addr, 0, sizeof(s->addr)); s->command = 0; s->count = 1; s->bufaddr = 0; s->config[0] = 0x40c0; s->config[1] = 0x0000; onenand_intr_update(s); qemu_irq_raise(s->rdy); s->status = 0x0000; s->intstatus = cold ? 0x8080 : 0x8010; s->unladdr[0] = 0; s->unladdr[1] = 0; s->wpstatus = 0x0002; s->cycle = 0; s->otpmode = 0; s->blk_cur = s->blk; s->current = s->image; s->secs_cur = s->secs; if (cold) { /* Lock the whole flash */ memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks); if (s->blk_cur && blk_read(s->blk_cur, 0, s->boot[0], 8) < 0) { hw_error("%s: Loading the BootRAM failed.\n", __func__); } } }


static void flush_packet(AVFormatContext *ctx, int stream_index, int64_t pts, int64_t dts, int64_t scr) { MpegMuxContext *s = ctx->priv_data; StreamInfo *stream = ctx->streams[stream_index]->priv_data; uint8_t *buf_ptr; int size, payload_size, startcode, id, len, stuffing_size, i, header_len; uint8_t buffer[128]; id = stream->id; #if 0 printf("packet ID=%2x PTS=%0.3f\n", id, pts / 90000.0); #endif buf_ptr = buffer; if (((s->packet_number % s->pack_header_freq) == 0)) { /* output pack and systems header if needed */ size = put_pack_header(ctx, buf_ptr, scr); buf_ptr += size; if ((s->packet_number % s->system_header_freq) == 0) { size = put_system_header(ctx, buf_ptr); buf_ptr += size; } } size = buf_ptr - buffer; put_buffer(&ctx->pb, buffer, size); /* packet header */ if (s->is_mpeg2) { header_len = 3; } else { header_len = 0; } if (pts != AV_NOPTS_VALUE) { if (dts != AV_NOPTS_VALUE) header_len += 5 + 5; else header_len += 5; } else { if (!s->is_mpeg2) header_len++; } payload_size = s->packet_size - (size + 6 + header_len); if (id < 0xc0) { startcode = PRIVATE_STREAM_1; payload_size -= 4; } else { startcode = 0x100 + id; } stuffing_size = payload_size - stream->buffer_ptr; if (stuffing_size < 0) stuffing_size = 0; put_be32(&ctx->pb, startcode); put_be16(&ctx->pb, payload_size + header_len); /* stuffing */ for(i=0;i<stuffing_size;i++) put_byte(&ctx->pb, 0xff); if (s->is_mpeg2) { put_byte(&ctx->pb, 0x80); /* mpeg2 id */ if (pts != AV_NOPTS_VALUE) { if (dts != AV_NOPTS_VALUE) { put_byte(&ctx->pb, 0xc0); /* flags */ put_byte(&ctx->pb, header_len - 3); put_timestamp(&ctx->pb, 0x03, pts); put_timestamp(&ctx->pb, 0x01, dts); } else { put_byte(&ctx->pb, 0x80); /* flags */ put_byte(&ctx->pb, header_len - 3); put_timestamp(&ctx->pb, 0x02, pts); } } else { put_byte(&ctx->pb, 0x00); /* flags */ put_byte(&ctx->pb, header_len - 3); } } else { if (pts != AV_NOPTS_VALUE) { if (dts != AV_NOPTS_VALUE) { put_timestamp(&ctx->pb, 0x03, pts); put_timestamp(&ctx->pb, 0x01, dts); } else { put_timestamp(&ctx->pb, 0x02, pts); } } else { put_byte(&ctx->pb, 0x0f); } } if (startcode == PRIVATE_STREAM_1) { put_byte(&ctx->pb, id); if (id >= 0x80 && id <= 0xbf) { /* XXX: need to check AC3 spec */ put_byte(&ctx->pb, 1); put_byte(&ctx->pb, 0); put_byte(&ctx->pb, 2); } } /* output data */ put_buffer(&ctx->pb, stream->buffer, payload_size - stuffing_size); put_flush_packet(&ctx->pb); /* preserve remaining data */ len = stream->buffer_ptr - payload_size; if (len < 0) len = 0; memmove(stream->buffer, stream->buffer + stream->buffer_ptr - len, len); stream->buffer_ptr = len; s->packet_number++; stream->packet_number++; }


static QPCIDevice *get_pci_device(void **bmdma_base, void **ide_base) { QPCIDevice *dev; uint16_t vendor_id, device_id; if (!pcibus) { pcibus = qpci_init_pc(NULL); } /* Find PCI device and verify it's the right one */ dev = qpci_device_find(pcibus, QPCI_DEVFN(IDE_PCI_DEV, IDE_PCI_FUNC)); g_assert(dev != NULL); vendor_id = qpci_config_readw(dev, PCI_VENDOR_ID); device_id = qpci_config_readw(dev, PCI_DEVICE_ID); g_assert(vendor_id == PCI_VENDOR_ID_INTEL); g_assert(device_id == PCI_DEVICE_ID_INTEL_82371SB_1); /* Map bmdma BAR */ *bmdma_base = qpci_iomap(dev, 4, NULL); *ide_base = qpci_legacy_iomap(dev, IDE_BASE); qpci_device_enable(dev); return dev; }


static av_always_inline void rgb16_32ToUV_half_c_template(int16_t *dstU, int16_t *dstV, const uint8_t *src, int width, enum AVPixelFormat origin, int shr, int shg, int shb, int shp, int maskr, int maskg, int maskb, int rsh, int gsh, int bsh, int S, int32_t *rgb2yuv) { const int ru = rgb2yuv[RU_IDX] << rsh, gu = rgb2yuv[GU_IDX] << gsh, bu = rgb2yuv[BU_IDX] << bsh, rv = rgb2yuv[RV_IDX] << rsh, gv = rgb2yuv[GV_IDX] << gsh, bv = rgb2yuv[BV_IDX] << bsh, maskgx = ~(maskr | maskb); const unsigned rnd = (256U<<(S)) + (1<<(S-6)); int i; maskr |= maskr << 1; maskb |= maskb << 1; maskg |= maskg << 1; for (i = 0; i < width; i++) { int px0 = input_pixel(2 * i + 0) >> shp; int px1 = input_pixel(2 * i + 1) >> shp; int b, r, g = (px0 & maskgx) + (px1 & maskgx); int rb = px0 + px1 - g; b = (rb & maskb) >> shb; if (shp || origin == AV_PIX_FMT_BGR565LE || origin == AV_PIX_FMT_BGR565BE || origin == AV_PIX_FMT_RGB565LE || origin == AV_PIX_FMT_RGB565BE) { g >>= shg; } else { g = (g & maskg) >> shg; } r = (rb & maskr) >> shr; dstU[i] = (ru * r + gu * g + bu * b + (unsigned)rnd) >> ((S)-6+1); dstV[i] = (rv * r + gv * g + bv * b + (unsigned)rnd) >> ((S)-6+1); } }


static int read_header(AVFormatContext *s1) { VideoDemuxData *s = s1->priv_data; int first_index, last_index, ret = 0; int width = 0, height = 0; AVStream *st; enum PixelFormat pix_fmt = PIX_FMT_NONE; AVRational framerate; s1->ctx_flags |= AVFMTCTX_NOHEADER; st = avformat_new_stream(s1, NULL); if (!st) { return AVERROR(ENOMEM); } if (s->pixel_format && (pix_fmt = av_get_pix_fmt(s->pixel_format)) == PIX_FMT_NONE) { av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n", s->pixel_format); return AVERROR(EINVAL); } if (s->video_size && (ret = av_parse_video_size(&width, &height, s->video_size)) < 0) { av_log(s, AV_LOG_ERROR, "Could not parse video size: %s.\n", s->video_size); return ret; } if ((ret = av_parse_video_rate(&framerate, s->framerate)) < 0) { av_log(s, AV_LOG_ERROR, "Could not parse framerate: %s.\n", s->framerate); return ret; } av_strlcpy(s->path, s1->filename, sizeof(s->path)); s->img_number = 0; s->img_count = 0; /* find format */ if (s1->iformat->flags & AVFMT_NOFILE) s->is_pipe = 0; else{ s->is_pipe = 1; st->need_parsing = AVSTREAM_PARSE_FULL; } avpriv_set_pts_info(st, 60, framerate.den, framerate.num); if (width && height) { st->codec->width = width; st->codec->height = height; } if (!s->is_pipe) { s->use_glob = is_glob(s->path); if (s->use_glob) { #if HAVE_GLOB char *p = s->path, *q, *dup; int gerr; dup = q = av_strdup(p); while (*q) { /* Do we have room for the next char and a \ insertion? */ if ((p - s->path) >= (sizeof(s->path) - 2)) break; if (*q == '%' && strspn(q + 1, "%*?[]{}")) ++q; else if (strspn(q, "\\*?[]{}")) *p++ = '\\'; *p++ = *q++; } *p = 0; av_free(dup); gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate); if (gerr != 0) { return AVERROR(ENOENT); } first_index = 0; last_index = s->globstate.gl_pathc - 1; #endif } else { if (find_image_range(&first_index, &last_index, s->path, s->start_number, s->start_number_range) < 0) { av_log(s1, AV_LOG_ERROR, "Could find no file with with path '%s' and index in the range %d-%d\n", s->path, s->start_number, s->start_number + s->start_number_range - 1); return AVERROR(ENOENT); } } s->img_first = first_index; s->img_last = last_index; s->img_number = first_index; /* compute duration */ st->start_time = 0; st->duration = last_index - first_index + 1; } if(s1->video_codec_id){ st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = s1->video_codec_id; }else if(s1->audio_codec_id){ st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = s1->audio_codec_id; }else{ const char *str= strrchr(s->path, '.'); s->split_planes = str && !av_strcasecmp(str + 1, "y"); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = ff_guess_image2_codec(s->path); if (st->codec->codec_id == AV_CODEC_ID_LJPEG) st->codec->codec_id = AV_CODEC_ID_MJPEG; } if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO && pix_fmt != PIX_FMT_NONE) st->codec->pix_fmt = pix_fmt; return 0; }


static int qdraw_probe(AVProbeData *p) { const uint8_t *b = p->buf; if (!b[10] && AV_RB32(b+11) == 0x1102ff0c && !b[15] || p->buf_size >= 528 && !b[522] && AV_RB32(b+523) == 0x1102ff0c && !b[527]) return AVPROBE_SCORE_EXTENSION + 1; return 0; }


static int decode_format80(VqaContext *s, int src_size, unsigned char *dest, int dest_size, int check_size) { int dest_index = 0; int count, opcode, start; int src_pos; unsigned char color; int i; start = bytestream2_tell(&s->gb); while (bytestream2_tell(&s->gb) - start < src_size) { opcode = bytestream2_get_byte(&s->gb); av_dlog(s->avctx, "opcode %02X: ", opcode); /* 0x80 means that frame is finished */ if (opcode == 0x80) return 0; if (dest_index >= dest_size) { av_log(s->avctx, AV_LOG_ERROR, "decode_format80 problem: dest_index (%d) exceeded dest_size (%d)\n", dest_index, dest_size); return AVERROR_INVALIDDATA; } if (opcode == 0xFF) { count = bytestream2_get_le16(&s->gb); src_pos = bytestream2_get_le16(&s->gb); av_dlog(s->avctx, "(1) copy %X bytes from absolute pos %X\n", count, src_pos); CHECK_COUNT(); CHECK_COPY(src_pos); for (i = 0; i < count; i++) dest[dest_index + i] = dest[src_pos + i]; dest_index += count; } else if (opcode == 0xFE) { count = bytestream2_get_le16(&s->gb); color = bytestream2_get_byte(&s->gb); av_dlog(s->avctx, "(2) set %X bytes to %02X\n", count, color); CHECK_COUNT(); memset(&dest[dest_index], color, count); dest_index += count; } else if ((opcode & 0xC0) == 0xC0) { count = (opcode & 0x3F) + 3; src_pos = bytestream2_get_le16(&s->gb); av_dlog(s->avctx, "(3) copy %X bytes from absolute pos %X\n", count, src_pos); CHECK_COUNT(); CHECK_COPY(src_pos); for (i = 0; i < count; i++) dest[dest_index + i] = dest[src_pos + i]; dest_index += count; } else if (opcode > 0x80) { count = opcode & 0x3F; av_dlog(s->avctx, "(4) copy %X bytes from source to dest\n", count); CHECK_COUNT(); bytestream2_get_buffer(&s->gb, &dest[dest_index], count); dest_index += count; } else { count = ((opcode & 0x70) >> 4) + 3; src_pos = bytestream2_get_byte(&s->gb) | ((opcode & 0x0F) << 8); av_dlog(s->avctx, "(5) copy %X bytes from relpos %X\n", count, src_pos); CHECK_COUNT(); CHECK_COPY(dest_index - src_pos); for (i = 0; i < count; i++) dest[dest_index + i] = dest[dest_index - src_pos + i]; dest_index += count; } } /* validate that the entire destination buffer was filled; this is * important for decoding frame maps since each vector needs to have a * codebook entry; it is not important for compressed codebooks because * not every entry needs to be filled */ if (check_size) if (dest_index < dest_size) av_log(s->avctx, AV_LOG_ERROR, "decode_format80 problem: decode finished with dest_index (%d) < dest_size (%d)\n", dest_index, dest_size); return 0; // let's display what we decoded anyway }


static int open_input_file(OptionsContext *o, const char *filename) { InputFile *f; AVFormatContext *ic; AVInputFormat *file_iformat = NULL; int err, i, ret; int64_t timestamp; uint8_t buf[128]; AVDictionary **opts; AVDictionary *unused_opts = NULL; AVDictionaryEntry *e = NULL; int orig_nb_streams; // number of streams before avformat_find_stream_info if (o->format) { if (!(file_iformat = av_find_input_format(o->format))) { av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format); exit_program(1); } } if (!strcmp(filename, "-")) filename = "pipe:"; using_stdin |= !strncmp(filename, "pipe:", 5) || !strcmp(filename, "/dev/stdin"); /* get default parameters from command line */ ic = avformat_alloc_context(); if (!ic) { print_error(filename, AVERROR(ENOMEM)); exit_program(1); } if (o->nb_audio_sample_rate) { snprintf(buf, sizeof(buf), "%d", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i); av_dict_set(&o->g->format_opts, "sample_rate", buf, 0); } if (o->nb_audio_channels) { /* because we set audio_channels based on both the "ac" and * "channel_layout" options, we need to check that the specified * demuxer actually has the "channels" option before setting it */ if (file_iformat && file_iformat->priv_class && av_opt_find(&file_iformat->priv_class, "channels", NULL, 0, AV_OPT_SEARCH_FAKE_OBJ)) { snprintf(buf, sizeof(buf), "%d", o->audio_channels[o->nb_audio_channels - 1].u.i); av_dict_set(&o->g->format_opts, "channels", buf, 0); } } if (o->nb_frame_rates) { /* set the format-level framerate option; * this is important for video grabbers, e.g. x11 */ if (file_iformat && file_iformat->priv_class && av_opt_find(&file_iformat->priv_class, "framerate", NULL, 0, AV_OPT_SEARCH_FAKE_OBJ)) { av_dict_set(&o->g->format_opts, "framerate", o->frame_rates[o->nb_frame_rates - 1].u.str, 0); } } if (o->nb_frame_sizes) { av_dict_set(&o->g->format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0); } if (o->nb_frame_pix_fmts) av_dict_set(&o->g->format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0); ic->flags |= AVFMT_FLAG_NONBLOCK; ic->interrupt_callback = int_cb; /* open the input file with generic libav function */ err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts); if (err < 0) { print_error(filename, err); exit_program(1); } assert_avoptions(o->g->format_opts); /* apply forced codec ids */ for (i = 0; i < ic->nb_streams; i++) choose_decoder(o, ic, ic->streams[i]); /* Set AVCodecContext options for avformat_find_stream_info */ opts = setup_find_stream_info_opts(ic, o->g->codec_opts); orig_nb_streams = ic->nb_streams; /* If not enough info to get the stream parameters, we decode the first frames to get it. (used in mpeg case for example) */ ret = avformat_find_stream_info(ic, opts); if (ret < 0) { av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename); avformat_close_input(&ic); exit_program(1); } timestamp = o->start_time; /* add the stream start time */ if (ic->start_time != AV_NOPTS_VALUE) timestamp += ic->start_time; /* if seeking requested, we execute it */ if (o->start_time != 0) { ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD); if (ret < 0) { av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n", filename, (double)timestamp / AV_TIME_BASE); } } /* update the current parameters so that they match the one of the input stream */ add_input_streams(o, ic); /* dump the file content */ av_dump_format(ic, nb_input_files, filename, 0); GROW_ARRAY(input_files, nb_input_files); f = av_mallocz(sizeof(*f)); if (!f) exit_program(1); input_files[nb_input_files - 1] = f; f->ctx = ic; f->ist_index = nb_input_streams - ic->nb_streams; f->ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp); f->nb_streams = ic->nb_streams; f->rate_emu = o->rate_emu; /* check if all codec options have been used */ unused_opts = strip_specifiers(o->g->codec_opts); for (i = f->ist_index; i < nb_input_streams; i++) { e = NULL; while ((e = av_dict_get(input_streams[i]->opts, "", e, AV_DICT_IGNORE_SUFFIX))) av_dict_set(&unused_opts, e->key, NULL, 0); } e = NULL; while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) { const AVClass *class = avcodec_get_class(); const AVOption *option = av_opt_find(&class, e->key, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ); if (!option) continue; if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) { av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for " "input file #%d (%s) is not a decoding option.\n", e->key, option->help ? option->help : "", nb_input_files - 1, filename); exit_program(1); } av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for " "input file #%d (%s) has not been used for any stream. The most " "likely reason is either wrong type (e.g. a video option with " "no video streams) or that it is a private option of some decoder " "which was not actually used for any stream.\n", e->key, option->help ? option->help : "", nb_input_files - 1, filename); } av_dict_free(&unused_opts); for (i = 0; i < o->nb_dump_attachment; i++) { int j; for (j = 0; j < ic->nb_streams; j++) { AVStream *st = ic->streams[j]; if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1) dump_attachment(st, o->dump_attachment[i].u.str); } } for (i = 0; i < orig_nb_streams; i++) av_dict_free(&opts[i]); av_freep(&opts); return 0; }


static int theora_packet(AVFormatContext *s, int idx) { struct ogg *ogg = s->priv_data; struct ogg_stream *os = ogg->streams + idx; int duration; /* first packet handling here we parse the duration of each packet in the first page and compare the total duration to the page granule to find the encoder delay and set the first timestamp */ if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) { int seg; duration = 1; for (seg = os->segp; seg < os->nsegs; seg++) { if (os->segments[seg] < 255) duration ++; } os->lastpts = os->lastdts = theora_gptopts(s, idx, os->granule, NULL) - duration; if(s->streams[idx]->start_time == AV_NOPTS_VALUE) { s->streams[idx]->start_time = os->lastpts; if (s->streams[idx]->duration) s->streams[idx]->duration -= s->streams[idx]->start_time; } } /* parse packet duration */ if (os->psize > 0) { os->pduration = 1; } return 0; }


static int mov_write_wfex_tag(AVIOContext *pb, MOVTrack *track) { int64_t pos = avio_tell(pb); avio_wb32(pb, 0); ffio_wfourcc(pb, "wfex"); ff_put_wav_header(pb, track->enc, FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX); return update_size(pb, pos); }


static void denoise_depth(HQDN3DContext *s, uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t **frame_ant_ptr, int w, int h, int sstride, int dstride, int16_t *spatial, int16_t *temporal, int depth) { // FIXME: For 16bit depth, frame_ant could be a pointer to the previous // filtered frame rather than a separate buffer. long x, y; uint16_t *frame_ant = *frame_ant_ptr; if (!frame_ant) { uint8_t *frame_src = src; *frame_ant_ptr = frame_ant = av_malloc(w*h*sizeof(uint16_t)); for (y = 0; y < h; y++, src += sstride, frame_ant += w) for (x = 0; x < w; x++) frame_ant[x] = LOAD(x); src = frame_src; frame_ant = *frame_ant_ptr; } if (spatial[0]) denoise_spatial(s, src, dst, line_ant, frame_ant, w, h, sstride, dstride, spatial, temporal, depth); else denoise_temporal(src, dst, frame_ant, w, h, sstride, dstride, temporal, depth); emms_c(); }


static void FUNC(transquant_bypass8x8)(uint8_t *_dst, int16_t *coeffs, ptrdiff_t stride) { int x, y; pixel *dst = (pixel *)_dst; stride /= sizeof(pixel); for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { dst[x] += *coeffs; coeffs++; } dst += stride; } }


static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) { int addr_reg, r0, r1, rbase, data_reg, mem_index, bswap; #ifdef CONFIG_SOFTMMU int r2; void *label1_ptr, *label2_ptr; #endif data_reg = *args++; addr_reg = *args++; mem_index = *args; #ifdef CONFIG_SOFTMMU r0 = 3; r1 = 4; r2 = 0; rbase = 0; tcg_out_tlb_read (s, r0, r1, r2, addr_reg, opc, offsetof (CPUState, tlb_table[mem_index][0].addr_write)); tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1) | CMP_L); label1_ptr = s->code_ptr; #ifdef FAST_PATH tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE); #endif /* slow path */ tcg_out_mov (s, 3, addr_reg); tcg_out_rld (s, RLDICL, 4, data_reg, 0, 64 - (1 << (3 + opc))); tcg_out_movi (s, TCG_TYPE_I64, 5, mem_index); tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1); label2_ptr = s->code_ptr; tcg_out32 (s, B); /* label1: fast path */ #ifdef FAST_PATH reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr); #endif tcg_out32 (s, (LD_ADDEND | RT (r0) | RA (r0) | (offsetof (CPUTLBEntry, addend) - offsetof (CPUTLBEntry, addr_write)) )); /* r0 = env->tlb_table[mem_index][index].addend */ tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg)); /* r0 = env->tlb_table[mem_index][index].addend + addr */ #else /* !CONFIG_SOFTMMU */ #if TARGET_LONG_BITS == 32 tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32); #endif r1 = 3; r0 = addr_reg; rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0; #endif #ifdef TARGET_WORDS_BIGENDIAN bswap = 0; #else bswap = 1; #endif switch (opc) { case 0: tcg_out32 (s, STBX | SAB (data_reg, rbase, r0)); break; case 1: if (bswap) tcg_out32 (s, STHBRX | SAB (data_reg, rbase, r0)); else tcg_out32 (s, STHX | SAB (data_reg, rbase, r0)); break; case 2: if (bswap) tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0)); else tcg_out32 (s, STWX | SAB (data_reg, rbase, r0)); break; case 3: if (bswap) { tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0)); tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4); tcg_out_rld (s, RLDICL, 0, data_reg, 32, 0); tcg_out32 (s, STWBRX | SAB (0, rbase, r1)); } else tcg_out32 (s, STDX | SAB (data_reg, rbase, r0)); break; } #ifdef CONFIG_SOFTMMU reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr); #endif }


int omap_validate_imif_addr(struct omap_mpu_state_s *s, target_phys_addr_t addr) { return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size; }


static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr, CPUState *cs) { sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); sPAPRCapabilities caps; caps = smc->default_caps; /* TODO: clamp according to cpu model */ return caps; }


int qio_channel_socket_listen_sync(QIOChannelSocket *ioc, SocketAddressLegacy *addr, Error **errp) { int fd; trace_qio_channel_socket_listen_sync(ioc, addr); fd = socket_listen(addr, errp); if (fd < 0) { trace_qio_channel_socket_listen_fail(ioc); return -1; } trace_qio_channel_socket_listen_complete(ioc, fd); if (qio_channel_socket_set_fd(ioc, fd, errp) < 0) { close(fd); return -1; } qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_LISTEN); return 0; }


uint64_t ptimer_get_count(ptimer_state *s) { int64_t now; uint64_t counter; if (s->enabled) { now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); /* Figure out the current counter value. */ if (now - s->next_event > 0 || s->period == 0) { /* Prevent timer underflowing if it should already have triggered. */ counter = 0; } else { uint64_t rem; uint64_t div; int clz1, clz2; int shift; /* We need to divide time by period, where time is stored in rem (64-bit integer) and period is stored in period/period_frac (64.32 fixed point). Doing full precision division is hard, so scale values and do a 64-bit division. The result should be rounded down, so that the rounding error never causes the timer to go backwards. */ rem = s->next_event - now; div = s->period; clz1 = clz64(rem); clz2 = clz64(div); shift = clz1 < clz2 ? clz1 : clz2; rem <<= shift; div <<= shift; if (shift >= 32) { div |= ((uint64_t)s->period_frac << (shift - 32)); } else { if (shift != 0) div |= (s->period_frac >> (32 - shift)); /* Look at remaining bits of period_frac and round div up if necessary. */ if ((uint32_t)(s->period_frac << shift)) div += 1; } counter = rem / div; } } else { counter = s->delta; } return counter; }


int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, int is_write1, int is_user, int is_softmmu) { uint64_t ptep, pte; uint32_t pdpe_addr, pde_addr, pte_addr; int error_code, is_dirty, prot, page_size, ret, is_write; unsigned long paddr, page_offset; target_ulong vaddr, virt_addr; #if defined(DEBUG_MMU) printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n", addr, is_write1, is_user, env->eip); #endif is_write = is_write1 & 1; if (!(env->cr[0] & CR0_PG_MASK)) { pte = addr; virt_addr = addr & TARGET_PAGE_MASK; prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; page_size = 4096; goto do_mapping; } if (env->cr[4] & CR4_PAE_MASK) { uint64_t pde, pdpe; /* XXX: we only use 32 bit physical addresses */ #ifdef TARGET_X86_64 if (env->hflags & HF_LMA_MASK) { uint32_t pml4e_addr; uint64_t pml4e; int32_t sext; /* test virtual address sign extension */ sext = (int64_t)addr >> 47; if (sext != 0 && sext != -1) { error_code = 0; goto do_fault; } pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) & env->a20_mask; pml4e = ldq_phys(pml4e_addr); if (!(pml4e & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) { error_code = PG_ERROR_RSVD_MASK; goto do_fault; } if (!(pml4e & PG_ACCESSED_MASK)) { pml4e |= PG_ACCESSED_MASK; stl_phys_notdirty(pml4e_addr, pml4e); } ptep = pml4e ^ PG_NX_MASK; pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) & env->a20_mask; pdpe = ldq_phys(pdpe_addr); if (!(pdpe & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) { error_code = PG_ERROR_RSVD_MASK; goto do_fault; } ptep &= pdpe ^ PG_NX_MASK; if (!(pdpe & PG_ACCESSED_MASK)) { pdpe |= PG_ACCESSED_MASK; stl_phys_notdirty(pdpe_addr, pdpe); } } else #endif { /* XXX: load them when cr3 is loaded ? */ pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 30) << 3)) & env->a20_mask; pdpe = ldq_phys(pdpe_addr); if (!(pdpe & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK; } pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) & env->a20_mask; pde = ldq_phys(pde_addr); if (!(pde & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) { error_code = PG_ERROR_RSVD_MASK; goto do_fault; } ptep &= pde ^ PG_NX_MASK; if (pde & PG_PSE_MASK) { /* 2 MB page */ page_size = 2048 * 1024; ptep ^= PG_NX_MASK; if ((ptep & PG_NX_MASK) && is_write1 == 2) goto do_fault_protect; if (is_user) { if (!(ptep & PG_USER_MASK)) goto do_fault_protect; if (is_write && !(ptep & PG_RW_MASK)) goto do_fault_protect; } else { if ((env->cr[0] & CR0_WP_MASK) && is_write && !(ptep & PG_RW_MASK)) goto do_fault_protect; } is_dirty = is_write && !(pde & PG_DIRTY_MASK); if (!(pde & PG_ACCESSED_MASK) || is_dirty) { pde |= PG_ACCESSED_MASK; if (is_dirty) pde |= PG_DIRTY_MASK; stl_phys_notdirty(pde_addr, pde); } /* align to page_size */ pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff); virt_addr = addr & ~(page_size - 1); } else { /* 4 KB page */ if (!(pde & PG_ACCESSED_MASK)) { pde |= PG_ACCESSED_MASK; stl_phys_notdirty(pde_addr, pde); } pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) & env->a20_mask; pte = ldq_phys(pte_addr); if (!(pte & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) { error_code = PG_ERROR_RSVD_MASK; goto do_fault; } /* combine pde and pte nx, user and rw protections */ ptep &= pte ^ PG_NX_MASK; ptep ^= PG_NX_MASK; if ((ptep & PG_NX_MASK) && is_write1 == 2) goto do_fault_protect; if (is_user) { if (!(ptep & PG_USER_MASK)) goto do_fault_protect; if (is_write && !(ptep & PG_RW_MASK)) goto do_fault_protect; } else { if ((env->cr[0] & CR0_WP_MASK) && is_write && !(ptep & PG_RW_MASK)) goto do_fault_protect; } is_dirty = is_write && !(pte & PG_DIRTY_MASK); if (!(pte & PG_ACCESSED_MASK) || is_dirty) { pte |= PG_ACCESSED_MASK; if (is_dirty) pte |= PG_DIRTY_MASK; stl_phys_notdirty(pte_addr, pte); } page_size = 4096; virt_addr = addr & ~0xfff; pte = pte & (PHYS_ADDR_MASK | 0xfff); } } else { uint32_t pde; /* page directory entry */ pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)) & env->a20_mask; pde = ldl_phys(pde_addr); if (!(pde & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } /* if PSE bit is set, then we use a 4MB page */ if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { page_size = 4096 * 1024; if (is_user) { if (!(pde & PG_USER_MASK)) goto do_fault_protect; if (is_write && !(pde & PG_RW_MASK)) goto do_fault_protect; } else { if ((env->cr[0] & CR0_WP_MASK) && is_write && !(pde & PG_RW_MASK)) goto do_fault_protect; } is_dirty = is_write && !(pde & PG_DIRTY_MASK); if (!(pde & PG_ACCESSED_MASK) || is_dirty) { pde |= PG_ACCESSED_MASK; if (is_dirty) pde |= PG_DIRTY_MASK; stl_phys_notdirty(pde_addr, pde); } pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */ ptep = pte; virt_addr = addr & ~(page_size - 1); } else { if (!(pde & PG_ACCESSED_MASK)) { pde |= PG_ACCESSED_MASK; stl_phys_notdirty(pde_addr, pde); } /* page directory entry */ pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask; pte = ldl_phys(pte_addr); if (!(pte & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } /* combine pde and pte user and rw protections */ ptep = pte & pde; if (is_user) { if (!(ptep & PG_USER_MASK)) goto do_fault_protect; if (is_write && !(ptep & PG_RW_MASK)) goto do_fault_protect; } else { if ((env->cr[0] & CR0_WP_MASK) && is_write && !(ptep & PG_RW_MASK)) goto do_fault_protect; } is_dirty = is_write && !(pte & PG_DIRTY_MASK); if (!(pte & PG_ACCESSED_MASK) || is_dirty) { pte |= PG_ACCESSED_MASK; if (is_dirty) pte |= PG_DIRTY_MASK; stl_phys_notdirty(pte_addr, pte); } page_size = 4096; virt_addr = addr & ~0xfff; } } /* the page can be put in the TLB */ prot = PAGE_READ; if (!(ptep & PG_NX_MASK)) prot |= PAGE_EXEC; if (pte & PG_DIRTY_MASK) { /* only set write access if already dirty... otherwise wait for dirty access */ if (is_user) { if (ptep & PG_RW_MASK) prot |= PAGE_WRITE; } else { if (!(env->cr[0] & CR0_WP_MASK) || (ptep & PG_RW_MASK)) prot |= PAGE_WRITE; } } do_mapping: pte = pte & env->a20_mask; /* Even if 4MB pages, we map only one 4KB page in the cache to avoid filling it too fast */ page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1); paddr = (pte & TARGET_PAGE_MASK) + page_offset; vaddr = virt_addr + page_offset; ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); return ret; do_fault_protect: error_code = PG_ERROR_P_MASK; do_fault: env->cr[2] = addr; error_code |= (is_write << PG_ERROR_W_BIT); if (is_user) error_code |= PG_ERROR_U_MASK; if (is_write1 == 2 && (env->efer & MSR_EFER_NXE) && (env->cr[4] & CR4_PAE_MASK)) error_code |= PG_ERROR_I_D_MASK; env->error_code = error_code; return 1; }


static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len) { unsigned char response[VNC_AUTH_CHALLENGE_SIZE]; int i, j, pwlen; unsigned char key[8]; time_t now = time(NULL); if (!vs->vd->password || !vs->vd->password[0]) { VNC_DEBUG("No password configured on server"); goto reject; } if (vs->vd->expires < now) { VNC_DEBUG("Password is expired"); goto reject; } memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE); /* Calculate the expected challenge response */ pwlen = strlen(vs->vd->password); for (i=0; i<sizeof(key); i++) key[i] = i<pwlen ? vs->vd->password[i] : 0; deskey(key, EN0); for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8) des(response+j, response+j); /* Compare expected vs actual challenge response */ if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) { VNC_DEBUG("Client challenge reponse did not match\n"); goto reject; } else { VNC_DEBUG("Accepting VNC challenge response\n"); vnc_write_u32(vs, 0); /* Accept auth */ vnc_flush(vs); start_client_init(vs); } return 0; reject: vnc_write_u32(vs, 1); /* Reject auth */ if (vs->minor >= 8) { static const char err[] = "Authentication failed"; vnc_write_u32(vs, sizeof(err)); vnc_write(vs, err, sizeof(err)); } vnc_flush(vs); vnc_client_error(vs); return 0; }


static void img_copy(uint8_t *dst, int dst_wrap, uint8_t *src, int src_wrap, int width, int height) { for(;height > 0; height--) { memcpy(dst, src, width); dst += dst_wrap; src += src_wrap; } }


static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip) { CPUState *cs = CPU(cpu); CPUX86State *env = &cpu->env; VAPICHandlers *handlers; uint8_t opcode[2]; uint32_t imm32 = 0; target_ulong current_pc = 0; target_ulong current_cs_base = 0; uint32_t current_flags = 0; if (smp_cpus == 1) { handlers = &s->rom_state.up; } else { handlers = &s->rom_state.mp; } if (!kvm_enabled()) { cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base, &current_flags); } pause_all_vcpus(); cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0); switch (opcode[0]) { case 0x89: /* mov r32 to r/m32 */ patch_byte(cpu, ip, 0x50 + modrm_reg(opcode[1])); /* push reg */ patch_call(s, cpu, ip + 1, handlers->set_tpr); break; case 0x8b: /* mov r/m32 to r32 */ patch_byte(cpu, ip, 0x90); patch_call(s, cpu, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]); break; case 0xa1: /* mov abs to eax */ patch_call(s, cpu, ip, handlers->get_tpr[0]); break; case 0xa3: /* mov eax to abs */ patch_call(s, cpu, ip, handlers->set_tpr_eax); break; case 0xc7: /* mov imm32, r/m32 (c7/0) */ patch_byte(cpu, ip, 0x68); /* push imm32 */ cpu_memory_rw_debug(cs, ip + 6, (void *)&imm32, sizeof(imm32), 0); cpu_memory_rw_debug(cs, ip + 1, (void *)&imm32, sizeof(imm32), 1); patch_call(s, cpu, ip + 5, handlers->set_tpr); break; case 0xff: /* push r/m32 */ patch_byte(cpu, ip, 0x50); /* push eax */ patch_call(s, cpu, ip + 1, handlers->get_tpr_stack); break; default: abort(); } resume_all_vcpus(); if (!kvm_enabled()) { tb_gen_code(cs, current_pc, current_cs_base, current_flags, 1); cpu_resume_from_signal(cs, NULL); } }


static void qcow_close(BlockDriverState *bs) { BDRVQcowState *s = bs->opaque; qcrypto_cipher_free(s->cipher); s->cipher = NULL; g_free(s->l1_table); qemu_vfree(s->l2_cache); g_free(s->cluster_cache); g_free(s->cluster_data); migrate_del_blocker(s->migration_blocker); error_free(s->migration_blocker); }


static void qmp_input_free(Visitor *v) { QmpInputVisitor *qiv = to_qiv(v); while (!QSLIST_EMPTY(&qiv->stack)) { StackObject *tos = QSLIST_FIRST(&qiv->stack); QSLIST_REMOVE_HEAD(&qiv->stack, node); qmp_input_stack_object_free(tos); } qobject_decref(qiv->root); g_free(qiv); }


static void qcow_aio_write_cb(void *opaque, int ret) { QCowAIOCB *acb = opaque; BlockDriverState *bs = acb->common.bs; BDRVQcowState *s = bs->opaque; int index_in_cluster; const uint8_t *src_buf; int n_end; acb->hd_aiocb = NULL; if (ret >= 0) { ret = qcow2_alloc_cluster_link_l2(bs, acb->cluster_offset, &acb->l2meta); } run_dependent_requests(&acb->l2meta); if (ret < 0) goto done; acb->nb_sectors -= acb->n; acb->sector_num += acb->n; acb->buf += acb->n * 512; if (acb->nb_sectors == 0) { /* request completed */ ret = 0; goto done; } index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); n_end = index_in_cluster + acb->nb_sectors; if (s->crypt_method && n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors; acb->cluster_offset = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9, index_in_cluster, n_end, &acb->n, &acb->l2meta); /* Need to wait for another request? If so, we are done for now. */ if (!acb->cluster_offset && acb->l2meta.depends_on != NULL) { LIST_INSERT_HEAD(&acb->l2meta.depends_on->dependent_requests, acb, next_depend); return; } if (!acb->cluster_offset || (acb->cluster_offset & 511) != 0) { ret = -EIO; goto done; } if (s->crypt_method) { if (!acb->cluster_data) { acb->cluster_data = qemu_mallocz(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); } qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf, acb->n, 1, &s->aes_encrypt_key); src_buf = acb->cluster_data; } else { src_buf = acb->buf; } acb->hd_iov.iov_base = (void *)src_buf; acb->hd_iov.iov_len = acb->n * 512; qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); acb->hd_aiocb = bdrv_aio_writev(s->hd, (acb->cluster_offset >> 9) + index_in_cluster, &acb->hd_qiov, acb->n, qcow_aio_write_cb, acb); if (acb->hd_aiocb == NULL) goto done; return; done: if (acb->qiov->niov > 1) qemu_vfree(acb->orig_buf); acb->common.cb(acb->common.opaque, ret); qemu_aio_release(acb); }


int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) { int ret; trace_blk_co_preadv(blk, blk_bs(blk), offset, bytes, flags); ret = blk_check_byte_request(blk, offset, bytes); if (ret < 0) { return ret; } /* throttling disk I/O */ if (blk->public.throttle_state) { throttle_group_co_io_limits_intercept(blk, bytes, false); } return bdrv_co_preadv(blk_bs(blk), offset, bytes, qiov, flags); }


bool virtio_disk_is_scsi(void) { if (guessed_disk_nature) { return (blk_cfg.blk_size == 512); } return (blk_cfg.geometry.heads == 255) && (blk_cfg.geometry.sectors == 63) && (blk_cfg.blk_size == 512); }


iscsi_aio_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) { IscsiLun *iscsilun = bs->opaque; struct iscsi_context *iscsi = iscsilun->iscsi; IscsiAIOCB *acb; struct unmap_list list[1]; acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque); acb->iscsilun = iscsilun; acb->canceled = 0; acb->bh = NULL; acb->status = -EINPROGRESS; acb->buf = NULL; list[0].lba = sector_qemu2lun(sector_num, iscsilun); list[0].num = nb_sectors * BDRV_SECTOR_SIZE / iscsilun->block_size; acb->task = iscsi_unmap_task(iscsi, iscsilun->lun, 0, 0, &list[0], 1, iscsi_unmap_cb, acb); if (acb->task == NULL) { error_report("iSCSI: Failed to send unmap command. %s", iscsi_get_error(iscsi)); qemu_aio_release(acb); return NULL; } iscsi_set_events(iscsilun); return &acb->common; }


static void stream_desc_store(struct Stream *s, hwaddr addr) { struct SDesc *d = &s->desc; int i; /* Convert from host endianness into LE. */ d->buffer_address = cpu_to_le64(d->buffer_address); d->nxtdesc = cpu_to_le64(d->nxtdesc); d->control = cpu_to_le32(d->control); d->status = cpu_to_le32(d->status); for (i = 0; i < ARRAY_SIZE(d->app); i++) { d->app[i] = cpu_to_le32(d->app[i]); } cpu_physical_memory_write(addr, (void *) d, sizeof *d); }


static void cs_mem_write(void *opaque, target_phys_addr_t addr, uint64_t val, unsigned size) { CSState *s = opaque; uint32_t saddr; saddr = addr >> 2; trace_cs4231_mem_writel_reg(saddr, s->regs[saddr], val); switch (saddr) { case 1: trace_cs4231_mem_writel_dreg(CS_RAP(s), s->dregs[CS_RAP(s)], val); switch(CS_RAP(s)) { case 11: case 25: // Read only break; case 12: val &= 0x40; val |= CS_CDC_VER; // Codec version s->dregs[CS_RAP(s)] = val; break; default: s->dregs[CS_RAP(s)] = val; break; } break; case 2: // Read only break; case 4: if (val & 1) { cs_reset(&s->busdev.qdev); } val &= 0x7f; s->regs[saddr] = val; break; default: s->regs[saddr] = val; break; } }


static int mxf_parse_structural_metadata(MXFContext *mxf) { MXFPackage *material_package = NULL; MXFPackage *source_package = NULL; MXFPackage *temp_package = NULL; int i, j, k; dprintf("metadata sets count %d\n", mxf->metadata_sets_count); /* TODO: handle multiple material packages (OP3x) */ for (i = 0; i < mxf->packages_count; i++) { if (!(temp_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i]))) { av_log(mxf->fc, AV_LOG_ERROR, "could not resolve package strong ref\n"); return -1; } if (temp_package->type == MaterialPackage) { material_package = temp_package; break; } } if (!material_package) { av_log(mxf->fc, AV_LOG_ERROR, "no material package found\n"); return -1; } for (i = 0; i < material_package->tracks_count; i++) { MXFTrack *material_track = NULL; MXFTrack *source_track = NULL; MXFTrack *temp_track = NULL; MXFDescriptor *descriptor = NULL; MXFStructuralComponent *component = NULL; const MXFCodecUL *codec_ul = NULL; const MXFCodecUL *container_ul = NULL; AVStream *st; if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i]))) { av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n"); continue; } if (!(material_track->sequence = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref))) { av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track sequence strong ref\n"); return -1; } /* TODO: handle multiple source clips */ for (j = 0; j < material_track->sequence->structural_components_count; j++) { /* TODO: handle timecode component */ component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j]); if (!component || component->type != SourceClip) continue; for (k = 0; k < mxf->packages_count; k++) { if (!(temp_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[k]))) { av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n"); return -1; } if (!memcmp(temp_package->package_uid, component->source_package_uid, 16)) { source_package = temp_package; break; } } if (!source_package) { av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source package found\n", material_track->track_id); break; } for (k = 0; k < source_package->tracks_count; k++) { if (!(temp_track = mxf_resolve_strong_ref(mxf, &source_package->tracks_refs[k]))) { av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n"); return -1; } if (temp_track->track_id == component->source_track_id) { source_track = temp_track; break; } } if (!source_track) { av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source track found\n", material_track->track_id); break; } } if (!source_track) continue; st = av_new_stream(mxf->fc, source_track->track_id); st->priv_data = source_track; st->duration = component->duration; if (st->duration == -1) st->duration = AV_NOPTS_VALUE; st->start_time = component->start_position; av_set_pts_info(st, 64, material_track->edit_rate.num, material_track->edit_rate.den); if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref))) { av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n"); return -1; } #ifdef DEBUG PRINT_KEY("data definition ul", source_track->sequence->data_definition_ul); #endif st->codec->codec_type = mxf_get_codec_type(mxf_data_definition_uls, &source_track->sequence->data_definition_ul); source_package->descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor_ref); if (source_package->descriptor) { if (source_package->descriptor->type == MultipleDescriptor) { for (j = 0; j < source_package->descriptor->sub_descriptors_count; j++) { MXFDescriptor *sub_descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor->sub_descriptors_refs[j]); if (!sub_descriptor) { av_log(mxf->fc, AV_LOG_ERROR, "could not resolve sub descriptor strong ref\n"); continue; } if (sub_descriptor->linked_track_id == source_track->track_id) { descriptor = sub_descriptor; break; } } } else descriptor = source_package->descriptor; } if (!descriptor) { av_log(mxf->fc, AV_LOG_INFO, "source track %d: stream %d, no descriptor found\n", source_track->track_id, st->index); continue; } #ifdef DEBUG PRINT_KEY("essence codec ul", descriptor->essence_codec_ul); PRINT_KEY("essence container ul", descriptor->essence_container_ul); #endif /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */ codec_ul = mxf_get_codec_ul(mxf_codec_uls, &descriptor->essence_codec_ul); st->codec->codec_id = codec_ul->id; if (descriptor->extradata) { st->codec->extradata = descriptor->extradata; st->codec->extradata_size = descriptor->extradata_size; } if (st->codec->codec_type == CODEC_TYPE_VIDEO) { container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, &descriptor->essence_container_ul); if (st->codec->codec_id == CODEC_ID_NONE) st->codec->codec_id = container_ul->id; st->codec->width = descriptor->width; st->codec->height = descriptor->height; st->codec->bits_per_sample = descriptor->bits_per_sample; /* Uncompressed */ st->need_parsing = 2; /* only parse headers */ } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) { container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, &descriptor->essence_container_ul); if (st->codec->codec_id == CODEC_ID_NONE) st->codec->codec_id = container_ul->id; st->codec->channels = descriptor->channels; st->codec->bits_per_sample = descriptor->bits_per_sample; st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den; /* TODO: implement CODEC_ID_RAWAUDIO */ if (st->codec->codec_id == CODEC_ID_PCM_S16LE) { if (descriptor->bits_per_sample == 24) st->codec->codec_id = CODEC_ID_PCM_S24LE; else if (descriptor->bits_per_sample == 32) st->codec->codec_id = CODEC_ID_PCM_S32LE; } else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) { if (descriptor->bits_per_sample == 24) st->codec->codec_id = CODEC_ID_PCM_S24BE; else if (descriptor->bits_per_sample == 32) st->codec->codec_id = CODEC_ID_PCM_S32BE; if (descriptor->essence_container_ul[13] == 0x01) /* D-10 Mapping */ st->codec->channels = 8; /* force channels to 8 */ } else if (st->codec->codec_id == CODEC_ID_MP2) { st->need_parsing = 1; } } if (container_ul && container_ul->wrapping == Clip) { dprintf("stream %d: clip wrapped essence\n", st->index); st->need_parsing = 1; } } return 0; }


void virtqueue_map(VirtQueueElement *elem) { virtqueue_map_iovec(elem->in_sg, elem->in_addr, &elem->in_num, VIRTQUEUE_MAX_SIZE, 1); virtqueue_map_iovec(elem->out_sg, elem->out_addr, &elem->out_num, VIRTQUEUE_MAX_SIZE, 0); }


static SCSIDiskReq *scsi_new_request(SCSIDiskState *s, uint32_t tag, uint32_t lun) { SCSIRequest *req; SCSIDiskReq *r; req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, tag, lun); r = DO_UPCAST(SCSIDiskReq, req, req); r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE); return r; }


static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn) { uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask; int dp, veclen; TCGv addr; TCGv tmp; TCGv tmp2; if (!arm_feature(env, ARM_FEATURE_VFP)) return 1; if (!s->vfp_enabled) { /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */ if ((insn & 0x0fe00fff) != 0x0ee00a10) return 1; rn = (insn >> 16) & 0xf; if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) return 1; } dp = ((insn & 0xf00) == 0xb00); switch ((insn >> 24) & 0xf) { case 0xe: if (insn & (1 << 4)) { /* single register transfer */ rd = (insn >> 12) & 0xf; if (dp) { int size; int pass; VFP_DREG_N(rn, insn); if (insn & 0xf) return 1; if (insn & 0x00c00060 && !arm_feature(env, ARM_FEATURE_NEON)) return 1; pass = (insn >> 21) & 1; if (insn & (1 << 22)) { size = 0; offset = ((insn >> 5) & 3) * 8; } else if (insn & (1 << 5)) { size = 1; offset = (insn & (1 << 6)) ? 16 : 0; } else { size = 2; offset = 0; } if (insn & ARM_CP_RW_BIT) { /* vfp->arm */ tmp = neon_load_reg(rn, pass); switch (size) { case 0: if (offset) tcg_gen_shri_i32(tmp, tmp, offset); if (insn & (1 << 23)) gen_uxtb(tmp); else gen_sxtb(tmp); break; case 1: if (insn & (1 << 23)) { if (offset) { tcg_gen_shri_i32(tmp, tmp, 16); } else { gen_uxth(tmp); } } else { if (offset) { tcg_gen_sari_i32(tmp, tmp, 16); } else { gen_sxth(tmp); } } break; case 2: break; } store_reg(s, rd, tmp); } else { /* arm->vfp */ tmp = load_reg(s, rd); if (insn & (1 << 23)) { /* VDUP */ if (size == 0) { gen_neon_dup_u8(tmp, 0); } else if (size == 1) { gen_neon_dup_low16(tmp); } for (n = 0; n <= pass * 2; n++) { tmp2 = tcg_temp_new_i32(); tcg_gen_mov_i32(tmp2, tmp); neon_store_reg(rn, n, tmp2); } neon_store_reg(rn, n, tmp); } else { /* VMOV */ switch (size) { case 0: tmp2 = neon_load_reg(rn, pass); tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8); tcg_temp_free_i32(tmp2); break; case 1: tmp2 = neon_load_reg(rn, pass); tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16); tcg_temp_free_i32(tmp2); break; case 2: break; } neon_store_reg(rn, pass, tmp); } } } else { /* !dp */ if ((insn & 0x6f) != 0x00) return 1; rn = VFP_SREG_N(insn); if (insn & ARM_CP_RW_BIT) { /* vfp->arm */ if (insn & (1 << 21)) { /* system register */ rn >>= 1; switch (rn) { case ARM_VFP_FPSID: /* VFP2 allows access to FSID from userspace. VFP3 restricts all id registers to privileged accesses. */ if (IS_USER(s) && arm_feature(env, ARM_FEATURE_VFP3)) return 1; tmp = load_cpu_field(vfp.xregs[rn]); break; case ARM_VFP_FPEXC: if (IS_USER(s)) return 1; tmp = load_cpu_field(vfp.xregs[rn]); break; case ARM_VFP_FPINST: case ARM_VFP_FPINST2: /* Not present in VFP3. */ if (IS_USER(s) || arm_feature(env, ARM_FEATURE_VFP3)) return 1; tmp = load_cpu_field(vfp.xregs[rn]); break; case ARM_VFP_FPSCR: if (rd == 15) { tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]); tcg_gen_andi_i32(tmp, tmp, 0xf0000000); } else { tmp = tcg_temp_new_i32(); gen_helper_vfp_get_fpscr(tmp, cpu_env); } break; case ARM_VFP_MVFR0: case ARM_VFP_MVFR1: if (IS_USER(s) || !arm_feature(env, ARM_FEATURE_MVFR)) return 1; tmp = load_cpu_field(vfp.xregs[rn]); break; default: return 1; } } else { gen_mov_F0_vreg(0, rn); tmp = gen_vfp_mrs(); } if (rd == 15) { /* Set the 4 flag bits in the CPSR. */ gen_set_nzcv(tmp); tcg_temp_free_i32(tmp); } else { store_reg(s, rd, tmp); } } else { /* arm->vfp */ tmp = load_reg(s, rd); if (insn & (1 << 21)) { rn >>= 1; /* system register */ switch (rn) { case ARM_VFP_FPSID: case ARM_VFP_MVFR0: case ARM_VFP_MVFR1: /* Writes are ignored. */ break; case ARM_VFP_FPSCR: gen_helper_vfp_set_fpscr(cpu_env, tmp); tcg_temp_free_i32(tmp); gen_lookup_tb(s); break; case ARM_VFP_FPEXC: if (IS_USER(s)) return 1; /* TODO: VFP subarchitecture support. * For now, keep the EN bit only */ tcg_gen_andi_i32(tmp, tmp, 1 << 30); store_cpu_field(tmp, vfp.xregs[rn]); gen_lookup_tb(s); break; case ARM_VFP_FPINST: case ARM_VFP_FPINST2: store_cpu_field(tmp, vfp.xregs[rn]); break; default: return 1; } } else { gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rn); } } } } else { /* data processing */ /* The opcode is in bits 23, 21, 20 and 6. */ op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1); if (dp) { if (op == 15) { /* rn is opcode */ rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1); } else { /* rn is register number */ VFP_DREG_N(rn, insn); } if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) { /* Integer or single precision destination. */ rd = VFP_SREG_D(insn); } else { VFP_DREG_D(rd, insn); } if (op == 15 && (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) { /* VCVT from int is always from S reg regardless of dp bit. * VCVT with immediate frac_bits has same format as SREG_M */ rm = VFP_SREG_M(insn); } else { VFP_DREG_M(rm, insn); } } else { rn = VFP_SREG_N(insn); if (op == 15 && rn == 15) { /* Double precision destination. */ VFP_DREG_D(rd, insn); } else { rd = VFP_SREG_D(insn); } /* NB that we implicitly rely on the encoding for the frac_bits * in VCVT of fixed to float being the same as that of an SREG_M */ rm = VFP_SREG_M(insn); } veclen = s->vec_len; if (op == 15 && rn > 3) veclen = 0; /* Shut up compiler warnings. */ delta_m = 0; delta_d = 0; bank_mask = 0; if (veclen > 0) { if (dp) bank_mask = 0xc; else bank_mask = 0x18; /* Figure out what type of vector operation this is. */ if ((rd & bank_mask) == 0) { /* scalar */ veclen = 0; } else { if (dp) delta_d = (s->vec_stride >> 1) + 1; else delta_d = s->vec_stride + 1; if ((rm & bank_mask) == 0) { /* mixed scalar/vector */ delta_m = 0; } else { /* vector */ delta_m = delta_d; } } } /* Load the initial operands. */ if (op == 15) { switch (rn) { case 16: case 17: /* Integer source */ gen_mov_F0_vreg(0, rm); break; case 8: case 9: /* Compare */ gen_mov_F0_vreg(dp, rd); gen_mov_F1_vreg(dp, rm); break; case 10: case 11: /* Compare with zero */ gen_mov_F0_vreg(dp, rd); gen_vfp_F1_ld0(dp); break; case 20: case 21: case 22: case 23: case 28: case 29: case 30: case 31: /* Source and destination the same. */ gen_mov_F0_vreg(dp, rd); break; case 4: case 5: case 6: case 7: /* VCVTB, VCVTT: only present with the halfprec extension, * UNPREDICTABLE if bit 8 is set (we choose to UNDEF) */ if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) { return 1; } /* Otherwise fall through */ default: /* One source operand. */ gen_mov_F0_vreg(dp, rm); break; } } else { /* Two source operands. */ gen_mov_F0_vreg(dp, rn); gen_mov_F1_vreg(dp, rm); } for (;;) { /* Perform the calculation. */ switch (op) { case 0: /* VMLA: fd + (fn * fm) */ /* Note that order of inputs to the add matters for NaNs */ gen_vfp_F1_mul(dp); gen_mov_F0_vreg(dp, rd); gen_vfp_add(dp); break; case 1: /* VMLS: fd + -(fn * fm) */ gen_vfp_mul(dp); gen_vfp_F1_neg(dp); gen_mov_F0_vreg(dp, rd); gen_vfp_add(dp); break; case 2: /* VNMLS: -fd + (fn * fm) */ /* Note that it isn't valid to replace (-A + B) with (B - A) * or similar plausible looking simplifications * because this will give wrong results for NaNs. */ gen_vfp_F1_mul(dp); gen_mov_F0_vreg(dp, rd); gen_vfp_neg(dp); gen_vfp_add(dp); break; case 3: /* VNMLA: -fd + -(fn * fm) */ gen_vfp_mul(dp); gen_vfp_F1_neg(dp); gen_mov_F0_vreg(dp, rd); gen_vfp_neg(dp); gen_vfp_add(dp); break; case 4: /* mul: fn * fm */ gen_vfp_mul(dp); break; case 5: /* nmul: -(fn * fm) */ gen_vfp_mul(dp); gen_vfp_neg(dp); break; case 6: /* add: fn + fm */ gen_vfp_add(dp); break; case 7: /* sub: fn - fm */ gen_vfp_sub(dp); break; case 8: /* div: fn / fm */ gen_vfp_div(dp); break; case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */ case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */ case 12: /* VFMA : fd = muladd( fd, fn, fm) */ case 13: /* VFMS : fd = muladd( fd, -fn, fm) */ /* These are fused multiply-add, and must be done as one * floating point operation with no rounding between the * multiplication and addition steps. * NB that doing the negations here as separate steps is * correct : an input NaN should come out with its sign bit * flipped if it is a negated-input. */ if (!arm_feature(env, ARM_FEATURE_VFP4)) { return 1; } if (dp) { TCGv_ptr fpst; TCGv_i64 frd; if (op & 1) { /* VFNMS, VFMS */ gen_helper_vfp_negd(cpu_F0d, cpu_F0d); } frd = tcg_temp_new_i64(); tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd)); if (op & 2) { /* VFNMA, VFNMS */ gen_helper_vfp_negd(frd, frd); } fpst = get_fpstatus_ptr(0); gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d, cpu_F1d, frd, fpst); tcg_temp_free_ptr(fpst); tcg_temp_free_i64(frd); } else { TCGv_ptr fpst; TCGv_i32 frd; if (op & 1) { /* VFNMS, VFMS */ gen_helper_vfp_negs(cpu_F0s, cpu_F0s); } frd = tcg_temp_new_i32(); tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd)); if (op & 2) { gen_helper_vfp_negs(frd, frd); } fpst = get_fpstatus_ptr(0); gen_helper_vfp_muladds(cpu_F0s, cpu_F0s, cpu_F1s, frd, fpst); tcg_temp_free_ptr(fpst); tcg_temp_free_i32(frd); } break; case 14: /* fconst */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; n = (insn << 12) & 0x80000000; i = ((insn >> 12) & 0x70) | (insn & 0xf); if (dp) { if (i & 0x40) i |= 0x3f80; else i |= 0x4000; n |= i << 16; tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32); } else { if (i & 0x40) i |= 0x780; else i |= 0x800; n |= i << 19; tcg_gen_movi_i32(cpu_F0s, n); } break; case 15: /* extension space */ switch (rn) { case 0: /* cpy */ /* no-op */ break; case 1: /* abs */ gen_vfp_abs(dp); break; case 2: /* neg */ gen_vfp_neg(dp); break; case 3: /* sqrt */ gen_vfp_sqrt(dp); break; case 4: /* vcvtb.f32.f16 */ tmp = gen_vfp_mrs(); tcg_gen_ext16u_i32(tmp, tmp); gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env); tcg_temp_free_i32(tmp); break; case 5: /* vcvtt.f32.f16 */ tmp = gen_vfp_mrs(); tcg_gen_shri_i32(tmp, tmp, 16); gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env); tcg_temp_free_i32(tmp); break; case 6: /* vcvtb.f16.f32 */ tmp = tcg_temp_new_i32(); gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); gen_mov_F0_vreg(0, rd); tmp2 = gen_vfp_mrs(); tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); tcg_gen_or_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); gen_vfp_msr(tmp); break; case 7: /* vcvtt.f16.f32 */ tmp = tcg_temp_new_i32(); gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); tcg_gen_shli_i32(tmp, tmp, 16); gen_mov_F0_vreg(0, rd); tmp2 = gen_vfp_mrs(); tcg_gen_ext16u_i32(tmp2, tmp2); tcg_gen_or_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); gen_vfp_msr(tmp); break; case 8: /* cmp */ gen_vfp_cmp(dp); break; case 9: /* cmpe */ gen_vfp_cmpe(dp); break; case 10: /* cmpz */ gen_vfp_cmp(dp); break; case 11: /* cmpez */ gen_vfp_F1_ld0(dp); gen_vfp_cmpe(dp); break; case 15: /* single<->double conversion */ if (dp) gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env); else gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env); break; case 16: /* fuito */ gen_vfp_uito(dp, 0); break; case 17: /* fsito */ gen_vfp_sito(dp, 0); break; case 20: /* fshto */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_shto(dp, 16 - rm, 0); break; case 21: /* fslto */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_slto(dp, 32 - rm, 0); break; case 22: /* fuhto */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_uhto(dp, 16 - rm, 0); break; case 23: /* fulto */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_ulto(dp, 32 - rm, 0); break; case 24: /* ftoui */ gen_vfp_toui(dp, 0); break; case 25: /* ftouiz */ gen_vfp_touiz(dp, 0); break; case 26: /* ftosi */ gen_vfp_tosi(dp, 0); break; case 27: /* ftosiz */ gen_vfp_tosiz(dp, 0); break; case 28: /* ftosh */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_tosh(dp, 16 - rm, 0); break; case 29: /* ftosl */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_tosl(dp, 32 - rm, 0); break; case 30: /* ftouh */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_touh(dp, 16 - rm, 0); break; case 31: /* ftoul */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_toul(dp, 32 - rm, 0); break; default: /* undefined */ return 1; } break; default: /* undefined */ return 1; } /* Write back the result. */ if (op == 15 && (rn >= 8 && rn <= 11)) ; /* Comparison, do nothing. */ else if (op == 15 && dp && ((rn & 0x1c) == 0x18)) /* VCVT double to int: always integer result. */ gen_mov_vreg_F0(0, rd); else if (op == 15 && rn == 15) /* conversion */ gen_mov_vreg_F0(!dp, rd); else gen_mov_vreg_F0(dp, rd); /* break out of the loop if we have finished */ if (veclen == 0) break; if (op == 15 && delta_m == 0) { /* single source one-many */ while (veclen--) { rd = ((rd + delta_d) & (bank_mask - 1)) | (rd & bank_mask); gen_mov_vreg_F0(dp, rd); } break; } /* Setup the next operands. */ veclen--; rd = ((rd + delta_d) & (bank_mask - 1)) | (rd & bank_mask); if (op == 15) { /* One source operand. */ rm = ((rm + delta_m) & (bank_mask - 1)) | (rm & bank_mask); gen_mov_F0_vreg(dp, rm); } else { /* Two source operands. */ rn = ((rn + delta_d) & (bank_mask - 1)) | (rn & bank_mask); gen_mov_F0_vreg(dp, rn); if (delta_m) { rm = ((rm + delta_m) & (bank_mask - 1)) | (rm & bank_mask); gen_mov_F1_vreg(dp, rm); } } } } break; case 0xc: case 0xd: if ((insn & 0x03e00000) == 0x00400000) { /* two-register transfer */ rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; if (dp) { VFP_DREG_M(rm, insn); } else { rm = VFP_SREG_M(insn); } if (insn & ARM_CP_RW_BIT) { /* vfp->arm */ if (dp) { gen_mov_F0_vreg(0, rm * 2); tmp = gen_vfp_mrs(); store_reg(s, rd, tmp); gen_mov_F0_vreg(0, rm * 2 + 1); tmp = gen_vfp_mrs(); store_reg(s, rn, tmp); } else { gen_mov_F0_vreg(0, rm); tmp = gen_vfp_mrs(); store_reg(s, rd, tmp); gen_mov_F0_vreg(0, rm + 1); tmp = gen_vfp_mrs(); store_reg(s, rn, tmp); } } else { /* arm->vfp */ if (dp) { tmp = load_reg(s, rd); gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rm * 2); tmp = load_reg(s, rn); gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rm * 2 + 1); } else { tmp = load_reg(s, rd); gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rm); tmp = load_reg(s, rn); gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rm + 1); } } } else { /* Load/store */ rn = (insn >> 16) & 0xf; if (dp) VFP_DREG_D(rd, insn); else rd = VFP_SREG_D(insn); if ((insn & 0x01200000) == 0x01000000) { /* Single load/store */ offset = (insn & 0xff) << 2; if ((insn & (1 << 23)) == 0) offset = -offset; if (s->thumb && rn == 15) { /* This is actually UNPREDICTABLE */ addr = tcg_temp_new_i32(); tcg_gen_movi_i32(addr, s->pc & ~2); } else { addr = load_reg(s, rn); } tcg_gen_addi_i32(addr, addr, offset); if (insn & (1 << 20)) { gen_vfp_ld(s, dp, addr); gen_mov_vreg_F0(dp, rd); } else { gen_mov_F0_vreg(dp, rd); gen_vfp_st(s, dp, addr); } tcg_temp_free_i32(addr); } else { /* load/store multiple */ int w = insn & (1 << 21); if (dp) n = (insn >> 1) & 0x7f; else n = insn & 0xff; if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) { /* P == U , W == 1 => UNDEF */ return 1; } if (n == 0 || (rd + n) > 32 || (dp && n > 16)) { /* UNPREDICTABLE cases for bad immediates: we choose to * UNDEF to avoid generating huge numbers of TCG ops */ return 1; } if (rn == 15 && w) { /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */ return 1; } if (s->thumb && rn == 15) { /* This is actually UNPREDICTABLE */ addr = tcg_temp_new_i32(); tcg_gen_movi_i32(addr, s->pc & ~2); } else { addr = load_reg(s, rn); } if (insn & (1 << 24)) /* pre-decrement */ tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2)); if (dp) offset = 8; else offset = 4; for (i = 0; i < n; i++) { if (insn & ARM_CP_RW_BIT) { /* load */ gen_vfp_ld(s, dp, addr); gen_mov_vreg_F0(dp, rd + i); } else { /* store */ gen_mov_F0_vreg(dp, rd + i); gen_vfp_st(s, dp, addr); } tcg_gen_addi_i32(addr, addr, offset); } if (w) { /* writeback */ if (insn & (1 << 24)) offset = -offset * n; else if (dp && (insn & 1)) offset = 4; else offset = 0; if (offset != 0) tcg_gen_addi_i32(addr, addr, offset); store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } } } break; default: /* Should never happen. */ return 1; } return 0; }


static void do_address_space_destroy(AddressSpace *as) { MemoryListener *listener; address_space_destroy_dispatch(as); QTAILQ_FOREACH(listener, &memory_listeners, link) { assert(listener->address_space_filter != as); } flatview_unref(as->current_map); g_free(as->name); g_free(as->ioeventfds); }


static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id) { int i; int cur = 0; int skip = 0; int len, toks; TM2Codes codes; /* get stream length in dwords */ len = AV_RB32(buf); buf += 4; cur += 4; skip = len * 4 + 4; if(len == 0) return 4; toks = AV_RB32(buf); buf += 4; cur += 4; if(toks & 1) { len = AV_RB32(buf); buf += 4; cur += 4; if(len == TM2_ESCAPE) { len = AV_RB32(buf); buf += 4; cur += 4; } if(len > 0) { init_get_bits(&ctx->gb, buf, (skip - cur) * 8); if(tm2_read_deltas(ctx, stream_id) == -1) return -1; buf += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; cur += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; } } /* skip unused fields */ if(AV_RB32(buf) == TM2_ESCAPE) { buf += 4; cur += 4; /* some unknown length - could be escaped too */ } buf += 4; cur += 4; buf += 4; cur += 4; /* unused by decoder */ init_get_bits(&ctx->gb, buf, (skip - cur) * 8); if(tm2_build_huff_table(ctx, &codes) == -1) return -1; buf += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; cur += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; toks >>= 1; /* check if we have sane number of tokens */ if((toks < 0) || (toks > 0xFFFFFF)){ av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks); tm2_free_codes(&codes); return -1; } ctx->tokens[stream_id] = av_realloc(ctx->tokens[stream_id], toks * sizeof(int)); ctx->tok_lens[stream_id] = toks; len = AV_RB32(buf); buf += 4; cur += 4; if(len > 0) { init_get_bits(&ctx->gb, buf, (skip - cur) * 8); for(i = 0; i < toks; i++) ctx->tokens[stream_id][i] = tm2_get_token(&ctx->gb, &codes); } else { for(i = 0; i < toks; i++) ctx->tokens[stream_id][i] = codes.recode[0]; } tm2_free_codes(&codes); return skip; }


static void do_dma_memory_set(dma_addr_t addr, uint8_t c, dma_addr_t len) { #define FILLBUF_SIZE 512 uint8_t fillbuf[FILLBUF_SIZE]; int l; memset(fillbuf, c, FILLBUF_SIZE); while (len > 0) { l = len < FILLBUF_SIZE ? len : FILLBUF_SIZE; cpu_physical_memory_rw(addr, fillbuf, l, true); len -= len; addr += len; } }


static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta) { int nearest_delta_ms = (delta + 999999) / 1000000; if (nearest_delta_ms < 1) { nearest_delta_ms = 1; } timeKillEvent(mm_timer); mm_timer = timeSetEvent(nearest_delta_ms, mm_period, mm_alarm_handler, (DWORD_PTR)t, TIME_ONESHOT | TIME_CALLBACK_FUNCTION); if (!mm_timer) { fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n", GetLastError()); timeEndPeriod(mm_period); exit(1); } }


static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) { MOVQ_BFE(mm6); JUMPALIGN(); do { __asm__ volatile( "movq %1, %%mm0 \n\t" "movq 1%1, %%mm1 \n\t" "movq %0, %%mm3 \n\t" PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6) "movq %%mm0, %0 \n\t" "movq 8%1, %%mm0 \n\t" "movq 9%1, %%mm1 \n\t" "movq 8%0, %%mm3 \n\t" PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6) "movq %%mm0, 8%0 \n\t" :"+m"(*block) :"m"(*pixels) :"memory"); pixels += line_size; block += line_size; } while (--h); }


static int config_output(AVFilterLink *outlink) { static const char hdcd_baduse[] = "The HDCD filter is unlikely to produce a desirable result in this context."; AVFilterContext *ctx = outlink->src; HDCDContext *s = ctx->priv; AVFilterLink *lk = outlink; while(lk != NULL) { AVFilterContext *nextf = lk->dst; if (lk->type == AVMEDIA_TYPE_AUDIO) { if (lk->format == AV_SAMPLE_FMT_S16 || lk->format == AV_SAMPLE_FMT_U8) { av_log(ctx, AV_LOG_WARNING, "s24 output is being truncated to %s at %s.\n", av_get_sample_fmt_name(lk->format), (nextf->name) ? nextf->name : "<unknown>" ); s->bad_config = 1; break; } } lk = (nextf->outputs) ? nextf->outputs[0] : NULL; } if (s->bad_config) av_log(ctx, AV_LOG_WARNING, "%s\n", hdcd_baduse); return 0; }


static inline int copy_siginfo_to_user(target_siginfo_t *tinfo, const target_siginfo_t *info) { tswap_siginfo(tinfo, info); return 0; }


iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) { IscsiLun *iscsilun = bs->opaque; struct iscsi_context *iscsi = iscsilun->iscsi; IscsiAIOCB *acb; size_t size; uint32_t num_sectors; uint64_t lba; #if !defined(LIBISCSI_FEATURE_IOVECTOR) struct iscsi_data data; #endif int ret; acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque); trace_iscsi_aio_writev(iscsi, sector_num, nb_sectors, opaque, acb); acb->iscsilun = iscsilun; acb->qiov = qiov; acb->canceled = 0; acb->bh = NULL; acb->status = -EINPROGRESS; acb->buf = NULL; /* this will allow us to get rid of 'buf' completely */ size = nb_sectors * BDRV_SECTOR_SIZE; #if !defined(LIBISCSI_FEATURE_IOVECTOR) data.size = MIN(size, acb->qiov->size); /* if the iovec only contains one buffer we can pass it directly */ if (acb->qiov->niov == 1) { data.data = acb->qiov->iov[0].iov_base; } else { acb->buf = g_malloc(data.size); qemu_iovec_to_buf(acb->qiov, 0, acb->buf, data.size); data.data = acb->buf; } #endif acb->task = malloc(sizeof(struct scsi_task)); if (acb->task == NULL) { error_report("iSCSI: Failed to allocate task for scsi WRITE16 " "command. %s", iscsi_get_error(iscsi)); qemu_aio_release(acb); return NULL; } memset(acb->task, 0, sizeof(struct scsi_task)); acb->task->xfer_dir = SCSI_XFER_WRITE; acb->task->cdb_size = 16; acb->task->cdb[0] = 0x8a; lba = sector_qemu2lun(sector_num, iscsilun); *(uint32_t *)&acb->task->cdb[2] = htonl(lba >> 32); *(uint32_t *)&acb->task->cdb[6] = htonl(lba & 0xffffffff); num_sectors = size / iscsilun->block_size; *(uint32_t *)&acb->task->cdb[10] = htonl(num_sectors); acb->task->expxferlen = size; #if defined(LIBISCSI_FEATURE_IOVECTOR) ret = iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task, iscsi_aio_write16_cb, NULL, acb); #else ret = iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task, iscsi_aio_write16_cb, &data, acb); #endif if (ret != 0) { scsi_free_scsi_task(acb->task); g_free(acb->buf); qemu_aio_release(acb); return NULL; } #if defined(LIBISCSI_FEATURE_IOVECTOR) scsi_task_set_iov_out(acb->task, (struct scsi_iovec*) acb->qiov->iov, acb->qiov->niov); #endif iscsi_set_events(iscsilun); return &acb->common; }


static void mtree_print_flatview(fprintf_function p, void *f, AddressSpace *as) { FlatView *view = address_space_get_flatview(as); FlatRange *range = &view->ranges[0]; MemoryRegion *mr; int n = view->nr; if (n <= 0) { p(f, MTREE_INDENT "No rendered FlatView for " "address space '%s'\n", as->name); flatview_unref(view); return; } while (n--) { mr = range->mr; p(f, MTREE_INDENT TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d, %s): %s\n", int128_get64(range->addr.start), int128_get64(range->addr.start) + MR_SIZE(range->addr.size), mr->priority, memory_region_type(mr), memory_region_name(mr)); range++; } flatview_unref(view); }


static inline uint32_t efsctuf(uint32_t val) { CPU_FloatU u; float32 tmp; u.l = val; /* NaN are not treated the same way IEEE 754 does */ if (unlikely(float32_is_nan(u.f))) return 0; tmp = uint64_to_float32(1ULL << 32, &env->vec_status); u.f = float32_mul(u.f, tmp, &env->vec_status); return float32_to_uint32(u.f, &env->vec_status); }


void ppce500_init(PPCE500Params *params) { MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); PCIBus *pci_bus; CPUPPCState *env = NULL; uint64_t elf_entry; uint64_t elf_lowaddr; hwaddr entry=0; hwaddr loadaddr=UIMAGE_LOAD_BASE; target_long kernel_size=0; target_ulong dt_base = 0; target_ulong initrd_base = 0; target_long initrd_size=0; int i=0; unsigned int pci_irq_nrs[4] = {1, 2, 3, 4}; qemu_irq **irqs, *mpic; DeviceState *dev; CPUPPCState *firstenv = NULL; MemoryRegion *ccsr_addr_space; SysBusDevice *s; PPCE500CCSRState *ccsr; /* Setup CPUs */ if (params->cpu_model == NULL) { params->cpu_model = "e500v2_v30"; } irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB); for (i = 0; i < smp_cpus; i++) { PowerPCCPU *cpu; qemu_irq *input; cpu = cpu_ppc_init(params->cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to initialize CPU!\n"); exit(1); } env = &cpu->env; if (!firstenv) { firstenv = env; } irqs[i] = irqs[0] + (i * OPENPIC_OUTPUT_NB); input = (qemu_irq *)env->irq_inputs; irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT]; irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT]; env->spr[SPR_BOOKE_PIR] = env->cpu_index = i; env->mpic_cpu_base = MPC8544_CCSRBAR_BASE + MPC8544_MPIC_REGS_OFFSET + 0x20000; ppc_booke_timers_init(env, 400000000, PPC_TIMER_E500); /* Register reset handler */ if (!i) { /* Primary CPU */ struct boot_info *boot_info; boot_info = g_malloc0(sizeof(struct boot_info)); qemu_register_reset(ppce500_cpu_reset, cpu); env->load_info = boot_info; } else { /* Secondary CPUs */ qemu_register_reset(ppce500_cpu_reset_sec, cpu); } } env = firstenv; /* Fixup Memory size on a alignment boundary */ ram_size &= ~(RAM_SIZES_ALIGN - 1); /* Register Memory */ memory_region_init_ram(ram, "mpc8544ds.ram", ram_size); vmstate_register_ram_global(ram); memory_region_add_subregion(address_space_mem, 0, ram); dev = qdev_create(NULL, "e500-ccsr"); object_property_add_child(qdev_get_machine(), "e500-ccsr", OBJECT(dev), NULL); qdev_init_nofail(dev); ccsr = CCSR(dev); ccsr_addr_space = &ccsr->ccsr_space; memory_region_add_subregion(address_space_mem, MPC8544_CCSRBAR_BASE, ccsr_addr_space); /* MPIC */ mpic = mpic_init(ccsr_addr_space, MPC8544_MPIC_REGS_OFFSET, smp_cpus, irqs, NULL); if (!mpic) { cpu_abort(env, "MPIC failed to initialize\n"); } /* Serial */ if (serial_hds[0]) { serial_mm_init(ccsr_addr_space, MPC8544_SERIAL0_REGS_OFFSET, 0, mpic[42], 399193, serial_hds[0], DEVICE_BIG_ENDIAN); } if (serial_hds[1]) { serial_mm_init(ccsr_addr_space, MPC8544_SERIAL1_REGS_OFFSET, 0, mpic[42], 399193, serial_hds[1], DEVICE_BIG_ENDIAN); } /* General Utility device */ dev = qdev_create(NULL, "mpc8544-guts"); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); memory_region_add_subregion(ccsr_addr_space, MPC8544_UTIL_OFFSET, sysbus_mmio_get_region(s, 0)); /* PCI */ dev = qdev_create(NULL, "e500-pcihost"); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); sysbus_connect_irq(s, 0, mpic[pci_irq_nrs[0]]); sysbus_connect_irq(s, 1, mpic[pci_irq_nrs[1]]); sysbus_connect_irq(s, 2, mpic[pci_irq_nrs[2]]); sysbus_connect_irq(s, 3, mpic[pci_irq_nrs[3]]); memory_region_add_subregion(ccsr_addr_space, MPC8544_PCI_REGS_OFFSET, sysbus_mmio_get_region(s, 0)); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0"); if (!pci_bus) printf("couldn't create PCI controller!\n"); sysbus_mmio_map(sysbus_from_qdev(dev), 1, MPC8544_PCI_IO); if (pci_bus) { /* Register network interfaces. */ for (i = 0; i < nb_nics; i++) { pci_nic_init_nofail(&nd_table[i], "virtio", NULL); } } /* Register spinning region */ sysbus_create_simple("e500-spin", MPC8544_SPIN_BASE, NULL); /* Load kernel. */ if (params->kernel_filename) { kernel_size = load_uimage(params->kernel_filename, &entry, &loadaddr, NULL); if (kernel_size < 0) { kernel_size = load_elf(params->kernel_filename, NULL, NULL, &elf_entry, &elf_lowaddr, NULL, 1, ELF_MACHINE, 0); entry = elf_entry; loadaddr = elf_lowaddr; } /* XXX try again as binary */ if (kernel_size < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", params->kernel_filename); exit(1); } } /* Load initrd. */ if (params->initrd_filename) { initrd_base = (loadaddr + kernel_size + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK; initrd_size = load_image_targphys(params->initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", params->initrd_filename); exit(1); } } /* If we're loading a kernel directly, we must load the device tree too. */ if (params->kernel_filename) { struct boot_info *boot_info; int dt_size; dt_base = (loadaddr + kernel_size + DTC_LOAD_PAD) & ~DTC_PAD_MASK; dt_size = ppce500_load_device_tree(env, params, dt_base, initrd_base, initrd_size); if (dt_size < 0) { fprintf(stderr, "couldn't load device tree\n"); exit(1); } boot_info = env->load_info; boot_info->entry = entry; boot_info->dt_base = dt_base; boot_info->dt_size = dt_size; } if (kvm_enabled()) { kvmppc_init(); } }


int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, uint32_t nbdflags, uint8_t *data) { struct nbd_request request; struct nbd_reply reply; int ret; TRACE("Reading request."); if (nbd_receive_request(csock, &request) == -1) return -1; if (request.len + NBD_REPLY_SIZE > NBD_BUFFER_SIZE) { LOG("len (%u) is larger than max len (%u)", request.len + NBD_REPLY_SIZE, NBD_BUFFER_SIZE); errno = EINVAL; return -1; } if ((request.from + request.len) < request.from) { LOG("integer overflow detected! " "you're probably being attacked"); errno = EINVAL; return -1; } if ((request.from + request.len) > size) { LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64 ", Offset: %" PRIu64 "\n", request.from, request.len, (uint64_t)size, dev_offset); LOG("requested operation past EOF--bad client?"); errno = EINVAL; return -1; } TRACE("Decoding type"); reply.handle = request.handle; reply.error = 0; switch (request.type & NBD_CMD_MASK_COMMAND) { case NBD_CMD_READ: TRACE("Request type is READ"); ret = bdrv_read(bs, (request.from + dev_offset) / 512, data + NBD_REPLY_SIZE, request.len / 512); if (ret < 0) { LOG("reading from file failed"); reply.error = -ret; request.len = 0; } TRACE("Read %u byte(s)", request.len); /* Reply [ 0 .. 3] magic (NBD_REPLY_MAGIC) [ 4 .. 7] error (0 == no error) [ 7 .. 15] handle */ cpu_to_be32w((uint32_t*)data, NBD_REPLY_MAGIC); cpu_to_be32w((uint32_t*)(data + 4), reply.error); cpu_to_be64w((uint64_t*)(data + 8), reply.handle); TRACE("Sending data to client"); if (write_sync(csock, data, request.len + NBD_REPLY_SIZE) != request.len + NBD_REPLY_SIZE) { LOG("writing to socket failed"); errno = EINVAL; return -1; } break; case NBD_CMD_WRITE: TRACE("Request type is WRITE"); TRACE("Reading %u byte(s)", request.len); if (read_sync(csock, data, request.len) != request.len) { LOG("reading from socket failed"); errno = EINVAL; return -1; } if (nbdflags & NBD_FLAG_READ_ONLY) { TRACE("Server is read-only, return error"); reply.error = 1; } else { TRACE("Writing to device"); ret = bdrv_write(bs, (request.from + dev_offset) / 512, data, request.len / 512); if (ret < 0) { LOG("writing to file failed"); reply.error = -ret; request.len = 0; } if (request.type & NBD_CMD_FLAG_FUA) { ret = bdrv_flush(bs); if (ret < 0) { LOG("flush failed"); reply.error = -ret; } } } if (nbd_send_reply(csock, &reply) == -1) return -1; break; case NBD_CMD_DISC: TRACE("Request type is DISCONNECT"); errno = 0; return 1; case NBD_CMD_FLUSH: TRACE("Request type is FLUSH"); ret = bdrv_flush(bs); if (ret < 0) { LOG("flush failed"); reply.error = -ret; } if (nbd_send_reply(csock, &reply) == -1) return -1; break; case NBD_CMD_TRIM: TRACE("Request type is TRIM"); ret = bdrv_discard(bs, (request.from + dev_offset) / 512, request.len / 512); if (ret < 0) { LOG("discard failed"); reply.error = -ret; } if (nbd_send_reply(csock, &reply) == -1) return -1; break; default: LOG("invalid request type (%u) received", request.type); errno = EINVAL; return -1; } TRACE("Request/Reply complete"); return 0; }


test_opts_range_unvisited(void) { intList *list = NULL; intList *tail; QemuOpts *opts; Visitor *v; opts = qemu_opts_parse(qemu_find_opts("userdef"), "ilist=0-2", false, &error_abort); v = opts_visitor_new(opts); visit_start_struct(v, NULL, NULL, 0, &error_abort); /* Would be simpler if the visitor genuinely supported virtual walks */ visit_start_list(v, "ilist", (GenericList **)&list, sizeof(*list), &error_abort); tail = list; visit_type_int(v, NULL, &tail->value, &error_abort); g_assert_cmpint(tail->value, ==, 0); tail = (intList *)visit_next_list(v, (GenericList *)tail, sizeof(*list)); g_assert(tail); visit_type_int(v, NULL, &tail->value, &error_abort); g_assert_cmpint(tail->value, ==, 1); tail = (intList *)visit_next_list(v, (GenericList *)tail, sizeof(*list)); g_assert(tail); visit_end_list(v, (void **)&list); /* BUG: unvisited tail not reported; actually not reportable by design */ visit_check_struct(v, &error_abort); visit_end_struct(v, NULL); qapi_free_intList(list); visit_free(v); qemu_opts_del(opts); }


static int mpeg_decode_mb(MpegEncContext *s, DCTELEM block[12][64]) { int i, j, k, cbp, val, mb_type, motion_type; dprintf("decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y); assert(s->mb_skiped==0); if (s->mb_skip_run-- != 0) { if(s->pict_type == I_TYPE){ av_log(s->avctx, AV_LOG_ERROR, "skiped MB in I frame at %d %d\n", s->mb_x, s->mb_y); return -1; } /* 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 == P_TYPE) { /* 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; s->mb_skiped = 1; s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; } 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]; s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride - 1] | MB_TYPE_SKIP; // assert(s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride - 1]&(MB_TYPE_16x16|MB_TYPE_16x8)); if((s->mv[0][0][0]|s->mv[0][0][1]|s->mv[1][0][0]|s->mv[1][0][1])==0) s->mb_skiped = 1; } return 0; } switch(s->pict_type) { default: case I_TYPE: if (get_bits1(&s->gb) == 0) { if (get_bits1(&s->gb) == 0){ av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in I Frame at %d %d\n", s->mb_x, s->mb_y); return -1; } mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA; } else { mb_type = MB_TYPE_INTRA; } break; case P_TYPE: mb_type = get_vlc2(&s->gb, mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1); if (mb_type < 0){ av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y); return -1; } mb_type = ptype2mb_type[ mb_type ]; break; case B_TYPE: mb_type = get_vlc2(&s->gb, mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1); if (mb_type < 0){ av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y); return -1; } mb_type = btype2mb_type[ mb_type ]; break; } dprintf("mb_type=%x\n", mb_type); // motion_type = 0; /* avoid warning */ if (IS_INTRA(mb_type)) { /* compute dct type */ if (s->picture_structure == PICT_FRAME && //FIXME add a interlaced_dct coded var? !s->frame_pred_frame_dct) { s->interlaced_dct = get_bits1(&s->gb); } if (IS_QUANT(mb_type)) s->qscale = get_qscale(s); if (s->concealment_motion_vectors) { /* just parse them */ if (s->picture_structure != PICT_FRAME) skip_bits1(&s->gb); /* field select */ s->mv[0][0][0]= s->last_mv[0][0][0]= s->last_mv[0][1][0] = mpeg_decode_motion(s, s->mpeg_f_code[0][0], s->last_mv[0][0][0]); s->mv[0][0][1]= s->last_mv[0][0][1]= s->last_mv[0][1][1] = mpeg_decode_motion(s, s->mpeg_f_code[0][1], s->last_mv[0][0][1]); skip_bits1(&s->gb); /* marker */ }else memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */ s->mb_intra = 1; #ifdef HAVE_XVMC //one 1 we memcpy blocks in xvmcvideo if(s->avctx->xvmc_acceleration > 1){ XVMC_pack_pblocks(s,-1);//inter are always full blocks if(s->swap_uv){ exchange_uv(s); } } #endif if (s->codec_id == CODEC_ID_MPEG2VIDEO) { for(i=0;i<4+(1<<s->chroma_format);i++) { if (mpeg2_decode_block_intra(s, s->pblocks[i], i) < 0) return -1; } } else { for(i=0;i<6;i++) { if (mpeg1_decode_block_intra(s, s->pblocks[i], i) < 0) return -1; } } } else { if (mb_type & MB_TYPE_ZERO_MV){ assert(mb_type & MB_TYPE_CBP); /* compute dct type */ if (s->picture_structure == PICT_FRAME && //FIXME add a interlaced_dct coded var? !s->frame_pred_frame_dct) { s->interlaced_dct = get_bits1(&s->gb); } if (IS_QUANT(mb_type)) s->qscale = get_qscale(s); s->mv_dir = MV_DIR_FORWARD; if(s->picture_structure == PICT_FRAME) s->mv_type = MV_TYPE_16X16; else{ s->mv_type = MV_TYPE_FIELD; mb_type |= MB_TYPE_INTERLACED; s->field_select[0][0]= s->picture_structure - 1; } s->last_mv[0][0][0] = 0; s->last_mv[0][0][1] = 0; s->last_mv[0][1][0] = 0; s->last_mv[0][1][1] = 0; s->mv[0][0][0] = 0; s->mv[0][0][1] = 0; }else{ assert(mb_type & MB_TYPE_L0L1); //FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED /* get additionnal motion vector type */ if (s->frame_pred_frame_dct) motion_type = MT_FRAME; else{ motion_type = get_bits(&s->gb, 2); } /* compute dct type */ if (s->picture_structure == PICT_FRAME && //FIXME add a interlaced_dct coded var? !s->frame_pred_frame_dct && HAS_CBP(mb_type)) { s->interlaced_dct = get_bits1(&s->gb); } if (IS_QUANT(mb_type)) s->qscale = get_qscale(s); /* motion vectors */ s->mv_dir = 0; for(i=0;i<2;i++) { if (USES_LIST(mb_type, i)) { s->mv_dir |= (MV_DIR_FORWARD >> i); dprintf("motion_type=%d\n", motion_type); switch(motion_type) { case MT_FRAME: /* or MT_16X8 */ if (s->picture_structure == PICT_FRAME) { /* MT_FRAME */ mb_type |= MB_TYPE_16x16; s->mv_type = MV_TYPE_16X16; s->mv[i][0][0]= s->last_mv[i][0][0]= s->last_mv[i][1][0] = mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]); s->mv[i][0][1]= s->last_mv[i][0][1]= s->last_mv[i][1][1] = mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][0][1]); /* full_pel: only for mpeg1 */ if (s->full_pel[i]){ s->mv[i][0][0] <<= 1; s->mv[i][0][1] <<= 1; } } else { /* MT_16X8 */ mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; s->mv_type = MV_TYPE_16X8; for(j=0;j<2;j++) { s->field_select[i][j] = get_bits1(&s->gb); for(k=0;k<2;k++) { val = mpeg_decode_motion(s, s->mpeg_f_code[i][k], s->last_mv[i][j][k]); s->last_mv[i][j][k] = val; s->mv[i][j][k] = val; } } } break; case MT_FIELD: s->mv_type = MV_TYPE_FIELD; if (s->picture_structure == PICT_FRAME) { mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; for(j=0;j<2;j++) { s->field_select[i][j] = get_bits1(&s->gb); val = mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][j][0]); s->last_mv[i][j][0] = val; s->mv[i][j][0] = val; dprintf("fmx=%d\n", val); val = mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][j][1] >> 1); s->last_mv[i][j][1] = val << 1; s->mv[i][j][1] = val; dprintf("fmy=%d\n", val); } } else { mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; s->field_select[i][0] = get_bits1(&s->gb); for(k=0;k<2;k++) { val = mpeg_decode_motion(s, s->mpeg_f_code[i][k], s->last_mv[i][0][k]); s->last_mv[i][0][k] = val; s->last_mv[i][1][k] = val; s->mv[i][0][k] = val; } } break; case MT_DMV: { int dmx, dmy, mx, my, m; mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]); s->last_mv[i][0][0] = mx; s->last_mv[i][1][0] = mx; dmx = get_dmv(s); my = mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][0][1] >> 1); dmy = get_dmv(s); s->mv_type = MV_TYPE_DMV; s->last_mv[i][0][1] = my<<1; s->last_mv[i][1][1] = my<<1; s->mv[i][0][0] = mx; s->mv[i][0][1] = my; s->mv[i][1][0] = mx;//not used s->mv[i][1][1] = my;//not used if (s->picture_structure == PICT_FRAME) { mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; //m = 1 + 2 * s->top_field_first; m = s->top_field_first ? 1 : 3; /* top -> top pred */ s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx; s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1; m = 4 - m; s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx; s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1; } else { mb_type |= MB_TYPE_16x16; s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx; s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy; if(s->picture_structure == PICT_TOP_FIELD) s->mv[i][2][1]--; else s->mv[i][2][1]++; } } break; default: av_log(s->avctx, AV_LOG_ERROR, "00 motion_type at %d %d\n", s->mb_x, s->mb_y); return -1; } } } } s->mb_intra = 0; if (HAS_CBP(mb_type)) { cbp = get_vlc2(&s->gb, mb_pat_vlc.table, MB_PAT_VLC_BITS, 1); if (cbp < 0){ av_log(s->avctx, AV_LOG_ERROR, "invalid cbp at %d %d\n", s->mb_x, s->mb_y); return -1; } cbp++; if(s->chroma_format == 2){//CHROMA422 cbp|= ( get_bits(&s->gb,2) ) << 6; }else if(s->chroma_format > 2){//CHROMA444 cbp|= ( get_bits(&s->gb,6) ) << 6; } #ifdef HAVE_XVMC //on 1 we memcpy blocks in xvmcvideo if(s->avctx->xvmc_acceleration > 1){ XVMC_pack_pblocks(s,cbp); if(s->swap_uv){ exchange_uv(s); } } #endif if (s->codec_id == CODEC_ID_MPEG2VIDEO) { for(i=0;i<6;i++) { if (cbp & (1<<(5-i)) ) { if (mpeg2_decode_block_non_intra(s, s->pblocks[i], i) < 0) return -1; } else { s->block_last_index[i] = -1; } } if (s->chroma_format >= 2) { if (s->chroma_format == 2) {//CHROMA_422) for(i=6;i<8;i++) { if (cbp & (1<<(6+7-i)) ) { if (mpeg2_decode_block_non_intra(s, s->pblocks[i], i) < 0) return -1; } else { s->block_last_index[i] = -1; } } }else{ /*CHROMA_444*/ for(i=6;i<12;i++) { if (cbp & (1<<(6+11-i)) ) { if (mpeg2_decode_block_non_intra(s, s->pblocks[i], i) < 0) return -1; } else { s->block_last_index[i] = -1; } } } } } else { for(i=0;i<6;i++) { if (cbp & 32) { if (mpeg1_decode_block_inter(s, s->pblocks[i], i) < 0) return -1; } else { s->block_last_index[i] = -1; } cbp+=cbp; } } }else{ for(i=0;i<6;i++) s->block_last_index[i] = -1; } } s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= mb_type; return 0; }


static av_cold int rv10_decode_init(AVCodecContext *avctx) { RVDecContext *rv = avctx->priv_data; MpegEncContext *s = &rv->m; static int done=0; int major_ver, minor_ver, micro_ver; if (avctx->extradata_size < 8) { av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n"); return -1; } ff_MPV_decode_defaults(s); s->avctx= avctx; s->out_format = FMT_H263; s->codec_id= avctx->codec_id; s->orig_width = s->width = avctx->coded_width; s->orig_height= s->height = avctx->coded_height; s->h263_long_vectors= ((uint8_t*)avctx->extradata)[3] & 1; rv->sub_id = AV_RB32((uint8_t*)avctx->extradata + 4); major_ver = RV_GET_MAJOR_VER(rv->sub_id); minor_ver = RV_GET_MINOR_VER(rv->sub_id); micro_ver = RV_GET_MICRO_VER(rv->sub_id); s->low_delay = 1; switch (major_ver) { case 1: s->rv10_version = micro_ver ? 3 : 1; s->obmc = micro_ver == 2; break; case 2: if (minor_ver >= 2) { s->low_delay = 0; s->avctx->has_b_frames = 1; } break; default: av_log(s->avctx, AV_LOG_ERROR, "unknown header %X\n", rv->sub_id); av_log_missing_feature(avctx, "RV1/2 version", 1); return AVERROR_PATCHWELCOME; } if(avctx->debug & FF_DEBUG_PICT_INFO){ av_log(avctx, AV_LOG_DEBUG, "ver:%X ver0:%X\n", rv->sub_id, avctx->extradata_size >= 4 ? ((uint32_t*)avctx->extradata)[0] : -1); } avctx->pix_fmt = AV_PIX_FMT_YUV420P; if (ff_MPV_common_init(s) < 0) return -1; ff_h263_decode_init_vlc(); /* init rv vlc */ if (!done) { INIT_VLC_STATIC(&rv_dc_lum, DC_VLC_BITS, 256, rv_lum_bits, 1, 1, rv_lum_code, 2, 2, 16384); INIT_VLC_STATIC(&rv_dc_chrom, DC_VLC_BITS, 256, rv_chrom_bits, 1, 1, rv_chrom_code, 2, 2, 16388); done = 1; } return 0; }


static inline float32 ucf64_itos(uint32_t i) { union { uint32_t i; float32 s; } v; v.i = i; return v.s; }