]> git.sesse.net Git - vlc/blob - modules/codec/dirac.c
codec/dirac: remove decoder functionality
[vlc] / modules / codec / dirac.c
1 /*****************************************************************************
2  * dirac.c: Dirac encoder module making use of libdirac.
3  *          (http://www.bbc.co.uk/rd/projects/dirac/index.shtml)
4  *****************************************************************************
5  * Copyright (C) 1999-2001 the VideoLAN team
6  * $Id$
7  *
8  * Authors: Gildas Bazin <gbazin@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_codec.h>
35 #include <vlc_sout.h>
36 #include <vlc_vout.h>
37
38 #include <libdirac_decoder/dirac_parser.h>
39 #include <libdirac_encoder/dirac_encoder.h>
40
41 /*****************************************************************************
42  * Local prototypes
43  *****************************************************************************/
44 static int  OpenEncoder( vlc_object_t *p_this );
45 static void CloseEncoder( vlc_object_t *p_this );
46 static block_t *Encode( encoder_t *p_enc, picture_t *p_pict );
47
48 #define ENC_CFG_PREFIX "sout-dirac-"
49
50 static const char *const ppsz_enc_options[] = {
51     "quality", NULL
52 };
53
54 /*****************************************************************************
55  * Module descriptor
56  *****************************************************************************/
57 #define ENC_QUALITY_TEXT N_("Encoding quality")
58 #define ENC_QUALITY_LONGTEXT N_( \
59   "Quality of the encoding between 1.0 (low) and 10.0 (high)." )
60
61 vlc_module_begin ()
62     set_category( CAT_INPUT )
63     set_subcategory( SUBCAT_INPUT_VCODEC )
64     set_description( N_("Dirac video encoder") )
65     set_capability( "encoder", 100 )
66     set_callbacks( OpenEncoder, CloseEncoder )
67     add_float( ENC_CFG_PREFIX "quality", 7.0, NULL, ENC_QUALITY_TEXT,
68                ENC_QUALITY_LONGTEXT, false );
69
70 vlc_module_end ()
71
72 /*****************************************************************************
73  * encoder_sys_t : dirac encoder descriptor
74  *****************************************************************************/
75 #define ENC_BUFSIZE 1024*1024
76 struct encoder_sys_t
77 {
78     /*
79      * Dirac properties
80      */
81     dirac_encoder_t *p_dirac;
82     dirac_encoder_context_t ctx;
83
84     uint8_t *p_buffer_in;
85     int i_buffer_in;
86
87     uint8_t p_buffer_out[ENC_BUFSIZE];
88 };
89
90 /*****************************************************************************
91  * OpenEncoder: probe the encoder and return score
92  *****************************************************************************/
93 static int OpenEncoder( vlc_object_t *p_this )
94 {
95     encoder_t *p_enc = (encoder_t *)p_this;
96     encoder_sys_t *p_sys = p_enc->p_sys;
97     vlc_value_t val;
98     float f_quality;
99
100     if( p_enc->fmt_out.i_codec != VLC_FOURCC('d','r','a','c') &&
101         !p_enc->b_force )
102     {
103         return VLC_EGENERIC;
104     }
105
106     /* Allocate the memory needed to store the decoder's structure */
107     if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
108         return VLC_ENOMEM;
109     memset( p_sys, 0, sizeof(encoder_sys_t) );
110     p_enc->p_sys = p_sys;
111
112     p_enc->pf_encode_video = Encode;
113     p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','0');
114     p_enc->fmt_in.video.i_bits_per_pixel = 12;
115     p_enc->fmt_out.i_codec = VLC_FOURCC('d','r','a','c');
116
117     config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
118
119     dirac_encoder_context_init( &p_sys->ctx, VIDEO_FORMAT_CUSTOM );
120     /* */
121     p_sys->ctx.src_params.width = p_enc->fmt_in.video.i_width;
122     p_sys->ctx.src_params.height = p_enc->fmt_in.video.i_height;
123     p_sys->ctx.src_params.chroma = format420;
124     /* */
125     p_sys->ctx.src_params.frame_rate.numerator =
126         p_enc->fmt_in.video.i_frame_rate;
127     p_sys->ctx.src_params.frame_rate.denominator =
128         p_enc->fmt_in.video.i_frame_rate_base;
129     p_sys->ctx.src_params.source_sampling = 0;
130     p_sys->ctx.src_params.topfieldfirst = 0;
131
132     var_Get( p_enc, ENC_CFG_PREFIX "quality", &val );
133     f_quality = val.f_float;
134     if( f_quality > 10 ) f_quality = 10;
135     if( f_quality < 1 ) f_quality = 1;
136     p_sys->ctx.enc_params.qf = f_quality;
137
138     /* Initialise the encoder with the encoder context */
139     p_sys->p_dirac = dirac_encoder_init( &p_sys->ctx, 0 );
140
141     /* Set the buffer size for the encoded picture */
142     p_sys->i_buffer_in = p_enc->fmt_in.video.i_width *
143         p_enc->fmt_in.video.i_height * 3 / 2;
144     p_sys->p_buffer_in = malloc( p_sys->i_buffer_in );
145
146     return VLC_SUCCESS;
147 }
148
149 /****************************************************************************
150  * Encode: the whole thing
151  ****************************************************************************
152  * This function spits out ogg packets.
153  ****************************************************************************/
154 static block_t *Encode( encoder_t *p_enc, picture_t *p_pic )
155 {
156     encoder_sys_t *p_sys = p_enc->p_sys;
157     block_t *p_block, *p_chain = NULL;
158     int i_plane, i_line, i_width, i_src_stride;
159     uint8_t *p_dst;
160
161     /* Copy input picture in encoder input buffer (stride by stride) */
162     p_dst = p_sys->p_buffer_in;
163     for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
164     {
165         uint8_t *p_src = p_pic->p[i_plane].p_pixels;
166         i_width = p_pic->p[i_plane].i_visible_pitch;
167         i_src_stride = p_pic->p[i_plane].i_pitch;
168
169         for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines; i_line++ )
170         {
171             vlc_memcpy( p_dst, p_src, i_width );
172             p_dst += i_width;
173             p_src += i_src_stride;
174         }
175     }
176
177     /* Load one frame of data into encoder */
178     if( dirac_encoder_load( p_sys->p_dirac, p_sys->p_buffer_in,
179                             p_sys->i_buffer_in ) >= 0 )
180     {
181         dirac_encoder_state_t state;
182
183         msg_Dbg( p_enc, "dirac_encoder_load" );
184
185         /* Retrieve encoded frames from encoder */
186         do
187         {
188             p_sys->p_dirac->enc_buf.buffer = p_sys->p_buffer_out;
189             p_sys->p_dirac->enc_buf.size = ENC_BUFSIZE;
190             state = dirac_encoder_output( p_sys->p_dirac );
191             msg_Dbg( p_enc, "dirac_encoder_output: %i", state );
192             switch( state )
193             {
194             case ENC_STATE_AVAIL:
195                  // Encoded frame available in encoder->enc_buf
196                  // Encoded frame params available in enccoder->enc_fparams
197                  // Encoded frame stats available in enccoder->enc_fstats
198                  p_block = block_New( p_enc, p_sys->p_dirac->enc_buf.size );
199                  memcpy( p_block->p_buffer, p_sys->p_dirac->enc_buf.buffer,
200                          p_sys->p_dirac->enc_buf.size );
201                  p_block->i_dts = p_block->i_pts = p_pic->date;
202                  block_ChainAppend( &p_chain, p_block );
203
204                  break;
205             case ENC_STATE_BUFFER:
206                 break;
207             case ENC_STATE_INVALID:
208             default:
209                 break;
210             }
211             if( p_sys->p_dirac->decoded_frame_avail )
212             {
213                 //locally decoded frame is available in
214                 //encoder->dec_buf
215                 //locally decoded frame parameters available
216                 //in encoder->dec_fparams
217             }
218             if( p_sys->p_dirac->instr_data_avail )
219             {
220                 //Instrumentation data (motion vectors etc.)
221                 //available in encoder->instr
222             }
223
224         } while( state == ENC_STATE_AVAIL );
225     }
226     else
227     {
228         msg_Dbg( p_enc, "dirac_encoder_load() error" );
229     }
230
231     return p_chain;
232 }
233
234 /*****************************************************************************
235  * CloseEncoder: dirac encoder destruction
236  *****************************************************************************/
237 static void CloseEncoder( vlc_object_t *p_this )
238 {
239     encoder_t *p_enc = (encoder_t *)p_this;
240     encoder_sys_t *p_sys = p_enc->p_sys;
241
242     msg_Dbg( p_enc, "resulting bit-rate: %lld bits/sec",
243              p_sys->p_dirac->enc_seqstats.bit_rate );
244
245     /* Free the encoder resources */
246     dirac_encoder_close( p_sys->p_dirac );
247  
248     free( p_sys->p_buffer_in );
249     free( p_sys );
250 }