Changeset 09d997200c05de78bb05ea4e2219fec752aef5a9

Show
Ignore:
Timestamp:
21/11/03 21:49:14 (5 years ago)
Author:
Gildas Bazin <gbazin@videolan.org>
git-committer:
Gildas Bazin <gbazin@videolan.org> 1069447754 +0000
git-parent:

[ea1b641e16d5dda49f420b7b0298e2b2c65ebc11]

git-author:
Gildas Bazin <gbazin@videolan.org> 1069447754 +0000
Message:

* modules/codec/flac.c: added a FLAC encoder.
* modules/mux/dummy.c, modules/mux/ogg.c: you can output "normal" flac streams with the es/dummy muxer or output them with an Ogg container.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/codec/flac.c

    r662af91 r09d9972  
    11/***************************************************************************** 
    2  * flac.c: flac decoder/packetizer module making use of libflac 
     2 * flac.c: flac decoder/packetizer/encoder module making use of libflac 
    33 ***************************************************************************** 
    44 * Copyright (C) 1999-2001 VideoLAN 
    5  * $Id: flac.c,v 1.2 2003/11/21 12:18:54 gbazin Exp $ 
     5 * $Id: flac.c,v 1.3 2003/11/21 20:49:13 gbazin Exp $ 
    66 * 
    77 * Authors: Gildas Bazin <gbazin@netcourrier.com> 
     
    3131 
    3232#include <FLAC/stream_decoder.h> 
     33#include <FLAC/stream_encoder.h> 
    3334 
    3435#include "vlc_block_helper.h" 
     
    104105static void CloseDecoder  ( vlc_object_t * ); 
    105106 
     107static int OpenEncoder   ( vlc_object_t * ); 
     108static void CloseEncoder ( vlc_object_t * ); 
     109 
    106110static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** ); 
    107111static block_t *PacketizeBlock( decoder_t *, block_t ** ); 
     
    150154    set_capability( "packetizer", 100 ); 
    151155    set_callbacks( OpenPacketizer, CloseDecoder ); 
     156 
     157    add_submodule(); 
     158    set_description( _("Flac audio encoder") ); 
     159    set_capability( "encoder", 100 ); 
     160    set_callbacks( OpenEncoder, CloseEncoder ); 
    152161 
    153162vlc_module_end(); 
     
    212221    /* Decode STREAMINFO */ 
    213222    msg_Dbg( p_dec, "decode STREAMINFO" ); 
    214     p_sys->p_block = block_New( p_dec, p_dec->fmt_in.i_extra + 4 ); 
    215     memcpy( p_sys->p_block->p_buffer + 4, p_dec->fmt_in.p_extra, 
     223    p_sys->p_block = block_New( p_dec, p_dec->fmt_in.i_extra ); 
     224    memcpy( p_sys->p_block->p_buffer, p_dec->fmt_in.p_extra, 
    216225            p_dec->fmt_in.i_extra ); 
    217     memcpy( p_sys->p_block->p_buffer, "fLaC", 4 ); 
    218226    FLAC__stream_decoder_process_until_end_of_metadata( p_sys->p_flac ); 
    219227    msg_Dbg( p_dec, "STREAMINFO decoded" ); 
     
    231239    { 
    232240        p_dec->p_sys->b_packetizer = VLC_TRUE; 
    233         p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','a','c'); 
     241        es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in ); 
    234242    } 
    235243 
     
    10101018    return crc; 
    10111019} 
     1020 
     1021/***************************************************************************** 
     1022 * encoder_sys_t : flac encoder descriptor 
     1023 *****************************************************************************/ 
     1024struct encoder_sys_t 
     1025{ 
     1026    /* 
     1027     * Input properties 
     1028     */ 
     1029    int i_headers; 
     1030 
     1031    int i_samples_delay; 
     1032    int i_channels; 
     1033 
     1034    FLAC__int32 *p_buffer; 
     1035    int         i_buffer; 
     1036 
     1037    block_t *p_chain; 
     1038 
     1039    /* 
     1040     * FLAC properties 
     1041     */ 
     1042    FLAC__StreamEncoder *p_flac; 
     1043    FLAC__StreamMetadata_StreamInfo stream_info; 
     1044 
     1045    /* 
     1046     * Common properties 
     1047     */ 
     1048    mtime_t i_pts; 
     1049}; 
     1050 
     1051#define STREAMINFO_SIZE 38 
     1052 
     1053static block_t *Encode( encoder_t *, aout_buffer_t * ); 
     1054 
     1055static FLAC__StreamEncoderWriteStatus 
     1056EncoderWriteCallback( const FLAC__StreamEncoder *encoder, 
     1057                      const FLAC__byte buffer[], 
     1058                      unsigned bytes, unsigned samples, 
     1059                      unsigned current_frame, void *client_data ); 
     1060 
     1061static void EncoderMetadataCallback( const FLAC__StreamEncoder *encoder, 
     1062                                     const FLAC__StreamMetadata *metadata, 
     1063                                     void *client_data ); 
     1064 
     1065/***************************************************************************** 
     1066 * OpenEncoder: probe the encoder and return score 
     1067 *****************************************************************************/ 
     1068static int OpenEncoder( vlc_object_t *p_this ) 
     1069{ 
     1070    encoder_t *p_enc = (encoder_t *)p_this; 
     1071    encoder_sys_t *p_sys; 
     1072 
     1073    if( p_enc->fmt_out.i_codec != VLC_FOURCC('f','l','a','c') ) 
     1074    { 
     1075        return VLC_EGENERIC; 
     1076    } 
     1077 
     1078    /* Allocate the memory needed to store the decoder's structure */ 
     1079    if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL ) 
     1080    { 
     1081        msg_Err( p_enc, "out of memory" ); 
     1082        return VLC_EGENERIC; 
     1083    } 
     1084    p_enc->p_sys = p_sys; 
     1085    p_enc->pf_encode_audio = Encode; 
     1086    p_sys->i_headers = 0; 
     1087    p_sys->p_buffer = 0; 
     1088    p_sys->i_buffer = 0; 
     1089 
     1090    /* Create flac encoder */ 
     1091    p_sys->p_flac = FLAC__stream_encoder_new(); 
     1092 
     1093    FLAC__stream_encoder_set_streamable_subset( p_sys->p_flac, 1 ); 
     1094    FLAC__stream_encoder_set_channels( p_sys->p_flac, 
     1095                                       p_enc->fmt_in.audio.i_channels ); 
     1096    FLAC__stream_encoder_set_sample_rate( p_sys->p_flac, 
     1097                                          p_enc->fmt_in.audio.i_rate ); 
     1098    FLAC__stream_encoder_set_bits_per_sample( p_sys->p_flac, 16 ); 
     1099    p_enc->fmt_in.i_codec = AOUT_FMT_S16_NE; 
     1100 
     1101    FLAC__stream_encoder_set_write_callback( p_sys->p_flac, 
     1102        EncoderWriteCallback ); 
     1103    FLAC__stream_encoder_set_metadata_callback( p_sys->p_flac, 
     1104        EncoderMetadataCallback ); 
     1105    FLAC__stream_encoder_set_client_data( p_sys->p_flac, p_enc ); 
     1106 
     1107    /* Get and store the STREAMINFO metadata block as a p_extra */ 
     1108    p_sys->p_chain = 0; 
     1109    FLAC__stream_encoder_init( p_sys->p_flac ); 
     1110 
     1111    return VLC_SUCCESS; 
     1112} 
     1113 
     1114/**************************************************************************** 
     1115 * Encode: the whole thing 
     1116 **************************************************************************** 
     1117 * This function spits out ogg packets. 
     1118 ****************************************************************************/ 
     1119static block_t *Encode( encoder_t *p_enc, aout_buffer_t *p_aout_buf ) 
     1120{ 
     1121    encoder_sys_t *p_sys = p_enc->p_sys; 
     1122    block_t *p_chain; 
     1123    int i; 
     1124 
     1125    p_sys->i_pts = p_aout_buf->start_date - 
     1126                (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay / 
     1127                (mtime_t)p_enc->fmt_in.audio.i_rate; 
     1128 
     1129    p_sys->i_samples_delay += p_aout_buf->i_nb_samples; 
     1130 
     1131    /* Convert samples to FLAC__int32 */ 
     1132    if( p_sys->i_buffer < p_aout_buf->i_nb_bytes * 2 ) 
     1133    { 
     1134        p_sys->p_buffer = 
     1135            realloc( p_sys->p_buffer, p_aout_buf->i_nb_bytes * 2 ); 
     1136        p_sys->i_buffer = p_aout_buf->i_nb_bytes * 2; 
     1137    } 
     1138 
     1139    for( i = 0 ; i < p_aout_buf->i_nb_bytes / 2 ; i++ ) 
     1140    { 
     1141        p_sys->p_buffer[i]= ((int16_t *)p_aout_buf->p_buffer)[i]; 
     1142    } 
     1143 
     1144    FLAC__stream_encoder_process_interleaved( p_sys->p_flac, p_sys->p_buffer, 
     1145                                              p_aout_buf->i_nb_samples ); 
     1146 
     1147    p_chain = p_sys->p_chain; 
     1148    p_sys->p_chain = 0; 
     1149 
     1150    return p_chain; 
     1151} 
     1152 
     1153/***************************************************************************** 
     1154 * CloseEncoder: encoder destruction 
     1155 *****************************************************************************/ 
     1156static void CloseEncoder( vlc_object_t *p_this ) 
     1157{ 
     1158    encoder_t *p_enc = (encoder_t *)p_this; 
     1159    encoder_sys_t *p_sys = p_enc->p_sys; 
     1160 
     1161    FLAC__stream_encoder_delete( p_sys->p_flac ); 
     1162 
     1163    if( p_sys->p_buffer ) free( p_sys->p_buffer ); 
     1164    free( p_sys ); 
     1165} 
     1166 
     1167/***************************************************************************** 
     1168 * EncoderMetadataCallback: called by libflac to output metadata 
     1169 *****************************************************************************/ 
     1170static void EncoderMetadataCallback( const FLAC__StreamEncoder *encoder, 
     1171                                     const FLAC__StreamMetadata *metadata, 
     1172                                     void *client_data ) 
     1173{ 
     1174    encoder_t *p_enc = (encoder_t *)client_data; 
     1175 
     1176    msg_Err( p_enc, "MetadataCallback: %i", metadata->type ); 
     1177    return; 
     1178} 
     1179 
     1180/***************************************************************************** 
     1181 * EncoderWriteCallback: called by libflac to output encoded samples 
     1182 *****************************************************************************/ 
     1183static FLAC__StreamEncoderWriteStatus 
     1184EncoderWriteCallback( const FLAC__StreamEncoder *encoder, 
     1185                      const FLAC__byte buffer[], 
     1186                      unsigned bytes, unsigned samples, 
     1187                      unsigned current_frame, void *client_data ) 
     1188{ 
     1189    encoder_t *p_enc = (encoder_t *)client_data; 
     1190    encoder_sys_t *p_sys = p_enc->p_sys; 
     1191    block_t *p_block; 
     1192 
     1193    if( samples == 0 && p_sys->i_headers <= 1 ) 
     1194    { 
     1195        if( p_sys->i_headers == 1 ) 
     1196        { 
     1197            msg_Err( p_enc, "Writing STREAMINFO: %i", bytes ); 
     1198 
     1199            /* Backup the STREAMINFO metadata block */ 
     1200            p_enc->fmt_out.i_extra = STREAMINFO_SIZE + 4; 
     1201            p_enc->fmt_out.p_extra = malloc( STREAMINFO_SIZE + 4 ); 
     1202            memcpy( p_enc->fmt_out.p_extra, "fLaC", 4 ); 
     1203            memcpy( ((uint8_t *)p_enc->fmt_out.p_extra) + 4, buffer, 
     1204                    STREAMINFO_SIZE + 4 ); 
     1205 
     1206            /* Fake this as the last metadata block */ 
     1207            ((uint8_t*)p_enc->fmt_out.p_extra)[4] |= 0x80; 
     1208        } 
     1209        p_sys->i_headers++; 
     1210        return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; 
     1211    } 
     1212 
     1213    p_block = block_New( p_enc, bytes ); 
     1214    memcpy( p_block->p_buffer, buffer, bytes ); 
     1215 
     1216    p_block->i_dts = p_block->i_pts = p_block->i_length = 0; 
     1217 
     1218    block_ChainAppend( &p_sys->p_chain, p_block ); 
     1219 
     1220    return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; 
     1221} 
  • modules/demux/flac.c

    r662af91 r09d9972  
    33 ***************************************************************************** 
    44 * Copyright (C) 2001 VideoLAN 
    5  * $Id: flac.c,v 1.7 2003/11/21 12:18:54 gbazin Exp $ 
     5 * $Id: flac.c,v 1.8 2003/11/21 20:49:13 gbazin Exp $ 
    66 * 
    77 * Authors: Gildas Bazin <gbazin@netcourrier.com> 
     
    100100    p_sys->b_start = VLC_TRUE; 
    101101 
    102     /* Skip stream marker */ 
    103     stream_Read( p_input->s, NULL, 4 ); 
    104  
    105102    /* We need to read and store the STREAMINFO metadata */ 
    106     i_peek = stream_Peek( p_input->s, &p_peek, 4 ); 
    107     if( p_peek[0] & 0x7F ) 
     103    i_peek = stream_Peek( p_input->s, &p_peek, 8 ); 
     104    if( p_peek[4] & 0x7F ) 
    108105    { 
    109106        msg_Err( p_input, "This isn't a STREAMINFO metadata block" ); 
     
    111108    } 
    112109 
    113     if( ((p_peek[1]<<16)+(p_peek[2]<<8)+p_peek[3]) != (STREAMINFO_SIZE - 4) ) 
     110    if( ((p_peek[5]<<16)+(p_peek[6]<<8)+p_peek[7]) != (STREAMINFO_SIZE - 4) ) 
    114111    { 
    115112        msg_Err( p_input, "Invalid size for a STREAMINFO metadata block" ); 
     
    133130 
    134131    /* Store STREAMINFO for the decoder and packetizer */ 
    135     p_sys->p_packetizer->fmt_in.i_extra = fmt.i_extra = STREAMINFO_SIZE
    136     p_sys->p_packetizer->fmt_in.p_extra = malloc( STREAMINFO_SIZE ); 
     132    p_sys->p_packetizer->fmt_in.i_extra = fmt.i_extra = STREAMINFO_SIZE + 4
     133    p_sys->p_packetizer->fmt_in.p_extra = malloc( STREAMINFO_SIZE + 4 ); 
    137134    stream_Read( p_input->s, p_sys->p_packetizer->fmt_in.p_extra, 
    138                  STREAMINFO_SIZE ); 
     135                 STREAMINFO_SIZE + 4 ); 
    139136 
    140137    /* Fake this as the last metadata block */ 
    141     ((uint8_t*)p_sys->p_packetizer->fmt_in.p_extra)[0] |= 0x80; 
    142     fmt.p_extra = malloc( STREAMINFO_SIZE ); 
    143     memcpy( fmt.p_extra, p_sys->p_packetizer->fmt_in.p_extra, STREAMINFO_SIZE); 
     138    ((uint8_t*)p_sys->p_packetizer->fmt_in.p_extra)[4] |= 0x80; 
     139    fmt.p_extra = malloc( STREAMINFO_SIZE + 4 ); 
     140    memcpy( fmt.p_extra, p_sys->p_packetizer->fmt_in.p_extra, 
     141            STREAMINFO_SIZE + 4 ); 
    144142 
    145143    p_sys->p_packetizer->p_module = 
  • modules/mux/dummy.c

    rfa34194 r09d9972  
    11/***************************************************************************** 
    2  * dummy.c 
     2 * dummy.c: dummy muxer module for vlc 
    33 ***************************************************************************** 
    44 * Copyright (C) 2001, 2002 VideoLAN 
    5  * $Id: dummy.c,v 1.8 2003/08/17 18:44:26 fenrir Exp $ 
     5 * $Id: dummy.c,v 1.9 2003/11/21 20:49:14 gbazin Exp $ 
    66 * 
    77 * Authors: Laurent Aimar <fenrir@via.ecp.fr> 
     
    4848vlc_module_end(); 
    4949 
    50  
    5150/***************************************************************************** 
    5251 * Exported prototypes 
     
    5756static int  Mux      ( sout_mux_t * ); 
    5857 
     58struct sout_mux_sys_t 
     59{ 
     60    /* Some streams have special initialization data, we'll output this 
     61     * data as an header in the stream. */ 
     62    vlc_bool_t b_header; 
     63}; 
     64 
    5965/***************************************************************************** 
    6066 * Open: 
     
    6369{ 
    6470    sout_mux_t *p_mux = (sout_mux_t*)p_this; 
     71    sout_mux_sys_t  *p_sys; 
    6572 
    6673    msg_Dbg( p_mux, "Dummy/Raw muxer opened" ); 
     
    7178    p_mux->pf_delstream = DelStream; 
    7279    p_mux->pf_mux       = Mux; 
     80 
     81    p_mux->p_sys = p_sys = malloc( sizeof( sout_mux_sys_t ) ); 
     82    p_sys->b_header      = VLC_TRUE; 
    7383 
    7484    return VLC_SUCCESS; 
     
    8292{ 
    8393    sout_mux_t *p_mux = (sout_mux_t*)p_this; 
     94    sout_mux_sys_t *p_sys = p_mux->p_sys; 
    8495 
    8596    msg_Dbg( p_mux, "Dummy/Raw muxer closed" ); 
     97    free( p_sys ); 
    8698} 
    8799 
     
    102114{ 
    103115    msg_Dbg( p_mux, "adding input" ); 
    104     return( 0 )
     116    return VLC_SUCCESS
    105117} 
    106118 
    107119static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input ) 
    108120{ 
    109  
    110121    msg_Dbg( p_mux, "removing input" ); 
    111     return( 0 )
     122    return VLC_SUCCESS
    112123} 
    113124 
    114 static int Mux      ( sout_mux_t *p_mux ) 
     125static int Mux( sout_mux_t *p_mux ) 
    115126{ 
     127    sout_mux_sys_t *p_sys = p_mux->p_sys; 
    116128    int i; 
     129 
    117130    for( i = 0; i < p_mux->i_nb_inputs; i++ ) 
    118131    { 
    119132        int i_count; 
    120133        sout_fifo_t *p_fifo; 
     134 
     135        if( p_sys->b_header && p_mux->pp_inputs[i]->p_fmt->i_extra ) 
     136        { 
     137            /* Write header data */ 
     138            sout_buffer_t *p_data; 
     139            p_data = sout_BufferNew( p_mux->p_sout, 
     140                                     p_mux->pp_inputs[i]->p_fmt->i_extra ); 
     141 
     142            memcpy( p_data->p_buffer, p_mux->pp_inputs[i]->p_fmt->p_extra, 
     143                    p_mux->pp_inputs[i]->p_fmt->i_extra ); 
     144 
     145            p_data->i_size = p_mux->pp_inputs[i]->p_fmt->i_extra; 
     146            p_data->i_dts = p_data->i_pts = p_data->i_length = 0; 
     147 
     148            msg_Dbg( p_mux, "writing header data" ); 
     149            sout_AccessOutWrite( p_mux->p_access, p_data ); 
     150        } 
    121151 
    122152        p_fifo = p_mux->pp_inputs[i]->p_fifo; 
     
    134164 
    135165    } 
    136     return( 0 ); 
     166    p_sys->b_header = VLC_FALSE; 
     167 
     168    return VLC_SUCCESS; 
    137169} 
    138  
  • modules/mux/ogg.c

    rbfeea8d r09d9972  
    33 ***************************************************************************** 
    44 * Copyright (C) 2001, 2002 VideoLAN 
    5  * $Id: ogg.c,v 1.21 2003/11/21 15:32:08 fenrir Exp $ 
     5 * $Id: ogg.c,v 1.22 2003/11/21 20:49:14 gbazin Exp $ 
    66 * 
    77 * Authors: Laurent Aimar <fenrir@via.ecp.fr> 
     
    427427            break; 
    428428 
     429        case VLC_FOURCC( 'f', 'l', 'a', 'c' ): 
     430            msg_Dbg( p_mux, "flac stream" ); 
     431            break; 
     432 
    429433        default: 
    430434            FREE( p_input->p_sys ); 
     
    638642                } 
    639643            } 
     644        } 
     645        else if( p_stream->i_fourcc == VLC_FOURCC( 'f', 'l', 'a', 'c' ) ) 
     646        { 
     647            /* flac stream marker (yeah, only that in the 1st packet) */ 
     648            op.packet = "fLaC"; 
     649            op.bytes  = 4; 
     650            op.b_o_s  = 1; 
     651            op.e_o_s  = 0; 
     652            op.granulepos = 0; 
     653            op.packetno = p_stream->i_packet_no++; 
     654            ogg_stream_packetin( &p_stream->os, &op ); 
     655            p_og = OggStreamFlush( p_mux, &p_stream->os, 0 ); 
    640656        } 
    641657        else 
     
    690706            } 
    691707        } 
    692         else 
     708        else if( p_stream->i_fourcc != VLC_FOURCC( 'f', 'l', 'a', 'c' ) ) 
    693709        { 
    694710            uint8_t com[128]; 
     
    709725        } 
    710726 
    711         /* Special case for mp4v */ 
    712         if( p_stream->i_fourcc == VLC_FOURCC( 'm', 'p', '4', 'v' ) && 
     727        /* Special case for mp4v and flac */ 
     728        if( ( p_stream->i_fourcc == VLC_FOURCC( 'm', 'p', '4', 'v' ) || 
     729              p_stream->i_fourcc == VLC_FOURCC( 'f', 'l', 'a', 'c' ) ) && 
    713730            p_mux->pp_inputs[i]->p_fmt->i_extra ) 
    714731        { 
    715             /* Send a packet with the VOL data */ 
     732            /* Send a packet with the VOL data for mp4v 
     733             * or STREAMINFO for flac */ 
     734            msg_Dbg( p_mux, "writing extra data" ); 
    716735            op.bytes  = p_mux->pp_inputs[i]->p_fmt->i_extra; 
    717736            op.packet = p_mux->pp_inputs[i]->p_fmt->p_extra; 
     737            if( p_stream->i_fourcc == VLC_FOURCC( 'f', 'l', 'a', 'c' ) ) 
     738            { 
     739                /* Skip the flac stream marker */ 
     740                ((uint8_t *)op.bytes) -= 4; 
     741                ((uint8_t *)op.packet) += 4; 
     742            } 
    718743            op.b_o_s  = 0; 
    719744            op.e_o_s  = 0;