udp_emu(struct socket *so, struct mbuf *m) { struct sockaddr_in addr; int addrlen = sizeof(addr); #ifdef EMULATE_TALK CTL_MSG_OLD *omsg; CTL_MSG *nmsg; char buff[sizeof(CTL_MSG)]; u_char type; struct talk_request { struct talk_request *next; struct socket *udp_so; struct socket *tcp_so; } *req; static struct talk_request *req_tbl = 0; #endif struct cu_header { uint16_t d_family; // destination family uint16_t d_port; // destination port uint32_t d_addr; // destination address uint16_t s_family; // source family uint16_t s_port; // source port uint32_t so_addr; // source address uint32_t seqn; // sequence number uint16_t message; // message uint16_t data_type; // data type uint16_t pkt_len; // packet length } *cu_head; switch(so->so_emu) { #ifdef EMULATE_TALK case EMU_TALK: case EMU_NTALK: /* * Talk emulation. We always change the ctl_addr to get * some answers from the daemon. When an ANNOUNCE comes, * we send LEAVE_INVITE to the local daemons. Also when a * DELETE comes, we send copies to the local daemons. */ if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0) return; #define IS_OLD (so->so_emu == EMU_TALK) #define COPY_MSG(dest, src) { dest->type = src->type; \ dest->id_num = src->id_num; \ dest->pid = src->pid; \ dest->addr = src->addr; \ dest->ctl_addr = src->ctl_addr; \ memcpy(&dest->l_name, &src->l_name, NAME_SIZE_OLD); \ memcpy(&dest->r_name, &src->r_name, NAME_SIZE_OLD); \ memcpy(&dest->r_tty, &src->r_tty, TTY_SIZE); } #define OTOSIN(ptr, field) ((struct sockaddr_in *)&ptr->field) /* old_sockaddr to sockaddr_in */ if (IS_OLD) { /* old talk */ omsg = mtod(m, CTL_MSG_OLD*); nmsg = (CTL_MSG *) buff; type = omsg->type; OTOSIN(omsg, ctl_addr)->sin_port = addr.sin_port; OTOSIN(omsg, ctl_addr)->sin_addr = our_addr; strncpy(omsg->l_name, getlogin(), NAME_SIZE_OLD); } else { /* new talk */ omsg = (CTL_MSG_OLD *) buff; nmsg = mtod(m, CTL_MSG *); type = nmsg->type; OTOSIN(nmsg, ctl_addr)->sin_port = addr.sin_port; OTOSIN(nmsg, ctl_addr)->sin_addr = our_addr; strncpy(nmsg->l_name, getlogin(), NAME_SIZE_OLD); } if (type == LOOK_UP) return; /* for LOOK_UP this is enough */ if (IS_OLD) { /* make a copy of the message */ COPY_MSG(nmsg, omsg); nmsg->vers = 1; nmsg->answer = 0; } else COPY_MSG(omsg, nmsg); /* * If if is an ANNOUNCE message, we go through the * request table to see if a tcp port has already * been redirected for this socket. If not, we solisten() * a new socket and add this entry to the table. * The port number of the tcp socket and our IP * are put to the addr field of the message structures. * Then a LEAVE_INVITE is sent to both local daemon * ports, 517 and 518. This is why we have two copies * of the message, one in old talk and one in new talk * format. */ if (type == ANNOUNCE) { int s; u_short temp_port; for(req = req_tbl; req; req = req->next) if (so == req->udp_so) break; /* found it */ if (!req) { /* no entry for so, create new */ req = (struct talk_request *) malloc(sizeof(struct talk_request)); req->udp_so = so; req->tcp_so = solisten(0, OTOSIN(omsg, addr)->sin_addr.s_addr, OTOSIN(omsg, addr)->sin_port, SS_FACCEPTONCE); req->next = req_tbl; req_tbl = req; } /* replace port number in addr field */ addrlen = sizeof(addr); getsockname(req->tcp_so->s, (struct sockaddr *) &addr, &addrlen); OTOSIN(omsg, addr)->sin_port = addr.sin_port; OTOSIN(omsg, addr)->sin_addr = our_addr; OTOSIN(nmsg, addr)->sin_port = addr.sin_port; OTOSIN(nmsg, addr)->sin_addr = our_addr; /* send LEAVE_INVITEs */ temp_port = OTOSIN(omsg, ctl_addr)->sin_port; OTOSIN(omsg, ctl_addr)->sin_port = 0; OTOSIN(nmsg, ctl_addr)->sin_port = 0; omsg->type = nmsg->type = LEAVE_INVITE; s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); addr.sin_addr = our_addr; addr.sin_family = AF_INET; addr.sin_port = htons(517); sendto(s, (char *)omsg, sizeof(*omsg), 0, (struct sockaddr *)&addr, sizeof(addr)); addr.sin_port = htons(518); sendto(s, (char *)nmsg, sizeof(*nmsg), 0, (struct sockaddr *) &addr, sizeof(addr)); closesocket(s) ; omsg->type = nmsg->type = ANNOUNCE; OTOSIN(omsg, ctl_addr)->sin_port = temp_port; OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; } /* * If it is a DELETE message, we send a copy to the * local daemons. Then we delete the entry corresponding * to our socket from the request table. */ if (type == DELETE) { struct talk_request *temp_req, *req_next; int s; u_short temp_port; temp_port = OTOSIN(omsg, ctl_addr)->sin_port; OTOSIN(omsg, ctl_addr)->sin_port = 0; OTOSIN(nmsg, ctl_addr)->sin_port = 0; s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); addr.sin_addr = our_addr; addr.sin_family = AF_INET; addr.sin_port = htons(517); sendto(s, (char *)omsg, sizeof(*omsg), 0, (struct sockaddr *)&addr, sizeof(addr)); addr.sin_port = htons(518); sendto(s, (char *)nmsg, sizeof(*nmsg), 0, (struct sockaddr *)&addr, sizeof(addr)); closesocket(s); OTOSIN(omsg, ctl_addr)->sin_port = temp_port; OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; /* delete table entry */ if (so == req_tbl->udp_so) { temp_req = req_tbl; req_tbl = req_tbl->next; free(temp_req); } else { temp_req = req_tbl; for(req = req_tbl->next; req; req = req_next) { req_next = req->next; if (so == req->udp_so) { temp_req->next = req_next; free(req); break; } else { temp_req = req; } } } } return; #endif case EMU_CUSEEME: /* * Cu-SeeMe emulation. * Hopefully the packet is more that 16 bytes long. We don't * do any other tests, just replace the address and port * fields. */ if (m->m_len >= sizeof (*cu_head)) { if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0) return; cu_head = mtod(m, struct cu_header *); cu_head->s_port = addr.sin_port; cu_head->so_addr = our_addr.s_addr; } return; } }


static ssize_t usbnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size) { USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque; struct rndis_packet_msg_type *msg; if (s->rndis) { msg = (struct rndis_packet_msg_type *) s->in_buf; if (!s->rndis_state == RNDIS_DATA_INITIALIZED) return -1; if (size + sizeof(struct rndis_packet_msg_type) > sizeof(s->in_buf)) return -1; memset(msg, 0, sizeof(struct rndis_packet_msg_type)); msg->MessageType = cpu_to_le32(RNDIS_PACKET_MSG); msg->MessageLength = cpu_to_le32(size + sizeof(struct rndis_packet_msg_type)); msg->DataOffset = cpu_to_le32(sizeof(struct rndis_packet_msg_type) - 8); msg->DataLength = cpu_to_le32(size); /* msg->OOBDataOffset; * msg->OOBDataLength; * msg->NumOOBDataElements; * msg->PerPacketInfoOffset; * msg->PerPacketInfoLength; * msg->VcHandle; * msg->Reserved; */ memcpy(msg + 1, buf, size); s->in_len = size + sizeof(struct rndis_packet_msg_type); } else { if (size > sizeof(s->in_buf)) return -1; memcpy(s->in_buf, buf, size); s->in_len = size; } s->in_ptr = 0; return size; }


static void mpcore_priv_map_setup(mpcore_priv_state *s) { int i; SysBusDevice *gicbusdev = sysbus_from_qdev(s->gic); SysBusDevice *busdev = sysbus_from_qdev(s->mptimer); memory_region_init(&s->container, "mpcode-priv-container", 0x2000); memory_region_init_io(&s->iomem, &mpcore_scu_ops, s, "mpcore-scu", 0x100); memory_region_add_subregion(&s->container, 0, &s->iomem); /* GIC CPU interfaces: "current CPU" at 0x100, then specific CPUs * at 0x200, 0x300... */ for (i = 0; i < (s->num_cpu + 1); i++) { target_phys_addr_t offset = 0x100 + (i * 0x100); memory_region_add_subregion(&s->container, offset, sysbus_mmio_get_region(gicbusdev, i + 1)); } /* Add the regions for timer and watchdog for "current CPU" and * for each specific CPU. */ for (i = 0; i < (s->num_cpu + 1) * 2; i++) { /* Timers at 0x600, 0x700, ...; watchdogs at 0x620, 0x720, ... */ target_phys_addr_t offset = 0x600 + (i >> 1) * 0x100 + (i & 1) * 0x20; memory_region_add_subregion(&s->container, offset, sysbus_mmio_get_region(busdev, i)); } memory_region_add_subregion(&s->container, 0x1000, sysbus_mmio_get_region(gicbusdev, 0)); /* Wire up the interrupt from each watchdog and timer. * For each core the timer is PPI 29 and the watchdog PPI 30. */ for (i = 0; i < s->num_cpu; i++) { int ppibase = (s->num_irq - 32) + i * 32; sysbus_connect_irq(busdev, i * 2, qdev_get_gpio_in(s->gic, ppibase + 29)); sysbus_connect_irq(busdev, i * 2 + 1, qdev_get_gpio_in(s->gic, ppibase + 30)); } }


static int proxy_readdir_r(FsContext *ctx, V9fsFidOpenState *fs, struct dirent *entry, struct dirent **result) { return readdir_r(fs->dir, entry, result); }


int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) { const SPS *sps; const PPS *pps; unsigned int first_mb_in_slice; unsigned int pps_id; int ret; unsigned int slice_type, tmp, i, j; int last_pic_structure, last_pic_droppable; int needs_reinit = 0; int field_pic_flag, bottom_field_flag; int frame_num, droppable, picture_structure; int mb_aff_frame = 0; h->qpel_put = h->h264qpel.put_h264_qpel_pixels_tab; h->qpel_avg = h->h264qpel.avg_h264_qpel_pixels_tab; first_mb_in_slice = get_ue_golomb(&sl->gb); if (first_mb_in_slice == 0) { // FIXME better field boundary detection if (h->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) { ff_h264_field_end(h, sl, 1); } h->current_slice = 0; if (!h->first_field) { if (h->cur_pic_ptr && !h->droppable) { ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, h->picture_structure == PICT_BOTTOM_FIELD); } h->cur_pic_ptr = NULL; } } slice_type = get_ue_golomb_31(&sl->gb); if (slice_type > 9) { av_log(h->avctx, AV_LOG_ERROR, "slice type %d too large at %d\n", slice_type, first_mb_in_slice); return AVERROR_INVALIDDATA; } if (slice_type > 4) { slice_type -= 5; sl->slice_type_fixed = 1; } else sl->slice_type_fixed = 0; slice_type = ff_h264_golomb_to_pict_type[slice_type]; sl->slice_type = slice_type; sl->slice_type_nos = slice_type & 3; if (h->nal_unit_type == NAL_IDR_SLICE && sl->slice_type_nos != AV_PICTURE_TYPE_I) { av_log(h->avctx, AV_LOG_ERROR, "A non-intra slice in an IDR NAL unit.\n"); return AVERROR_INVALIDDATA; } // to make a few old functions happy, it's wrong though if (!h->setup_finished) h->pict_type = sl->slice_type; pps_id = get_ue_golomb(&sl->gb); if (pps_id >= MAX_PPS_COUNT) { av_log(h->avctx, AV_LOG_ERROR, "pps_id %u out of range\n", pps_id); return AVERROR_INVALIDDATA; } if (!h->ps.pps_list[pps_id]) { av_log(h->avctx, AV_LOG_ERROR, "non-existing PPS %u referenced\n", pps_id); return AVERROR_INVALIDDATA; } if (!h->setup_finished) { h->ps.pps = (const PPS*)h->ps.pps_list[pps_id]->data; } else if (h->ps.pps != (const PPS*)h->ps.pps_list[pps_id]->data) { av_log(h->avctx, AV_LOG_ERROR, "PPS changed between slices\n"); return AVERROR_INVALIDDATA; } if (!h->ps.sps_list[h->ps.pps->sps_id]) { av_log(h->avctx, AV_LOG_ERROR, "non-existing SPS %u referenced\n", h->ps.pps->sps_id); return AVERROR_INVALIDDATA; } if (h->ps.sps != (const SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data) { h->ps.sps = (SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data; if (h->bit_depth_luma != h->ps.sps->bit_depth_luma || h->chroma_format_idc != h->ps.sps->chroma_format_idc) needs_reinit = 1; if (h->flags & AV_CODEC_FLAG_LOW_DELAY || (h->ps.sps->bitstream_restriction_flag && !h->ps.sps->num_reorder_frames)) { if (h->avctx->has_b_frames > 1 || h->delayed_pic[0]) av_log(h->avctx, AV_LOG_WARNING, "Delayed frames seen. " "Reenabling low delay requires a codec flush.\n"); else h->low_delay = 1; } if (h->avctx->has_b_frames < 2) h->avctx->has_b_frames = !h->low_delay; } pps = h->ps.pps; sps = h->ps.sps; if (!h->setup_finished) { h->avctx->profile = ff_h264_get_profile(sps); h->avctx->level = sps->level_idc; h->avctx->refs = sps->ref_frame_count; if (h->mb_width != sps->mb_width || h->mb_height != sps->mb_height * (2 - sps->frame_mbs_only_flag)) needs_reinit = 1; h->mb_width = sps->mb_width; h->mb_height = sps->mb_height * (2 - sps->frame_mbs_only_flag); h->mb_num = h->mb_width * h->mb_height; h->mb_stride = h->mb_width + 1; h->b_stride = h->mb_width * 4; h->chroma_y_shift = sps->chroma_format_idc <= 1; // 400 uses yuv420p h->width = 16 * h->mb_width; h->height = 16 * h->mb_height; ret = init_dimensions(h); if (ret < 0) return ret; if (sps->video_signal_type_present_flag) { h->avctx->color_range = sps->full_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; if (sps->colour_description_present_flag) { if (h->avctx->colorspace != sps->colorspace) needs_reinit = 1; h->avctx->color_primaries = sps->color_primaries; h->avctx->color_trc = sps->color_trc; h->avctx->colorspace = sps->colorspace; } } } if (h->context_initialized && needs_reinit) { h->context_initialized = 0; if (sl != h->slice_ctx) { av_log(h->avctx, AV_LOG_ERROR, "changing width %d -> %d / height %d -> %d on " "slice %d\n", h->width, h->avctx->coded_width, h->height, h->avctx->coded_height, h->current_slice + 1); return AVERROR_INVALIDDATA; } ff_h264_flush_change(h); if ((ret = get_pixel_format(h)) < 0) return ret; h->avctx->pix_fmt = ret; av_log(h->avctx, AV_LOG_INFO, "Reinit context to %dx%d, " "pix_fmt: %d\n", h->width, h->height, h->avctx->pix_fmt); if ((ret = h264_slice_header_init(h)) < 0) { av_log(h->avctx, AV_LOG_ERROR, "h264_slice_header_init() failed\n"); return ret; } } if (!h->context_initialized) { if (sl != h->slice_ctx) { av_log(h->avctx, AV_LOG_ERROR, "Cannot (re-)initialize context during parallel decoding.\n"); return AVERROR_PATCHWELCOME; } if ((ret = get_pixel_format(h)) < 0) return ret; h->avctx->pix_fmt = ret; if ((ret = h264_slice_header_init(h)) < 0) { av_log(h->avctx, AV_LOG_ERROR, "h264_slice_header_init() failed\n"); return ret; } } frame_num = get_bits(&sl->gb, sps->log2_max_frame_num); if (!h->setup_finished) h->frame_num = frame_num; sl->mb_mbaff = 0; last_pic_structure = h->picture_structure; last_pic_droppable = h->droppable; droppable = h->nal_ref_idc == 0; if (sps->frame_mbs_only_flag) { picture_structure = PICT_FRAME; } else { field_pic_flag = get_bits1(&sl->gb); if (field_pic_flag) { bottom_field_flag = get_bits1(&sl->gb); picture_structure = PICT_TOP_FIELD + bottom_field_flag; } else { picture_structure = PICT_FRAME; mb_aff_frame = sps->mb_aff; } } if (!h->setup_finished) { h->droppable = droppable; h->picture_structure = picture_structure; h->mb_aff_frame = mb_aff_frame; } sl->mb_field_decoding_flag = h->picture_structure != PICT_FRAME; if (h->current_slice != 0) { if (last_pic_structure != picture_structure || last_pic_droppable != droppable) { av_log(h->avctx, AV_LOG_ERROR, "Changing field mode (%d -> %d) between slices is not allowed\n", last_pic_structure, h->picture_structure); return AVERROR_INVALIDDATA; } else if (!h->cur_pic_ptr) { av_log(h->avctx, AV_LOG_ERROR, "unset cur_pic_ptr on slice %d\n", h->current_slice + 1); return AVERROR_INVALIDDATA; } } else { /* Shorten frame num gaps so we don't have to allocate reference * frames just to throw them away */ if (h->frame_num != h->prev_frame_num) { int unwrap_prev_frame_num = h->prev_frame_num; int max_frame_num = 1 << sps->log2_max_frame_num; if (unwrap_prev_frame_num > h->frame_num) unwrap_prev_frame_num -= max_frame_num; if ((h->frame_num - unwrap_prev_frame_num) > sps->ref_frame_count) { unwrap_prev_frame_num = (h->frame_num - sps->ref_frame_count) - 1; if (unwrap_prev_frame_num < 0) unwrap_prev_frame_num += max_frame_num; h->prev_frame_num = unwrap_prev_frame_num; } } /* See if we have a decoded first field looking for a pair... * Here, we're using that to see if we should mark previously * decode frames as "finished". * We have to do that before the "dummy" in-between frame allocation, * since that can modify s->current_picture_ptr. */ if (h->first_field) { assert(h->cur_pic_ptr); assert(h->cur_pic_ptr->f->buf[0]); assert(h->cur_pic_ptr->reference != DELAYED_PIC_REF); /* figure out if we have a complementary field pair */ if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) { /* Previous field is unmatched. Don't display it, but let it * remain for reference if marked as such. */ if (!last_pic_droppable && last_pic_structure != PICT_FRAME) { ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, last_pic_structure == PICT_TOP_FIELD); } } else { if (h->cur_pic_ptr->frame_num != h->frame_num) { /* This and previous field were reference, but had * different frame_nums. Consider this field first in * pair. Throw away previous field except for reference * purposes. */ if (!last_pic_droppable && last_pic_structure != PICT_FRAME) { ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, last_pic_structure == PICT_TOP_FIELD); } } else { /* Second field in complementary pair */ if (!((last_pic_structure == PICT_TOP_FIELD && h->picture_structure == PICT_BOTTOM_FIELD) || (last_pic_structure == PICT_BOTTOM_FIELD && h->picture_structure == PICT_TOP_FIELD))) { av_log(h->avctx, AV_LOG_ERROR, "Invalid field mode combination %d/%d\n", last_pic_structure, h->picture_structure); h->picture_structure = last_pic_structure; h->droppable = last_pic_droppable; return AVERROR_INVALIDDATA; } else if (last_pic_droppable != h->droppable) { avpriv_request_sample(h->avctx, "Found reference and non-reference fields in the same frame, which"); h->picture_structure = last_pic_structure; h->droppable = last_pic_droppable; return AVERROR_PATCHWELCOME; } } } } while (h->frame_num != h->prev_frame_num && h->frame_num != (h->prev_frame_num + 1) % (1 << sps->log2_max_frame_num)) { H264Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL; av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n", h->frame_num, h->prev_frame_num); ret = initialize_cur_frame(h); if (ret < 0) { h->first_field = 0; return ret; } h->prev_frame_num++; h->prev_frame_num %= 1 << sps->log2_max_frame_num; h->cur_pic_ptr->frame_num = h->prev_frame_num; ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0); ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1); ret = ff_generate_sliding_window_mmcos(h, 1); if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) return ret; ret = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index); if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) return ret; /* Error concealment: If a ref is missing, copy the previous ref * in its place. * FIXME: Avoiding a memcpy would be nice, but ref handling makes * many assumptions about there being no actual duplicates. * FIXME: This does not copy padding for out-of-frame motion * vectors. Given we are concealing a lost frame, this probably * is not noticeable by comparison, but it should be fixed. */ if (h->short_ref_count) { if (prev && h->short_ref[0]->f->width == prev->f->width && h->short_ref[0]->f->height == prev->f->height && h->short_ref[0]->f->format == prev->f->format) { av_image_copy(h->short_ref[0]->f->data, h->short_ref[0]->f->linesize, (const uint8_t **)prev->f->data, prev->f->linesize, prev->f->format, h->mb_width * 16, h->mb_height * 16); h->short_ref[0]->poc = prev->poc + 2; } h->short_ref[0]->frame_num = h->prev_frame_num; } } /* See if we have a decoded first field looking for a pair... * We're using that to see whether to continue decoding in that * frame, or to allocate a new one. */ if (h->first_field) { assert(h->cur_pic_ptr); assert(h->cur_pic_ptr->f->buf[0]); assert(h->cur_pic_ptr->reference != DELAYED_PIC_REF); /* figure out if we have a complementary field pair */ if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) { /* Previous field is unmatched. Don't display it, but let it * remain for reference if marked as such. */ h->cur_pic_ptr = NULL; h->first_field = FIELD_PICTURE(h); } else { if (h->cur_pic_ptr->frame_num != h->frame_num) { /* This and the previous field had different frame_nums. * Consider this field first in pair. Throw away previous * one except for reference purposes. */ h->first_field = 1; h->cur_pic_ptr = NULL; } else { /* Second field in complementary pair */ h->first_field = 0; } } } else { /* Frame or first field in a potentially complementary pair */ h->first_field = FIELD_PICTURE(h); } if (!FIELD_PICTURE(h) || h->first_field) { if (h264_frame_start(h) < 0) { h->first_field = 0; return AVERROR_INVALIDDATA; } } else { release_unused_pictures(h, 0); } } assert(h->mb_num == h->mb_width * h->mb_height); if (first_mb_in_slice << FIELD_OR_MBAFF_PICTURE(h) >= h->mb_num || first_mb_in_slice >= h->mb_num) { av_log(h->avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n"); return AVERROR_INVALIDDATA; } sl->resync_mb_x = sl->mb_x = first_mb_in_slice % h->mb_width; sl->resync_mb_y = sl->mb_y = (first_mb_in_slice / h->mb_width) << FIELD_OR_MBAFF_PICTURE(h); if (h->picture_structure == PICT_BOTTOM_FIELD) sl->resync_mb_y = sl->mb_y = sl->mb_y + 1; assert(sl->mb_y < h->mb_height); if (h->picture_structure == PICT_FRAME) { h->curr_pic_num = h->frame_num; h->max_pic_num = 1 << sps->log2_max_frame_num; } else { h->curr_pic_num = 2 * h->frame_num + 1; h->max_pic_num = 1 << (sps->log2_max_frame_num + 1); } if (h->nal_unit_type == NAL_IDR_SLICE) get_ue_golomb(&sl->gb); /* idr_pic_id */ if (sps->poc_type == 0) { int poc_lsb = get_bits(&sl->gb, sps->log2_max_poc_lsb); if (!h->setup_finished) h->poc_lsb = poc_lsb; if (pps->pic_order_present == 1 && h->picture_structure == PICT_FRAME) { int delta_poc_bottom = get_se_golomb(&sl->gb); if (!h->setup_finished) h->delta_poc_bottom = delta_poc_bottom; } } if (sps->poc_type == 1 && !sps->delta_pic_order_always_zero_flag) { int delta_poc = get_se_golomb(&sl->gb); if (!h->setup_finished) h->delta_poc[0] = delta_poc; if (pps->pic_order_present == 1 && h->picture_structure == PICT_FRAME) { delta_poc = get_se_golomb(&sl->gb); if (!h->setup_finished) h->delta_poc[1] = delta_poc; } } if (!h->setup_finished) ff_init_poc(h, h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc); if (pps->redundant_pic_cnt_present) sl->redundant_pic_count = get_ue_golomb(&sl->gb); if (sl->slice_type_nos == AV_PICTURE_TYPE_B) sl->direct_spatial_mv_pred = get_bits1(&sl->gb); ret = ff_h264_parse_ref_count(&sl->list_count, sl->ref_count, &sl->gb, pps, sl->slice_type_nos, h->picture_structure); if (ret < 0) return ret; if (sl->slice_type_nos != AV_PICTURE_TYPE_I) { ret = ff_h264_decode_ref_pic_list_reordering(h, sl); if (ret < 0) { sl->ref_count[1] = sl->ref_count[0] = 0; return ret; } } if ((pps->weighted_pred && sl->slice_type_nos == AV_PICTURE_TYPE_P) || (pps->weighted_bipred_idc == 1 && sl->slice_type_nos == AV_PICTURE_TYPE_B)) ff_h264_pred_weight_table(&sl->gb, sps, sl->ref_count, sl->slice_type_nos, &sl->pwt); else if (pps->weighted_bipred_idc == 2 && sl->slice_type_nos == AV_PICTURE_TYPE_B) { implicit_weight_table(h, sl, -1); } else { sl->pwt.use_weight = 0; for (i = 0; i < 2; i++) { sl->pwt.luma_weight_flag[i] = 0; sl->pwt.chroma_weight_flag[i] = 0; } } // If frame-mt is enabled, only update mmco tables for the first slice // in a field. Subsequent slices can temporarily clobber h->mmco_index // or h->mmco, which will cause ref list mix-ups and decoding errors // further down the line. This may break decoding if the first slice is // corrupt, thus we only do this if frame-mt is enabled. if (h->nal_ref_idc) { ret = ff_h264_decode_ref_pic_marking(h, &sl->gb, !(h->avctx->active_thread_type & FF_THREAD_FRAME) || h->current_slice == 0); if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) return AVERROR_INVALIDDATA; } if (FRAME_MBAFF(h)) { ff_h264_fill_mbaff_ref_list(h, sl); if (pps->weighted_bipred_idc == 2 && sl->slice_type_nos == AV_PICTURE_TYPE_B) { implicit_weight_table(h, sl, 0); implicit_weight_table(h, sl, 1); } } if (sl->slice_type_nos == AV_PICTURE_TYPE_B && !sl->direct_spatial_mv_pred) ff_h264_direct_dist_scale_factor(h, sl); ff_h264_direct_ref_list_init(h, sl); if (sl->slice_type_nos != AV_PICTURE_TYPE_I && pps->cabac) { tmp = get_ue_golomb_31(&sl->gb); if (tmp > 2) { av_log(h->avctx, AV_LOG_ERROR, "cabac_init_idc %u overflow\n", tmp); return AVERROR_INVALIDDATA; } sl->cabac_init_idc = tmp; } sl->last_qscale_diff = 0; tmp = pps->init_qp + get_se_golomb(&sl->gb); if (tmp > 51 + 6 * (sps->bit_depth_luma - 8)) { av_log(h->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp); return AVERROR_INVALIDDATA; } sl->qscale = tmp; sl->chroma_qp[0] = get_chroma_qp(h, 0, sl->qscale); sl->chroma_qp[1] = get_chroma_qp(h, 1, sl->qscale); // FIXME qscale / qp ... stuff if (sl->slice_type == AV_PICTURE_TYPE_SP) get_bits1(&sl->gb); /* sp_for_switch_flag */ if (sl->slice_type == AV_PICTURE_TYPE_SP || sl->slice_type == AV_PICTURE_TYPE_SI) get_se_golomb(&sl->gb); /* slice_qs_delta */ sl->deblocking_filter = 1; sl->slice_alpha_c0_offset = 0; sl->slice_beta_offset = 0; if (pps->deblocking_filter_parameters_present) { tmp = get_ue_golomb_31(&sl->gb); if (tmp > 2) { av_log(h->avctx, AV_LOG_ERROR, "deblocking_filter_idc %u out of range\n", tmp); return AVERROR_INVALIDDATA; } sl->deblocking_filter = tmp; if (sl->deblocking_filter < 2) sl->deblocking_filter ^= 1; // 1<->0 if (sl->deblocking_filter) { sl->slice_alpha_c0_offset = get_se_golomb(&sl->gb) * 2; sl->slice_beta_offset = get_se_golomb(&sl->gb) * 2; if (sl->slice_alpha_c0_offset > 12 || sl->slice_alpha_c0_offset < -12 || sl->slice_beta_offset > 12 || sl->slice_beta_offset < -12) { av_log(h->avctx, AV_LOG_ERROR, "deblocking filter parameters %d %d out of range\n", sl->slice_alpha_c0_offset, sl->slice_beta_offset); return AVERROR_INVALIDDATA; } } } if (h->avctx->skip_loop_filter >= AVDISCARD_ALL || (h->avctx->skip_loop_filter >= AVDISCARD_NONKEY && sl->slice_type_nos != AV_PICTURE_TYPE_I) || (h->avctx->skip_loop_filter >= AVDISCARD_BIDIR && sl->slice_type_nos == AV_PICTURE_TYPE_B) || (h->avctx->skip_loop_filter >= AVDISCARD_NONREF && h->nal_ref_idc == 0)) sl->deblocking_filter = 0; if (sl->deblocking_filter == 1 && h->max_contexts > 1) { if (h->avctx->flags2 & AV_CODEC_FLAG2_FAST) { /* Cheat slightly for speed: * Do not bother to deblock across slices. */ sl->deblocking_filter = 2; } else { h->max_contexts = 1; if (!h->single_decode_warning) { av_log(h->avctx, AV_LOG_INFO, "Cannot parallelize deblocking type 1, decoding such frames in sequential order\n"); h->single_decode_warning = 1; } if (sl != h->slice_ctx) { av_log(h->avctx, AV_LOG_ERROR, "Deblocking switched inside frame.\n"); return 1; } } } sl->qp_thresh = 15 - FFMIN(sl->slice_alpha_c0_offset, sl->slice_beta_offset) - FFMAX3(0, pps->chroma_qp_index_offset[0], pps->chroma_qp_index_offset[1]) + 6 * (sps->bit_depth_luma - 8); sl->slice_num = ++h->current_slice; if (sl->slice_num >= MAX_SLICES) { av_log(h->avctx, AV_LOG_ERROR, "Too many slices, increase MAX_SLICES and recompile\n"); } for (j = 0; j < 2; j++) { int id_list[16]; int *ref2frm = sl->ref2frm[sl->slice_num & (MAX_SLICES - 1)][j]; for (i = 0; i < 16; i++) { id_list[i] = 60; if (j < sl->list_count && i < sl->ref_count[j] && sl->ref_list[j][i].parent->f->buf[0]) { int k; AVBuffer *buf = sl->ref_list[j][i].parent->f->buf[0]->buffer; for (k = 0; k < h->short_ref_count; k++) if (h->short_ref[k]->f->buf[0]->buffer == buf) { id_list[i] = k; break; } for (k = 0; k < h->long_ref_count; k++) if (h->long_ref[k] && h->long_ref[k]->f->buf[0]->buffer == buf) { id_list[i] = h->short_ref_count + k; break; } } } ref2frm[0] = ref2frm[1] = -1; for (i = 0; i < 16; i++) ref2frm[i + 2] = 4 * id_list[i] + (sl->ref_list[j][i].reference & 3); ref2frm[18 + 0] = ref2frm[18 + 1] = -1; for (i = 16; i < 48; i++) ref2frm[i + 4] = 4 * id_list[(i - 16) >> 1] + (sl->ref_list[j][i].reference & 3); } if (h->avctx->debug & FF_DEBUG_PICT_INFO) { av_log(h->avctx, AV_LOG_DEBUG, "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n", sl->slice_num, (h->picture_structure == PICT_FRAME ? "F" : h->picture_structure == PICT_TOP_FIELD ? "T" : "B"), first_mb_in_slice, av_get_picture_type_char(sl->slice_type), sl->slice_type_fixed ? " fix" : "", h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "", pps_id, h->frame_num, h->cur_pic_ptr->field_poc[0], h->cur_pic_ptr->field_poc[1], sl->ref_count[0], sl->ref_count[1], sl->qscale, sl->deblocking_filter, sl->slice_alpha_c0_offset, sl->slice_beta_offset, sl->pwt.use_weight, sl->pwt.use_weight == 1 && sl->pwt.use_weight_chroma ? "c" : "", sl->slice_type == AV_PICTURE_TYPE_B ? (sl->direct_spatial_mv_pred ? "SPAT" : "TEMP") : ""); } return 0; }


void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb) { uint32_t type; struct iovec *in_iov = req->elem.in_sg; struct iovec *iov = req->elem.out_sg; unsigned in_num = req->elem.in_num; unsigned out_num = req->elem.out_num; if (req->elem.out_num < 1 || req->elem.in_num < 1) { error_report("virtio-blk missing headers"); exit(1); } if (unlikely(iov_to_buf(iov, out_num, 0, &req->out, sizeof(req->out)) != sizeof(req->out))) { error_report("virtio-blk request outhdr too short"); exit(1); } iov_discard_front(&iov, &out_num, sizeof(req->out)); if (in_num < 1 || in_iov[in_num - 1].iov_len < sizeof(struct virtio_blk_inhdr)) { error_report("virtio-blk request inhdr too short"); exit(1); } /* We always touch the last byte, so just see how big in_iov is. */ req->in_len = iov_size(in_iov, in_num); req->in = (void *)in_iov[in_num - 1].iov_base + in_iov[in_num - 1].iov_len - sizeof(struct virtio_blk_inhdr); iov_discard_back(in_iov, &in_num, sizeof(struct virtio_blk_inhdr)); type = virtio_ldl_p(VIRTIO_DEVICE(req->dev), &req->out.type); /* VIRTIO_BLK_T_OUT defines the command direction. VIRTIO_BLK_T_BARRIER * is an optional flag. Although a guest should not send this flag if * not negotiated we ignored it in the past. So keep ignoring it. */ switch (type & ~(VIRTIO_BLK_T_OUT | VIRTIO_BLK_T_BARRIER)) { case VIRTIO_BLK_T_IN: { bool is_write = type & VIRTIO_BLK_T_OUT; req->sector_num = virtio_ldq_p(VIRTIO_DEVICE(req->dev), &req->out.sector); if (is_write) { qemu_iovec_init_external(&req->qiov, iov, out_num); trace_virtio_blk_handle_write(req, req->sector_num, req->qiov.size / BDRV_SECTOR_SIZE); } else { qemu_iovec_init_external(&req->qiov, in_iov, in_num); trace_virtio_blk_handle_read(req, req->sector_num, req->qiov.size / BDRV_SECTOR_SIZE); } if (!virtio_blk_sect_range_ok(req->dev, req->sector_num, req->qiov.size)) { virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR); virtio_blk_free_request(req); return; } block_acct_start(blk_get_stats(req->dev->blk), &req->acct, req->qiov.size, is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ); /* merge would exceed maximum number of requests or IO direction * changes */ if (mrb->num_reqs > 0 && (mrb->num_reqs == VIRTIO_BLK_MAX_MERGE_REQS || is_write != mrb->is_write || !req->dev->conf.request_merging)) { virtio_blk_submit_multireq(req->dev->blk, mrb); } assert(mrb->num_reqs < VIRTIO_BLK_MAX_MERGE_REQS); mrb->reqs[mrb->num_reqs++] = req; mrb->is_write = is_write; break; } case VIRTIO_BLK_T_FLUSH: virtio_blk_handle_flush(req, mrb); break; case VIRTIO_BLK_T_SCSI_CMD: virtio_blk_handle_scsi(req); break; case VIRTIO_BLK_T_GET_ID: { VirtIOBlock *s = req->dev; /* * NB: per existing s/n string convention the string is * terminated by '\0' only when shorter than buffer. */ const char *serial = s->conf.serial ? s->conf.serial : ""; size_t size = MIN(strlen(serial) + 1, MIN(iov_size(in_iov, in_num), VIRTIO_BLK_ID_BYTES)); iov_from_buf(in_iov, in_num, 0, serial, size); virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); virtio_blk_free_request(req); break; } default: virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP); virtio_blk_free_request(req); } }


static void net_vhost_user_event(void *opaque, int event) { VhostUserState *s = opaque; switch (event) { case CHR_EVENT_OPENED: vhost_user_start(s); net_vhost_link_down(s, false); error_report("chardev \"%s\" went up", s->chr->label); break; case CHR_EVENT_CLOSED: net_vhost_link_down(s, true); vhost_user_stop(s); error_report("chardev \"%s\" went down", s->chr->label); break; } }


static uint32_t virtio_blk_get_features(VirtIODevice *vdev) { VirtIOBlock *s = to_virtio_blk(vdev); uint32_t features = 0; features |= (1 << VIRTIO_BLK_F_SEG_MAX); features |= (1 << VIRTIO_BLK_F_GEOMETRY); if (bdrv_enable_write_cache(s->bs)) features |= (1 << VIRTIO_BLK_F_WCACHE); #ifdef __linux__ features |= (1 << VIRTIO_BLK_F_SCSI); #endif if (strcmp(s->serial_str, "0")) features |= 1 << VIRTIO_BLK_F_IDENTIFY; if (bdrv_is_read_only(s->bs)) features |= 1 << VIRTIO_BLK_F_RO; return features; }


static void vmsvga_bios_write(void *opaque, uint32_t address, uint32_t data) { printf("%s: what are we supposed to do with (%08x)?\n", __FUNCTION__, data); }


static void platform_ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, pcibus_t size, int type) { PCIXenPlatformState *d = DO_UPCAST(PCIXenPlatformState, pci_dev, pci_dev); register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d); register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d); }


static void qemu_chr_fire_open_event(void *opaque) { CharDriverState *s = opaque; qemu_chr_be_event(s, CHR_EVENT_OPENED); qemu_free_timer(s->open_timer); s->open_timer = NULL; }


static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) { BDRVSheepdogState *s = bs->opaque; BDRVSheepdogState *old_s; char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN]; char *buf = NULL; uint32_t vid; uint32_t snapid = 0; int ret = 0, fd; old_s = g_malloc(sizeof(BDRVSheepdogState)); memcpy(old_s, s, sizeof(BDRVSheepdogState)); pstrcpy(vdi, sizeof(vdi), s->name); snapid = strtoul(snapshot_id, NULL, 10); if (snapid) { tag[0] = 0; } else { pstrcpy(tag, sizeof(tag), s->name); } ret = find_vdi_name(s, vdi, snapid, tag, &vid, 1); if (ret) { error_report("Failed to find_vdi_name"); goto out; } fd = connect_to_sdog(s->addr, s->port); if (fd < 0) { error_report("failed to connect"); ret = fd; goto out; } buf = g_malloc(SD_INODE_SIZE); ret = read_object(fd, buf, vid_to_vdi_oid(vid), s->inode.nr_copies, SD_INODE_SIZE, 0, s->cache_enabled); closesocket(fd); if (ret) { goto out; } memcpy(&s->inode, buf, sizeof(s->inode)); if (!s->inode.vm_state_size) { error_report("Invalid snapshot"); ret = -ENOENT; goto out; } s->is_snapshot = true; g_free(buf); g_free(old_s); return 0; out: /* recover bdrv_sd_state */ memcpy(s, old_s, sizeof(BDRVSheepdogState)); g_free(buf); g_free(old_s); error_report("failed to open. recover old bdrv_sd_state."); return ret; }


static void ehci_advance_state(EHCIState *ehci, int async) { EHCIQueue *q = NULL; int again; int iter = 0; do { if (ehci_get_state(ehci, async) == EST_FETCHQH) { iter++; /* if we are roaming a lot of QH without executing a qTD * something is wrong with the linked list. TO-DO: why is * this hack needed? */ assert(iter < MAX_ITERATIONS); #if 0 if (iter > MAX_ITERATIONS) { DPRINTF("\n*** advance_state: bailing on MAX ITERATIONS***\n"); ehci_set_state(ehci, async, EST_ACTIVE); break; } #endif } switch(ehci_get_state(ehci, async)) { case EST_WAITLISTHEAD: again = ehci_state_waitlisthead(ehci, async); break; case EST_FETCHENTRY: again = ehci_state_fetchentry(ehci, async); break; case EST_FETCHQH: q = ehci_state_fetchqh(ehci, async); again = q ? 1 : 0; break; case EST_FETCHITD: again = ehci_state_fetchitd(ehci, async); break; case EST_FETCHSITD: again = ehci_state_fetchsitd(ehci, async); break; case EST_ADVANCEQUEUE: again = ehci_state_advqueue(q, async); break; case EST_FETCHQTD: again = ehci_state_fetchqtd(q, async); break; case EST_HORIZONTALQH: again = ehci_state_horizqh(q, async); break; case EST_EXECUTE: iter = 0; again = ehci_state_execute(q, async); break; case EST_EXECUTING: assert(q != NULL); again = ehci_state_executing(q, async); break; case EST_WRITEBACK: assert(q != NULL); again = ehci_state_writeback(q, async); break; default: fprintf(stderr, "Bad state!\n"); again = -1; assert(0); break; } if (again < 0) { fprintf(stderr, "processing error - resetting ehci HC\n"); ehci_reset(ehci); again = 0; } } while (again); ehci_commit_interrupt(ehci); }


static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int field_based, int bottom_field, int field_select, uint8_t **ref_picture, h264_chroma_mc_func *pix_op, int motion_x, int motion_y, int h, int mb_y) { uint8_t *ptr_y, *ptr_cb, *ptr_cr; int mx, my, src_x, src_y, uvsrc_x, uvsrc_y, uvlinesize, linesize, sx, sy, uvsx, uvsy; const int lowres = s->avctx->lowres; const int op_index = FFMIN(lowres-1+s->chroma_x_shift, 2); const int block_s = 8>>lowres; const int s_mask = (2 << lowres) - 1; const int h_edge_pos = s->h_edge_pos >> lowres; const int v_edge_pos = s->v_edge_pos >> lowres; linesize = s->current_picture.f.linesize[0] << field_based; uvlinesize = s->current_picture.f.linesize[1] << field_based; // FIXME obviously not perfect but qpel will not work in lowres anyway if (s->quarter_sample) { motion_x /= 2; motion_y /= 2; } if(field_based){ motion_y += (bottom_field - field_select)*((1 << lowres)-1); } sx = motion_x & s_mask; sy = motion_y & s_mask; src_x = s->mb_x * 2 * block_s + (motion_x >> lowres + 1); src_y = (mb_y * 2 * block_s >> field_based) + (motion_y >> lowres + 1); if (s->out_format == FMT_H263) { uvsx = ((motion_x >> 1) & s_mask) | (sx & 1); uvsy = ((motion_y >> 1) & s_mask) | (sy & 1); uvsrc_x = src_x >> 1; uvsrc_y = src_y >> 1; } else if (s->out_format == FMT_H261) { // even chroma mv's are full pel in H261 mx = motion_x / 4; my = motion_y / 4; uvsx = (2 * mx) & s_mask; uvsy = (2 * my) & s_mask; uvsrc_x = s->mb_x * block_s + (mx >> lowres); uvsrc_y = mb_y * block_s + (my >> lowres); } else { if(s->chroma_y_shift){ mx = motion_x / 2; my = motion_y / 2; uvsx = mx & s_mask; uvsy = my & s_mask; uvsrc_x = s->mb_x * block_s + (mx >> lowres + 1); uvsrc_y = (mb_y * block_s >> field_based) + (my >> lowres + 1); } else { if(s->chroma_x_shift){ //Chroma422 mx = motion_x / 2; uvsx = mx & s_mask; uvsy = motion_y & s_mask; uvsrc_y = src_y; uvsrc_x = s->mb_x*block_s + (mx >> (lowres+1)); } else { //Chroma444 uvsx = motion_x & s_mask; uvsy = motion_y & s_mask; uvsrc_x = src_x; uvsrc_y = src_y; } } } ptr_y = ref_picture[0] + src_y * linesize + src_x; ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; if ((unsigned) src_x > FFMAX( h_edge_pos - (!!sx) - 2 * block_s, 0) || uvsrc_y<0 || (unsigned) src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) { s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, linesize >> field_based, 17, 17 + field_based, src_x, src_y << field_based, h_edge_pos, v_edge_pos); ptr_y = s->edge_emu_buffer; if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) { uint8_t *uvbuf = s->edge_emu_buffer + 18 * s->linesize; s->vdsp.emulated_edge_mc(uvbuf , ptr_cb, uvlinesize >> field_based, 9, 9 + field_based, uvsrc_x, uvsrc_y << field_based, h_edge_pos >> 1, v_edge_pos >> 1); s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr, uvlinesize >> field_based, 9, 9 + field_based, uvsrc_x, uvsrc_y << field_based, h_edge_pos >> 1, v_edge_pos >> 1); ptr_cb = uvbuf; ptr_cr = uvbuf + 16; } } // FIXME use this for field pix too instead of the obnoxious hack which changes picture.f.data if (bottom_field) { dest_y += s->linesize; dest_cb += s->uvlinesize; dest_cr += s->uvlinesize; } if (field_select) { ptr_y += s->linesize; ptr_cb += s->uvlinesize; ptr_cr += s->uvlinesize; } sx = (sx << 2) >> lowres; sy = (sy << 2) >> lowres; pix_op[lowres - 1](dest_y, ptr_y, linesize, h, sx, sy); if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) { int hc = s->chroma_y_shift ? (h+1-bottom_field)>>1 : h; uvsx = (uvsx << 2) >> lowres; uvsy = (uvsy << 2) >> lowres; if (hc) { pix_op[op_index](dest_cb, ptr_cb, uvlinesize, hc, uvsx, uvsy); pix_op[op_index](dest_cr, ptr_cr, uvlinesize, hc, uvsx, uvsy); } } // FIXME h261 lowres loop filter }


static bool run_poll_handlers_once(AioContext *ctx) { bool progress = false; AioHandler *node; QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) { if (!node->deleted && node->io_poll && aio_node_check(ctx, node->is_external) && node->io_poll(node->opaque)) { progress = true; } /* Caller handles freeing deleted nodes. Don't do it here. */ } return progress; }


print_insn_ppi (int field_b, struct disassemble_info *info) { static const char *sx_tab[] = { "x0", "x1", "a0", "a1" }; static const char *sy_tab[] = { "y0", "y1", "m0", "m1" }; fprintf_ftype fprintf_fn = info->fprintf_func; void *stream = info->stream; unsigned int nib1, nib2, nib3; unsigned int altnib1, nib4; const char *dc = NULL; const sh_opcode_info *op; if ((field_b & 0xe800) == 0) { fprintf_fn (stream, "psh%c\t#%d,", field_b & 0x1000 ? 'a' : 'l', (field_b >> 4) & 127); print_dsp_reg (field_b & 0xf, fprintf_fn, stream); return; } if ((field_b & 0xc000) == 0x4000 && (field_b & 0x3000) != 0x1000) { static const char *du_tab[] = { "x0", "y0", "a0", "a1" }; static const char *se_tab[] = { "x0", "x1", "y0", "a1" }; static const char *sf_tab[] = { "y0", "y1", "x0", "a1" }; static const char *sg_tab[] = { "m0", "m1", "a0", "a1" }; if (field_b & 0x2000) { fprintf_fn (stream, "p%s %s,%s,%s\t", (field_b & 0x1000) ? "add" : "sub", sx_tab[(field_b >> 6) & 3], sy_tab[(field_b >> 4) & 3], du_tab[(field_b >> 0) & 3]); } else if ((field_b & 0xf0) == 0x10 && info->mach != bfd_mach_sh_dsp && info->mach != bfd_mach_sh3_dsp) { fprintf_fn (stream, "pclr %s \t", du_tab[(field_b >> 0) & 3]); } else if ((field_b & 0xf3) != 0) { fprintf_fn (stream, ".word 0x%x\t", field_b); } fprintf_fn (stream, "pmuls%c%s,%s,%s", field_b & 0x2000 ? ' ' : '\t', se_tab[(field_b >> 10) & 3], sf_tab[(field_b >> 8) & 3], sg_tab[(field_b >> 2) & 3]); return; } nib1 = PPIC; nib2 = field_b >> 12 & 0xf; nib3 = field_b >> 8 & 0xf; nib4 = field_b >> 4 & 0xf; switch (nib3 & 0x3) { case 0: dc = ""; nib1 = PPI3; break; case 1: dc = ""; break; case 2: dc = "dct "; nib3 -= 1; break; case 3: dc = "dcf "; nib3 -= 2; break; } if (nib1 == PPI3) altnib1 = PPI3NC; else altnib1 = nib1; for (op = sh_table; op->name; op++) { if ((op->nibbles[1] == nib1 || op->nibbles[1] == altnib1) && op->nibbles[2] == nib2 && op->nibbles[3] == nib3) { int n; switch (op->nibbles[4]) { case HEX_0: break; case HEX_XX00: if ((nib4 & 3) != 0) continue; break; case HEX_1: if ((nib4 & 3) != 1) continue; break; case HEX_00YY: if ((nib4 & 0xc) != 0) continue; break; case HEX_4: if ((nib4 & 0xc) != 4) continue; break; default: abort (); } fprintf_fn (stream, "%s%s\t", dc, op->name); for (n = 0; n < 3 && op->arg[n] != A_END; n++) { if (n && op->arg[1] != A_END) fprintf_fn (stream, ","); switch (op->arg[n]) { case DSP_REG_N: print_dsp_reg (field_b & 0xf, fprintf_fn, stream); break; case DSP_REG_X: fprintf_fn (stream, sx_tab[(field_b >> 6) & 3]); break; case DSP_REG_Y: fprintf_fn (stream, sy_tab[(field_b >> 4) & 3]); break; case A_MACH: fprintf_fn (stream, "mach"); break; case A_MACL: fprintf_fn (stream, "macl"); break; default: abort (); } } return; } } /* Not found. */ fprintf_fn (stream, ".word 0x%x", field_b); }


static int monitor_parse(const char *devname) { static int index = 0; char label[32]; if (strcmp(devname, "none") == 0) return 0; if (index == MAX_MONITOR_DEVICES) { fprintf(stderr, "qemu: too many monitor devices\n"); exit(1); } if (index == 0) { snprintf(label, sizeof(label), "monitor"); } else { snprintf(label, sizeof(label), "monitor%d", index); } monitor_hds[index] = qemu_chr_open(label, devname, NULL); if (!monitor_hds[index]) { fprintf(stderr, "qemu: could not open monitor device '%s'\n", devname); return -1; } index++; return 0; }


void ppc_store_sdr1(CPUPPCState *env, target_ulong value) { qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value); assert(!env->external_htab); env->spr[SPR_SDR1] = value; #if defined(TARGET_PPC64) if (env->mmu_model & POWERPC_MMU_64) { PowerPCCPU *cpu = ppc_env_get_cpu(env); Error *local_err = NULL; ppc_hash64_set_sdr1(cpu, value, &local_err); if (local_err) { error_report_err(local_err); error_free(local_err); } } else #endif /* defined(TARGET_PPC64) */ { /* FIXME: Should check for valid HTABMASK values */ env->htab_mask = ((value & SDR_32_HTABMASK) << 16) | 0xFFFF; env->htab_base = value & SDR_32_HTABORG; } }


static av_always_inline void idct_internal(uint8_t *dst, DCTELEM *block, int stride, int block_stride, int shift, int add){ int i; uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; block[0] += 1<<(shift-1); for(i=0; i<4; i++){ const int z0= block[0 + block_stride*i] + block[2 + block_stride*i]; const int z1= block[0 + block_stride*i] - block[2 + block_stride*i]; const int z2= (block[1 + block_stride*i]>>1) - block[3 + block_stride*i]; const int z3= block[1 + block_stride*i] + (block[3 + block_stride*i]>>1); block[0 + block_stride*i]= z0 + z3; block[1 + block_stride*i]= z1 + z2; block[2 + block_stride*i]= z1 - z2; block[3 + block_stride*i]= z0 - z3; } for(i=0; i<4; i++){ const int z0= block[i + block_stride*0] + block[i + block_stride*2]; const int z1= block[i + block_stride*0] - block[i + block_stride*2]; const int z2= (block[i + block_stride*1]>>1) - block[i + block_stride*3]; const int z3= block[i + block_stride*1] + (block[i + block_stride*3]>>1); dst[i + 0*stride]= cm[ add*dst[i + 0*stride] + ((z0 + z3) >> shift) ]; dst[i + 1*stride]= cm[ add*dst[i + 1*stride] + ((z1 + z2) >> shift) ]; dst[i + 2*stride]= cm[ add*dst[i + 2*stride] + ((z1 - z2) >> shift) ]; dst[i + 3*stride]= cm[ add*dst[i + 3*stride] + ((z0 - z3) >> shift) ]; } }


static int mp_dacl_removexattr(FsContext *ctx, const char *path, const char *name) { int ret; char buffer[PATH_MAX]; ret = lremovexattr(rpath(ctx, path, buffer), MAP_ACL_DEFAULT); if (ret == -1 && errno == ENODATA) { /* * We don't get ENODATA error when trying to remove a * posix acl that is not present. So don't throw the error * even in case of mapped security model */ errno = 0; ret = 0; } return ret; }


void *qemu_thread_join(QemuThread *thread) { QemuThreadData *data; void *ret; HANDLE handle; data = thread->data; if (!data) { return NULL; } /* * Because multiple copies of the QemuThread can exist via * qemu_thread_get_self, we need to store a value that cannot * leak there. The simplest, non racy way is to store the TID, * discard the handle that _beginthreadex gives back, and * get another copy of the handle here. */ EnterCriticalSection(&data->cs); if (!data->exited) { handle = OpenThread(SYNCHRONIZE, FALSE, thread->tid); LeaveCriticalSection(&data->cs); WaitForSingleObject(handle, INFINITE); CloseHandle(handle); } else { LeaveCriticalSection(&data->cs); } ret = data->ret; DeleteCriticalSection(&data->cs); g_free(data); return ret; }


void OPPROTO op_sti(void) { raise_exception(EXCP0D_GPF); }


static void test_pci_spec(void) { AHCIQState *ahci; ahci = ahci_boot(); ahci_test_pci_spec(ahci); ahci_shutdown(ahci); }


static uint32_t nvdimm_rw_label_data_check(NVDIMMDevice *nvdimm, uint32_t offset, uint32_t length) { uint32_t ret = 3 /* Invalid Input Parameters */; if (offset + length < offset) { nvdimm_debug("offset %#x + length %#x is overflow.\n", offset, length); return ret; } if (nvdimm->label_size < offset + length) { nvdimm_debug("position %#x is beyond label data (len = %" PRIx64 ").\n", offset + length, nvdimm->label_size); return ret; } if (length > nvdimm_get_max_xfer_label_size()) { nvdimm_debug("length (%#x) is larger than max_xfer (%#x).\n", length, nvdimm_get_max_xfer_label_size()); return ret; } return 0 /* Success */; }


static inline void gen_evmwumia(DisasContext *ctx) { TCGv_i64 tmp; if (unlikely(!ctx->spe_enabled)) { gen_exception(ctx, POWERPC_EXCP_APU); return; } gen_evmwumi(ctx); /* rD := rA * rB */ tmp = tcg_temp_new_i64(); /* acc := rD */ gen_load_gpr64(tmp, rD(ctx->opcode)); tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc)); tcg_temp_free_i64(tmp); }


QmpInputVisitor *qmp_input_visitor_new(QObject *obj, bool strict) { QmpInputVisitor *v; v = g_malloc0(sizeof(*v)); v->visitor.type = VISITOR_INPUT; v->visitor.start_struct = qmp_input_start_struct; v->visitor.end_struct = qmp_input_end_struct; v->visitor.start_list = qmp_input_start_list; v->visitor.next_list = qmp_input_next_list; v->visitor.end_list = qmp_input_end_list; v->visitor.start_alternate = qmp_input_start_alternate; v->visitor.type_int64 = qmp_input_type_int64; v->visitor.type_uint64 = qmp_input_type_uint64; v->visitor.type_bool = qmp_input_type_bool; v->visitor.type_str = qmp_input_type_str; v->visitor.type_number = qmp_input_type_number; v->visitor.type_any = qmp_input_type_any; v->visitor.optional = qmp_input_optional; v->strict = strict; qmp_input_push(v, obj, NULL); qobject_incref(obj); return v; }


static int mxf_parse_index(MXFContext *mxf, int track_id, AVStream *st) { int64_t accumulated_offset = 0; int j, k, ret, nb_sorted_segments; MXFIndexTableSegment **sorted_segments; int n_delta = track_id - 1; /* TrackID = 1-based stream index */ if (track_id < 1) { av_log(mxf->fc, AV_LOG_ERROR, "TrackID not positive: %i\n", track_id); return AVERROR_INVALIDDATA; } if ((ret = mxf_get_sorted_table_segments(mxf, &nb_sorted_segments, &sorted_segments))) return ret; for (j = 0; j < nb_sorted_segments; j++) { int duration, sample_duration = 1, last_sample_size = 0; int64_t segment_size; MXFIndexTableSegment *tableseg = sorted_segments[j]; /* reset accumulated_offset on BodySID change */ if (j > 0 && tableseg->body_sid != sorted_segments[j-1]->body_sid) accumulated_offset = 0; if (n_delta >= tableseg->nb_delta_entries && st->index != 0) continue; duration = tableseg->index_duration > 0 ? tableseg->index_duration : st->duration - st->nb_index_entries; segment_size = tableseg->edit_unit_byte_count * duration; /* check small EditUnitByteCount for audio */ if (tableseg->edit_unit_byte_count && tableseg->edit_unit_byte_count < 32 && !tableseg->index_duration) { /* duration might be prime relative to the new sample_duration, * which means we need to handle the last frame differently */ sample_duration = 8192; last_sample_size = (duration % sample_duration) * tableseg->edit_unit_byte_count; tableseg->edit_unit_byte_count *= sample_duration; duration /= sample_duration; if (last_sample_size) duration++; } for (k = 0; k < duration; k++) { int64_t pos; int size, flags = 0; if (k < tableseg->nb_index_entries) { pos = tableseg->stream_offset_entries[k]; if (n_delta < tableseg->nb_delta_entries) { if (n_delta < tableseg->nb_delta_entries - 1) { size = tableseg->slice_offset_entries[k][tableseg->slice[n_delta+1]-1] + tableseg->element_delta[n_delta+1] - tableseg->element_delta[n_delta]; if (tableseg->slice[n_delta] > 0) size -= tableseg->slice_offset_entries[k][tableseg->slice[n_delta]-1]; } else if (k < duration - 1) { size = tableseg->stream_offset_entries[k+1] - tableseg->stream_offset_entries[k] - tableseg->slice_offset_entries[k][tableseg->slice[tableseg->nb_delta_entries-1]-1] - tableseg->element_delta[tableseg->nb_delta_entries-1]; } else size = 0; if (tableseg->slice[n_delta] > 0) pos += tableseg->slice_offset_entries[k][tableseg->slice[n_delta]-1]; pos += tableseg->element_delta[n_delta]; } else size = 0; flags = !(tableseg->flag_entries[k] & 0x30) ? AVINDEX_KEYFRAME : 0; } else { pos = (int64_t)k * tableseg->edit_unit_byte_count + accumulated_offset; if (n_delta < tableseg->nb_delta_entries - 1) size = tableseg->element_delta[n_delta+1] - tableseg->element_delta[n_delta]; else { /* use smaller size for last sample if we should */ if (last_sample_size && k == duration - 1) size = last_sample_size; else size = tableseg->edit_unit_byte_count; if (tableseg->nb_delta_entries) size -= tableseg->element_delta[tableseg->nb_delta_entries-1]; } if (n_delta < tableseg->nb_delta_entries) pos += tableseg->element_delta[n_delta]; flags = AVINDEX_KEYFRAME; } if (mxf_absolute_bodysid_offset(mxf, tableseg->body_sid, pos, &pos) < 0) { /* probably partial file - no point going further for this stream */ break; } av_dlog(mxf->fc, "Stream %d IndexEntry %d TrackID %d Offset %"PRIx64" Timestamp %"PRId64"\n", st->index, st->nb_index_entries, track_id, pos, sample_duration * st->nb_index_entries); if ((ret = av_add_index_entry(st, pos, sample_duration * st->nb_index_entries, size, 0, flags)) < 0) return ret; } accumulated_offset += segment_size; } av_free(sorted_segments); return 0; }


static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, const HEVCContext *h, DXVA_PicParams_HEVC *pp) { const HEVCFrame *current_picture = h->ref; int i, j, k; memset(pp, 0, sizeof(*pp)); pp->PicWidthInMinCbsY = h->sps->min_cb_width; pp->PicHeightInMinCbsY = h->sps->min_cb_height; pp->wFormatAndSequenceInfoFlags = (h->sps->chroma_format_idc << 0) | (h->sps->separate_colour_plane_flag << 2) | ((h->sps->bit_depth - 8) << 3) | ((h->sps->bit_depth - 8) << 6) | ((h->sps->log2_max_poc_lsb - 4) << 9) | (0 << 13) | (0 << 14) | (0 << 15); fill_picture_entry(&pp->CurrPic, ff_dxva2_get_surface_index(avctx, ctx, current_picture->frame), 0); pp->sps_max_dec_pic_buffering_minus1 = h->sps->temporal_layer[h->sps->max_sub_layers - 1].max_dec_pic_buffering - 1; pp->log2_min_luma_coding_block_size_minus3 = h->sps->log2_min_cb_size - 3; pp->log2_diff_max_min_luma_coding_block_size = h->sps->log2_diff_max_min_coding_block_size; pp->log2_min_transform_block_size_minus2 = h->sps->log2_min_tb_size - 2; pp->log2_diff_max_min_transform_block_size = h->sps->log2_max_trafo_size - h->sps->log2_min_tb_size; pp->max_transform_hierarchy_depth_inter = h->sps->max_transform_hierarchy_depth_inter; pp->max_transform_hierarchy_depth_intra = h->sps->max_transform_hierarchy_depth_intra; pp->num_short_term_ref_pic_sets = h->sps->nb_st_rps; pp->num_long_term_ref_pics_sps = h->sps->num_long_term_ref_pics_sps; pp->num_ref_idx_l0_default_active_minus1 = h->pps->num_ref_idx_l0_default_active - 1; pp->num_ref_idx_l1_default_active_minus1 = h->pps->num_ref_idx_l1_default_active - 1; pp->init_qp_minus26 = h->pps->pic_init_qp_minus26; if (h->sh.short_term_ref_pic_set_sps_flag == 0 && h->sh.short_term_rps) { pp->ucNumDeltaPocsOfRefRpsIdx = h->sh.short_term_rps->num_delta_pocs; pp->wNumBitsForShortTermRPSInSlice = h->sh.short_term_ref_pic_set_size; } pp->dwCodingParamToolFlags = (h->sps->scaling_list_enable_flag << 0) | (h->sps->amp_enabled_flag << 1) | (h->sps->sao_enabled << 2) | (h->sps->pcm_enabled_flag << 3) | ((h->sps->pcm_enabled_flag ? (h->sps->pcm.bit_depth - 1) : 0) << 4) | ((h->sps->pcm_enabled_flag ? (h->sps->pcm.bit_depth_chroma - 1) : 0) << 8) | ((h->sps->pcm_enabled_flag ? (h->sps->pcm.log2_min_pcm_cb_size - 3) : 0) << 12) | ((h->sps->pcm_enabled_flag ? (h->sps->pcm.log2_max_pcm_cb_size - h->sps->pcm.log2_min_pcm_cb_size) : 0) << 14) | (h->sps->pcm.loop_filter_disable_flag << 16) | (h->sps->long_term_ref_pics_present_flag << 17) | (h->sps->sps_temporal_mvp_enabled_flag << 18) | (h->sps->sps_strong_intra_smoothing_enable_flag << 19) | (h->pps->dependent_slice_segments_enabled_flag << 20) | (h->pps->output_flag_present_flag << 21) | (h->pps->num_extra_slice_header_bits << 22) | (h->pps->sign_data_hiding_flag << 25) | (h->pps->cabac_init_present_flag << 26) | (0 << 27); pp->dwCodingSettingPicturePropertyFlags = (h->pps->constrained_intra_pred_flag << 0) | (h->pps->transform_skip_enabled_flag << 1) | (h->pps->cu_qp_delta_enabled_flag << 2) | (h->pps->pic_slice_level_chroma_qp_offsets_present_flag << 3) | (h->pps->weighted_pred_flag << 4) | (h->pps->weighted_bipred_flag << 5) | (h->pps->transquant_bypass_enable_flag << 6) | (h->pps->tiles_enabled_flag << 7) | (h->pps->entropy_coding_sync_enabled_flag << 8) | (h->pps->uniform_spacing_flag << 9) | ((h->pps->tiles_enabled_flag ? h->pps->loop_filter_across_tiles_enabled_flag : 0) << 10) | (h->pps->seq_loop_filter_across_slices_enabled_flag << 11) | (h->pps->deblocking_filter_override_enabled_flag << 12) | (h->pps->disable_dbf << 13) | (h->pps->lists_modification_present_flag << 14) | (h->pps->slice_header_extension_present_flag << 15) | (IS_IRAP(h) << 16) | (IS_IDR(h) << 17) | /* IntraPicFlag */ (IS_IRAP(h) << 18) | (0 << 19); pp->pps_cb_qp_offset = h->pps->cb_qp_offset; pp->pps_cr_qp_offset = h->pps->cr_qp_offset; if (h->pps->tiles_enabled_flag) { pp->num_tile_columns_minus1 = h->pps->num_tile_columns - 1; pp->num_tile_rows_minus1 = h->pps->num_tile_rows - 1; if (!h->pps->uniform_spacing_flag) { for (i = 0; i < h->pps->num_tile_columns; i++) pp->column_width_minus1[i] = h->pps->column_width[i] - 1; for (i = 0; i < h->pps->num_tile_rows; i++) pp->row_height_minus1[i] = h->pps->row_height[i] - 1; } } pp->diff_cu_qp_delta_depth = h->pps->diff_cu_qp_delta_depth; pp->pps_beta_offset_div2 = h->pps->beta_offset / 2; pp->pps_tc_offset_div2 = h->pps->tc_offset / 2; pp->log2_parallel_merge_level_minus2 = h->pps->log2_parallel_merge_level - 2; pp->CurrPicOrderCntVal = h->poc; // empty the lists memset(&pp->RefPicList, 0xff, sizeof(pp->RefPicList)); memset(&pp->RefPicSetStCurrBefore, 0xff, sizeof(pp->RefPicSetStCurrBefore)); memset(&pp->RefPicSetStCurrAfter, 0xff, sizeof(pp->RefPicSetStCurrAfter)); memset(&pp->RefPicSetLtCurr, 0xff, sizeof(pp->RefPicSetLtCurr)); // fill RefPicList from the DPB for (i = 0, j = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) { const HEVCFrame *frame = &h->DPB[i]; if (frame != current_picture && (frame->flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) { fill_picture_entry(&pp->RefPicList[j], ff_dxva2_get_surface_index(avctx, ctx, frame->frame), !!(frame->flags & HEVC_FRAME_FLAG_LONG_REF)); pp->PicOrderCntValList[j] = frame->poc; j++; } } #define DO_REF_LIST(ref_idx, ref_list) { \ const RefPicList *rpl = &h->rps[ref_idx]; \ av_assert0(rpl->nb_refs <= FF_ARRAY_ELEMS(pp->ref_list)); \ for (j = 0, k = 0; j < rpl->nb_refs; j++) { \ if (rpl->ref[j]) { \ pp->ref_list[k] = get_refpic_index(pp, ff_dxva2_get_surface_index(avctx, ctx, rpl->ref[j]->frame)); \ k++; \ } \ } \ } // Fill short term and long term lists DO_REF_LIST(ST_CURR_BEF, RefPicSetStCurrBefore); DO_REF_LIST(ST_CURR_AFT, RefPicSetStCurrAfter); DO_REF_LIST(LT_CURR, RefPicSetLtCurr); pp->StatusReportFeedbackNumber = 1 + DXVA_CONTEXT_REPORT_ID(avctx, ctx)++; }


static void isa_ipmi_bmc_check(Object *obj, const char *name, Object *val, Error **errp) { IPMIBmc *bmc = IPMI_BMC(val); if (bmc->intf) error_setg(errp, "BMC object is already in use"); }


av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int fullRange, int brightness, int contrast, int saturation) { const int isRgb = c->dstFormat == AV_PIX_FMT_RGB32 || c->dstFormat == AV_PIX_FMT_RGB32_1 || c->dstFormat == AV_PIX_FMT_BGR24 || c->dstFormat == AV_PIX_FMT_RGB565BE || c->dstFormat == AV_PIX_FMT_RGB565LE || c->dstFormat == AV_PIX_FMT_RGB555BE || c->dstFormat == AV_PIX_FMT_RGB555LE || c->dstFormat == AV_PIX_FMT_RGB444BE || c->dstFormat == AV_PIX_FMT_RGB444LE || c->dstFormat == AV_PIX_FMT_RGB8 || c->dstFormat == AV_PIX_FMT_RGB4 || c->dstFormat == AV_PIX_FMT_RGB4_BYTE || c->dstFormat == AV_PIX_FMT_MONOBLACK; const int isNotNe = c->dstFormat == AV_PIX_FMT_NE(RGB565LE, RGB565BE) || c->dstFormat == AV_PIX_FMT_NE(RGB555LE, RGB555BE) || c->dstFormat == AV_PIX_FMT_NE(RGB444LE, RGB444BE) || c->dstFormat == AV_PIX_FMT_NE(BGR565LE, BGR565BE) || c->dstFormat == AV_PIX_FMT_NE(BGR555LE, BGR555BE) || c->dstFormat == AV_PIX_FMT_NE(BGR444LE, BGR444BE); const int bpp = c->dstFormatBpp; uint8_t *y_table; uint16_t *y_table16; uint32_t *y_table32; int i, base, rbase, gbase, bbase, av_uninit(abase), needAlpha; const int yoffs = fullRange ? 384 : 326; int64_t crv = inv_table[0]; int64_t cbu = inv_table[1]; int64_t cgu = -inv_table[2]; int64_t cgv = -inv_table[3]; int64_t cy = 1 << 16; int64_t oy = 0; int64_t yb = 0; if (!fullRange) { cy = (cy * 255) / 219; oy = 16 << 16; } else { crv = (crv * 224) / 255; cbu = (cbu * 224) / 255; cgu = (cgu * 224) / 255; cgv = (cgv * 224) / 255; } cy = (cy * contrast) >> 16; crv = (crv * contrast * saturation) >> 32; cbu = (cbu * contrast * saturation) >> 32; cgu = (cgu * contrast * saturation) >> 32; cgv = (cgv * contrast * saturation) >> 32; oy -= 256 * brightness; c->uOffset = 0x0400040004000400LL; c->vOffset = 0x0400040004000400LL; c->yCoeff = roundToInt16(cy * 8192) * 0x0001000100010001ULL; c->vrCoeff = roundToInt16(crv * 8192) * 0x0001000100010001ULL; c->ubCoeff = roundToInt16(cbu * 8192) * 0x0001000100010001ULL; c->vgCoeff = roundToInt16(cgv * 8192) * 0x0001000100010001ULL; c->ugCoeff = roundToInt16(cgu * 8192) * 0x0001000100010001ULL; c->yOffset = roundToInt16(oy * 8) * 0x0001000100010001ULL; c->yuv2rgb_y_coeff = (int16_t)roundToInt16(cy << 13); c->yuv2rgb_y_offset = (int16_t)roundToInt16(oy << 9); c->yuv2rgb_v2r_coeff = (int16_t)roundToInt16(crv << 13); c->yuv2rgb_v2g_coeff = (int16_t)roundToInt16(cgv << 13); c->yuv2rgb_u2g_coeff = (int16_t)roundToInt16(cgu << 13); c->yuv2rgb_u2b_coeff = (int16_t)roundToInt16(cbu << 13); //scale coefficients by cy crv = ((crv << 16) + 0x8000) / cy; cbu = ((cbu << 16) + 0x8000) / cy; cgu = ((cgu << 16) + 0x8000) / cy; cgv = ((cgv << 16) + 0x8000) / cy; av_freep(&c->yuvTable); switch (bpp) { case 1: c->yuvTable = av_malloc(1024); y_table = c->yuvTable; yb = -(384 << 16) - oy; for (i = 0; i < 1024 - 110; i++) { y_table[i + 110] = av_clip_uint8((yb + 0x8000) >> 16) >> 7; yb += cy; } fill_table(c->table_gU, 1, cgu, y_table + yoffs); fill_gv_table(c->table_gV, 1, cgv); break; case 4: case 4 | 128: rbase = isRgb ? 3 : 0; gbase = 1; bbase = isRgb ? 0 : 3; c->yuvTable = av_malloc(1024 * 3); y_table = c->yuvTable; yb = -(384 << 16) - oy; for (i = 0; i < 1024 - 110; i++) { int yval = av_clip_uint8((yb + 0x8000) >> 16); y_table[i + 110] = (yval >> 7) << rbase; y_table[i + 37 + 1024] = ((yval + 43) / 85) << gbase; y_table[i + 110 + 2048] = (yval >> 7) << bbase; yb += cy; } fill_table(c->table_rV, 1, crv, y_table + yoffs); fill_table(c->table_gU, 1, cgu, y_table + yoffs + 1024); fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048); fill_gv_table(c->table_gV, 1, cgv); break; case 8: rbase = isRgb ? 5 : 0; gbase = isRgb ? 2 : 3; bbase = isRgb ? 0 : 6; c->yuvTable = av_malloc(1024 * 3); y_table = c->yuvTable; yb = -(384 << 16) - oy; for (i = 0; i < 1024 - 38; i++) { int yval = av_clip_uint8((yb + 0x8000) >> 16); y_table[i + 16] = ((yval + 18) / 36) << rbase; y_table[i + 16 + 1024] = ((yval + 18) / 36) << gbase; y_table[i + 37 + 2048] = ((yval + 43) / 85) << bbase; yb += cy; } fill_table(c->table_rV, 1, crv, y_table + yoffs); fill_table(c->table_gU, 1, cgu, y_table + yoffs + 1024); fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048); fill_gv_table(c->table_gV, 1, cgv); break; case 12: rbase = isRgb ? 8 : 0; gbase = 4; bbase = isRgb ? 0 : 8; c->yuvTable = av_malloc(1024 * 3 * 2); y_table16 = c->yuvTable; yb = -(384 << 16) - oy; for (i = 0; i < 1024; i++) { uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16); y_table16[i] = (yval >> 4) << rbase; y_table16[i + 1024] = (yval >> 4) << gbase; y_table16[i + 2048] = (yval >> 4) << bbase; yb += cy; } if (isNotNe) for (i = 0; i < 1024 * 3; i++) y_table16[i] = av_bswap16(y_table16[i]); fill_table(c->table_rV, 2, crv, y_table16 + yoffs); fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + 1024); fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2048); fill_gv_table(c->table_gV, 2, cgv); break; case 15: case 16: rbase = isRgb ? bpp - 5 : 0; gbase = 5; bbase = isRgb ? 0 : (bpp - 5); c->yuvTable = av_malloc(1024 * 3 * 2); y_table16 = c->yuvTable; yb = -(384 << 16) - oy; for (i = 0; i < 1024; i++) { uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16); y_table16[i] = (yval >> 3) << rbase; y_table16[i + 1024] = (yval >> (18 - bpp)) << gbase; y_table16[i + 2048] = (yval >> 3) << bbase; yb += cy; } if (isNotNe) for (i = 0; i < 1024 * 3; i++) y_table16[i] = av_bswap16(y_table16[i]); fill_table(c->table_rV, 2, crv, y_table16 + yoffs); fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + 1024); fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2048); fill_gv_table(c->table_gV, 2, cgv); break; case 24: case 48: c->yuvTable = av_malloc(1024); y_table = c->yuvTable; yb = -(384 << 16) - oy; for (i = 0; i < 1024; i++) { y_table[i] = av_clip_uint8((yb + 0x8000) >> 16); yb += cy; } fill_table(c->table_rV, 1, crv, y_table + yoffs); fill_table(c->table_gU, 1, cgu, y_table + yoffs); fill_table(c->table_bU, 1, cbu, y_table + yoffs); fill_gv_table(c->table_gV, 1, cgv); break; case 32: case 64: base = (c->dstFormat == AV_PIX_FMT_RGB32_1 || c->dstFormat == AV_PIX_FMT_BGR32_1) ? 8 : 0; rbase = base + (isRgb ? 16 : 0); gbase = base + 8; bbase = base + (isRgb ? 0 : 16); needAlpha = CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat); if (!needAlpha) abase = (base + 24) & 31; c->yuvTable = av_malloc(1024 * 3 * 4); y_table32 = c->yuvTable; yb = -(384 << 16) - oy; for (i = 0; i < 1024; i++) { unsigned yval = av_clip_uint8((yb + 0x8000) >> 16); y_table32[i] = (yval << rbase) + (needAlpha ? 0 : (255u << abase)); y_table32[i + 1024] = yval << gbase; y_table32[i + 2048] = yval << bbase; yb += cy; } fill_table(c->table_rV, 4, crv, y_table32 + yoffs); fill_table(c->table_gU, 4, cgu, y_table32 + yoffs + 1024); fill_table(c->table_bU, 4, cbu, y_table32 + yoffs + 2048); fill_gv_table(c->table_gV, 4, cgv); break; default: if(!isPlanar(c->dstFormat) || bpp <= 24) av_log(c, AV_LOG_ERROR, "%ibpp not supported by yuv2rgb\n", bpp); return -1; } return 0; }