static void handle_last_input_buffer (int *pneed_input, int *pinbuf_added) { switch (inbuf_end) { case 0: if (inbuf_copying != NULL && inbuf_copied > 0) { inbuf_copying->flen = inbuf_copied; if (buflist_add (&inbuf_used, inbuf_copying)) *pneed_input = 1; *pinbuf_added = 1; inbuf_copying = NULL; } inbuf_end = 1; /* fall through */ case 1: if (inbuf_copying == NULL) { inbuf_copying = buflist_pop (&inbuf_free); if (inbuf_copying == NULL) break; } inbuf_copying->flen = 0; if (buflist_add (&inbuf_used, inbuf_copying)) *pneed_input = 1; *pinbuf_added = 1; inbuf_copying = NULL; inbuf_end = 2; /* fall through */ case 2: break; } }
static void buflist_init (void *buf, uint32_t addr, struct buflist **buflist, struct buflist_head *buf_free, struct buflist_head *buf_used, int blocksize, int totalsize) { uint8_t *bufc; struct buflist *p; bufc = (uint8_t *)buf; *buflist = NULL; buf_free->next = NULL; buf_free->prevnext = &buf_free->next; pthread_mutex_init (&buf_free->lock, NULL); buf_used->next = NULL; buf_used->prevnext = &buf_used->next; pthread_mutex_init (&buf_used->lock, NULL); while (totalsize >= blocksize) { /* skip chunks which lie across BUFALIGNMENT boundary */ if (BUFALIGNMENT - (addr % BUFALIGNMENT) >= blocksize) { p = malloc (sizeof *p); if (p == NULL) abort (); p->buf = (void *)bufc; p->addr = addr; p->alen = blocksize; p->anext = *buflist; *buflist = p; buflist_add (buf_free, p); } bufc += blocksize; addr += blocksize; totalsize -= blocksize; } }
static int copy_output_buffer (void **destbuf, void *destend, int *pneed_output, void **data, int *datalen) { uint8_t *_dstbuf; int _dstlen, copylen; int first = 1; *data = NULL; *datalen = 0; _dstbuf = (uint8_t *)*destbuf; _dstlen = (uint8_t *)destend - _dstbuf; if (outbuf_copying == NULL) { get_outbuf: outbuf_copying = buflist_pop (&outbuf_used); outbuf_copied = 0; } while (outbuf_copying != NULL) { copylen = outbuf_copying->flen - outbuf_copied; if (copylen == 0) { if (buflist_add (&outbuf_free, outbuf_copying)) *pneed_output = 1; goto get_outbuf; } if (_dstlen == 0) break; if (outdata.head == NULL) break; if (copylen > _dstlen) copylen = _dstlen; if (output_remain > 0 && copylen > output_remain) copylen = copylen - output_remain; memcpy (_dstbuf, (uint8_t *)outbuf_copying->buf + outbuf_copied, copylen); _dstbuf += copylen; _dstlen -= copylen; outbuf_copied += copylen; if (first != 0) { datalist_sub (&outdata, data, datalen, copylen); first = 0; } else { datalist_sub (&outdata, NULL, NULL, copylen); } if (output_remain == 0) format_current = format_next; output_remain -= copylen; if (output_remain == 0) break; } if (*destbuf == (void *)_dstbuf && *destbuf != destend) return 0; *destbuf = (void *)_dstbuf; return 1; }
static int copy_input_buffer (void **srcbuf, void *srcend, int *pneed_input, int *pinbuf_added, void *data, int datalen) { uint8_t *_srcbuf; int _srclen, copylen; if (srcbuf == NULL) { handle_last_input_buffer (pneed_input, pinbuf_added); return 1; } _srcbuf = (uint8_t *)*srcbuf; _srclen = (uint8_t *)srcend - _srcbuf; if (inbuf_copying == NULL) { get_inbuf: inbuf_copying = buflist_pop (&inbuf_free); inbuf_copied = 0; } while (inbuf_copying != NULL) { copylen = inbuf_copying->alen - inbuf_copied; if (copylen == 0) { inbuf_copying->flen = inbuf_copied; if (buflist_add (&inbuf_used, inbuf_copying)) *pneed_input = 1; *pinbuf_added = 1; goto get_inbuf; } if (_srclen == 0) break; if (copylen > _srclen) copylen = _srclen; memcpy ((uint8_t *)inbuf_copying->buf + inbuf_copied, _srcbuf, copylen); _srcbuf += copylen; _srclen -= copylen; inbuf_copied += copylen; datalist_add (&indata, data, datalen, copylen); } if (*srcbuf == (void *)_srcbuf && *srcbuf != srcend) return 0; *srcbuf = (void *)_srcbuf; return 1; }
static void pcm_output_end_cb (unsigned long size, unsigned long flush) { struct buflist *p; if (outbuf_current != NULL) { outbuf_current->flen = size * 2; buflist_add (&outbuf_used, outbuf_current); outbuf_current = NULL; } if (flush == 0) { p = outbuf_current = buflist_pop (&outbuf_free); if (p == NULL) { pthread_mutex_lock (&transfer_lock); if (transfer_flag != 0) { transfer_flag = 0; pthread_mutex_unlock (&transfer_done); } pthread_mutex_unlock (&transfer_lock); return; } if (RSACPDS_TransferPcm (paac, (short *)p->addr, p->alen / 2) < RSACPDS_RTN_GOOD) ERR ("RSACPDS_TransferPcm error"); } else { if (size == 0) { ERR ("decode error, decoded size is zero"); callbk_err = 1; fprintf(stderr, "StatusCode=%08ld\n", RSACPDS_GetStatusCode(paac)); } pthread_mutex_lock (&transfer_lock); if (transfer_flag != 0) { transfer_flag = 0; pthread_mutex_unlock (&transfer_done); } outbuf_end = 1; pthread_mutex_unlock (&transfer_lock); } }
static void stream_input_end_cb (unsigned long size) { struct buflist *p; if (inbuf_current != NULL) { buflist_add (&inbuf_free, inbuf_current); inbuf_current = NULL; } p = inbuf_current = buflist_pop (&inbuf_used); if (p == NULL) { pthread_mutex_lock (&transfer_lock); if (transfer_flag != 0) { transfer_flag = 0; pthread_mutex_unlock (&transfer_done); } pthread_mutex_unlock (&transfer_lock); return; } if (RSACPDS_TransferStream (paac, (unsigned char *)p->addr, p->flen) < RSACPDS_RTN_GOOD) ERR ("RSACPDS_TransferStream error"); }
/* * Read the errorfile into memory, line by line, building the error list. * Return FAIL for error, OK for success. */ int qf_init() { char_u namebuf[CMDBUFFSIZE + 1]; char_u errmsg[CMDBUFFSIZE + 1]; int col; int type; int valid; long lnum; int enr; FILE *fd; struct qf_line *qfp = NULL; struct qf_line *qfprev = NULL; /* init to make SASC shut up */ char_u *pfmt, *fmtstr; #ifdef UTS2 char_u *(adr[7]); #else void *(adr[7]); #endif int adr_cnt = 0; int maxlen; int i; if (p_ef == NULL || *p_ef == NUL) { emsg(e_errorf); return FAIL; } if ((fd = fopen((char *)p_ef, "r")) == NULL) { emsg2(e_openerrf, p_ef); return FAIL; } qf_free(); qf_index = 0; for (i = 0; i < 7; ++i) adr[i] = NULL; /* * The format string is copied and modified from p_efm to fmtstr. * Only a few % characters are allowed. */ /* get some space to modify the format string into */ /* must be able to do the largest expansion 7 times (7 x 3) */ maxlen = STRLEN(p_efm) + 25; fmtstr = alloc(maxlen); if (fmtstr == NULL) goto error2; for (pfmt = p_efm, i = 0; *pfmt; ++pfmt, ++i) { if (pfmt[0] != '%') /* copy normal character */ fmtstr[i] = pfmt[0]; else { fmtstr[i++] = '%'; switch (pfmt[1]) { case 'f': /* filename */ adr[adr_cnt++] = namebuf; case 'm': /* message */ if (pfmt[1] == 'm') adr[adr_cnt++] = errmsg; fmtstr[i++] = '['; fmtstr[i++] = '^'; if (pfmt[2]) fmtstr[i++] = pfmt[2]; else #ifdef MSDOS fmtstr[i++] = '\r'; #else fmtstr[i++] = '\n'; #endif fmtstr[i] = ']'; break; case 'c': /* column */ adr[adr_cnt++] = &col; fmtstr[i] = 'd'; break; case 'l': /* line */ adr[adr_cnt++] = &lnum; fmtstr[i++] = 'l'; fmtstr[i] = 'd'; break; case 'n': /* error number */ adr[adr_cnt++] = &enr; fmtstr[i] = 'd'; break; case 't': /* error type */ adr[adr_cnt++] = &type; fmtstr[i] = 'c'; break; case '%': /* %% */ case '*': /* %*: no assignment */ fmtstr[i] = pfmt[1]; break; default: EMSG("invalid % in format string"); goto error2; } if (adr_cnt == 7) { EMSG("too many % in format string"); goto error2; } ++pfmt; } if (i >= maxlen - 6) { EMSG("invalid format string"); goto error2; } } fmtstr[i] = NUL; while (fgets((char *)IObuff, CMDBUFFSIZE, fd) != NULL && !got_int) { if ((qfp = (struct qf_line *)alloc((unsigned)sizeof(struct qf_line))) == NULL) goto error2; IObuff[CMDBUFFSIZE] = NUL; /* for very long lines */ namebuf[0] = NUL; errmsg[0] = NUL; lnum = 0; col = 0; enr = -1; type = 0; valid = TRUE; if (sscanf((char *)IObuff, (char *)fmtstr, adr[0], adr[1], adr[2], adr[3], adr[4], adr[5]) != adr_cnt) { namebuf[0] = NUL; /* something failed, remove file name */ valid = FALSE; STRCPY(errmsg, IObuff); /* copy whole line to error message */ if ((pfmt = STRRCHR(errmsg, '\n')) != NULL) *pfmt = NUL; #ifdef MSDOS if ((pfmt = STRRCHR(errmsg, '\r')) != NULL) *pfmt = NUL; #endif } if (namebuf[0] == NUL) /* no file name */ qfp->qf_fnum = 0; else qfp->qf_fnum = buflist_add(namebuf); if ((qfp->qf_text = strsave(errmsg)) == NULL) goto error1; qfp->qf_lnum = lnum; qfp->qf_col = col; qfp->qf_nr = enr; qfp->qf_type = type; qfp->qf_valid = valid; if (qf_count == 0) /* first element in the list */ { qf_start = qfp; qfp->qf_prev = qfp; /* first element points to itself */ } else { qfp->qf_prev = qfprev; qfprev->qf_next = qfp; } qfp->qf_next = qfp; /* last element points to itself */ qfp->qf_cleared = FALSE; qfprev = qfp; ++qf_count; if (qf_index == 0 && qfp->qf_valid) /* first valid entry */ { qf_index = qf_count; qf_ptr = qfp; } breakcheck(); } free(fmtstr); if (!ferror(fd)) { if (qf_index == 0) /* no valid entry found */ { qf_ptr = qf_start; qf_index = 1; qf_nonevalid = TRUE; } else qf_nonevalid = FALSE; fclose(fd); qf_jump(0, 0); /* display first error */ return OK; } emsg(e_readerrf); error1: free(qfp); error2: fclose(fd); qf_free(); return FAIL; }
long spu_aac_decode (void **destbuf, void *destend, void **srcbuf, void *srcend, struct spu_aac_decode_fmt *format, void *dataout, void *datain, int datalen) { long status; int need_input, need_output; int inbuf_added; int endflag; int state_decode; int state_decode_end, state_decode_really_end; int incopy, outcopy; unsigned long nblk; long err = RSACPDS_RTN_GOOD; void *_dataout; int _dataoutlen; once_again: need_input = 0; need_output = 0; inbuf_added = 0; if (state.init == 0) { if (init2 () < 0) return -1; state.init = 1; } pthread_mutex_lock (&transfer_lock); while (output_remain <= 0 && outlendata.head != NULL) { int *outlen; struct spu_aac_decode_fmt *outfmt; void *p; int tmp; datalist_sub (&outlendata, &p, &tmp, 1); outlen = p; datalist_sub (&outfmtdata, &p, &tmp, 1); outfmt = p; output_remain += *outlen; format_next = *outfmt; free (outlen); free (outfmt); } endflag = outbuf_end; state_decode_end = state.decode_end; state_decode_really_end = state.decode_really_end; transfer_flag = 1; pthread_mutex_unlock (&transfer_lock); outcopy = copy_output_buffer (destbuf, destend, &need_output, &_dataout, &_dataoutlen); incopy = copy_input_buffer (srcbuf, srcend, &need_input, &inbuf_added, datain, datalen); if (_dataoutlen != 0) { if (_dataoutlen > datalen) _dataoutlen = datalen; memcpy (dataout, _dataout, _dataoutlen); free (_dataout); } *format = format_current; if (state.open == 0) { state_decode = 0; state.decode_end = 0; state.decode_really_end = 0; state_decode_end = 0; state_decode_really_end = 0; callbk_err = 0; inbuf_end = 0; pthread_mutex_lock (&transfer_lock); outbuf_end = 0; pthread_mutex_unlock (&transfer_lock); if (inbuf_added == 0) goto unlock_ret; if ((err = middleware_open ()) < 0) goto ret; if ((err = RSACPDS_SetDecOpt(paac, 0)) < RSACPDS_RTN_GOOD) { ERR ("RSACPDS_SetDecOpt error"); goto close_and_ret; } err = RSACPDS_RTN_GOOD; state.first_block = 1; state.open = 1; need_input = 1; need_output = 0; output_remain = 0; } else { state_decode = 1; if (state_decode_really_end != 0) state_decode = 0; } status = 0; if (state_decode_end != 0) { if (state.first_block != 0) { state.first_block = 0; need_output = 1; } if (output_remain <= 0) { state_decode = 0; state.decode_end = 0; err = RSACPDS_DecodeStatus (paac, &status); if (err < RSACPDS_RTN_GOOD) { ERR ("RSACPDS_DecodeStatus error"); goto close_and_ret; } } } if (need_input != 0) stream_input_end_cb (0); if (need_output != 0) pcm_output_end_cb (0, 0); if (state_decode == 0 && state_decode_really_end == 0) { err = get_header_and_pce (status); if (err < 0) goto close_and_ret; nblk = 0; if (format_type == SPU_AAC_DECODE_SETFMT_TYPE_RAW_AAC || format_type == SPU_AAC_DECODE_SETFMT_TYPE_RAW_AACPLUS) nblk = 1; if (state.first_block != 0) nblk = 1; if (RSACPDS_Decode (paac, nblk) < RSACPDS_RTN_GOOD) { err = RSACPDS_GetStatusCode (paac); ERR ("RSACPDS_Decode error"); goto close_and_ret; } state_decode = 1; } if (inbuf_end == 2 && endflag != 0 && outbuf_copying == NULL && buflist_poll (&outbuf_used) == NULL) { if (decode_end_status != RSACPDS_ERR_DATA_EMPTY) ERR ("strange statusCode; ignored"); err = decoder_close (0); state.open = 0; goto ret; } if (callbk_err != 0) { err = -1; goto close_and_ret; } if ((inbuf_end != 0 || incopy == 0) && outcopy == 0) { pthread_mutex_lock (&transfer_done); goto once_again; } goto unlock_ret; close_and_ret: if (state.decode_end != 0 || state.decode_really_end != 0) state_decode = 0; decoder_close (state_decode); state.open = 0; ret: if (inbuf_copying != NULL) { buflist_add (&inbuf_free, inbuf_copying); inbuf_copying = NULL; } if (outbuf_current != NULL) { buflist_add (&outbuf_free, outbuf_current); outbuf_current = NULL; } do { if (inbuf_current != NULL) buflist_add (&inbuf_free, inbuf_current); inbuf_current = buflist_pop (&inbuf_used); } while (inbuf_current != NULL); do { if (outbuf_copying != NULL) buflist_add (&outbuf_free, outbuf_copying); outbuf_copying = buflist_pop (&outbuf_used); } while (outbuf_copying != NULL); while (indata.head != NULL) datalist_sub (&indata, NULL, NULL, indata.head->len); while (outdata.head != NULL) datalist_sub (&outdata, NULL, NULL, outdata.head->len); while (delaydata.head != NULL) datalist_sub (&delaydata, NULL, NULL, delaydata.head->len); unlock_ret: pthread_mutex_lock (&transfer_lock); if (transfer_flag == 0) { pthread_mutex_unlock (&transfer_lock); pthread_mutex_lock (&transfer_done); } else { transfer_flag = 0; pthread_mutex_unlock (&transfer_lock); } return err; }
static long get_header_and_pce (long status) { RSACPDS_AdtsHeader adtsheader; RSACPDS_AdifHeader adifheader; unsigned long bcnt; struct buflist *p; RSACPDS_PCE pce; switch (format_type) { case SPU_AAC_DECODE_SETFMT_TYPE_ADTS: if (state.first_block == 0 && (status & 0x10) != 0) break; if (RSACPDS_GetAdtsHeader (paac, &adtsheader, &bcnt) < RSACPDS_RTN_GOOD) { ERR ("RSACPDS_GetAdtsHeader error"); return -1; } next_sampling_frequency_index = adtsheader.sampling_frequency_index; break; case SPU_AAC_DECODE_SETFMT_TYPE_ADIF: if (state.first_block == 0) break; if (RSACPDS_GetAdifHeader (paac, &adifheader, &bcnt) < RSACPDS_RTN_GOOD) { ERR ("RSACPDS_GetAdifHeader error"); return -1; } /* No outbuf should be used before decoding the first block. */ p = buflist_pop (&outbuf_free); if (p == NULL) { ERR ("No buffers available for GetPce"); return -1; } if (sizeof pce > p->alen) { ERR ("Buffer is too small for GetPce"); return -1; } if (RSACPDS_GetPce (paac, (RSACPDS_PCE *)p->addr) < RSACPDS_RTN_GOOD) { ERR ("RSACPDS_GetPce error"); return -1; } memcpy (&pce, p->buf, sizeof pce); buflist_add (&outbuf_free, p); next_sampling_frequency_index = pce.sampling_frequency_index; break; default: if (state.first_block == 0) break; if (RSACPDS_SetFormat (paac, sampling_frequency_index) < RSACPDS_RTN_GOOD) { ERR ("RSACPDS_SetFormat error"); return -1; } next_sampling_frequency_index = sampling_frequency_index; break; } return 0; }