static void v210_convert(void *frame_bytes, picture_t *pic, int dst_stride) { int width = pic->format.i_width; int height = pic->format.i_height; int line_padding = dst_stride - ((width * 8 + 11) / 12) * 4; int h, w; uint8_t *data = (uint8_t*)frame_bytes; const uint16_t *y = (const uint16_t*)pic->p[0].p_pixels; const uint16_t *u = (const uint16_t*)pic->p[1].p_pixels; const uint16_t *v = (const uint16_t*)pic->p[2].p_pixels; #define WRITE_PIXELS(a, b, c) \ do { \ val = clip(*a++); \ val |= (clip(*b++) << 10) | \ (clip(*c++) << 20); \ put_le32(&data, val); \ } while (0) for (h = 0; h < height; h++) { uint32_t val = 0; for (w = 0; w < width - 5; w += 6) { WRITE_PIXELS(u, y, v); WRITE_PIXELS(y, u, y); WRITE_PIXELS(v, y, u); WRITE_PIXELS(y, v, y); } if (w < width - 1) { WRITE_PIXELS(u, y, v); val = clip(*y++); if (w == width - 2) put_le32(&data, val); #undef WRITE_PIXELS } if (w < width - 3) { val |= (clip(*u++) << 10) | (clip(*y++) << 20); put_le32(&data, val); val = clip(*v++) | (clip(*y++) << 10); put_le32(&data, val); } memset(data, 0, line_padding); data += line_padding; y += pic->p[0].i_pitch / 2 - width; u += pic->p[1].i_pitch / 2 - width / 2; v += pic->p[2].i_pitch / 2 - width / 2; } }
void upipe_planar_to_v210_10_c(const uint16_t *y, const uint16_t *u, const uint16_t *v, uint8_t *dst, ptrdiff_t pixels) { uint32_t val; int i; for( i = 0; i < pixels-5; i += 6 ){ WRITE_PIXELS(u, y, v); WRITE_PIXELS(y, u, y); WRITE_PIXELS(v, y, u); WRITE_PIXELS(y, v, y); } }
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pic, int *got_packet) { int aligned_width = ((avctx->width + 47) / 48) * 48; int stride = aligned_width * 8 / 3; int line_padding = stride - ((avctx->width * 8 + 11) / 12) * 4; int h, w, ret; const uint16_t *y = (const uint16_t*)pic->data[0]; const uint16_t *u = (const uint16_t*)pic->data[1]; const uint16_t *v = (const uint16_t*)pic->data[2]; PutByteContext p; if ((ret = ff_alloc_packet2(avctx, pkt, avctx->height * stride)) < 0) return ret; bytestream2_init_writer(&p, pkt->data, pkt->size); #define CLIP(v) av_clip(v, 4, 1019) #define WRITE_PIXELS(a, b, c) \ do { \ val = CLIP(*a++); \ val |= (CLIP(*b++) << 10) | \ (CLIP(*c++) << 20); \ bytestream2_put_le32u(&p, val); \ } while (0) for (h = 0; h < avctx->height; h++) { uint32_t val; for (w = 0; w < avctx->width - 5; w += 6) { WRITE_PIXELS(u, y, v); WRITE_PIXELS(y, u, y); WRITE_PIXELS(v, y, u); WRITE_PIXELS(y, v, y); } if (w < avctx->width - 1) { WRITE_PIXELS(u, y, v); val = CLIP(*y++); if (w == avctx->width - 2) bytestream2_put_le32u(&p, val); if (w < avctx->width - 3) { val |= (CLIP(*u++) << 10) | (CLIP(*y++) << 20); bytestream2_put_le32u(&p, val); val = CLIP(*v++) | (CLIP(*y++) << 10); bytestream2_put_le32u(&p, val); } } bytestream2_set_buffer(&p, 0, line_padding); y += pic->linesize[0] / 2 - avctx->width; u += pic->linesize[1] / 2 - avctx->width / 2; v += pic->linesize[2] / 2 - avctx->width / 2; } pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; return 0; }
static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data) { const AVFrame *pic = data; int aligned_width = ((avctx->width + 47) / 48) * 48; int stride = aligned_width * 8 / 3; int h, w; const uint16_t *y = (const uint16_t*)pic->data[0]; const uint16_t *u = (const uint16_t*)pic->data[1]; const uint16_t *v = (const uint16_t*)pic->data[2]; uint8_t *p = buf; uint8_t *pdst = buf; if (buf_size < aligned_width * avctx->height * 8 / 3) { av_log(avctx, AV_LOG_ERROR, "output buffer too small\n"); return -1; } #define CLIP(v) av_clip(v, 4, 1019) #define WRITE_PIXELS(a, b, c) \ do { \ val = CLIP(*a++); \ val |= (CLIP(*b++) << 10) | \ (CLIP(*c++) << 20); \ bytestream_put_le32(&p, val); \ } while (0) for (h = 0; h < avctx->height; h++) { uint32_t val; for (w = 0; w < avctx->width - 5; w += 6) { WRITE_PIXELS(u, y, v); WRITE_PIXELS(y, u, y); WRITE_PIXELS(v, y, u); WRITE_PIXELS(y, v, y); } if (w < avctx->width - 1) { WRITE_PIXELS(u, y, v); val = CLIP(*y++); if (w == avctx->width - 2) bytestream_put_le32(&p, val); } if (w < avctx->width - 3) { val |= (CLIP(*u++) << 10) | (CLIP(*y++) << 20); bytestream_put_le32(&p, val); val = CLIP(*v++) | (CLIP(*y++) << 10); bytestream_put_le32(&p, val); } pdst += stride; memset(p, 0, pdst - p); p = pdst; y += pic->linesize[0] / 2 - avctx->width; u += pic->linesize[1] / 2 - avctx->width / 2; v += pic->linesize[2] / 2 - avctx->width / 2; } return p - buf; }