OSDN Git Service

4d74fc68f5269d7fdeaa99c51dee0ccd2b976c13
[handbrake-jp/handbrake-jp-git.git] / libhb / decavcodec.c
1 /* $Id: decavcodec.c,v 1.6 2005/03/06 04:08:54 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 "ffmpeg/avcodec.h"
10
11 int  decavcodecInit( hb_work_object_t *, hb_job_t * );
12 int  decavcodecWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
13 void decavcodecClose( hb_work_object_t * );
14
15 hb_work_object_t hb_decavcodec =
16 {
17     WORK_DECAVCODEC,
18     "MPGA decoder (libavcodec)",
19     decavcodecInit,
20     decavcodecWork,
21     decavcodecClose
22 };
23
24 struct hb_work_private_s
25 {
26     hb_job_t       * job;
27
28     AVCodecContext * context;
29     int64_t          pts_last;
30 };
31
32
33 /***********************************************************************
34  * hb_work_decavcodec_init
35  ***********************************************************************
36  *
37  **********************************************************************/
38 int decavcodecInit( hb_work_object_t * w, hb_job_t * job )
39 {
40     AVCodec * codec;
41     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
42     w->private_data = pv;
43
44     pv->job   = job;
45
46     codec = avcodec_find_decoder( CODEC_ID_MP2 );
47     pv->context = avcodec_alloc_context();
48     avcodec_open( pv->context, codec );
49     pv->pts_last = -1;
50
51     return 0;
52 }
53
54 /***********************************************************************
55  * Close
56  ***********************************************************************
57  *
58  **********************************************************************/
59 void decavcodecClose( hb_work_object_t * w )
60 {
61     hb_work_private_t * pv = w->private_data;
62     avcodec_close( pv->context );
63 }
64
65 /***********************************************************************
66  * Work
67  ***********************************************************************
68  *
69  **********************************************************************/
70 int decavcodecWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
71                     hb_buffer_t ** buf_out )
72 {
73     hb_work_private_t * pv = w->private_data;
74     hb_buffer_t * in = *buf_in, * buf, * last = NULL;
75     int   pos, len, out_size, i;
76     short buffer[AVCODEC_MAX_AUDIO_FRAME_SIZE];
77     uint64_t cur;
78
79     *buf_out = NULL;
80
81     if( in->start < 0 ||
82         ( pv->pts_last > 0 &&
83           in->start > pv->pts_last &&
84           in->start - pv->pts_last < 5000 ) ) /* Hacky */
85     {
86         cur = pv->pts_last;
87     }
88     else
89     {
90         cur = in->start;
91     }
92
93     pos = 0;
94     while( pos < in->size )
95     {
96         len = avcodec_decode_audio( pv->context, buffer, &out_size,
97                                     in->data + pos, in->size - pos );
98         if( out_size )
99         {
100             short * s16;
101             float * fl32;
102
103             buf = hb_buffer_init( 2 * out_size );
104
105             buf->start = cur;
106             buf->stop  = cur + 90000 * ( out_size / 4 ) /
107                          pv->context->sample_rate;
108             cur = buf->stop;
109
110             s16  = buffer;
111             fl32 = (float *) buf->data;
112             for( i = 0; i < out_size / 2; i++ )
113             {
114                 fl32[i] = s16[i];
115             }
116
117             if( last )
118             {
119                 last = last->next = buf;
120             }
121             else
122             {
123                 *buf_out = last = buf;
124             }
125         }
126
127         pos += len;
128     }
129
130     pv->pts_last = cur;
131
132     return HB_WORK_OK;
133 }
134