static obj_t * lang_if(obj_t **frame, obj_t **tailp) { obj_t *expr = *frame_ref(frame, 0); obj_t *pred, *todo, *otherwise; *tailp = tail_token; pred = pair_car(expr); todo = pair_cadr(expr); otherwise = pair_cddr(expr); if (nullp(otherwise)) { otherwise = unspec_wrap(); } else if (!nullp(pair_cdr(otherwise))) { fatal_error("if -- too many arguments", frame); } else { otherwise = pair_car(otherwise); } { // start to evaluate the predicate. obj_t **pred_frame = frame_extend( frame, 1, FR_CONTINUE_ENV | FR_SAVE_PREV); *frame_ref(pred_frame, 0) = pred; pred = eval_frame(pred_frame); } if (to_boolean(pred)) { return todo; } else { return otherwise; } }
static obj_t * lang_define(obj_t **frame, obj_t **tailp) { obj_t *expr = *frame_ref(frame, 0); obj_t *first, *name, *result; *tailp = NULL; first = pair_car(expr); if (symbolp(first)) { // Binding an expression // XXX: check for expr length? obj_t *to_eval = pair_car(pair_cdr(expr)); // Get the value of the expression before binding. obj_t **expr_frame = frame_extend( frame, 1, FR_CONTINUE_ENV | FR_SAVE_PREV); *frame_ref(expr_frame, 0) = to_eval; result = eval_frame(expr_frame); name = first; } else if (pairp(first)) { // short hand for (define name (lambda ...)) // x: the formals, v: the body obj_t *formals, *body; name = pair_car(first); formals = pair_cdr(first); body = pair_cdr(expr); result = closure_wrap(frame, frame_env(frame), formals, body); } else { fatal_error("define -- first argument is neither a " "symbol nor a pair", frame); } environ_def(frame, frame_env(frame), name, result); return unspec_wrap(); }
static obj_t * lang_begin(obj_t **frame, obj_t **tailp) { obj_t *expr = *frame_ref(frame, 0); *tailp = tail_token; obj_t *iter; for (iter = expr; pairp(iter); iter = pair_cdr(iter)) { // Eval each expression except the last. if (!pairp(pair_cdr(iter))) { break; } obj_t **expr_frame = frame_extend(frame, 1, FR_SAVE_PREV | FR_CONTINUE_ENV); *frame_ref(expr_frame, 0) = pair_car(iter); eval_frame(expr_frame); } if (nullp(iter)) { // Empty (begin) expression return unspec_wrap(); } else if (!nullp(pair_cdr(iter))) { fatal_error("begin -- not a well-formed list", frame); } return pair_car(iter); }
static obj_t * lang_lambda(obj_t **frame, obj_t **tailp) { obj_t *expr = *frame_ref(frame, 0); *tailp = NULL; return closure_wrap(frame, frame_env(frame), pair_car(expr), pair_cdr(expr)); }
static obj_t * lang_quote(obj_t **frame, obj_t **tailp) { obj_t *expr = *frame_ref(frame, 0); *tailp = NULL; if (nullp(expr) || !nullp(pair_cdr(expr))) { fatal_error("quote -- wrong number of argument", frame); } return pair_car(expr); }
static obj_t * lang_lambda_syntax(obj_t **frame, obj_t **tailp) { obj_t *expr = *frame_ref(frame, 0); obj_t *clos; *tailp = NULL; // LOL!!! clos = closure_wrap(frame, frame_env(frame), pair_car(expr), pair_cdr(expr)); SGC_ROOT1(frame, clos); return macro_wrap(frame, clos); }
static inline void * __page_get(void) { void *hp = cos_get_vas_page(); struct frame *f = frame_alloc(); assert(hp && f); frame_ref(f); if (cos_mmap_cntl(COS_MMAP_GRANT, 0, cos_spd_id(), (vaddr_t)hp, frame_index(f))) { BUG(); } return hp; }
static obj_t * lang_quasiquote(obj_t **frame, obj_t **tailp) { obj_t *expr = *frame_ref(frame, 0); obj_t *content; *tailp = NULL; if (nullp(expr) || !nullp(pair_cdr(expr))) { fatal_error("quasiquote -- wrong number of argument", frame); } // Expand... content = pair_car(expr); return expand_quasiquote(frame, content, NULL); }
static obj_t * lang_set(obj_t **frame, obj_t **tailp) { obj_t *expr = *frame_ref(frame, 0); obj_t *first, *name, *result; *tailp = NULL; first = pair_car(expr); if (symbolp(first)) { // Binding an expression // XXX: check for expr length? obj_t *to_eval = pair_car(pair_cdr(expr)); // Get the value of the expression before binding. obj_t **expr_frame = frame_extend( frame, 1, FR_CONTINUE_ENV | FR_SAVE_PREV); *frame_ref(expr_frame, 0) = to_eval; result = eval_frame(expr_frame); name = first; } else { fatal_error("set! -- first argument is not a symbol", frame); } environ_set(frame_env(frame), name, result); return unspec_wrap(); }
bool LibAVFilterPrivate::pull(Frame *f) { AVFrameHolderRef frame_ref(new AVFrameHolder()); int ret = av_buffersink_get_frame(out_filter_ctx, frame_ref->frame()); if (ret < 0) { qWarning("av_buffersink_get_frame error: %s", av_err2str(ret)); return false; } VideoFrame vf(frame_ref->frame()->width, frame_ref->frame()->height, VideoFormat(frame_ref->frame()->format)); vf.setBits(frame_ref->frame()->data); vf.setBytesPerLine(frame_ref->frame()->linesize); vf.setMetaData("avframe_hoder_ref", QVariant::fromValue(frame_ref)); *f = vf; return true; }
static inline void * __page_get(void) { void *hp = cos_get_vas_page(); struct frame *f = frame_alloc(); assert(hp && f); frame_ref(f); f->nmaps = -1; /* belongs to us... */ f->c.addr = (vaddr_t)hp; /* ...at this address */ if (cos_mmap_cntl(COS_MMAP_GRANT, MAPPING_RW, cos_spd_id(), (vaddr_t)hp, frame_index(f))) { printc("grant @ %p for frame %d\n", hp, frame_index(f)); BUG(); } return hp; }
/* Make a child mapping */ static struct mapping * mapping_crt(struct mapping *p, struct frame *f, spdid_t dest, vaddr_t to, int flags) { struct comp_vas *cv = cvas_lookup(dest); struct mapping *m = NULL; long idx = to >> PAGE_SHIFT; assert(!p || p->f == f); assert(dest && to); /* no vas structure for this spd yet... */ if (!cv) { cv = cvas_alloc(dest); if (!cv) goto done; assert(cv == cvas_lookup(dest)); } assert(cv->pages); if (cvect_lookup(cv->pages, idx)) goto collision; cvas_ref(cv); m = cslab_alloc_mapping(); if (!m) goto collision; if (cos_mmap_cntl(COS_MMAP_GRANT, flags, dest, to, frame_index(f))) { printc("mem_man: could not grant at %x:%d\n", dest, (int)to); goto no_mapping; } mapping_init(m, dest, to, p, f); assert(!p || frame_nrefs(f) > 0); frame_ref(f); assert(frame_nrefs(f) > 0); if (cvect_add(cv->pages, m, idx)) BUG(); done: return m; no_mapping: cslab_free_mapping(m); collision: cvas_deref(cv); m = NULL; goto done; }
vaddr_t mman_get_page(spdid_t spd, vaddr_t addr, int flags) { struct frame *f; struct mapping *m = NULL; vaddr_t ret = -1; LOCK(); mm_init(); f = frame_alloc(); if (!f) goto done; /* -ENOMEM */ frame_ref(f); m = mapping_crt(NULL, f, spd, addr); if (!m) goto dealloc; assert(m->addr == addr); assert(m->spdid == spd); assert(m == mapping_lookup(spd, addr)); ret = m->addr; done: UNLOCK(); return ret; dealloc: frame_deref(f); goto done; /* -EINVAL */ }
static obj_t * expand_quasiquote(obj_t **frame, obj_t *content, enum quasiquote_return_flag *flag) { if (!pairp(content)) { return content; } // Manually compare each item with unquote/unquote-splicing obj_t *qq = symbol_quasiquote; obj_t *uq = symbol_unquote; obj_t *spl = symbol_unquote_splicing; if (pair_car(content) == qq) { if (flag) flag = QQ_DEFAULT; return content; // XXX: NESTED QQ... /* obj_t *body = pair_cadr(content); frame = frame_extend(frame, 1, FR_SAVE_PREV | FR_CONTINUE_ENV); *frame_ref(frame, 0) = content; obj_t *res = expand_quasiquote(frame, body, NULL); // nested QQ obj_t *wrap = pair_wrap(frame, res, nil_wrap()); return pair_wrap(frame, qq, wrap); */ } else if (pair_car(content) == uq) { obj_t *uq_body = pair_cadr(content); frame = frame_extend(frame, 1, FR_SAVE_PREV | FR_CONTINUE_ENV); *frame_ref(frame, 0) = uq_body; if (flag) *flag = QQ_UNQUOTE; return eval_frame(frame); } else if (pair_car(content) == spl) { obj_t *spl_body = pair_cadr(content); obj_t *retval; frame = frame_extend(frame, 1, FR_SAVE_PREV | FR_CONTINUE_ENV); *frame_ref(frame, 0) = spl_body; retval = eval_frame(frame); if (flag) *flag = QQ_SPLICING; return retval; } else { // Copy the pair content. content = pair_copy_list(frame, content); // Append a dummy header for unquote-splicing to use. content = pair_wrap(frame, nil_wrap(), content); // Mark the content. frame = frame_extend(frame, 1, FR_SAVE_PREV | FR_CONTINUE_ENV); *frame_ref(frame, 0) = content; // For linking unquote-splicing, we look at the next item of // the iterator. That's why we need a dummy header here. obj_t *iter, *next, *got; enum quasiquote_return_flag ret_flag; for (iter = content; pairp(iter); iter = pair_cdr(iter)) { // `next` will always be null or pair, since `content` is a list. loop_begin: next = pair_cdr(iter); if (nullp(next)) // we are done. break; // XXX: this is strange. why do we need to initialize it? ret_flag = QQ_DEFAULT; got = expand_quasiquote(frame, pair_car(next), &ret_flag); if (ret_flag & QQ_SPLICING) { // Special handling for unquote-splicing // WARNING: messy code below! got = pair_copy_list(frame, got); if (nullp(got)) { pair_set_cdr(iter, pair_cdr(next)); } else { pair_set_cdr(iter, got); // iter -> got while (pairp(pair_cdr(got))) { got = pair_cdr(got); } pair_set_cdr(got, pair_cdr(next)); // got -> (next->next) iter = got; // make sure the next iteration is correct goto loop_begin; // And this... } } else { // Not unquote-splicing, easy... pair_set_car(next, got); } } if (flag) *flag = QQ_DEFAULT; return pair_cdr(content); } }
int main(int argc, char** argv) { AVFormatContext* avfmt_ctx = NULL; int video_stream; enum AVCodecID video_codec; if (argc < 2) { fprintf(stderr, "Usage: %s filename\n", argv[0]); exit(EXIT_FAILURE); } char *filename = argv[1]; av_register_all(); if (avformat_open_input(&avfmt_ctx, filename, NULL, NULL) < 0) { fprintf(stderr, "Could not open source file %s\n", filename); exit(1); } if (avformat_find_stream_info(avfmt_ctx, NULL) < 0) { fprintf(stderr, "Could not find stream information\n"); avformat_close_input(&avfmt_ctx); exit(1); } video_stream = av_find_best_stream(avfmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); if (video_stream < 0) { fprintf(stderr, "Could not find video stream in input file\n"); avformat_close_input(&avfmt_ctx); exit(1); } video_codec = avfmt_ctx->streams[video_stream]->codec->codec_id; if (video_codec != AV_CODEC_ID_MPEG1VIDEO && video_codec != AV_CODEC_ID_MPEG2VIDEO) { fprintf(stderr, "Can't handle codec %s\n", avcodec_get_name(video_codec)); avformat_close_input(&avfmt_ctx); exit(1); } AVPacket pkt; av_init_packet(&pkt); pkt.data = NULL; pkt.size = 0; struct mpeg_t mpeg; memset(&mpeg, 0, sizeof(mpeg)); if (video_codec == AV_CODEC_ID_MPEG1VIDEO) mpeg.type = MPEG1; else mpeg.type = MPEG2; if (!ve_open()) err(EXIT_FAILURE, "Can't open VE"); struct frame_buffers_t frame_buffers = { NULL, NULL, NULL }; unsigned int disp_frame = 0, gop_offset = 0, gop_frames = 0, last_gop = 0; struct frame_t *frames[RING_BUFFER_SIZE]; memset(frames, 0, sizeof(frames)); // activate MPEG engine writel(ve_get_regs() + 0x00, 0x00130000); printf("Playing now... press Enter for next frame!\n"); while (av_read_frame(avfmt_ctx, &pkt) >= 0) { mpeg.data = pkt.data; mpeg.len = pkt.size; mpeg.pos = 0; if (pkt.stream_index == video_stream && parse_mpeg(&mpeg)) { // create output buffer frame_buffers.output = frame_new(mpeg.width, mpeg.height, COLOR_YUV420); if (!frame_buffers.backward) frame_buffers.backward = frame_ref(frame_buffers.output); if (!frame_buffers.forward) frame_buffers.forward = frame_ref(frame_buffers.output); // decode frame decode_mpeg(&frame_buffers, &mpeg); // simple frame reordering (not safe, only for testing) // count frames if (mpeg.gop > last_gop) { last_gop = mpeg.gop; gop_offset += gop_frames; gop_frames = 0; } gop_frames++; // save frame in ringbuffer if (frames[(gop_offset + mpeg.temporal_reference) % RING_BUFFER_SIZE] != NULL) { printf("Buffer overrun!\n"); frame_unref(frames[(gop_offset + mpeg.temporal_reference) % RING_BUFFER_SIZE]); } frames[(gop_offset + mpeg.temporal_reference) % RING_BUFFER_SIZE] = frame_buffers.output; // if we decoded a displayable frame, show it if (frames[disp_frame % RING_BUFFER_SIZE] != NULL) { frame_show(frames[disp_frame % RING_BUFFER_SIZE]); frame_unref(frames[(disp_frame - 2) % RING_BUFFER_SIZE]); frames[(disp_frame - 2) % RING_BUFFER_SIZE] = NULL; disp_frame++; getchar(); } } av_free_packet(&pkt); } // stop MPEG engine writel(ve_get_regs() + 0x0, 0x00130007); // show left over frames while (disp_frame < gop_offset + gop_frames && frames[disp_frame % RING_BUFFER_SIZE] != NULL) { frame_show(frames[disp_frame % RING_BUFFER_SIZE]); frame_unref(frames[(disp_frame - 2) % RING_BUFFER_SIZE]); frames[(disp_frame - 2) % RING_BUFFER_SIZE] = NULL; disp_frame++; getchar(); } disp_close(); frame_unref(frames[(disp_frame - 2) % RING_BUFFER_SIZE]); frame_unref(frames[(disp_frame - 1) % RING_BUFFER_SIZE]); frame_unref(frame_buffers.forward); frame_unref(frame_buffers.backward); ve_close(); avformat_close_input(&avfmt_ctx); return 0; }
void decode_mpeg(struct frame_buffers_t *frame_buffers, const struct mpeg_t * const mpeg) { int input_size = (mpeg->len + 65535) & ~65535; uint8_t *input_buffer = ve_malloc(input_size); memcpy(input_buffer, mpeg->data, mpeg->len); ve_flush_cache(input_buffer, mpeg->len); void *ve_regs = ve_get_regs(); // set quantisation tables set_quantization_tables(ve_regs, mpeg_default_intra_quant, mpeg_default_non_intra_quant); // set size uint16_t width = (mpeg->width + 15) / 16; uint16_t height = (mpeg->height + 15) / 16; writel(ve_regs + 0x100 + 0x08, (width << 8) | height); writel(ve_regs + 0x100 + 0x0c, ((width * 16) << 16) | (height * 16)); // set picture header uint32_t pic_header = 0x00000000; pic_header |= ((mpeg->picture_coding_type & 0xf) << 28); pic_header |= ((mpeg->f_code[0][0] & 0xf) << 24); pic_header |= ((mpeg->f_code[0][1] & 0xf) << 20); pic_header |= ((mpeg->f_code[1][0] & 0xf) << 16); pic_header |= ((mpeg->f_code[1][1] & 0xf) << 12); pic_header |= ((mpeg->intra_dc_precision & 0x3) << 10); pic_header |= ((mpeg->picture_structure & 0x3) << 8); pic_header |= ((mpeg->top_field_first & 0x1) << 7); pic_header |= ((mpeg->frame_pred_frame_dct & 0x1) << 6); pic_header |= ((mpeg->concealment_motion_vectors & 0x1) << 5); pic_header |= ((mpeg->q_scale_type & 0x1) << 4); pic_header |= ((mpeg->intra_vlc_format & 0x1) << 3); pic_header |= ((mpeg->alternate_scan & 0x1) << 2); pic_header |= ((mpeg->full_pel_forward_vector & 0x1) << 1); pic_header |= ((mpeg->full_pel_backward_vector & 0x1) << 0); writel(ve_regs + 0x100 + 0x00, pic_header); // ?? writel(ve_regs + 0x100 + 0x10, 0x00000000); // ?? writel(ve_regs + 0x100 + 0x14, 0x800001b8); // ?? writel(ve_regs + 0x100 + 0xc4, 0x00000000); // ?? writel(ve_regs + 0x100 + 0xc8, 0x00000000); // set forward/backward predicion buffers if (mpeg->picture_coding_type == PCT_I || mpeg->picture_coding_type == PCT_P) { frame_unref(frame_buffers->forward); frame_buffers->forward = frame_ref(frame_buffers->backward); frame_unref(frame_buffers->backward); frame_buffers->backward = frame_ref(frame_buffers->output); } writel(ve_regs + 0x100 + 0x50, ve_virt2phys(frame_buffers->forward->luma_buffer)); writel(ve_regs + 0x100 + 0x54, ve_virt2phys(frame_buffers->forward->chroma_buffer)); writel(ve_regs + 0x100 + 0x58, ve_virt2phys(frame_buffers->backward->luma_buffer)); writel(ve_regs + 0x100 + 0x5c, ve_virt2phys(frame_buffers->backward->chroma_buffer)); // set output buffers (Luma / Croma) writel(ve_regs + 0x100 + 0x48, ve_virt2phys(frame_buffers->output->luma_buffer)); writel(ve_regs + 0x100 + 0x4c, ve_virt2phys(frame_buffers->output->chroma_buffer)); writel(ve_regs + 0x100 + 0xcc, ve_virt2phys(frame_buffers->output->luma_buffer)); writel(ve_regs + 0x100 + 0xd0, ve_virt2phys(frame_buffers->output->chroma_buffer)); // set input offset in bits writel(ve_regs + 0x100 + 0x2c, (mpeg->pos - 4) * 8); // set input length in bits (+ little bit more, else it fails sometimes ??) writel(ve_regs + 0x100 + 0x30, (mpeg->len - (mpeg->pos - 4) + 16) * 8); // input end writel(ve_regs + 0x100 + 0x34, ve_virt2phys(input_buffer) + input_size - 1); // set input buffer writel(ve_regs + 0x100 + 0x28, ve_virt2phys(input_buffer) | 0x50000000); // trigger writel(ve_regs + 0x100 + 0x18, (mpeg->type ? 0x02000000 : 0x01000000) | 0x8000000f); // wait for interrupt ve_wait(1); // clean interrupt flag (??) writel(ve_regs + 0x100 + 0x1c, 0x0000c00f); ve_free(input_buffer); }