OSDN Git Service

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