OSDN Git Service

Fixed dvd_seek for titles which are not linear
[handbrake-jp/handbrake-jp-git.git] / libhb / encfaac.c
1 /* $Id: encfaac.c,v 1.13 2005/03/03 17:21:57 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.m0k.org/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include "hb.h"
8
9 #include "faac.h"
10
11 struct hb_work_object_s
12 {
13     HB_WORK_COMMON;
14
15     hb_job_t   * job;
16     hb_audio_t * audio;
17
18     faacEncHandle * faac;
19     unsigned long   input_samples;
20     unsigned long   output_bytes;
21     uint8_t       * buf;
22
23     hb_list_t     * list;
24     int64_t         pts;
25 };
26
27 /***********************************************************************
28  * Local prototypes
29  **********************************************************************/
30 static void Close( hb_work_object_t ** _w );
31 static int  Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
32                   hb_buffer_t ** buf_out );
33
34 /***********************************************************************
35  * hb_work_encfaac_init
36  ***********************************************************************
37  *
38  **********************************************************************/
39 hb_work_object_t * hb_work_encfaac_init( hb_job_t * job, hb_audio_t * audio )
40 {
41     hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
42     faacEncConfigurationPtr cfg;
43     w->name  = strdup( "AAC encoder (libfaac)" );
44     w->work  = Work;
45     w->close = Close;
46
47     w->job   = job;
48     w->audio = audio;
49
50     w->faac = faacEncOpen( job->arate, 2, &w->input_samples,
51                            &w->output_bytes );
52     w->buf  = malloc( w->input_samples * sizeof( float ) );
53     
54     cfg                = faacEncGetCurrentConfiguration( w->faac );
55     cfg->mpegVersion   = MPEG4;
56     cfg->aacObjectType = LOW;
57     cfg->allowMidside  = 1;
58     cfg->useLfe        = 0;
59     cfg->useTns        = 0;
60     cfg->bitRate       = job->abitrate * 500; /* Per channel */
61     cfg->bandWidth     = 0;
62     cfg->outputFormat  = 0;
63     cfg->inputFormat   =  FAAC_INPUT_FLOAT;
64     if( !faacEncSetConfiguration( w->faac, cfg ) )
65     {
66         hb_log( "faacEncSetConfiguration failed" );
67     }
68     if( faacEncGetDecoderSpecificInfo( w->faac, &audio->config.faac.decinfo,
69                                        &audio->config.faac.size ) < 0 )
70     {
71         hb_log( "faacEncGetDecoderSpecificInfo failed" );
72     }
73
74     w->list = hb_list_init();
75     w->pts  = -1;
76
77     return w;
78 }
79
80 /***********************************************************************
81  * Close
82  ***********************************************************************
83  *
84  **********************************************************************/
85 static void Close( hb_work_object_t ** _w )
86 {
87     hb_work_object_t * w = *_w;
88
89     faacEncClose( w->faac );
90     free( w->buf );
91     hb_list_empty( &w->list );
92     free( w->audio->config.faac.decinfo );
93
94     free( w->name );
95     free( w );
96     *_w = NULL;
97 }
98
99 /***********************************************************************
100  * Encode
101  ***********************************************************************
102  *
103  **********************************************************************/
104 static hb_buffer_t * Encode( hb_work_object_t * w )
105 {
106     hb_buffer_t * buf;
107     uint64_t      pts;
108     int           pos;
109
110     if( hb_list_bytes( w->list ) < w->input_samples * sizeof( float ) )
111     {
112         /* Need more data */
113         return NULL;
114     }
115
116     hb_list_getbytes( w->list, w->buf, w->input_samples * sizeof( float ),
117                       &pts, &pos );
118
119     buf        = hb_buffer_init( w->output_bytes );
120     buf->start = pts + 90000 * pos / 2 / sizeof( float ) / w->job->arate;
121     buf->stop  = buf->start + 90000 * w->input_samples / w->job->arate / 2;
122     buf->size  = faacEncEncode( w->faac, (int32_t *) w->buf,
123             w->input_samples, buf->data, w->output_bytes );
124     buf->key   = 1;
125
126     if( !buf->size )
127     {
128         /* Encoding was successful but we got no data. Try to encode
129            more */
130         hb_buffer_close( &buf );
131         return Encode( w );
132     }
133     else if( buf->size < 0 )
134     {
135         hb_log( "faacEncEncode failed" );
136         hb_buffer_close( &buf );
137         return NULL;
138     }
139
140     return buf;
141 }
142
143 /***********************************************************************
144  * Work
145  ***********************************************************************
146  *
147  **********************************************************************/
148 static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
149                  hb_buffer_t ** buf_out )
150 {
151     hb_buffer_t * buf;
152
153     hb_list_add( w->list, *buf_in );
154     *buf_in = NULL;
155
156     *buf_out = buf = Encode( w );
157
158     while( buf )
159     {
160         buf->next = Encode( w );
161         buf       = buf->next;
162     }
163     
164     return HB_WORK_OK;
165 }
166