Hi On Fri, May 13, 2016 at 04:30:34PM +0200, Vlad Tarca wrote: > Pro-MPEG Code of Practice #3 release 2 forward error correction for > rtp_mpegts streams > [...] > +static const AVClass prompeg_class = { > + .class_name = "prompeg", > + .item_name = av_default_item_name, > + .option = options, > + .version = LIBAVUTIL_VERSION_INT, > +}; > + > +static void xor64(const uint8_t *in1, const uint8_t *in2, uint8_t *out, int > size) { > + const uint64_t *p1, *p2; > + const uint8_t *q1, *q2; > + uint64_t *px; > + uint8_t *qx; > + int i, n, s; > + > + n = size / sizeof (uint64_t); > + s = n * sizeof (uint64_t); > + > + p1 = (uint64_t*) in1; > + p2 = (uint64_t*) in2; > + px = (uint64_t*) out;
> + > + for (i = 0; i < n; i++) { > + px[i] = p1[i] ^ p2[i]; this is a strict aliassing violation probably or at least it can become one easily if any access to this array is different than char* type its ore robust to use union or AV_RN64A/AV_WN64A or similar > + } > + > + if (s == size) > + return; > + > + q1 = in1 + s; > + q2 = in2 + s; > + qx = out + s; > + n = size - s; > + > + for (i = 0; i < n; i++) { > + qx[i] = q1[i] ^ q2[i]; > + } > +} > + > +static inline uint32_t rtp_get_ts(const uint8_t *buf) { > + return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]; AV_RB32() > +} > + > +static inline uint16_t rtp_get_sn(const uint8_t *buf) { > + return (buf[2] << 8) | buf[3]; AV_RB16() [...] > +static int prompeg_init(URLContext *h, const uint8_t *buf, int size) { > + PrompegContext *s = h->priv_data; > + int i; > + > + s->packet_idx = 0; > + s->packet_idx_max = s->l * s->d; > + s->packet_size = size; > + s->length_recovery = size - 12; > + s->bitstring_size = (s->length_recovery + 8) * sizeof (uint8_t); > + s->fec_buf_len = 1 + 2 * s->l; // row + column tmp + column out > + s->rtp_buf_size = (12 + 16 + s->length_recovery) * sizeof (uint8_t); > + s->fec_buf = NULL; > + s->rtp_buf = NULL; > + s->rtp_col_sn = av_get_random_seed() & 0x0fff; > + s->rtp_row_sn = av_get_random_seed() & 0x0fff; you need only one call, it contains enough bits av_get_random_seed() is slow also a bitexact mode as in AVFMT_FLAG_BITEXACT might be usefull > + > + s->fec_buf = av_malloc(s->fec_buf_len * sizeof (PrompegFec*)); av_malloc_array() > + if (!s->fec_buf) { > + goto fail; > + } > + for (i = 0; i < s->fec_buf_len; i++) { > + s->fec_buf[i] = av_malloc(sizeof (PrompegFec)); > + if (!s->fec_buf[i]) { > + goto fail; > + } > + s->fec_buf[i]->bitstring = av_malloc(s->bitstring_size); > + if (!s->fec_buf[i]->bitstring) { > + av_free(s->fec_buf[i]); > + s->fec_buf[i] = NULL; av_freep() [...] > +static int prompeg_write(URLContext *h, const uint8_t *buf, int size) { > + PrompegContext *s = h->priv_data; > + PrompegFec *fec_tmp; > + uint8_t *bitstring = NULL; > + int col_idx, col_out_idx, row_idx; > + int ret; > + > + if (s->init && ((ret = prompeg_init(h, buf, size)) < 0)) > + goto fail; > + > + if ((ret = prompeg_create_bitstring(h, buf, size, &bitstring)) < 0) > + goto fail; > + > + col_idx = s->packet_idx % s->l; > + row_idx = s->packet_idx / s->l % s->d; > + > + // FEC' (row) send block-aligned, xor > + if (col_idx == 0) { > + if (!s->first || s->packet_idx > 0) { > + if ((ret = prompeg_write_fec(h, s->fec_row, PROMPEG_FEC_ROW)) < > 0) > + goto fail; > + } > + memcpy(s->fec_row->bitstring, bitstring, s->bitstring_size); > + s->fec_row->sn = rtp_get_sn(buf); > + s->fec_row->ts = rtp_get_ts(buf); > + } else { > + xor64(s->fec_row->bitstring, bitstring, s->fec_row->bitstring, > + s->bitstring_size); > + } > + > + // FEC (column) xor > + if (row_idx == 0) { > + if (!s->first) { > + // swap fec_col and fec_col_tmp > + fec_tmp = s->fec_col[col_idx]; > + s->fec_col[col_idx] = s->fec_col_tmp[col_idx]; > + s->fec_col_tmp[col_idx] = fec_tmp; > + } > + memcpy(s->fec_col_tmp[col_idx]->bitstring, bitstring, > s->bitstring_size); > + s->fec_col_tmp[col_idx]->sn = rtp_get_sn(buf); > + s->fec_col_tmp[col_idx]->ts = rtp_get_ts(buf); > + } else { > + xor64(s->fec_col_tmp[col_idx]->bitstring, bitstring, > + s->fec_col_tmp[col_idx]->bitstring, s->bitstring_size); > + } > + > + // FEC (column) send block-aligned > + if (!s->first && s->packet_idx % s->d == 0) { > + col_out_idx = s->packet_idx / s->l; > + if ((ret = prompeg_write_fec(h, s->fec_col[col_out_idx], > PROMPEG_FEC_COL)) < 0) > + goto fail; > + } > + > + if (++s->packet_idx >= s->packet_idx_max) { > + s->packet_idx = 0; > + if (s->first) > + s->first = 0; > + } > + > + av_free(bitstring); > + > + return 0; > + > +fail: > + if (bitstring) > + av_free(bitstring); av_free(NULL) is safe [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB No great genius has ever existed without some touch of madness. -- Aristotle
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel