+ fmt.p_extra = tk->p_extra = malloc( fmt.i_extra );
+ if( !fmt.p_extra ) goto error;
+ memcpy( fmt.p_extra, &p_auds->p_wf[1], fmt.i_extra );
+
+ /* Rewrite the vorbis headers from Xiph-like format
+ * to VLC internal format
+ *
+ * Xiph format:
+ * - 1st byte == N, is the number of packets - 1
+ * - Following bytes are the size of the N first packets:
+ * while( *p == 0xFF ) { size += 0xFF; p++ } size += *p;
+ * (the size of the last packet is the size of remaining
+ * data in the buffer)
+ * - Finally, all the packets concatenated
+ *
+ * VLC format:
+ * - Size of the packet on 16 bits (big endian) FIXME: should be 32 bits to be safe
+ * - The packet itself
+ * - Size of the next packet, and so on ...
+ */
+
+ if( tk->i_codec == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
+ {
+ uint8_t *p_extra = fmt.p_extra;
+ size_t i_extra = fmt.i_extra;
+
+ if( i_extra <= 1 ) break;
+ if( *p_extra++ != 2 ) break; /* 3 packets - 1 = 2 */
+ i_extra--;
+
+ size_t i_identifier_len = 0;
+ while( *p_extra == 0xFF )
+ {
+ i_identifier_len += 0xFF;
+ p_extra++;
+ if( --i_extra <= 1 ) break;
+ }
+ i_identifier_len += *p_extra++;
+ if( i_identifier_len > --i_extra ) break;
+
+ size_t i_comment_len = 0;
+ while( *p_extra == 0xFF )
+ {
+ i_comment_len += 0xFF;
+ p_extra++;
+ if( --i_extra <= 1 ) break;
+ }
+ i_comment_len += *p_extra++;
+ if( i_comment_len > --i_extra ) break;
+ size_t i_cookbook_len = i_extra;
+
+ size_t i_headers_size = 3 * 2 + i_identifier_len +
+ i_comment_len + i_cookbook_len;
+ uint8_t *p_out = malloc( i_headers_size );
+ if( !p_out ) goto error;
+ free( fmt.p_extra );
+ fmt.p_extra = tk->p_extra = p_out;
+ fmt.i_extra = i_headers_size;
+ #define copy_packet( len ) \
+ *p_out++ = len >> 8; \
+ *p_out++ = len & 0xFF; \
+ memcpy( p_out, p_extra, len ); \
+ p_out += len; \
+ p_extra += len;
+ copy_packet( i_identifier_len );
+ copy_packet( i_comment_len );
+ copy_packet( i_cookbook_len );
+ #undef copy_packet
+ break;
+ }