+ *pp_buffer = calloc( FISBONE_BASE_SIZE + headers.i_size, sizeof(uint8_t) );
+ if ( !*pp_buffer ) return;
+ p_buffer = *pp_buffer;
+
+ memcpy( p_buffer, "fisbone", 8 );
+ SetDWLE( &p_buffer[8], FISBONE_BASE_OFFSET ); /* offset to message headers */
+ SetDWLE( &p_buffer[12], p_stream->i_serial_no );
+ SetDWLE( &p_buffer[16], headers.i_count );
+
+ /* granulerate den */
+ switch ( p_input->p_fmt->i_cat )
+ {
+ case VIDEO_ES:
+ SetQWLE( &(*pp_buffer)[20], p_input->p_fmt->video.i_frame_rate );
+ SetQWLE( &(*pp_buffer)[28], p_input->p_fmt->video.i_frame_rate_base );
+ break;
+ case AUDIO_ES:
+ SetQWLE( &(*pp_buffer)[20], p_input->p_fmt->audio.i_rate );
+ SetQWLE( &(*pp_buffer)[28], 1 );
+ break;
+ default:
+ SetQWLE( &(*pp_buffer)[20], 1000 );
+ SetQWLE( &(*pp_buffer)[28], 1 );
+ }
+
+ /* preroll */
+ if ( p_input->p_fmt->p_extra )
+ SetDWLE( &(*pp_buffer)[44], xiph_CountHeaders( p_input->p_fmt->p_extra, p_input->p_fmt->i_extra ) );
+
+ if ( headers.i_size > 0 )
+ {
+ psz_header = *pp_buffer + FISBONE_BASE_SIZE;
+ memcpy( psz_header, headers.psz_content_type, strlen( headers.psz_content_type ) );
+ psz_header += strlen( headers.psz_content_type );
+ if ( headers.psz_role )
+ memcpy( psz_header, headers.psz_role, strlen( headers.psz_role ) );
+ }
+ *pi_size = FISBONE_BASE_SIZE + headers.i_size;
+
+ free( headers.psz_content_type );
+ free( headers.psz_role );
+}
+
+static void OggFillSkeletonFishead( uint8_t *p_buffer, sout_mux_t *p_mux )
+{
+ memcpy( p_buffer, "fishead", 8 );
+ SetWLE( &p_buffer[8], 4 );
+ SetWLE( &p_buffer[10], 0 );
+ SetQWLE( &p_buffer[20], 1000 );
+ SetQWLE( &p_buffer[36], 1000 );
+ SetQWLE( &p_buffer[64], p_mux->p_sys->i_pos - p_mux->p_sys->i_segment_start ); /* segment length */
+ SetQWLE( &p_buffer[72], p_mux->p_sys->i_data_start - p_mux->p_sys->i_segment_start ); /* data start offset */
+}
+
+static int32_t OggFillDsHeader( uint8_t *p_buffer, oggds_header_t *p_oggds_header, int i_cat )
+{
+ int index = 0;
+ p_buffer[index] = p_oggds_header->i_packet_type;
+ index++;
+ memcpy( &p_buffer[index], p_oggds_header->stream_type, sizeof(p_oggds_header->stream_type) );
+ index += sizeof(p_oggds_header->stream_type);
+ memcpy(&p_buffer[index], p_oggds_header->sub_type, sizeof(p_oggds_header->sub_type) );
+ index += sizeof(p_oggds_header->sub_type);
+
+ /* The size is filled at the end */
+ uint8_t *p_isize = &p_buffer[index];
+ index += 4;
+
+ SetQWLE( &p_buffer[index], p_oggds_header->i_time_unit );
+ index += 8;
+ SetQWLE( &p_buffer[index], p_oggds_header->i_samples_per_unit );
+ index += 8;
+ SetDWLE( &p_buffer[index], p_oggds_header->i_default_len );
+ index += 4;
+ SetDWLE( &p_buffer[index], p_oggds_header->i_buffer_size );
+ index += 4;
+ SetWLE( &p_buffer[index], p_oggds_header->i_bits_per_sample );
+ index += 2;
+ SetWLE( &p_buffer[index], p_oggds_header->i_padding_0 );
+ index += 2;
+ /* audio or video */
+ switch( i_cat )
+ {
+ case VIDEO_ES:
+ SetDWLE( &p_buffer[index], p_oggds_header->header.video.i_width );
+ SetDWLE( &p_buffer[index+4], p_oggds_header->header.video.i_height );
+ break;
+ case AUDIO_ES:
+ SetWLE( &p_buffer[index], p_oggds_header->header.audio.i_channels );
+ SetWLE( &p_buffer[index+2], p_oggds_header->header.audio.i_block_align );
+ SetDWLE( &p_buffer[index+4], p_oggds_header->header.audio.i_avgbytespersec );
+ break;
+ }
+ index += 8;
+ SetDWLE( &p_buffer[index], p_oggds_header->i_padding_1 );
+ index += 4;
+
+ /* extra header */
+ if( p_oggds_header->i_size > 0 )
+ {
+ memcpy( &p_buffer[index], (uint8_t *) p_oggds_header + sizeof(*p_oggds_header), p_oggds_header->i_size );
+ index += p_oggds_header->i_size;
+ }
+
+ SetDWLE( p_isize, index-1 );
+ return index;
+}
+
+static void OggFillVP8Header( uint8_t *p_buffer, sout_input_t *p_input )
+{
+ memcpy( p_buffer, "OVP80\x01\x01\x00", 8 );
+ SetWBE( &p_buffer[8], p_input->p_fmt->video.i_width );
+ SetDWBE( &p_buffer[14], p_input->p_fmt->video.i_sar_den );/* 24 bits, 15~ */
+ SetDWBE( &p_buffer[11], p_input->p_fmt->video.i_sar_num );/* 24 bits, 12~ */
+ SetWBE( &p_buffer[10], p_input->p_fmt->video.i_height );
+ SetDWBE( &p_buffer[18], p_input->p_fmt->video.i_frame_rate );
+ SetDWBE( &p_buffer[22], p_input->p_fmt->video.i_frame_rate_base );