Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 116 additions & 88 deletions lib/upipe-filters/upipe_audio_bar.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include "upipe/upipe_helper_upipe.h"
#include "upipe/upipe_helper_urefcount.h"
#include "upipe/upipe_helper_flow.h"
#include "upipe/upipe_helper_input.h"
#include "upipe/upipe_helper_output.h"
#include "upipe/upipe_helper_ubuf_mgr.h"
#include "upipe/upipe_helper_flow_format.h"
Expand All @@ -39,9 +38,6 @@
/** default alpha channel */
#define DEFAULT_ALPHA 0x60

/** @hidden */
static bool upipe_audiobar_handle(struct upipe *upipe, struct uref *uref,
struct upump **upump_p);
/** @hidden */
static int upipe_audiobar_check_flow_format(struct upipe *upipe,
struct uref *flow_format);
Expand Down Expand Up @@ -83,15 +79,6 @@ struct upipe_audiobar {
/* peak date */
uint64_t peak_date[255];

/** temporary uref storage (used during urequest) */
struct uchain urefs;
/** nb urefs in storage */
unsigned int nb_urefs;
/** max urefs in storage */
unsigned int max_urefs;
/** list of blockers (used during urequest) */
struct uchain blockers;

/** number of input channels */
uint8_t channels;
/** requested width */
Expand All @@ -105,15 +92,16 @@ struct upipe_audiobar {
/** inferred padding at end of line */
uint64_t pad_width;

/** 10 bit output */
bool tenbit;

/** public upipe structure */
struct upipe upipe;
};

UPIPE_HELPER_UPIPE(upipe_audiobar, upipe, UPIPE_AUDIO_BAR_SIGNATURE)
UPIPE_HELPER_UREFCOUNT(upipe_audiobar, urefcount, upipe_audiobar_free)
UPIPE_HELPER_FLOW(upipe_audiobar, OUTPUT_FLOW_DEF)
UPIPE_HELPER_INPUT(upipe_audiobar, urefs, nb_urefs, max_urefs, blockers,
upipe_audiobar_handle)
UPIPE_HELPER_OUTPUT(upipe_audiobar, output, flow_def, output_state, request_list)
UPIPE_HELPER_FLOW_FORMAT(upipe_audiobar, request,
upipe_audiobar_check_flow_format,
Expand Down Expand Up @@ -144,7 +132,6 @@ static struct upipe *upipe_audiobar_alloc(struct upipe_mgr *mgr,

struct upipe_audiobar *upipe_audiobar = upipe_audiobar_from_upipe(upipe);
upipe_audiobar_init_urefcount(upipe);
upipe_audiobar_init_input(upipe);
upipe_audiobar_init_output(upipe);
upipe_audiobar_init_ubuf_mgr(upipe);
upipe_audiobar_init_flow_format(upipe);
Expand Down Expand Up @@ -186,6 +173,49 @@ static double iec_scale(double dB)
return 1.0;
}

/** @internal @This copies pixels to the destination picture.
*
* @param dst array of destination chromas (planar YUV422P10LE)
* @param strides array of strides for each chroma
* @param hsubs array of hsubs of each chroma
* @param vsubs array of vsubs of each chroma
* @param color 16-bit color code
* @param row row number
* @param col column number
* @param w size of the copy
*/
static void copy_color10(uint8_t **dst, const size_t *strides,
const uint8_t *hsubs, const uint8_t *vsubs, const uint16_t *color,
unsigned row, unsigned col, unsigned w)
{
for (int i = 0; i < 3; i++) {
if (dst[i] == NULL)
continue;

uint16_t *d = (uint16_t*)&dst[i][(row / vsubs[i]) * strides[i]];

unsigned offset = col / hsubs[i];
unsigned count = w / hsubs[i];
for (unsigned j = 0; j < count; j++) {
d[offset + j] = color[i] << 2;
}
}

if (dst[3] != NULL)
memset(&dst[3][(row / vsubs[3]) * strides[3] + col / hsubs[3]],
color[3], w / hsubs[3]); // a8

if (dst[4] != NULL) { // u10v10l
uint16_t *d = (uint16_t*)&dst[4][(row / vsubs[4]) * strides[4] +
2 * col / hsubs[4]];

for (int i = 0; i < w / hsubs[4]; i++) {
d[i * 2] = color[1];
d[i * 2 + 1] = color[2];
}
}
}

/** @internal @This copies pixels to the destination picture.
*
* @param dst array of destination chromas (planar YUV422)
Expand All @@ -194,11 +224,11 @@ static double iec_scale(double dB)
* @param vsubs array of vsubs of each chroma
* @param color 32-bit color code
* @param row row number
* @param col colon number
* @param col column number
* @param w size of the copy
*/
static void copy_color(uint8_t **dst, size_t *strides,
uint8_t *hsubs, uint8_t *vsubs, const uint8_t *color,
static void copy_color8(uint8_t **dst, const size_t *strides,
const uint8_t *hsubs, const uint8_t *vsubs, const uint16_t *color,
unsigned row, unsigned col, unsigned w)
{
if (dst[0] != NULL)
Expand Down Expand Up @@ -230,49 +260,34 @@ static void copy_color(uint8_t **dst, size_t *strides,
* @param upump_p reference to pump that generated the buffer
* @return true if the packet was handled
*/
static bool upipe_audiobar_handle(struct upipe *upipe, struct uref *uref,
static void upipe_audiobar_input(struct upipe *upipe, struct uref *uref,
struct upump **upump_p)
{
struct upipe_audiobar *upipe_audiobar = upipe_audiobar_from_upipe(upipe);
const char *def;
if (unlikely(ubase_check(uref_flow_get_def(uref, &def)))) {
UBASE_FATAL(upipe,
uref_sound_flow_get_channels(uref, &upipe_audiobar->channels))
uref_sound_flow_clear_format(uref);
UBASE_FATAL(upipe,
uref_attr_import(uref, upipe_audiobar->flow_def_config))
uref_pic_flow_clear_format(uref);
UBASE_FATAL(upipe, uref_pic_flow_set_planes(uref, 0))
UBASE_FATAL(upipe, uref_pic_flow_set_macropixel(uref, 1))
UBASE_FATAL(upipe, uref_pic_flow_add_plane(uref, 1, 1, 1, "y8"))
UBASE_FATAL(upipe, uref_pic_flow_add_plane(uref, 2, 1, 1, "u8"))
UBASE_FATAL(upipe, uref_pic_flow_add_plane(uref, 2, 1, 1, "v8"))
UBASE_FATAL(upipe, uref_pic_flow_add_plane(uref, 1, 1, 1, "a8"))
UBASE_FATAL(upipe, uref_pic_set_progressive(uref))

upipe_audiobar->hsize = upipe_audiobar->vsize =
upipe_audiobar->sep_width = upipe_audiobar->pad_width = UINT64_MAX;
upipe_audiobar_require_flow_format(upipe, uref);
return true;
if (unlikely(!upipe_audiobar->ubuf_mgr || upipe_audiobar->hsize == UINT64_MAX)) {
uref_free(uref);
return;
}

if (!upipe_audiobar->ubuf_mgr)
return false;

if (unlikely(upipe_audiobar->hsize == UINT64_MAX))
return false;

struct ubuf *ubuf = ubuf_pic_alloc(upipe_audiobar->ubuf_mgr,
upipe_audiobar->hsize,
upipe_audiobar->vsize);
uref_attach_ubuf(uref, ubuf);

static const char *chroma[] = { "y8", "u8", "v8", "a8", "u8v8" };
#define NR_CHROMA UBASE_ARRAY_SIZE(chroma)
static const char *chroma8[] = { "y8", "u8", "v8", "a8", "u8v8" };
static const char *chroma10[] = { "y10l", "u10l", "v10l", "a8", "u10v10l" };
#define NR_CHROMA UBASE_ARRAY_SIZE(chroma8)
uint8_t *dst[NR_CHROMA];
size_t strides[NR_CHROMA];
uint8_t hsubs[NR_CHROMA];
uint8_t vsubs[NR_CHROMA];

const char **chroma = upipe_audiobar->tenbit ? chroma10 : chroma8;
void (*copy_color)(uint8_t **dst, const size_t *strides,
const uint8_t *hsubs, const uint8_t *vsubs, const uint16_t *color,
unsigned row, unsigned col, unsigned w) = upipe_audiobar->tenbit ? copy_color10 : copy_color8;

for (int i = 0; i < NR_CHROMA; i++) {
if (unlikely(!ubase_check(uref_pic_plane_write(uref, chroma[i],
0, 0, -1, -1, &dst[i])) ||
Expand All @@ -286,11 +301,11 @@ static bool upipe_audiobar_handle(struct upipe *upipe, struct uref *uref,
uint64_t h = upipe_audiobar->vsize;
const int hred = h - (iec_scale(-8.) * h);
const int hyellow = h - (iec_scale(-18.) * h);
uint8_t transparent[4] = { 0x10, 0x80, 0x80, 0 };
uint8_t black[4] = { 0x10, 0x80, 0x80, alpha };
uint8_t red[2][4] = { { 76, 85, 0xff, alpha }, { 37, 106, 191, alpha } };
uint8_t green[2][4] = { { 150, 44, 21, alpha }, { 74, 85, 74, alpha } };
uint8_t yellow[2][4] = { { 226, 1, 148, alpha }, { 112, 64, 138, alpha } };
uint16_t transparent[4] = { 0x10, 0x80, 0x80, 0 };
uint16_t black[4] = { 0x10, 0x80, 0x80, alpha };
uint16_t red[2][4] = { { 76, 85, 0xff, alpha }, { 37, 106, 191, alpha } };
uint16_t green[2][4] = { { 150, 44, 21, alpha }, { 74, 85, 74, alpha } };
uint16_t yellow[2][4] = { { 226, 1, 148, alpha }, { 112, 64, 138, alpha } };

uint64_t pts = 0;
if (unlikely(!ubase_check(uref_clock_get_pts_prog(uref, &pts)))) {
Expand Down Expand Up @@ -322,7 +337,7 @@ static bool upipe_audiobar_handle(struct upipe *upipe, struct uref *uref,
for (int row = 0; row < h; row++) {
bool bright = row > hmax;

const uint8_t *color = row < hred ? red[!bright] :
const uint16_t *color = row < hred ? red[!bright] :
row < hyellow ? yellow[!bright] :
green[!bright];

Expand Down Expand Up @@ -353,28 +368,6 @@ static bool upipe_audiobar_handle(struct upipe *upipe, struct uref *uref,
for (int i = 0; i < NR_CHROMA; i++)
ubuf_pic_plane_unmap(ubuf, chroma[i], 0, 0, -1, -1);
upipe_audiobar_output(upipe, uref, upump_p);
return true;
}

/** @internal @This inputs data.
*
* @param upipe description structure of the pipe
* @param uref uref structure
* @param upump_p reference to pump that generated the buffer
*/
static void upipe_audiobar_input(struct upipe *upipe, struct uref *uref,
struct upump **upump_p)
{
if (!upipe_audiobar_check_input(upipe)) {
upipe_audiobar_hold_input(upipe, uref);
upipe_audiobar_block_input(upipe, upump_p);
} else if (!upipe_audiobar_handle(upipe, uref, upump_p)) {
upipe_audiobar_hold_input(upipe, uref);
upipe_audiobar_block_input(upipe, upump_p);
/* Increment upipe refcount to avoid disappearing before all packets
* have been sent. */
upipe_use(upipe);
}
}

/** @internal @This provides a flow_format request.
Expand Down Expand Up @@ -405,6 +398,26 @@ static int upipe_audiobar_check_ubuf_mgr(struct upipe *upipe,
if (flow_format == NULL)
return UBASE_ERR_NONE;

if (!ubase_check(uref_pic_flow_find_chroma(flow_format, "a8", NULL))) {
upipe_err(upipe, "Missing alpha plane");
return UBASE_ERR_INVALID;
}

if (!ubase_check(uref_pic_flow_find_chroma(flow_format, "y8", NULL))
|| ((!ubase_check(uref_pic_flow_find_chroma(flow_format, "u8", NULL))
|| !ubase_check(uref_pic_flow_find_chroma(flow_format, "v8", NULL)))
&& !ubase_check(uref_pic_flow_find_chroma(flow_format, "u8v8", NULL)))) {
if (!ubase_check(uref_pic_flow_find_chroma(flow_format, "y10l", NULL))
|| ((!ubase_check(uref_pic_flow_find_chroma(flow_format, "u10l", NULL)))
&& !ubase_check(uref_pic_flow_find_chroma(flow_format, "u10v10l", NULL)))) {
upipe_err(upipe, "Unknown pixel format");
uref_dump(flow_format, upipe->uprobe);
return UBASE_ERR_INVALID;
}
upipe_audiobar->tenbit = true;
} else
upipe_audiobar->tenbit = false;

upipe_audiobar_store_flow_def(upipe, flow_format);
UBASE_RETURN(uref_pic_flow_get_hsize(flow_format, &upipe_audiobar->hsize))
UBASE_RETURN(uref_pic_flow_get_vsize(flow_format, &upipe_audiobar->vsize))
Expand All @@ -425,14 +438,7 @@ static int upipe_audiobar_check_ubuf_mgr(struct upipe *upipe,
upipe_audiobar->chan_width, upipe_audiobar->sep_width,
upipe_audiobar->pad_width);

bool was_buffered = !upipe_audiobar_check_input(upipe);
upipe_audiobar_output_input(upipe);
upipe_audiobar_unblock_input(upipe);
if (was_buffered && upipe_audiobar_check_input(upipe)) {
/* All packets have been output, release again the pipe that has been
* used in @ref upipe_audiobar_input. */
upipe_release(upipe);
}

return UBASE_ERR_NONE;
}

Expand All @@ -445,17 +451,40 @@ static int upipe_audiobar_check_ubuf_mgr(struct upipe *upipe,
static int upipe_audiobar_set_flow_def(struct upipe *upipe,
struct uref *flow_def)
{
struct upipe_audiobar *upipe_audiobar = upipe_audiobar_from_upipe(upipe);
if (flow_def == NULL)
return UBASE_ERR_INVALID;
uref_dump(flow_def, upipe->uprobe);
UBASE_RETURN(uref_flow_match_def(flow_def, INPUT_FLOW_DEF))
uint8_t channels;
UBASE_RETURN(uref_sound_flow_get_channels(flow_def, &channels))

struct uref *flow_def_dup;
if (unlikely((flow_def_dup = uref_dup(flow_def)) == NULL))
return UBASE_ERR_ALLOC;
upipe_input(upipe, flow_def_dup, NULL);
const char *def;
if (unlikely(ubase_check(uref_flow_get_def(flow_def, &def)))) {
flow_def = uref_dup(flow_def);
if (flow_def == NULL)
return UBASE_ERR_ALLOC;

UBASE_FATAL(upipe,
uref_sound_flow_get_channels(flow_def, &upipe_audiobar->channels))
uref_sound_flow_clear_format(flow_def);
UBASE_FATAL(upipe,
uref_attr_import(flow_def, upipe_audiobar->flow_def_config))
uref_pic_flow_clear_format(flow_def);
UBASE_FATAL(upipe, uref_pic_flow_set_planes(flow_def, 0))
UBASE_FATAL(upipe, uref_pic_flow_set_macropixel(flow_def, 1))
UBASE_FATAL(upipe, uref_pic_flow_add_plane(flow_def, 1, 1, 1, "y8"))
UBASE_FATAL(upipe, uref_pic_flow_add_plane(flow_def, 2, 1, 1, "u8"))
UBASE_FATAL(upipe, uref_pic_flow_add_plane(flow_def, 2, 1, 1, "v8"))
UBASE_FATAL(upipe, uref_pic_flow_add_plane(flow_def, 1, 1, 1, "a8"))
UBASE_FATAL(upipe, uref_pic_set_progressive(flow_def))
uref_dump(flow_def, upipe->uprobe);
upipe_audiobar->hsize = upipe_audiobar->vsize =
upipe_audiobar->sep_width = upipe_audiobar->pad_width = UINT64_MAX;

upipe_audiobar_require_flow_format(upipe, flow_def);
}

return UBASE_ERR_NONE;
}

Expand Down Expand Up @@ -548,7 +577,6 @@ static void upipe_audiobar_free(struct upipe *upipe)
upipe_audiobar_clean_flow_format(upipe);
upipe_audiobar_clean_ubuf_mgr(upipe);
upipe_audiobar_clean_output(upipe);
upipe_audiobar_clean_input(upipe);
upipe_audiobar_clean_urefcount(upipe);
upipe_audiobar_free_flow(upipe);
}
Expand Down
Loading