4040#include <upipe/upipe_helper_sync.h>
4141#include <upipe/upipe_helper_output.h>
4242#include <upipe/upipe_helper_flow_def.h>
43+ #include <upipe/upipe_helper_ubuf_mgr.h>
4344#include <upipe-framers/upipe_s302_framer.h>
4445
4546#include <stdlib.h>
5859/* Length in bytes of two audio samples */
5960static const uint8_t pair_lengths [] = {5 , 6 , 7 , 0 };
6061
62+ #define S302_MAX_PAIR_LENGTH 7
63+ #define S302_MAX_CHANNELS 8
64+
6165/** @internal @This is the private context of an s302f pipe. */
6266struct upipe_s302f {
6367 /** refcount management structure */
@@ -77,6 +81,13 @@ struct upipe_s302f {
7781 /** attributes in the sequence header */
7882 struct uref * flow_def_attr ;
7983
84+ /** ubuf manager */
85+ struct ubuf_mgr * ubuf_mgr ;
86+ /** flow format packet */
87+ struct uref * flow_format ;
88+ /** ubuf manager request */
89+ struct urequest ubuf_mgr_request ;
90+
8091 /** currently detected frame rate */
8192 struct urational fps ;
8293 /** currently detected octet rate */
@@ -93,6 +104,13 @@ struct upipe_s302f {
93104 * sequence header) */
94105 bool acquired ;
95106
107+ uint8_t scratch_buffer [S302_MAX_PAIR_LENGTH * S302_MAX_CHANNELS /2 ];
108+ uint8_t scratch_buffer_count ;
109+
110+ bool have_valid_header ;
111+ uint8_t pair_length , num_channels ;
112+ uint8_t header [S302_HEADER_SIZE ];
113+
96114 /** public upipe structure */
97115 struct upipe upipe ;
98116};
@@ -105,6 +123,18 @@ UPIPE_HELPER_SYNC(upipe_s302f, acquired)
105123UPIPE_HELPER_OUTPUT (upipe_s302f , output , flow_def , output_state , request_list )
106124UPIPE_HELPER_FLOW_DEF (upipe_s302f , flow_def_input , flow_def_attr )
107125
126+ static int upipe_s302f_check (struct upipe * upipe , struct uref * flow_format )
127+ {
128+ if (flow_format != NULL )
129+ upipe_s302f_store_flow_def (upipe , flow_format );
130+ return UBASE_ERR_NONE ;
131+ }
132+
133+ UPIPE_HELPER_UBUF_MGR (upipe_s302f , ubuf_mgr , flow_format , ubuf_mgr_request ,
134+ upipe_s302f_check ,
135+ upipe_s302f_register_output_request ,
136+ upipe_s302f_unregister_output_request )
137+
108138/** @internal @This allocates an s302f pipe.
109139 *
110140 * @param mgr common management structure
@@ -126,9 +156,13 @@ static struct upipe *upipe_s302f_alloc(struct upipe_mgr *mgr,
126156 upipe_s302f_init_sync (upipe );
127157 upipe_s302f_init_output (upipe );
128158 upipe_s302f_init_flow_def (upipe );
159+ upipe_s302f_init_ubuf_mgr (upipe );
129160 upipe_s302f -> octetrate = 0 ;
130161 upipe_s302f -> next_uref = NULL ;
131162 upipe_s302f -> next_uref_size = 0 ;
163+ upipe_s302f -> scratch_buffer_count = 0 ;
164+ upipe_s302f -> have_valid_header = false;
165+ upipe_s302f -> pair_length = upipe_s302f -> num_channels = 0 ;
132166 uref_init (& upipe_s302f -> au_uref_s );
133167 upipe_throw_ready (upipe );
134168 return upipe ;
@@ -254,6 +288,7 @@ static void upipe_s302f_input(struct upipe *upipe, struct uref *uref,
254288 }
255289 bool end = ubase_check (uref_block_get_end (uref ));
256290
291+ #if 0
257292 if (ubase_check (uref_block_get_start (uref ))) {
258293 if (upipe_s302f -> next_uref != NULL )
259294 upipe_s302f_work (upipe , upump_p );
@@ -277,6 +312,243 @@ static void upipe_s302f_input(struct upipe *upipe, struct uref *uref,
277312
278313 if (end )
279314 upipe_s302f_work (upipe , upump_p );
315+ #else
316+
317+ if (ubase_check (uref_block_get_start (uref ))) {
318+ int audio_packet_size ;
319+ uint8_t num_channels ;
320+ uint8_t bits_per_sample ;
321+ uint8_t pair_length ;
322+ int num_samples ;
323+
324+ /* Get header properties. */
325+ if (!ubase_check (uref_block_extract (uref , 0 , S302_HEADER_SIZE , upipe_s302f -> header ))) {
326+ uref_free (uref );
327+ return ;
328+ }
329+ audio_packet_size = (upipe_s302f -> header [0 ] << 8 ) | upipe_s302f -> header [1 ];
330+ upipe_s302f -> num_channels = num_channels = ((upipe_s302f -> header [2 ] >> 6 ) + 1 ) * 2 ;
331+ bits_per_sample = (upipe_s302f -> header [3 ] >> 4 ) & 0x3 ;
332+
333+ upipe_s302f -> pair_length = pair_length = pair_lengths [bits_per_sample ];
334+ if (!pair_length ) {
335+ uref_free (uref );
336+ upipe_s302f -> have_valid_header = false;
337+ return ;
338+ }
339+ upipe_s302f -> have_valid_header = true;
340+
341+
342+ /* Make/update output flow_def. */
343+ struct uref * flow_def = upipe_s302f_alloc_flow_def_attr (upipe );
344+ if (unlikely (flow_def == NULL )) {
345+ upipe_throw_fatal (upipe , UBASE_ERR_ALLOC );
346+ uref_free (uref );
347+ return ;
348+ }
349+
350+ UBASE_FATAL (upipe , uref_flow_set_def (flow_def , "block.s302m.sound." ))
351+ UBASE_FATAL (upipe , uref_sound_flow_set_rate (flow_def , S302_FREQUENCY ))
352+ UBASE_FATAL (upipe , uref_sound_flow_set_channels (flow_def , num_channels ))
353+
354+ flow_def = upipe_s302f_store_flow_def_attr (upipe , flow_def );
355+ if (unlikely (flow_def == NULL )) {
356+ upipe_throw_fatal (upipe , UBASE_ERR_ALLOC );
357+ uref_free (uref );
358+ return ;
359+ }
360+ upipe_s302f_sync_acquired (upipe );
361+
362+ /* Get a ubuf_mgr to alloc new blocks. */
363+ if (!upipe_s302f -> ubuf_mgr
364+ || !ubase_check (ubuf_mgr_check (upipe_s302f -> ubuf_mgr , flow_def )))
365+ upipe_s302f_require_ubuf_mgr (upipe , flow_def );
366+ else
367+ uref_free (flow_def );
368+
369+ /* Set header size to the max data that is in the uref. */
370+ num_samples = (uref_size - S302_HEADER_SIZE ) / (pair_length * (num_channels / 2 ));
371+ audio_packet_size = num_samples * (pair_length * (num_channels / 2 ));
372+ upipe_s302f -> header [0 ] = audio_packet_size >> 8 ;
373+ upipe_s302f -> header [1 ] = audio_packet_size ;
374+
375+ if (!upipe_s302f -> ubuf_mgr ) {
376+ upipe_verbose (upipe , "no ubuf_mgr, dropping uref" );
377+ uref_free (uref );
378+ return ;
379+ }
380+
381+ /* Create new block. */
382+ struct ubuf * ubuf = ubuf_block_alloc (upipe_s302f -> ubuf_mgr ,
383+ S302_HEADER_SIZE + audio_packet_size );
384+ if (unlikely (ubuf == NULL )) {
385+ upipe_throw_error (upipe , UBASE_ERR_ALLOC );
386+ uref_free (uref );
387+ return ;
388+ }
389+
390+ int size = -1 ;
391+ uint8_t * data ;
392+ int ret = ubuf_block_write (ubuf , 0 , & size , & data );
393+ if (!ubase_check (ret )) {
394+ upipe_throw_error (upipe , ret );
395+ uref_free (uref );
396+ ubuf_free (ubuf );
397+ return ;
398+ }
399+
400+ /* Copy header. */
401+ memcpy (data , upipe_s302f -> header , S302_HEADER_SIZE );
402+ /* Copy audio data. */
403+ ret = uref_block_extract (uref , S302_HEADER_SIZE , audio_packet_size , data + S302_HEADER_SIZE );
404+ if (!ubase_check (ret )) {
405+ upipe_throw_error (upipe , ret );
406+ uref_free (uref );
407+ ubuf_block_unmap (ubuf , 0 );
408+ ubuf_free (ubuf );
409+ return ;
410+ }
411+
412+ assert ((uref_size - S302_HEADER_SIZE - audio_packet_size ) <= S302_MAX_PAIR_LENGTH * S302_MAX_CHANNELS /2 );
413+
414+ /* Store tail of data that must be output next time. */
415+ ret = uref_block_extract (uref , S302_HEADER_SIZE + audio_packet_size , -1 ,
416+ upipe_s302f -> scratch_buffer );
417+ if (!ubase_check (ret )) {
418+ upipe_throw_error (upipe , ret );
419+ uref_free (uref );
420+ ubuf_block_unmap (ubuf , 0 );
421+ ubuf_free (ubuf );
422+ return ;
423+ }
424+ upipe_s302f -> scratch_buffer_count = uref_size - S302_HEADER_SIZE - audio_packet_size ;
425+
426+ ubuf_block_unmap (ubuf , 0 );
427+ uref_attach_ubuf (uref , ubuf );
428+
429+ /* Set clocks. */
430+ uint64_t duration = num_samples * UCLOCK_FREQ / S302_FREQUENCY ;
431+
432+ /* We work on encoded data so in the DTS domain. Rebase on DTS */
433+ uint64_t date ;
434+ struct urational drift_rate ;
435+ drift_rate .den = 0 ;
436+ uref_clock_get_rate (uref , & drift_rate );
437+ #define SET_DATE (dv ) \
438+ if (ubase_check(uref_clock_get_dts_##dv(uref, &date)))\
439+ uref_clock_set_dts_##dv(&upipe_s302f->au_uref_s, date); \
440+ if (ubase_check(uref_clock_get_dts_##dv(&upipe_s302f->au_uref_s, \
441+ &date))) { \
442+ uref_clock_set_dts_##dv(uref, date); \
443+ uref_clock_set_dts_##dv(&upipe_s302f->au_uref_s, date + duration); \
444+ }
445+ SET_DATE (sys )
446+ SET_DATE (prog )
447+ SET_DATE (orig )
448+ #undef SET_DATE
449+
450+ uref_clock_set_dts_pts_delay (uref , 0 );
451+ if (drift_rate .den )
452+ uref_clock_set_rate (uref , drift_rate );
453+
454+ upipe_s302f_output (upipe , uref , upump_p );
455+ }
456+
457+ else if (upipe_s302f -> have_valid_header ) {
458+ /* Number of whole samples in uref and scratch buffer. */
459+ int num_samples = (upipe_s302f -> scratch_buffer_count + uref_size ) / (upipe_s302f -> pair_length * (upipe_s302f -> num_channels / 2 ));
460+ int audio_packet_size = num_samples * (upipe_s302f -> pair_length * (upipe_s302f -> num_channels / 2 ));
461+
462+ upipe_s302f -> header [0 ] = audio_packet_size >> 8 ;
463+ upipe_s302f -> header [1 ] = audio_packet_size ;
464+
465+ /* Create new block. */
466+ struct ubuf * ubuf = ubuf_block_alloc (upipe_s302f -> ubuf_mgr ,
467+ S302_HEADER_SIZE + audio_packet_size );
468+ if (unlikely (ubuf == NULL )) {
469+ upipe_throw_error (upipe , UBASE_ERR_ALLOC );
470+ uref_free (uref );
471+ return ;
472+ }
473+
474+ int size = -1 ;
475+ uint8_t * data ;
476+ int ret = ubuf_block_write (ubuf , 0 , & size , & data );
477+ if (!ubase_check (ret )) {
478+ upipe_throw_error (upipe , ret );
479+ uref_free (uref );
480+ ubuf_free (ubuf );
481+ return ;
482+ }
483+
484+ /* Copy header. */
485+ memcpy (data , upipe_s302f -> header , S302_HEADER_SIZE );
486+ /* Copy tail of previous packet. */
487+ memcpy (data + S302_HEADER_SIZE , upipe_s302f -> scratch_buffer , upipe_s302f -> scratch_buffer_count );
488+ /* Copy audio data. */
489+ ret = uref_block_extract (uref , 0 , audio_packet_size - upipe_s302f -> scratch_buffer_count ,
490+ data + S302_HEADER_SIZE + upipe_s302f -> scratch_buffer_count );
491+ if (!ubase_check (ret )) {
492+ upipe_throw_error (upipe , ret );
493+ uref_free (uref );
494+ ubuf_block_unmap (ubuf , 0 );
495+ ubuf_free (ubuf );
496+ return ;
497+ }
498+
499+ assert (uref_size - audio_packet_size + upipe_s302f -> scratch_buffer_count <= S302_MAX_PAIR_LENGTH * S302_MAX_CHANNELS /2 );
500+ if (end )
501+ assert (uref_size - audio_packet_size + upipe_s302f -> scratch_buffer_count == 0 );
502+
503+ /* Store tail of data that must be output next time. */
504+ ret = uref_block_extract (uref , audio_packet_size - upipe_s302f -> scratch_buffer_count , -1 ,
505+ upipe_s302f -> scratch_buffer );
506+ if (!ubase_check (ret )) {
507+ upipe_throw_error (upipe , ret );
508+ uref_free (uref );
509+ ubuf_block_unmap (ubuf , 0 );
510+ ubuf_free (ubuf );
511+ return ;
512+ }
513+ upipe_s302f -> scratch_buffer_count = (uref_size + upipe_s302f -> scratch_buffer_count ) - audio_packet_size ;
514+
515+ ubuf_block_unmap (ubuf , 0 );
516+ uref_attach_ubuf (uref , ubuf );
517+
518+ /* Set clocks. */
519+ uint64_t duration = num_samples * UCLOCK_FREQ / S302_FREQUENCY ;
520+
521+ /* We work on encoded data so in the DTS domain. Rebase on DTS */
522+ uint64_t date ;
523+ struct urational drift_rate ;
524+ drift_rate .den = 0 ;
525+ uref_clock_get_rate (uref , & drift_rate );
526+ #define SET_DATE (dv ) \
527+ if (ubase_check(uref_clock_get_dts_##dv(uref, &date)))\
528+ uref_clock_set_dts_##dv(&upipe_s302f->au_uref_s, date); \
529+ if (ubase_check(uref_clock_get_dts_##dv(&upipe_s302f->au_uref_s, \
530+ &date))) { \
531+ uref_clock_set_dts_##dv(uref, date); \
532+ uref_clock_set_dts_##dv(&upipe_s302f->au_uref_s, date + duration); \
533+ }
534+ SET_DATE (sys )
535+ SET_DATE (prog )
536+ SET_DATE (orig )
537+ #undef SET_DATE
538+
539+ uref_clock_set_dts_pts_delay (uref , 0 );
540+ if (drift_rate .den )
541+ uref_clock_set_rate (uref , drift_rate );
542+
543+ upipe_s302f_output (upipe , uref , upump_p );
544+ }
545+
546+ else {
547+ upipe_verbose (upipe , "no valid header, dropping uref" );
548+ uref_free (uref );
549+ }
550+
551+ #endif
280552}
281553
282554/** @internal @This sets the input flow definition.
@@ -316,6 +588,22 @@ static int upipe_s302f_control(struct upipe *upipe, int command, va_list args)
316588{
317589 UBASE_HANDLED_RETURN (upipe_s302f_control_output (upipe , command , args ));
318590 switch (command ) {
591+ case UPIPE_REGISTER_REQUEST : {
592+ struct urequest * request = va_arg (args , struct urequest * );
593+ if (request -> type == UREQUEST_UBUF_MGR ||
594+ request -> type == UREQUEST_FLOW_FORMAT )
595+ return upipe_throw_provide_request (upipe , request );
596+ return upipe_s302f_alloc_output_proxy (upipe , request );
597+ }
598+
599+ case UPIPE_UNREGISTER_REQUEST : {
600+ struct urequest * request = va_arg (args , struct urequest * );
601+ if (request -> type == UREQUEST_UBUF_MGR ||
602+ request -> type == UREQUEST_FLOW_FORMAT )
603+ return UBASE_ERR_NONE ;
604+ return upipe_s302f_free_output_proxy (upipe , request );
605+ }
606+
319607 case UPIPE_SET_FLOW_DEF : {
320608 struct uref * flow_def = va_arg (args , struct uref * );
321609 return upipe_s302f_set_flow_def (upipe , flow_def );
@@ -339,6 +627,7 @@ static void upipe_s302f_free(struct upipe *upipe)
339627 upipe_s302f_clean_flow_def (upipe );
340628 upipe_s302f_clean_sync (upipe );
341629
630+ upipe_s302f_clean_ubuf_mgr (upipe );
342631 upipe_s302f_clean_urefcount (upipe );
343632 upipe_s302f_free_void (upipe );
344633}
0 commit comments