1 /* ***** BEGIN LICENSE BLOCK *****
2 *
3 * $Id: picture_byteio.cpp,v 1.3 2008/08/14 01:58:39 asuraparaju Exp $ $Name: Dirac_1_0_2 $
4 *
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 *
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/
11 *
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.
15 *
16 * The Original Code is BBC Research and Development code.
17 *
18 * The Initial Developer of the Original Code is the British Broadcasting
19 * Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 2004.
21 * All Rights Reserved.
22 *
23 * Contributor(s): Andrew Kennedy (Original Author),
24 *                 Anuradha Suraparaju
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
28 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
29 * the GPL or the LGPL are applicable instead of those above. If you wish to
30 * allow use of your version of this file only under the terms of the either
31 * the GPL or LGPL and not to allow others to use your version of this file
32 * under the MPL, indicate your decision by deleting the provisions above
33 * and replace them with the notice and other provisions required by the GPL
34 * or LGPL. If you do not delete the provisions above, a recipient may use
35 * your version of this file under the terms of any one of the MPL, the GPL
36 * or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
38 
39 #include "picture_byteio.h"
40 #include <libdirac_common/dirac_exception.h>
41 
42 using namespace dirac;
43 using namespace std;
44 
45 const unsigned int PP_PICTURE_NUM_SIZE = 4;
46 
47 const int CODE_ONE_REF_BIT =  0;
48 const int CODE_TWO_REF_BIT = 1;
49 const int CODE_REF_PICTURE_BIT = 2;
50 const int CODE_PUTYPE_1_BIT = 3;
51 const int CODE_VLC_ENTROPY_CODING_BIT = 6;
52 
53 // maximum number of refs allowed
54 const unsigned int MAX_NUM_REFS = 2;
55 
PictureByteIO(PictureParams & frame_params,int frame_num)56 PictureByteIO::PictureByteIO(PictureParams& frame_params,
57                          int frame_num) :
58 ParseUnitByteIO(),
59 m_frame_params(frame_params),
60 m_frame_num(frame_num),
61 m_mv_data(0),
62 m_transform_data(0)
63 {
64 
65 }
66 
PictureByteIO(PictureParams & frame_params,const ParseUnitByteIO & parseunit_byteio)67 PictureByteIO::PictureByteIO(PictureParams& frame_params,
68                          const ParseUnitByteIO& parseunit_byteio ):
69 ParseUnitByteIO(parseunit_byteio),
70 m_frame_params(frame_params),
71 m_frame_num(0),
72 m_mv_data(0),
73 m_transform_data(0)
74 {
75 
76 }
77 
78 
~PictureByteIO()79 PictureByteIO::~PictureByteIO()
80 {
81     //delete block data
82     if (m_mv_data)
83     {
84         delete m_mv_data;
85         m_mv_data = 0;
86     }
87     if (m_transform_data)
88     {
89         delete m_transform_data;
90         m_transform_data = 0;
91     }
92 }
93 
CollateByteStats(DiracByteStats & dirac_byte_stats)94 void PictureByteIO::CollateByteStats(DiracByteStats& dirac_byte_stats)
95 {
96     if(m_mv_data)
97         m_mv_data->CollateByteStats(dirac_byte_stats);
98     if(m_transform_data)
99         m_transform_data->CollateByteStats(dirac_byte_stats);
100 
101     ParseUnitByteIO::CollateByteStats(dirac_byte_stats);
102 }
103 
Input()104 bool PictureByteIO::Input()
105 {
106     // set picture type
107     SetPictureType();
108     SetReferenceType();
109     SetEntropyCodingFlag();
110 
111     // Use of VLC for entropy coding is supported for
112     // intra frames only
113     if (m_frame_params.GetPictureType() == INTER_PICTURE &&
114         m_frame_params.UsingAC() == false)
115     {
116         DIRAC_THROW_EXCEPTION(
117                     ERR_UNSUPPORTED_STREAM_DATA,
118                     "VLC codes for entropy coding of coefficient data supported for Intra frames only",
119                     SEVERITY_PICTURE_ERROR);
120     }
121 
122     // input picture number
123     m_frame_num = ReadUintLit(PP_PICTURE_NUM_SIZE);
124     m_frame_params.SetPictureNum(m_frame_num);
125 
126     // input reference Picture numbers
127     InputReferencePictures();
128 
129     // input retired Picture numbers list
130     m_frame_params.SetRetiredPictureNum(-1);
131     if (IsRef())
132         InputRetiredPicture();
133 
134     // byte align
135     ByteAlignInput();
136 
137     return true;
138 }
139 
GetBytes()140 const string PictureByteIO::GetBytes()
141 {
142     // Write mv data
143     if(m_frame_params.PicSort().IsInter() && m_mv_data)
144     {
145         OutputBytes(m_mv_data->GetBytes());
146     }
147 
148     // Write transform header
149     if (m_transform_data)
150     {
151         OutputBytes(m_transform_data->GetBytes());
152     }
153     return ParseUnitByteIO::GetBytes();
154 }
155 
GetSize() const156 int PictureByteIO::GetSize() const
157 {
158     int size = 0;
159     if (m_mv_data)
160         size += m_mv_data->GetSize();
161     if (m_transform_data)
162         size += m_transform_data->GetSize();
163 
164     //std::cerr << "Picture Header Size=" << ByteIO::GetSize();
165     //std::cerr << "Data Size=" << size << std::endl;
166 
167     return size+ParseUnitByteIO::GetSize()+ByteIO::GetSize();
168 }
169 
Output()170 void PictureByteIO::Output()
171 {
172     // output picture number
173     WriteUintLit(m_frame_num, PP_PICTURE_NUM_SIZE);
174 
175     if(m_frame_params.GetPictureType()==INTER_PICTURE)
176     {
177         // output reference picture numbers
178         const std::vector<int>& refs = m_frame_params.Refs();
179         for(size_t i=0; i < refs.size() && i < MAX_NUM_REFS; ++i)
180             WriteSint(refs[i] - m_frame_num);
181     }
182 
183     // output retired picture
184     ASSERTM (m_frame_params.GetReferenceType() == REFERENCE_PICTURE || m_frame_params.RetiredPictureNum() == -1, "Only Reference frames can retire frames");
185     if(m_frame_params.GetReferenceType() == REFERENCE_PICTURE)
186     {
187         if (m_frame_params.RetiredPictureNum() == -1)
188             WriteSint(0);
189         else
190         {
191             WriteSint (m_frame_params.RetiredPictureNum() - m_frame_num);
192         }
193     }
194     // byte align output
195     ByteAlignOutput();
196 
197 }
198 
199 
200 //-------------private-------------------------------------------------------
201 
CalcParseCode() const202 unsigned char PictureByteIO::CalcParseCode() const
203 {
204     unsigned char code = 0;
205 
206     int num_refs = m_frame_params.Refs().size();
207 
208     if(m_frame_params.GetPictureType()==INTER_PICTURE)
209     {
210         // set number of refs
211         if(num_refs == 1)
212             SetBit(code, CODE_ONE_REF_BIT);
213         if(num_refs > 1)
214             SetBit(code, CODE_TWO_REF_BIT);
215     }
216     // set ref type
217     if(m_frame_params.GetReferenceType()==REFERENCE_PICTURE)
218         SetBit(code, CODE_REF_PICTURE_BIT);
219 
220     // Set parse unit type
221     SetBit(code, CODE_PUTYPE_1_BIT);
222 
223     // Set Entropy Coding type
224     if (!m_frame_params.UsingAC())
225     {
226         SetBit(code, CODE_VLC_ENTROPY_CODING_BIT);
227     }
228     return code;
229 
230 
231 }
232 
InputReferencePictures()233 void PictureByteIO::InputReferencePictures()
234 {
235     // get number of frames referred to
236    int ref_count = NumRefs();
237 
238    // get the number of these frames
239     vector<int>& refs = m_frame_params.Refs();
240     refs.resize(ref_count);
241     for(int i=0; i < ref_count; ++i)
242         refs[i]=m_frame_num+ReadSint();
243 }
244 
InputRetiredPicture()245 void PictureByteIO::InputRetiredPicture()
246 {
247     TESTM(IsRef(), "Retired Picture offset only set for Reference Frames");
248 
249     // input retired picture offset
250     int offset = ReadSint();
251     // input retired frames
252     if (offset)
253     {
254         m_frame_params.SetRetiredPictureNum(m_frame_num + offset);
255     }
256 }
257 
SetPictureType()258 void PictureByteIO::SetPictureType()
259 {
260     if(IsIntra())
261         m_frame_params.SetPictureType(INTRA_PICTURE);
262     else if(IsInter())
263         m_frame_params.SetPictureType(INTER_PICTURE);
264 
265 }
266 
SetReferenceType()267 void PictureByteIO::SetReferenceType()
268 {
269     if(IsRef())
270         m_frame_params.SetReferenceType(REFERENCE_PICTURE);
271     else if(IsNonRef())
272         m_frame_params.SetReferenceType(NON_REFERENCE_PICTURE);
273 
274 }
275 
SetEntropyCodingFlag()276 void PictureByteIO::SetEntropyCodingFlag()
277 {
278     m_frame_params.SetUsingAC(IsUsingAC());
279 }
280