/** * Return 0 if ownership of 'data' has been transfered from caller */ static void submit_au(vdec_decoder_t *vdd, struct vdec_au *au, void *data, size_t len, int drop_non_ref, video_decoder_t *vd) { vdec_pic_t *vp; if(data != NULL && vdd->filter_aud) len = filter_aud(data, len); au->packet_addr = (intptr_t)data; au->packet_size = len; hts_mutex_lock(&vdd->mtx); vdd->submitted_au = 1; int r = vdec_decode_au(vdd->handle, drop_non_ref ? VDEC_DECODER_MODE_SKIP_NON_REF : VDEC_DECODER_MODE_NORMAL, au); if(r == 0) { while(vdd->submitted_au) { if(hts_cond_wait_timeout(&vdd->audone, &vdd->mtx, 5000)) { panic("Cell video decoder lockup"); } } } if(data == NULL) { // When we want to flush out all frames from the decoder // we just wait for them by sleeping. Lame but kinda works hts_mutex_unlock(&vdd->mtx); usleep(100000); hts_mutex_lock(&vdd->mtx); } while((vp = LIST_FIRST(&vdd->pictures)) != NULL) { // data == NULL means that we should do a complete flush if(vdd->flush_to < vp->order && data != NULL) break; LIST_REMOVE(vp, link); vdd->num_pictures--; hts_mutex_unlock(&vdd->mtx); emit_frame(vd, vp); hts_mutex_lock(&vdd->mtx); free(vp); } while(vdd->num_pictures > 16) { vp = LIST_FIRST(&vdd->pictures); assert(vp != NULL); release_picture(vp); vdd->num_pictures--; } hts_mutex_unlock(&vdd->mtx); }
static void free_picture_list(struct vdec_pic_list *l) { vdec_pic_t *vp; while((vp = LIST_FIRST(l)) != NULL) { TRACE(TRACE_DEBUG, "VDEC", "Free picture %p", vp); TRACE(TRACE_DEBUG, "VDEC", "Free RSX mem %x +%d", vp->vp_offset, vp->vp_size); release_picture(vp); } }
static void reset_active_pictures(vdec_decoder_t *vdd, const char *reason, int marked) { vdec_pic_t *vp; #if VDEC_DETAILED_DEBUG TRACE(TRACE_DEBUG, "VDEC DEC", "RESET: %s", reason); #endif hts_mutex_lock(&vdd->mtx); while((vp = LIST_FIRST(&vdd->pictures)) != NULL) release_picture(vp); hts_mutex_unlock(&vdd->mtx); }