static int doublefps_filter_audio(TCModuleInstance *self, aframe_list_t *frame) { DfpsPrivateData *pd = NULL; TC_MODULE_SELF_CHECK(self, "filter_audio"); TC_MODULE_SELF_CHECK(frame, "filter_audio"); pd = self->userdata; if (!(frame->attributes & TC_FRAME_WAS_CLONED)) { /* First field */ int bps = frame->a_chan * frame->a_bits / 8; int nsamples = frame->audio_size / bps; int nsamples_first = (nsamples+1) / 2; // put odd sample in 1st frame int nsamples_second = nsamples - nsamples_first; frame->attributes |= TC_FRAME_IS_CLONED; frame->audio_size = nsamples_first * bps; pd->saved_audio_len = nsamples_second * bps; if (pd->saved_audio_len > 0) { ac_memcpy(pd->saved_audio, frame->audio_buf + frame->audio_size, pd->saved_audio_len); } } else { /* Second frame */ frame->audio_size = pd->saved_audio_len; if (pd->saved_audio_len > 0) ac_memcpy(frame->audio_buf, pd->saved_audio, pd->saved_audio_len); } return TC_OK; }
static int tc_frame_audio_add_ogg_packet(VorbisPrivateData *pd, TCFrameAudio *f, ogg_packet *op) { int16_t *pkt_num = (int16_t*)f->audio_buf; double ts = vorbis_granule_time(&(pd->vd), op->granulepos); int needed = sizeof(*op) + op->bytes; int avail = f->audio_size - f->audio_len; TC_FRAME_SET_TIMESTAMP_DOUBLE(f, ts); if (avail < needed) { tc_log_error(__FILE__, "(%s) no buffer in frame: (avail=%i|needed=%i)", __func__, avail, needed); return TC_ERROR; } ac_memcpy(f->audio_buf + f->audio_len, op, sizeof(*op)); f->audio_len += sizeof(*op); ac_memcpy(f->audio_buf + f->audio_len, op->packet, op->bytes); f->audio_len += op->bytes; *pkt_num += 1; if (op->e_o_s) { f->attributes |= TC_FRAME_IS_END_OF_STREAM; // useless? } return TC_OK; }
static int yuv444p_copy(uint8_t **src, uint8_t **dest, int width, int height) { ac_memcpy(dest[0], src[0], width*height); ac_memcpy(dest[1], src[1], width*height); ac_memcpy(dest[2], src[2], width*height); return 1; }
static void ivtc_copy_field (unsigned char *dest, unsigned char *src, vframe_list_t * ptr, int field) { int y; if (field == 1) { src += ptr->v_width; dest += ptr->v_width; } for (y = 0; y < (ptr->v_height+1)/2; y++) { ac_memcpy(dest, src, ptr->v_width); src += ptr->v_width*2; dest += ptr->v_width*2; } if (field == 1) { src -= (ptr->v_width+1) / 2; dest -= (ptr->v_width+1) / 2; } for (y = 0; y < (ptr->v_height+1)/2; y++) { ac_memcpy(dest, src, ptr->v_width/2); src += ptr->v_width; dest += ptr->v_width; } }
/** * Initialize an AcArp * * See (RFC-826 Internet Protocol, V6)[https://tools.ietf.org/html/rfc826] * for the definition of the packet * * @return Length of the ArpReq */ AcU32 ac_arp_init( AcArp* pArpReq, ///< Arp Request to initialize AcU16 op, ///< Operation AcU16 hard_addr_frmt, ///< Format of the hardware address AcU8 hard_addr_len, ///< Length hardware address AcU16 proto_addr_frmt, ///< Format of the protocol address AcU8 proto_addr_len, ///< Length of a protocol address to convert AcU8* src_hard_addr, ///< Source hardware address, if AC_NULL zeroed AcU8* src_proto_addr, ///< Source protocol address, if AC_NULL zeroed AcU8* dst_hard_addr, ///< Destination hardware address, if AC_NULL zeroed AcU8* dst_proto_addr) { ///< Destination protocol address, if AC_NULL zeroed // Init header area pArpReq->frmt_hard_a = AC_HTON_U16(hard_addr_frmt); pArpReq->frmt_proto_a = AC_HTON_U16(proto_addr_frmt); pArpReq->len_hard_a = hard_addr_len; pArpReq->len_proto_a = proto_addr_len; pArpReq->op = AC_HTON_U16(op); AcU8* p = pArpReq->addresses; // Initialzie source hardware address if (src_hard_addr == AC_NULL) { ac_memset(p, 0, pArpReq->len_hard_a); } else { ac_memcpy(p, src_hard_addr, pArpReq->len_hard_a); } p += pArpReq->len_hard_a; // Initialzie source protocol address if (src_proto_addr == AC_NULL) { ac_memset(p, 0, pArpReq->len_proto_a); } else { ac_memcpy(p, src_proto_addr, pArpReq->len_proto_a); } p += pArpReq->len_proto_a; // Initialzie destination hardware address if (dst_hard_addr == AC_NULL) { ac_memset(p, 0, pArpReq->len_hard_a); } else { ac_memcpy(p, dst_hard_addr, pArpReq->len_hard_a); } p += pArpReq->len_hard_a; // Initialzie destination protocol address if (dst_proto_addr == AC_NULL) { ac_memset(p, 0, pArpReq->len_proto_a); } else { ac_memcpy(p, dst_proto_addr, pArpReq->len_proto_a); } p += pArpReq->len_proto_a; return p - (AcU8*)pArpReq; }
int tc_ogg_dup_packet(ogg_packet *dst, const ogg_packet *src) { int ret = TC_ERROR; ac_memcpy(dst, src, sizeof(ogg_packet)); dst->packet = tc_malloc(src->bytes); if (dst->packet) { ac_memcpy(dst->packet, src->packet, src->bytes); ret = TC_OK; } return ret; }
static int yuv420p_yuv444p_sse2(uint8_t **src, uint8_t **dest, int width, int height) { int y; ac_memcpy(dest[0], src[0], width*height); for (y = 0; y < height; y += 2) { REP_2H(src[1]+(y/2)*(width/2), dest[1]+y*width, width/2); ac_memcpy(dest[1]+(y+1)*width, dest[1]+y*width, width); REP_2H(src[2]+(y/2)*(width/2), dest[2]+y*width, width/2); ac_memcpy(dest[2]+(y+1)*width, dest[2]+y*width, width); } return 1; }
static int yuv420p_yuv422p(uint8_t **src, uint8_t **dest, int width, int height) { int y; ac_memcpy(dest[0], src[0], width*height); for (y = 0; y < (height & ~1); y += 2) { ac_memcpy(dest[1]+(y )*(width/2), src[1]+(y/2)*(width/2), width/2); ac_memcpy(dest[1]+(y+1)*(width/2), src[1]+(y/2)*(width/2), width/2); ac_memcpy(dest[2]+(y )*(width/2), src[2]+(y/2)*(width/2), width/2); ac_memcpy(dest[2]+(y+1)*(width/2), src[2]+(y/2)*(width/2), width/2); } return 1; }
static int yuv420p_yuv411p_sse2(uint8_t **src, uint8_t **dest, int width, int height) { int y; ac_memcpy(dest[0], src[0], width*height); for (y = 0; y < (height & ~1); y += 2) { AVG_2H(src[1]+(y/2)*(width/2), dest[1]+y*(width/4), width/4); ac_memcpy(dest[1]+(y+1)*(width/4), dest[1]+y*(width/4), width/4); AVG_2H(src[2]+(y/2)*(width/2), dest[2]+y*(width/4), width/4); ac_memcpy(dest[2]+(y+1)*(width/4), dest[2]+y*(width/4), width/4); } return 1; }
/* * swap_fields - Exchange one field of a frame (every other line) with another * NOTE: This function uses 'buffer' as a temporary space. */ static void swap_fields(char *buffer, char *f1, char *f2, int width, int height) { int increment = width * 2; height /= 2; while (height--) { ac_memcpy(buffer, f1, width); ac_memcpy(f1, f2, width); ac_memcpy(f2, buffer, width); f1 += increment; f2 += increment; } }
/* * we compute (ahead of time) samples value for later usage. */ void tc_framebuffer_set_specs(const TCFrameSpecs *specs) { /* silently ignore NULL specs */ if (specs != NULL) { double fps; /* raw copy first */ ac_memcpy(&tc_specs, specs, sizeof(TCFrameSpecs)); /* restore width/height/bpp * (FIXME: temp until we have a way to know the max size that will * be used through the decode/process/encode chain; without * this, -V yuv420p -y raw -F rgb (e.g.) crashes with a * buffer overrun) */ tc_specs.width = TC_MAX_V_FRAME_WIDTH; tc_specs.height = TC_MAX_V_FRAME_HEIGHT; tc_specs.format = TC_CODEC_RGB24; /* then deduct missing parameters */ if (tc_frc_code_to_value(tc_specs.frc, &fps) == TC_NULL_MATCH) { fps = 1.0; /* sane, very worst case value */ } /* tc_specs.samples = (double)tc_specs.rate/fps; */ tc_specs.samples = (double)tc_specs.rate; /* * FIXME * ok, so we use a MUCH larger buffer (big enough to store 1 *second* * of raw audio, not 1 *frame*) than needed for reasons similar as * seen for above video. * Most notably, this helps in keeping buffers large enough to be * suitable for encoder flush (see encode_lame.c first). */ } }
static int y8_yuv444p(uint8_t **src, uint8_t **dest, int width, int height) { ac_memcpy(dest[0], src[0], width*height); memset(dest[1], 128, width*height); memset(dest[2], 128, width*height); return 1; }
static int yuv420p_yuv444p(uint8_t **src, uint8_t **dest, int width, int height) { int x, y; ac_memcpy(dest[0], src[0], width*height); for (y = 0; y < height; y += 2) { for (x = 0; x < width; x += 2) { dest[1][y*width+x ] = dest[1][y*width+x+1] = src[1][(y/2)*(width/2)+(x/2)]; dest[2][y*width+x ] = dest[2][y*width+x+1] = src[2][(y/2)*(width/2)+(x/2)]; } ac_memcpy(dest[1]+(y+1)*width, dest[1]+y*width, width); ac_memcpy(dest[2]+(y+1)*width, dest[2]+y*width, width); } return 1; }
static int yuv420p_yuv411p(uint8_t **src, uint8_t **dest, int width, int height) { int x, y; ac_memcpy(dest[0], src[0], width*height); for (y = 0; y < (height & ~1); y += 2) { for (x = 0; x < (width/2 & ~1); x += 2) { dest[1][y*(width/4)+x/2] = (src[1][(y/2)*(width/2)+x] + src[1][(y/2)*(width/2)+x+1] + 1) / 2; dest[2][y*(width/4)+x/2] = (src[2][(y/2)*(width/2)+x] + src[2][(y/2)*(width/2)+x+1] + 1) / 2; } ac_memcpy(dest[1]+(y+1)*(width/4), dest[1]+y*(width/4), width/4); ac_memcpy(dest[2]+(y+1)*(width/4), dest[2]+y*(width/4), width/4); } return 1; }
static int faac_encode(TCModuleInstance *self, TCFrameAudio *in, TCFrameAudio *out) { PrivateData *pd; uint8_t *inptr; int nsamples; TC_MODULE_SELF_CHECK(self, "encode"); pd = self->userdata; if (in) { inptr = in->audio_buf; nsamples = in->audio_size / pd->bps; } else { inptr = NULL; nsamples = 0; } out->audio_len = 0; while (pd->audiobuf_len + nsamples >= pd->framesize) { int res; const int tocopy = (pd->framesize - pd->audiobuf_len) * pd->bps; ac_memcpy(pd->audiobuf + pd->audiobuf_len*pd->bps, inptr, tocopy); inptr += tocopy; nsamples -= tocopy / pd->bps; pd->audiobuf_len = 0; res = faacEncEncode(pd->handle, (int32_t *)pd->audiobuf, pd->framesize, out->audio_buf + out->audio_len, out->audio_size - out->audio_len); if (res > out->audio_size - out->audio_len) { tc_log_error(MOD_NAME, "Output buffer overflow! Try a lower bitrate."); return TC_ERROR; } out->audio_len += res; } if (nsamples > 0) { ac_memcpy(pd->audiobuf + pd->audiobuf_len*pd->bps, inptr, nsamples*pd->bps); pd->audiobuf_len += nsamples; } pd->need_flush = TC_TRUE; return TC_OK; }
static void copy_buf_yuv(char *dest, size_t size) { int y_size = bktr_buffer_size * 4 / 6; int u_size = bktr_buffer_size * 1 / 6; int y_offset = 0; int u1_offset = y_size + 0; int u2_offset = y_size + u_size; if (bktr_buffer_size != size) tc_log_warn(MOD_NAME, "buffer sizes do not match (input %lu != output %lu)", (unsigned long)bktr_buffer_size, (unsigned long)size); ac_memcpy(dest + y_offset, bktr_buffer + y_offset, y_size); ac_memcpy(dest + u1_offset, bktr_buffer + u1_offset, u_size); ac_memcpy(dest + u2_offset, bktr_buffer + u2_offset, u_size); }
static int adjust_save(AdjustContext *ctx, TCFrameVideo *vf) { if (vf->video_size != ctx->saved->video_size) { tc_log_error(__FILE__, "(%s) WRITEME!!", ctx->method_name); return TC_ERROR; } ac_memcpy(ctx->saved->video_buf, vf->video_buf, ctx->saved->video_size); return TC_OK; }
static int tc_v4l2_fetch_data_memcpy(V4L2Source *vs, uint8_t *src, int src_len, uint8_t *dst, int dst_len) { int ret = TC_ERROR; if (dst_len >= src_len) { ac_memcpy(dst, src, src_len); ret = TC_OK; } return ret; }
/* * copy_field - Copy one field of a frame (every other line) from one buffer * to another. */ static void copy_field(char *to, char *from, int width, int height) { int increment = width * 2; height /= 2; while (height--) { ac_memcpy(to, from, width); to += increment; from += increment; } }
static void copy_frame(const mpeg2_sequence_t *sequence, const mpeg2_info_t *info, transfer_t *param) { size_t len = 0; // Y plane len = sequence->width * sequence->height; ac_memcpy(param->buffer, info->display_fbuf->buf[0], len); param->size = len; len = sequence->chroma_width * sequence->chroma_height; // U plane ac_memcpy(param->buffer + param->size, info->display_fbuf->buf[1], len); param->size += len; // V plane ac_memcpy(param->buffer + param->size, info->display_fbuf->buf[2], len); param->size += len; }
/* bob a single field */ static void bob_field (uint8_t *in, uint8_t *out, int width, int height) { int i, j, w2 = 2*width; for (i = 0; i < height; i++) { /* First bob (average lines) */ for (j = 0; j < width; j++) out[j] = (((short)in[j]) + ((short)in[j+w2])) >>1; /* Then copy original line */ ac_memcpy (out+width, in+w2, width); in += w2; out += w2; } }
static int adjust_clone(AdjustContext *ctx, TCFrameVideo *vf) { if (!ctx->video_cloned) { tc_blank_video_frame(vf); } else { if (vf->video_size != ctx->saved->video_size) { tc_log_error(__FILE__, "(%s) WRITEME!!", ctx->method_name); return TC_ERROR; } ac_memcpy(vf->video_buf, ctx->saved->video_buf, vf->video_size); } return TC_OK; }
static int yuv411p_yuv422p(uint8_t **src, uint8_t **dest, int width, int height) { int x, y; ac_memcpy(dest[0], src[0], width*height); for (y = 0; y < height; y++) { for (x = 0; x < ((width/2) & ~1); x += 2) { dest[1][y*(width/2)+x ] = src[1][y*(width/4)+x/2]; dest[1][y*(width/2)+x+1] = src[1][y*(width/4)+x/2]; dest[2][y*(width/2)+x ] = src[2][y*(width/4)+x/2]; dest[2][y*(width/2)+x+1] = src[2][y*(width/4)+x/2]; } } return 1; }
static int yuv422p_yuv420p(uint8_t **src, uint8_t **dest, int width, int height) { int x, y; ac_memcpy(dest[0], src[0], width*height); for (y = 0; y < (height & ~1); y += 2) { for (x = 0; x < width/2; x++) { dest[1][(y/2)*(width/2)+x] = (src[1][y*(width/2)+x] + src[1][(y+1)*(width/2)+x] + 1) / 2; dest[2][(y/2)*(width/2)+x] = (src[2][y*(width/2)+x] + src[2][(y+1)*(width/2)+x] + 1) / 2; } } return 1; }
static int yuv444p_yuv422p(uint8_t **src, uint8_t **dest, int width, int height) { int x, y; ac_memcpy(dest[0], src[0], width*height); for (y = 0; y < height; y++) { for (x = 0; x < (width & ~1); x += 2) { dest[1][y*(width/2)+x/2] = (src[1][y*width+x] + src[1][y*width+x+1] + 1) / 2; dest[2][y*(width/2)+x/2] = (src[2][y*width+x] + src[2][y*width+x+1] + 1) / 2; } } return 1; }
static int yuv444p_yuv422p_sse2(uint8_t **src, uint8_t **dest, int width, int height) { ac_memcpy(dest[0], src[0], width*height); if (!(width & 1)) { /* Fast version, no bytes at end of row to skip */ AVG_2H(src[1], dest[1], (width/2)*height); AVG_2H(src[2], dest[2], (width/2)*height); } else { /* Slow version, loop through each row */ int y; for (y = 0; y < height; y++) { AVG_2H(src[1]+y*width, dest[1]+y*(width/2), width/2); AVG_2H(src[2]+y*width, dest[2]+y*(width/2), width/2); } } return 1; }
static int yuv444p_yuv420p(uint8_t **src, uint8_t **dest, int width, int height) { int x, y; ac_memcpy(dest[0], src[0], width*height); for (y = 0; y < (height & ~1); y += 2) { for (x = 0; x < (width & ~1); x += 2) { dest[1][(y/2)*(width/2)+x/2] = (src[1][y*width+x] + src[1][y*width+x+1] + src[1][(y+1)*width+x] + src[1][(y+1)*width+x+1] + 2) / 4; dest[2][(y/2)*(width/2)+x/2] = (src[2][y*width+x] + src[2][y*width+x+1] + src[2][(y+1)*width+x] + src[2][(y+1)*width+x+1] + 2) / 4; } } return 1; }
static int yuv444p_yuv411p(uint8_t **src, uint8_t **dest, int width, int height) { int x, y; ac_memcpy(dest[0], src[0], width*height); for (y = 0; y < height; y++) { for (x = 0; x < (width & ~3); x += 4) { dest[1][y*(width/4)+x/4] = (src[1][y*width+x] + src[1][y*width+x+1] + src[1][y*width+x+2] + src[1][y*width+x+3] + 2) / 4; dest[2][y*(width/4)+x/4] = (src[2][y*width+x] + src[2][y*width+x+1] + src[2][y*width+x+2] + src[2][y*width+x+3] + 2) / 4; } } return 1; }
void zoom_process(const ZoomInfo *zi, const uint8_t *src, uint8_t *dest) { int from_stride, to_stride; const uint8_t *from; uint8_t *to; from = src; from_stride = zi->old_stride; /* Apply filter to zoom horizontally from src to tmp (if necessary) */ if (zi->x_contrib) { int y; to = zi->tmpimage; to_stride = zi->new_w * zi->Bpp; for (y = 0; y < zi->old_h; y++, from += from_stride, to += to_stride) { int32_t *contrib = zi->x_contrib; int x; for (x = 0; x < zi->new_w * zi->Bpp; x++) { int32_t weight = DOUBLE_TO_FIXED(0.5); int n = *contrib++, i; for (i = 0; i < n; i++) { int pixel = *contrib++; weight += from[pixel] * (*contrib++); } to[x] = CLAMP(FIXED_TO_INT(weight), 0, 255); } } from = zi->tmpimage; from_stride = to_stride; } /* Apply filter to zoom vertically from tmp (or src) to dest */ /* Use Y as the outside loop to avoid cache thrashing on output buffer */ to = dest; to_stride = zi->new_stride; if (zi->y_contrib) { int32_t *contrib = zi->y_contrib; int y; for (y = 0; y < zi->new_h; y++, to += to_stride) { int n = *contrib++, x; for (x = 0; x < zi->new_w * zi->Bpp; x++) { int32_t weight = DOUBLE_TO_FIXED(0.5); int i; for (i = 0; i < n; i++) { int pixel = contrib[i*2]; weight += from[x+pixel] * contrib[i*2+1]; } to[x] = CLAMP(FIXED_TO_INT(weight), 0, 255); } contrib += 2*n; } } else { /* No zooming necessary, just copy */ if (from_stride == zi->new_w*zi->Bpp && to_stride == zi->new_w*zi->Bpp ) { /* We can copy the whole frame at once */ ac_memcpy(to, from, to_stride * zi->new_h); } else { /* Copy one row at a time */ int y; for (y = 0; y < zi->new_h; y++) { ac_memcpy(to + y*to_stride, from + y*from_stride, zi->new_w * zi->Bpp); } } } }
static int y8_copy(uint8_t **src, uint8_t **dest, int width, int height) { ac_memcpy(dest[0], src[0], width*height); return 1; }