1 /* ***** BEGIN LICENSE BLOCK *****
3 * $Id: enc_picture.cpp,v 1.1 2008/06/19 10:02:02 tjdwave Exp $ $Name: $
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 * The contents of this file are subject to the Mozilla Public License
8 * Version 1.1 (the "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
14 * the specific language governing rights and limitations under the License.
16 * The Original Code is BBC Research and Development code.
18 * The Initial Developer of the Original Code is the British Broadcasting
20 * Portions created by the Initial Developer are Copyright (C) 2008.
21 * All Rights Reserved.
23 * Contributor(s): Thomas Davies (Original Author),
25 * Alternatively, the contents of this file may be used under the terms of
26 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
27 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
28 * the GPL or the LGPL are applicable instead of those above. If you wish to
29 * allow use of your version of this file only under the terms of the either
30 * the GPL or LGPL and not to allow others to use your version of this file
31 * under the MPL, indicate your decision by deleting the provisions above
32 * and replace them with the notice and other provisions required by the GPL
33 * or LGPL. If you do not delete the provisions above, a recipient may use
34 * your version of this file under the terms of any one of the MPL, the GPL
36 * ***** END LICENSE BLOCK ***** */
38 #include <libdirac_encoder/enc_picture.h>
39 #include <libdirac_common/upconvert.h>
41 using namespace dirac
;
43 EncPicture::EncPicture( const PictureParams
& pp
):
48 m_norm_complexity( 1.0 ),
51 for (int c
=0; c
<3; ++c
){
52 m_orig_data
[c
] = new PicArray( m_pic_data
[c
]->LengthY(), m_pic_data
[c
]->LengthX() );
53 m_orig_up_data
[c
] = NULL
;
54 m_filt_data
[c
] = NULL
;
55 m_filt_up_data
[c
] = NULL
;
59 void EncPicture::ClearData(){
63 for (int c
=0;c
<3;++c
){
64 if (m_orig_data
[c
] != NULL
){
65 delete m_orig_data
[c
];
66 m_orig_data
[c
] = NULL
;
69 if (m_orig_up_data
[c
] != NULL
){
70 delete m_orig_up_data
[c
];
71 m_orig_up_data
[c
] = NULL
;
74 if (m_filt_data
[c
] != NULL
){
75 delete m_filt_data
[c
];
76 m_filt_data
[c
] = NULL
;
79 if (m_filt_up_data
[c
] != NULL
){
80 delete m_filt_up_data
[c
];
81 m_filt_up_data
[c
] = NULL
;
85 if ( m_me_data
!= NULL
)
89 EncPicture::~EncPicture()
94 void EncPicture::SetOrigData()
96 for ( int c
=0; c
<3 ; ++c
)
100 void EncPicture::SetOrigData( const int c
)
102 if ( m_pic_data
[c
] != NULL
)
103 *(m_orig_data
[c
]) = *(m_pic_data
[c
]);
106 void EncPicture::InitMEData( const PicturePredParams
& predparams
, const int num_refs
)
108 if (m_me_data
!= NULL
)
111 m_me_data
=new MEData( predparams
, num_refs
);
114 const PicArray
& EncPicture::DataForME( bool combined_me
) const{
117 return CombinedData();
119 return OrigData( Y_COMP
);
122 const PicArray
& EncPicture::UpDataForME( bool combined_me
) const{
125 return UpCombinedData();
127 return UpOrigData( Y_COMP
);
131 const PicArray
& EncPicture::UpOrigData(CompSort cs
) const
133 const int c
= (int) cs
;
135 if (m_orig_up_data
[c
] != NULL
)
136 return *m_orig_up_data
[c
];
138 {//we have to do the upconversion
140 m_orig_up_data
[c
] = new PicArray( 2*m_orig_data
[c
]->LengthY(),
141 2*m_orig_data
[c
]->LengthX() );
142 UpConverter
* myupconv
;
144 myupconv
= new UpConverter(-(1 << (m_pparams
.ChromaDepth()-1)),
145 (1 << (m_pparams
.ChromaDepth()-1))-1,
146 m_pparams
.ChromaXl(), m_pparams
.ChromaYl());
148 myupconv
= new UpConverter(-(1 << (m_pparams
.LumaDepth()-1)),
149 (1 << (m_pparams
.LumaDepth()-1))-1,
150 m_pparams
.Xl(), m_pparams
.Yl());
152 myupconv
->DoUpConverter( *(m_orig_data
[c
]) , *(m_orig_up_data
[c
]) );
156 return *(m_orig_up_data
[c
]);
161 const PicArray
& EncPicture::FiltData(CompSort cs
) const
163 const int c
= (int) cs
;
165 if (m_filt_data
[c
] != NULL
)
166 return *m_filt_data
[c
];
168 {//we have to do the filtering
170 if (m_orig_data
[c
] != NULL
)
171 m_filt_data
[c
] = new PicArray( m_orig_data
[c
]->LengthY(),
172 m_orig_data
[c
]->LengthX() );
174 AntiAliasFilter( *(m_filt_data
[c
]), *(m_orig_data
[c
]));
176 return *(m_filt_data
[c
]);
181 const PicArray
& EncPicture::UpFiltData(CompSort cs
) const
183 const int c
= (int) cs
;
185 if (m_filt_up_data
[c
] != NULL
)
186 return *m_filt_up_data
[c
];
188 {//we have to do the upconversion
190 const PicArray
& filt_data
= FiltData( cs
);
192 m_filt_up_data
[c
] = new PicArray( 2*filt_data
.LengthY(),
193 2*filt_data
.LengthX() );
194 UpConverter
* myupconv
;
196 myupconv
= new UpConverter(-(1 << (m_pparams
.ChromaDepth()-1)),
197 (1 << (m_pparams
.ChromaDepth()-1))-1,
198 m_pparams
.ChromaXl(), m_pparams
.ChromaYl());
200 myupconv
= new UpConverter(-(1 << (m_pparams
.LumaDepth()-1)),
201 (1 << (m_pparams
.LumaDepth()-1))-1,
202 m_pparams
.Xl(), m_pparams
.Yl());
204 myupconv
->DoUpConverter( filt_data
, *(m_filt_up_data
[c
]) );
208 return *(m_filt_up_data
[c
]);
213 void EncPicture::AntiAliasFilter( PicArray
& out_data
, const PicArray
& in_data
) const{
215 //Special case for first row
216 for (int i
= in_data
.FirstX(); i
<= in_data
.LastX(); ++i
)
218 out_data
[in_data
.FirstY()][i
] = (3*in_data
[in_data
.FirstY()][i
] +
219 in_data
[in_data
.FirstY()+1][i
] +2 )>>2;
222 for (int j
= in_data
.FirstY()+1; j
< in_data
.LastY(); ++j
)
224 for (int i
= in_data
.FirstX(); i
<= in_data
.LastX(); ++i
)
226 out_data
[j
][i
] = (in_data
[j
-1][i
] + 2*in_data
[j
][i
] + in_data
[j
+1][i
] + 2)>>2;
229 //Special case for last row
230 for (int i
= in_data
.FirstX(); i
<= in_data
.LastX(); ++i
)
232 out_data
[in_data
.LastY()][i
] = (in_data
[in_data
.LastY()-1][i
] +
233 3*in_data
[in_data
.LastY()][i
] + 2)>>2;
237 const PicArray
& EncPicture::CombinedData() const
240 if (m_filt_data
[Y_COMP
] != NULL
)
241 return *m_filt_data
[Y_COMP
];
243 {//we have to do the combining
245 if (m_orig_data
[Y_COMP
] != NULL
)
246 m_filt_data
[Y_COMP
] = new PicArray( m_orig_data
[Y_COMP
]->LengthY(),
247 m_orig_data
[Y_COMP
]->LengthX() );
249 Combine( *(m_filt_data
[Y_COMP
]), *(m_orig_data
[Y_COMP
]),
250 *(m_orig_data
[U_COMP
]), *(m_orig_data
[V_COMP
])
253 return *(m_filt_data
[Y_COMP
]);
258 const PicArray
& EncPicture::UpCombinedData() const
260 if (m_filt_up_data
[Y_COMP
] != NULL
)
261 return *m_filt_up_data
[Y_COMP
];
263 {//we have to do the upconversion
265 const PicArray
& filt_data
= CombinedData();
267 m_filt_up_data
[Y_COMP
] = new PicArray( 2*filt_data
.LengthY(),
268 2*filt_data
.LengthX() );
269 UpConverter
* myupconv
;
270 myupconv
= new UpConverter(-(1 << (m_pparams
.LumaDepth()-1)),
271 (1 << (m_pparams
.LumaDepth()-1))-1,
272 m_pparams
.Xl(), m_pparams
.Yl());
274 myupconv
->DoUpConverter( filt_data
, *(m_filt_up_data
[Y_COMP
]) );
278 return *(m_filt_up_data
[Y_COMP
]);
285 void EncPicture::Combine( PicArray
& comb_data
, const PicArray
& y_data
,
286 const PicArray
& u_data
, const PicArray
& v_data
) const
288 int hcr
= y_data
.LengthX()/u_data
.LengthX();
289 int vcr
= y_data
.LengthY()/u_data
.LengthY();
291 float val
, valc
, valy
;
294 for (int j
=0; j
<comb_data
.LengthY(); ++j
) {
295 if (hcr
==1){// 444 format
296 for (int i
=0; i
<comb_data
.LengthX(); ++i
){
297 val
= float(u_data
[j
][i
]);
301 val
= float(v_data
[j
][i
]);
305 valy
= float(y_data
[j
][i
]) + 128.0;
307 comb_data
[j
][i
] = ValueType( std::sqrt(valc
+valy
)-128.0 );
311 for (int i
=0; i
<comb_data
.LengthX(); i
+=2 ){
313 val
= float(u_data
[j
][i
>>1]);
317 val
= float(v_data
[j
][i
>>1]);
321 valy
= float(y_data
[j
][i
]) + 128.0;
323 comb_data
[j
][i
] = ValueType( std::sqrt(valc
+valy
)-128.0 );
325 valy
= float(y_data
[j
][i
+1]) + 128.0;
328 comb_data
[j
][i
+1] = ValueType( std::sqrt(valc
+valy
)-128.0 );
335 for (int j
=0; j
<comb_data
.LengthY(); j
+=2 ) {
337 for (int i
=0; i
<comb_data
.LengthX(); i
+=2 ){
339 val
= float(u_data
[j
>>1][i
>>1]);
343 val
= float(v_data
[j
>>1][i
>>1]);
347 valy
= float(y_data
[j
][i
]) + 128.0;
349 comb_data
[j
][i
] = ValueType( std::sqrt(valc
+valy
)-128.0 );
351 valy
= float(y_data
[j
][i
+1]) + 128.0;
353 comb_data
[j
][i
+1] = ValueType( std::sqrt(valc
+valy
)-128.0 );
355 valy
= float(y_data
[j
+1][i
]) + 128.0;
357 comb_data
[j
+1][i
] = ValueType( std::sqrt(valc
+valy
)-128.0 );
359 valy
= float(y_data
[j
+1][i
+1]) + 128.0;
361 comb_data
[j
+1][i
+1] = ValueType( std::sqrt(valc
+valy
)-128.0 );
372 void EncPicture::DropRef( int rindex
){
374 std::vector
<int>& refs
= m_pparams
.Refs();
376 if (rindex
==1 || rindex
==2 )
377 refs
.erase( refs
.begin()+rindex
-1 );
379 // Now reconfigure the motion data
380 if ( m_me_data
!=NULL
)
381 m_me_data
->DropRef( rindex
);