1 /* Copyright (c) MediaArea.net SARL. All Rights Reserved.
2 *
3 * Use of this source code is governed by a BSD-style license that can
4 * be found in the License.html file in the root of the source tree.
5 */
6
7 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 //
9 // http://www.ffmpeg.org/~michael/ffv1.html
10 //
11 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12
13 //---------------------------------------------------------------------------
14 // Pre-compilation
15 #include "MediaInfo/PreComp.h"
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19 //---------------------------------------------------------------------------
20
21 //---------------------------------------------------------------------------
22 #include "MediaInfo/Setup.h"
23 //---------------------------------------------------------------------------
24
25 //---------------------------------------------------------------------------
26 #if defined(MEDIAINFO_FFV1_YES)
27 //---------------------------------------------------------------------------
28
29 //---------------------------------------------------------------------------
30 #include "MediaInfo/Video/File_Ffv1.h"
31 #include "MediaInfo/MediaInfo_Config_MediaInfo.h"
32 #include "ZenLib/BitStream.h"
33 //---------------------------------------------------------------------------
34
35 #include <algorithm>
36 #include <math.h>
37 using namespace std;
38
39 //---------------------------------------------------------------------------
40 namespace MediaInfoLib
41 {
42
43 using namespace FFV1;
44
45 //***************************************************************************
46 // Const
47 //***************************************************************************
48
49 extern const int32u Psi_CRC_32_Table[256];
50 const int32u Slice::Context::N0 = 128;
51 const int32s Slice::Context::Cmax = 127;
52 const int32s Slice::Context::Cmin = -128;
53
54 //***************************************************************************
55 // Helpers
56 //***************************************************************************
57
58 //---------------------------------------------------------------------------
FFv1_CRC_Compute(const int8u * Buffer,size_t Size)59 static int32u FFv1_CRC_Compute(const int8u* Buffer, size_t Size)
60 {
61 int32u CRC_32 = 0;
62 const int8u* CRC_32_Buffer=Buffer;
63 const int8u* CRC_32_Buffer_End=CRC_32_Buffer+Size;
64
65 while(CRC_32_Buffer<CRC_32_Buffer_End)
66 {
67 CRC_32=(CRC_32<<8) ^ Psi_CRC_32_Table[(CRC_32>>24)^(*CRC_32_Buffer)];
68 CRC_32_Buffer++;
69 }
70 return CRC_32;
71 }
72
73 //---------------------------------------------------------------------------
74 #if MEDIAINFO_FIXITY
Ffv1_TryToFixCRC(const int8u * Buffer,size_t Buffer_Size)75 static size_t Ffv1_TryToFixCRC(const int8u* Buffer, size_t Buffer_Size)
76 {
77 //looking for a bit flip
78 int8u* Buffer2=new int8u[Buffer_Size];
79 memcpy(Buffer2, Buffer, Buffer_Size);
80 vector<size_t> BitPositions;
81 size_t BitPosition_Max=Buffer_Size*8;
82 for (size_t BitPosition=0; BitPosition<BitPosition_Max; BitPosition++)
83 {
84 size_t BytePosition=BitPosition>>3;
85 size_t BitInBytePosition=BitPosition&0x7;
86 Buffer2[BytePosition]^=1<<BitInBytePosition;
87 int32u crc_left_New=FFv1_CRC_Compute(Buffer2, Buffer_Size);
88 if (!crc_left_New)
89 {
90 BitPositions.push_back(BitPosition);
91 }
92 Buffer2[BytePosition]^=1<<BitInBytePosition;
93 }
94 delete[] Buffer2; //Buffer2=NULL
95
96 return BitPositions.size()==1?BitPositions[0]:(size_t)-1;
97 }
98 #endif //MEDIAINFO_FIXITY
99
100 //***************************************************************************
101 // RangeCoder
102 //***************************************************************************
103
104 class RangeCoder
105 {
106 public:
107 RangeCoder(const int8u* Buffer, size_t Buffer_Size, const state_transitions default_state_transition);
108
109 void AssignStateTransitions(const state_transitions new_state_transition);
110 void ResizeBuffer(size_t Buffer_Size); //Adapt the buffer limit
111 size_t BytesUsed();
112 bool Underrun();
113 void ForceUnderrun();
114
115 bool get_rac(int8u* States);
116 int32u get_symbol_u(int8u* States);
117 int32s get_symbol_s(int8u* States);
118
119 int32u Current;
120 int32u Mask;
121 state_transitions zero_state;
122 state_transitions one_state;
123
124 private:
125 const int8u* Buffer_Beg;
126 const int8u* Buffer_Cur;
127 const int8u* Buffer_End;
128 };
129
130 //---------------------------------------------------------------------------
RangeCoder(const int8u * Buffer,size_t Buffer_Size,const state_transitions default_state_transition)131 RangeCoder::RangeCoder (const int8u* Buffer, size_t Buffer_Size, const state_transitions default_state_transition)
132 {
133 //Assign buffer
134 Buffer_Beg=Buffer;
135 Buffer_Cur=Buffer;
136 Buffer_End=Buffer+Buffer_Size;
137
138 //Init
139 if (Buffer_Size)
140 Current=*Buffer_Cur;
141 Mask=0xFF;
142 Buffer_Cur++;
143
144 AssignStateTransitions(default_state_transition);
145 }
146
AssignStateTransitions(const state_transitions new_state_transition)147 void RangeCoder::AssignStateTransitions (const state_transitions new_state_transition)
148 {
149 //Assign StateTransitions
150 std::memcpy (one_state, new_state_transition, state_transitions_size);
151 zero_state[0]=0;
152 for (size_t i=1; i<state_transitions_size; i++)
153 zero_state[i]=-one_state[state_transitions_size-i];
154 }
155
156 //---------------------------------------------------------------------------
ResizeBuffer(size_t Buffer_Size)157 void RangeCoder::ResizeBuffer(size_t Buffer_Size)
158 {
159 Buffer_End=Buffer_Beg+Buffer_Size;
160 }
161
162 //---------------------------------------------------------------------------
BytesUsed()163 size_t RangeCoder::BytesUsed()
164 {
165 if (Buffer_Cur>Buffer_End)
166 return Buffer_End-Buffer_Beg;
167 return Buffer_Cur-Buffer_Beg-(Mask<0x100?0:1);
168 }
169
170 //---------------------------------------------------------------------------
Underrun()171 bool RangeCoder::Underrun()
172 {
173 return (Buffer_Cur-(Mask<0x100?0:1)>Buffer_End)?true:false;
174 }
175
176 //---------------------------------------------------------------------------
ForceUnderrun()177 void RangeCoder::ForceUnderrun()
178 {
179 Mask=0;
180 Buffer_Cur=Buffer_End+1;
181 }
182
183 //---------------------------------------------------------------------------
get_rac(int8u * States)184 bool RangeCoder::get_rac(int8u* States)
185 {
186 // Next byte
187 if (Mask<0x100)
188 {
189 Current<<=8;
190
191 // If less, consume the next byte
192 // If equal, last byte assumed to be 0x00
193 // If more, underrun, we return 0
194 if (Buffer_Cur<Buffer_End)
195 {
196 Current|=*Buffer_Cur;
197 }
198 else if (Buffer_Cur>Buffer_End)
199 {
200 return false;
201 }
202
203 Buffer_Cur++;
204 Mask<<=8;
205 }
206
207 //Range Coder boolean value computing
208 int32u Mask2=(Mask*(*States))>>8;
209 Mask-=Mask2;
210 if (Current<Mask)
211 {
212 *States=zero_state[*States];
213 return false;
214 }
215 Current-=Mask;
216 Mask=Mask2;
217 *States=one_state[*States];
218 return true;
219 }
220
221 //---------------------------------------------------------------------------
get_symbol_u(int8u * States)222 int32u RangeCoder::get_symbol_u(int8u* States)
223 {
224 if (get_rac(States))
225 return 0;
226
227 int e = 0;
228 while (get_rac(States + 1 + min(e, 9))) // 1..10
229 {
230 e++;
231 if (e > 31)
232 {
233 ForceUnderrun(); // stream is buggy or unsupported, we disable it completely and we indicate that it is NOK
234 return 0;
235 }
236 }
237
238 int32u a = 1;
239 int i = e - 1;
240 while (i >= 0)
241 {
242 a <<= 1;
243 if (get_rac(States + 22 + min(i, 9))) // 22..31
244 ++a;
245 i--;
246 }
247
248 return a;
249 }
250
251 //---------------------------------------------------------------------------
get_symbol_s(int8u * States)252 int32s RangeCoder::get_symbol_s(int8u* States)
253 {
254 if (get_rac(States))
255 return 0;
256
257 int e = 0;
258 while (get_rac(States + 1 + min(e, 9))) // 1..10
259 {
260 e++;
261 if (e > 31)
262 {
263 ForceUnderrun(); // stream is buggy or unsupported, we disable it completely and we indicate that it is NOK
264 return 0;
265 }
266 }
267
268 int32s a = 1;
269 int i = e - 1;
270 while (i >= 0)
271 {
272 a <<= 1;
273 if (get_rac(States + 22 + min(i, 9))) // 22..31
274 ++a;
275 i--;
276 }
277
278 if (get_rac(States + 11 + min(e, 10))) // 11..21
279 return -a;
280 else
281 return a;
282 }
283
284 //***************************************************************************
285 // Info
286 //***************************************************************************
287
Ffv1_coder_type(int8u coder_type)288 static const char* Ffv1_coder_type(int8u coder_type)
289 {
290 switch (coder_type)
291 {
292 case 0 :
293 return "Golomb Rice";
294 case 1 :
295 case 2 :
296 return "Range Coder";
297 default:
298 return "";
299 }
300 }
301
Ffv1_colorspace_type(int8u colorspace_type,bool chroma_planes,bool alpha_plane)302 static const string Ffv1_colorspace_type(int8u colorspace_type, bool chroma_planes, bool alpha_plane)
303 {
304 string ToReturn;
305 switch (colorspace_type)
306 {
307 case 0 :
308 ToReturn=chroma_planes?"YUV":"Y";
309 break;
310 case 1 : ToReturn="RGB"; break;
311 default: return string();
312 }
313
314 if (alpha_plane)
315 ToReturn+='A';
316
317 return ToReturn;
318 }
319
Ffv1_picture_structure_ScanType(int8u picture_structure)320 static const char* Ffv1_picture_structure_ScanType (int8u picture_structure)
321 {
322 switch (picture_structure)
323 {
324 case 1 :
325 case 2 : return "Interlaced";
326 case 3 : return "Progressive";
327 default: return "";
328 }
329 }
330
Ffv1_picture_structure_ScanOrder(int8u picture_structure)331 static const char* Ffv1_picture_structure_ScanOrder (int8u picture_structure)
332 {
333 switch (picture_structure)
334 {
335 case 1 : return "TFF";
336 case 2 : return "BFF";
337 default: return "";
338 }
339 }
340
341 static const state_transitions Ffv1_default_state_transition =
342 {
343 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27,
344 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42,
345 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57,
346 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
347 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
348 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99,100,101,102,103,
349 104,105,106,107,108,109,110,111,112,113,114,114,115,116,117,118,
350 119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,133,
351 134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,
352 150,151,152,152,153,154,155,156,157,158,159,160,161,162,163,164,
353 165,166,167,168,169,170,171,171,172,173,174,175,176,177,178,179,
354 180,181,182,183,184,185,186,187,188,189,190,190,191,192,194,194,
355 195,196,197,198,199,200,201,202,202,204,205,206,207,208,209,209,
356 210,211,212,213,215,215,216,217,218,219,220,220,222,223,224,225,
357 226,227,227,229,229,230,231,232,234,234,235,236,237,238,239,240,
358 241,242,243,244,245,246,247,248,248, 0, 0, 0, 0, 0, 0, 0,
359 };
360
361 // Coming from FFv1 spec.
362 static const int8u log2_run[41]={
363 0 , 0, 0, 0, 1, 1, 1, 1,
364 2 , 2, 2, 2, 3, 3, 3, 3,
365 4 , 4, 5, 5, 6, 6, 7, 7,
366 8 , 9,10,11,12,13,14,15,
367 16,17,18,19,20,21,22,23,
368 24,
369 };
370
371 static const int32u run[41] =
372 {
373 1 << 0,
374 1 << 0,
375 1 << 0,
376 1 << 0,
377 1 << 1,
378 1 << 1,
379 1 << 1,
380 1 << 1,
381 1 << 2,
382 1 << 2,
383 1 << 2,
384 1 << 2,
385 1 << 3,
386 1 << 3,
387 1 << 3,
388 1 << 3,
389 1 << 4,
390 1 << 4,
391 1 << 5,
392 1 << 5,
393 1 << 6,
394 1 << 6,
395 1 << 7,
396 1 << 7,
397 1 << 8,
398 1 << 9,
399 1 << 10,
400 1 << 11,
401 1 << 12,
402 1 << 13,
403 1 << 14,
404 1 << 15,
405 1 << 16,
406 1 << 17,
407 1 << 18,
408 1 << 19,
409 1 << 20,
410 1 << 21,
411 1 << 22,
412 1 << 23,
413 1 << 24,
414 };
415
416 //***************************************************************************
417 // Slice
418 //***************************************************************************
419
420 //---------------------------------------------------------------------------
contexts_clean()421 void Slice::contexts_clean()
422 {
423 for (size_t i = 0; i < MAX_PLANES; i++)
424 {
425 if (contexts[i])
426 delete[] contexts[i];
427 }
428 }
429
430 //---------------------------------------------------------------------------
contexts_init(int32u plane_count,int32u quant_table_index[MAX_PLANES],int32u context_count[MAX_QUANT_TABLES])431 void Slice::contexts_init(int32u plane_count, int32u quant_table_index[MAX_PLANES], int32u context_count[MAX_QUANT_TABLES])
432 {
433 contexts_clean();
434
435 for (size_t i = 0; i < MAX_PLANES; ++i)
436 {
437 if (i >= plane_count)
438 {
439 contexts[i] = NULL;
440 continue;
441 }
442 int32u idx = quant_table_index[i];
443 contexts[i] = new Context [context_count[idx]];
444 }
445 }
446
447 //***************************************************************************
448 // Constructor/Destructor
449 //***************************************************************************
450
451 //---------------------------------------------------------------------------
File_Ffv1()452 File_Ffv1::File_Ffv1()
453 :File__Analyze()
454 {
455 //Configuration
456 ParserName="FFV1";
457 #if MEDIAINFO_TRACE
458 Trace_Layers_Update(8); //Stream
459 #endif //MEDIAINFO_TRACE
460 StreamSource=IsStream;
461
462 //use Ffv1_default_state_transition by default
463 memcpy(state_transitions_table, Ffv1_default_state_transition,
464 sizeof(Ffv1_default_state_transition));
465
466 //Input
467 Width = (int32u)-1;
468 Height = (int32u)-1;
469
470 //Temp
471 for (size_t i=0; i < MAX_QUANT_TABLES; ++i)
472 {
473 plane_states[i] = NULL;
474 plane_states_maxsizes[i] = 0;
475 }
476 Parameters_IsValid=false;
477 ConfigurationRecord_IsPresent=false;
478 RC=NULL;
479 slices = NULL;
480 version = (int32u)-1;
481 picture_structure = (int32u)-1;
482 sample_aspect_ratio_num = 0;
483 sample_aspect_ratio_den = 0;
484 KeyFramePassed = false;
485 memset(context_count, 0, MAX_QUANT_TABLES*sizeof(int32u));
486 }
487
488 //---------------------------------------------------------------------------
~File_Ffv1()489 File_Ffv1::~File_Ffv1()
490 {
491 //Temp
492 if (slices)
493 {
494 for (size_t y = 0; y < num_v_slices; ++y)
495 for (size_t x = 0; x < num_h_slices; ++x)
496 plane_states_clean(slices[x + y * num_h_slices].plane_states);
497 delete[] slices;
498 }
499 for (size_t i = 0; i < MAX_QUANT_TABLES; ++i)
500 {
501 if (!plane_states[i])
502 continue;
503 for (size_t j = 0; j < context_count[i]; ++j)
504 delete[] plane_states[i][j];
505 delete[] plane_states[i];
506 plane_states[i] = NULL;
507 }
508 delete RC; //RC=NULL
509 }
510
511 //***************************************************************************
512 // Streams management
513 //***************************************************************************
514
515 //---------------------------------------------------------------------------
Streams_Accept()516 void File_Ffv1::Streams_Accept()
517 {
518 Stream_Prepare(Stream_Video);
519 Fill(Stream_Video, 0, Video_Format, "FFV1");
520 if (version!=(int32u)-1)
521 {
522 Ztring Version=__T("Version ")+Ztring::ToZtring(version);
523 if (version>=3 && version<=4)
524 {
525 Version+=__T('.');
526 Version+=Ztring::ToZtring(micro_version);
527 }
528 Fill(Stream_Video, 0, Video_Format_Version, Version);
529 }
530 Fill(Stream_Video, 0, Video_BitRate_Mode, "VBR");
531 }
532
533 //***************************************************************************
534 // RangeCoder
535 //***************************************************************************
536
537 #if MEDIAINFO_TRACE
538 //---------------------------------------------------------------------------
Get_RB(states & States,bool & Info,const char * Name)539 void File_Ffv1::Get_RB (states &States, bool &Info, const char* Name)
540 {
541 Info=RC->get_rac(States);
542
543 if (Trace_Activated)
544 {
545 Element_Offset+=RC->BytesUsed();
546 Param(Name, Info);
547 Element_Offset-=RC->BytesUsed();
548 }
549 }
550
551 //---------------------------------------------------------------------------
Get_RU(states & States,int32u & Info,const char * Name)552 void File_Ffv1::Get_RU (states &States, int32u &Info, const char* Name)
553 {
554 Info=RC->get_symbol_u(States);
555
556 if (Trace_Activated)
557 {
558 Element_Offset+=RC->BytesUsed();
559 Param(Name, Info);
560 Element_Offset-=RC->BytesUsed();
561 }
562 }
563
564 //---------------------------------------------------------------------------
Get_RS(states & States,int32s & Info,const char * Name)565 void File_Ffv1::Get_RS (states &States, int32s &Info, const char* Name)
566 {
567 Info=RC->get_symbol_s(States);
568
569 if (Trace_Activated)
570 {
571 Element_Offset+=RC->BytesUsed();
572 Param(Name, Info);
573 Element_Offset-=RC->BytesUsed();
574 }
575 }
576
577 //---------------------------------------------------------------------------
Get_RS(int8u * & States,int32s & Info,const char * Name)578 void File_Ffv1::Get_RS (int8u* &States, int32s &Info, const char* Name)
579 {
580 Info=RC->get_symbol_s(States);
581
582 if (Trace_Activated)
583 {
584 Element_Offset+=RC->BytesUsed();
585 Param(Name, Info);
586 Element_Offset-=RC->BytesUsed();
587 }
588 }
589
590 //---------------------------------------------------------------------------
Skip_RC(states & States,const char * Name)591 void File_Ffv1::Skip_RC (states &States, const char* Name)
592 {
593 int8u Info=RC->get_rac(States);
594
595 if (Trace_Activated)
596 {
597 Element_Offset+=RC->BytesUsed();
598 Param(Name, Info);
599 Element_Offset-=RC->BytesUsed();
600 }
601 }
602
603 //---------------------------------------------------------------------------
Skip_RU(states & States,const char * Name)604 void File_Ffv1::Skip_RU (states &States, const char* Name)
605 {
606 if (Trace_Activated)
607 {
608 Element_Offset+=RC->BytesUsed();
609 Param(Name, RC->get_symbol_u(States));
610 Element_Offset-=RC->BytesUsed();
611 }
612 else
613 RC->get_symbol_u(States);
614 }
615
616 //---------------------------------------------------------------------------
Skip_RS(states & States,const char * Name)617 void File_Ffv1::Skip_RS (states &States, const char* Name)
618 {
619 if (Trace_Activated)
620 {
621 Element_Offset+=RC->BytesUsed();
622 Param(Name, RC->get_symbol_s(States));
623 Element_Offset-=RC->BytesUsed();
624 }
625 else
626 RC->get_symbol_s(States);
627 }
628
629 #else //MEDIAINFO_TRACE
630 //---------------------------------------------------------------------------
Get_RB_(states & States,bool & Info)631 void File_Ffv1::Get_RB_ (states &States, bool &Info)
632 {
633 Info=RC->get_rac(States);
634 }
635
636 //---------------------------------------------------------------------------
Get_RU_(states & States,int32u & Info)637 void File_Ffv1::Get_RU_ (states &States, int32u &Info)
638 {
639 Info=RC->get_symbol_u(States);
640 }
641
642 //---------------------------------------------------------------------------
Get_RS_(states & States,int32s & Info)643 void File_Ffv1::Get_RS_ (states &States, int32s &Info)
644 {
645 Info=RC->get_symbol_s(States);
646 }
647
648 //---------------------------------------------------------------------------
Get_RS_(int8u * & States,int32s & Info)649 void File_Ffv1::Get_RS_ (int8u* &States, int32s &Info)
650 {
651 Info=RC->get_symbol_s(States);
652 }
653
654 //---------------------------------------------------------------------------
Skip_RC_(states & States)655 void File_Ffv1::Skip_RC_ (states &States)
656 {
657 RC->get_rac(States);
658 }
659
660 //---------------------------------------------------------------------------
Skip_RU_(states & States)661 void File_Ffv1::Skip_RU_ (states &States)
662 {
663 RC->get_symbol_u(States);
664 }
665
666 //---------------------------------------------------------------------------
Skip_RS_(states & States)667 void File_Ffv1::Skip_RS_ (states &States)
668 {
669 RC->get_symbol_s(States);
670 }
671
672 #endif //MEDIAINFO_TRACE
673
674 //***************************************************************************
675 // Buffer - Global
676 //***************************************************************************
677
678 //---------------------------------------------------------------------------
Read_Buffer_OutOfBand()679 void File_Ffv1::Read_Buffer_OutOfBand()
680 {
681 ConfigurationRecord_IsPresent=true;
682
683 //Coherency tests
684 if (Buffer_Size<4)
685 {
686 Skip_XX(Element_Size, "ConfigurationRecord");
687 Param_Error("FFV1-HEADER-END:1");
688 return;
689 }
690 int32u CRC_32=FFv1_CRC_Compute(Buffer+Buffer_Offset, (size_t)Element_Size);
691
692 Element_Begin1("ConfigurationRecord");
693 delete RC; RC=new RangeCoder(Buffer, Buffer_Size-4, Ffv1_default_state_transition);
694 Parameters();
695 delete RC; RC=NULL;
696 if (Element_Offset+4<Element_Size)
697 Skip_XX(Element_Size-Element_Offset-4, "Reserved");
698 Skip_B4( "configuration_record_crc_parity");
699 if (CRC_32)
700 Param_Error("FFV1-HEADER-configuration_record_crc_parity:1");
701 Element_End0();
702 }
703
704 //---------------------------------------------------------------------------
Skip_Frame()705 void File_Ffv1::Skip_Frame()
706 {
707 Skip_XX(Element_Size-Element_Offset, "Data");
708
709 Frame_Count++;
710
711 delete RC;
712 RC = NULL;
713
714 Fill();
715 if (Config->ParseSpeed<1.0)
716 Finish();
717 }
718
719 //---------------------------------------------------------------------------
Read_Buffer_Continue()720 void File_Ffv1::Read_Buffer_Continue()
721 {
722 if (ConfigurationRecord_IsPresent && !Parameters_IsValid)
723 {
724 Skip_Frame();
725 return;
726 }
727
728 if (!RC)
729 RC = new RangeCoder(Buffer, Buffer_Size, Ffv1_default_state_transition);
730
731 states States;
732 memset(States, 128, states_size);
733
734 Element_Begin1("Frame");
735
736 Get_RB (States, keyframe, "keyframe");
737 if (intra && !keyframe)
738 Param_Error("FFV1-FRAME-key_frame-ISNOTINTRA:1");
739 if (keyframe)
740 KeyFramePassed=true;
741
742 if (!ConfigurationRecord_IsPresent && keyframe)
743 {
744 #if MEDIAINFO_TRACE
745 bool Trace_Activated_Save=Trace_Activated;
746 if (Trace_Activated && Frame_Count)
747 Trace_Activated=false; // Trace is relatively huge, temporarary deactivating it. TODO: an option for it
748 #endif //MEDIAINFO_TRACE
749
750 Parameters();
751
752 #if MEDIAINFO_TRACE
753 Trace_Activated=Trace_Activated_Save; // Trace is too huge, reactivating it.
754 #endif //MEDIAINFO_TRACE
755 }
756
757 if (!Parameters_IsValid || !KeyFramePassed)
758 {
759 Skip_Frame();
760 return;
761 }
762
763 int32u tail = (version >= 3) ? 3 : 0;
764 tail += ec == 1 ? 5 : 0;
765
766 vector<int32u> Slices_BufferSizes;
767 if (version>=3)
768 {
769 int64u Slices_BufferPos=Element_Size;
770 while (Slices_BufferPos)
771 {
772 if (Slices_BufferPos<tail)
773 {
774 //There is a problem
775 Slices_BufferSizes.clear();
776 break;
777 }
778
779 int32u Size=BigEndian2int24u(Buffer+Buffer_Offset+(size_t)Slices_BufferPos-tail);
780 Size+=tail;
781
782 if (Size>Slices_BufferPos)
783 {
784 //There is a problem
785 Slices_BufferSizes.clear();
786 break;
787 }
788 Slices_BufferPos-=Size;
789
790 Slices_BufferSizes.insert(Slices_BufferSizes.begin(), Size);
791 }
792 }
793
794 size_t Pos=0;
795 BuggySlices=false;
796 while (Element_Offset<Element_Size || (!Pos && coder_type)) // With some v0 RC, content may be in the last byte of the RC which is also in the Parameter() part
797 {
798 Element_Begin1("Slice");
799 int64u Element_Offset_Begin=Element_Offset;
800 int64u Element_Size_Save=Element_Size;
801 if (Pos<Slices_BufferSizes.size())
802 Element_Size=Element_Offset+Slices_BufferSizes[Pos];
803 int32u crc_left=0;
804 if (ec == 1)
805 crc_left=FFv1_CRC_Compute(Buffer+Buffer_Offset+(size_t)Element_Offset, (size_t)(Element_Size-Element_Offset));
806 Element_Size-=tail;
807
808 if (Pos)
809 {
810 delete RC; RC = new RangeCoder(Buffer+Buffer_Offset+(size_t)Element_Offset, Element_Size-Element_Offset, state_transitions_table);
811 }
812 else
813 {
814 RC->ResizeBuffer(Element_Size);
815 RC->AssignStateTransitions(state_transitions_table);
816 }
817
818 //SliceHeader
819 bool ParseContent;
820 if (version>=3)
821 {
822 ParseContent=SliceHeader(States);
823 if (!ParseContent)
824 BuggySlices=true;
825 }
826 else
827 ParseContent=true;
828
829 //SliceContent
830 #if MEDIAINFO_TRACE
831 if (ParseContent && (!Frame_Count || Trace_Activated)) // Parse slice only if trace feature is activated
832 {
833 SliceContent(States);
834 }
835 else
836 #endif //MEDIAINFO_TRACE
837 Skip_XX(Element_Size-Element_Offset, "SliceContent");
838 if (version<=1 && Element_Offset+5==Element_Size)
839 {
840 crc_left=FFv1_CRC_Compute(Buffer+Buffer_Offset+(size_t)Element_Offset_Begin, (size_t)(Element_Size-Element_Offset_Begin));
841 Element_Size-=5;
842 ec = 1;
843 if (Frame_Count==0)
844 Fill(Stream_Video, 0, "ErrorDetectionType", "Per slice");
845 }
846 if (Element_Offset<Element_Size)
847 {
848 Skip_XX(Element_Size-Element_Offset, "Junk");
849 Param_Error("FFV1-SLICE-JUNK:1");
850 }
851
852 //SliceFooter
853 Element_Size=Element_Size_Save;
854 if (version>=3 || ec == 1)
855 Element_Begin1("SliceFooter");
856 if (version>=3)
857 {
858 int32u slice_size;
859 Get_B3 (slice_size, "slice_size");
860 if (Element_Offset_Begin+slice_size+3!=Element_Offset)
861 Param_Error("FFV1-SLICE-slice_size:1");
862 }
863 {
864 if (ec == 1)
865 {
866 int8u error_status;
867 Get_B1 (error_status, "error_status");
868 if (error_status)
869 Param_Error("FFV1-SLICE-error_status:1");
870 Skip_B4( "slice_crc_parity");
871 if (crc_left)
872 {
873 Param_Error("FFV1-SLICE-slice_crc_parity:1");
874
875 #if MEDIAINFO_FIXITY
876 if (Config->TryToFix_Get())
877 {
878 size_t BitPosition=Ffv1_TryToFixCRC(Buffer+Buffer_Offset+(size_t)Element_Offset_Begin, Element_Offset-Element_Offset_Begin);
879 if (BitPosition!=(size_t)-1)
880 {
881 size_t BytePosition=BitPosition>>3;
882 size_t BitInBytePosition=BitPosition&0x7;
883 int8u Modified=Buffer[Buffer_Offset+(size_t)Element_Offset_Begin+BytePosition];
884 Modified^=1<<BitInBytePosition;
885 FixFile(File_Offset+Buffer_Offset+(size_t)Element_Offset_Begin+BytePosition, &Modified, 1)?Param_Info1("Fixed"):Param_Info1("Not fixed");
886 }
887 }
888 #endif //MEDIAINFO_FIXITY
889 }
890 }
891 }
892 if (version>=3 || ec==1)
893 Element_End0();
894
895 Element_End0();
896 Pos++;
897 }
898
899 //Integrity test
900 if (!BuggySlices && version>=3 && slices)
901 {
902 vector<size_t> SlicesPlaces;
903 size_t SlicesPlaces_Size=num_h_slices*num_v_slices;
904 SlicesPlaces.resize(num_h_slices*num_v_slices);
905 Slice* Slice_Max=slices+SlicesPlaces_Size;
906 current_slice=slices;
907 while (current_slice<Slice_Max)
908 {
909 if (current_slice->sample_buffer)
910 SlicesPlaces[current_slice->slice_y*num_h_slices+current_slice->slice_x]++;
911
912 current_slice++;
913 }
914 for (size_t i=0; i<SlicesPlaces_Size; i++)
915 if (SlicesPlaces[i]!=1)
916 {
917 Element_Error("FFV1-FRAME-END:1");
918 break;
919 }
920 }
921
922 Element_End0();
923
924 FILLING_BEGIN();
925 if (Frame_Count==0)
926 {
927 Fill(Stream_Video, 0, Video_ScanType, Ffv1_picture_structure_ScanType(picture_structure));
928 Fill(Stream_Video, 0, Video_ScanOrder, Ffv1_picture_structure_ScanOrder(picture_structure));
929 if (sample_aspect_ratio_num && sample_aspect_ratio_den)
930 Fill(Stream_Video, 0, Video_PixelAspectRatio, ((float64)sample_aspect_ratio_num)/sample_aspect_ratio_den);
931 }
932
933 Frame_Count++;
934 FILLING_END();
935
936 delete RC;
937 RC = NULL;
938
939 Fill();
940 if (Config->ParseSpeed<1.0)
941 Finish();
942 }
943
944 //***************************************************************************
945 // Elements
946 //***************************************************************************
947
948 //---------------------------------------------------------------------------
Parameters()949 void File_Ffv1::Parameters()
950 {
951 Element_Begin1("Parameters");
952
953 //Parsing
954 states States;
955 memset(States, 128, states_size);
956 Get_RU (States, version, "version");
957 if ( ConfigurationRecord_IsPresent && version<=1)
958 {
959 Param_Error("FFV1-HEADER-version-OUTOFBAND:1");
960 Accept(); //TODO: better check without removing error info in trace
961 Element_End0();
962 return;
963 }
964 if (!ConfigurationRecord_IsPresent && version> 1)
965 {
966 Param_Error("FFV1-HEADER-version-OUTOFBAND:1");
967 Accept(); //TODO: better check without removing error info in trace
968 Element_End0();
969 return;
970 }
971 if (version==2 || version>3)
972 {
973 Param_Error(version==2?"FFV1-HEADER-version-EXPERIMENTAL:1":"FFV1-HEADER-version-LATERVERSION:1");
974 if (version==2 || version>4)
975 {
976 Accept();
977 Element_End0();
978 return;
979 }
980 }
981 if (version>=3)
982 Get_RU (States, micro_version, "micro_version");
983 if ((version==3 && micro_version<4))
984 {
985 Param_Error("FFV1-HEADER-micro_version-EXPERIMENTAL:1");
986 Accept();
987 Element_End0();
988 return;
989 }
990 if (version==4) // Version 4 is still experimental at the time of writing but contains micro_version so we show it
991 {
992 Accept();
993 Element_End0();
994 return;
995 }
996 if (Frame_Count==0)
997 Accept(); //TODO: better check without removing error info in trace
998 Get_RU (States, coder_type, "coder_type");
999 if (coder_type>2)
1000 {
1001 Param_Error("FFV1-HEADER-coder_type:1");
1002 Element_End0();
1003 return;
1004 }
1005 if (coder_type==2) //Range coder with custom state transition table
1006 {
1007 Element_Begin1("state_transition_deltas");
1008 for (size_t i = 1; i < state_transitions_size; i++)
1009 {
1010 int32s state_transition_delta;
1011 Get_RS (States, state_transition_delta, "state_transition_delta");
1012 state_transition_delta+=RC->one_state[i];
1013 Param_Info1(state_transition_delta);
1014 if (state_transition_delta<0x00 || state_transition_delta>0xFF)
1015 {
1016 Param_Error("FFV1-HEADER-state_transition_delta:1");
1017 Element_End0();
1018 Element_End0();
1019 return;
1020 }
1021 state_transitions_table[i]=(int8u)state_transition_delta;
1022 }
1023 Element_End0();
1024 }
1025 Get_RU (States, colorspace_type, "colorspace_type");
1026 if (colorspace_type>1)
1027 {
1028 Param_Error("FFV1-HEADER-colorspace_type:1");
1029 Element_End0();
1030 Element_End0();
1031 return;
1032 }
1033 if (version)
1034 {
1035 Get_RU (States, bits_per_raw_sample, "bits_per_raw_sample");
1036 if (bits_per_raw_sample>64)
1037 {
1038 Param_Error("FFV1-HEADER-bits_per_raw_sample:1");
1039 Element_End0();
1040 return;
1041 }
1042 if (bits_per_raw_sample==0)
1043 bits_per_raw_sample=8; // Spec decision due to old encoders
1044 }
1045 else
1046 {
1047 bits_per_raw_sample=8;
1048 }
1049
1050 Get_RB (States, chroma_planes, "chroma_planes");
1051 Get_RU (States, h_chroma_subsample_log2, "log2(h_chroma_subsample)");
1052 Get_RU (States, v_chroma_subsample_log2, "log2(h_chroma_subsample)");
1053 Get_RB (States, alpha_plane, "alpha_plane");
1054 if (version>1)
1055 {
1056 Get_RU (States, num_h_slices, "num_h_slices_minus1");
1057 if (num_h_slices>=Width)
1058 {
1059 Param_Error("FFV1-HEADER-num_h_slices:1");
1060 Element_End0();
1061 return;
1062 }
1063 Get_RU (States, num_v_slices, "num_v_slices_minus1");
1064 if (num_v_slices>=Height)
1065 {
1066 Param_Error("FFV1-HEADER-num_v_slices:1");
1067 Element_End0();
1068 return;
1069 }
1070 num_h_slices++;
1071 num_v_slices++;
1072 Get_RU (States, quant_table_count, "quant_table_count");
1073 if (quant_table_count>8)
1074 {
1075 Param_Error("FFV1-HEADER-quant_table_count:1");
1076 Element_End0();
1077 return;
1078 }
1079 }
1080 else
1081 {
1082 num_h_slices=1;
1083 num_v_slices=1;
1084 quant_table_count=1;
1085 }
1086 for (size_t i=0; i<quant_table_count; i++)
1087 if (!QuantizationTable(i))
1088 {
1089 Element_End0();
1090 return;
1091 }
1092 for (size_t i=0; i<quant_table_count; i++)
1093 {
1094 if (version>=2)
1095 Element_Begin1("initial_state");
1096 bool present=false;
1097 if (version>=2)
1098 Get_RB (States, present, "states_coded");
1099
1100 if (coder_type && context_count[i]>plane_states_maxsizes[i])
1101 {
1102 states_context_plane plane_state_old = plane_states[i];
1103 plane_states[i] = new int8u*[context_count[i]];
1104 if (plane_state_old)
1105 {
1106 memcpy(plane_states[i], plane_state_old, plane_states_maxsizes[i] * sizeof(int8u*));
1107 delete[] plane_state_old;
1108 }
1109 for (size_t j = plane_states_maxsizes[i]; j < context_count[i]; j++)
1110 plane_states[i][j] = new int8u[states_size];
1111 plane_states_maxsizes[i] = context_count[i];
1112 }
1113
1114 for (size_t j = 0; j < context_count[i]; j++)
1115 {
1116 if (present)
1117 {
1118 Element_Begin1("initial_state_deltas");
1119 for (size_t k = 0; k < states_size; k++)
1120 {
1121 int32s value;
1122 Get_RS (States, value, "initial_state_delta");
1123 if (coder_type)
1124 plane_states[i][j][k] = value;
1125 }
1126 Element_End0();
1127 }
1128 else if (coder_type)
1129 {
1130 for (size_t k = 0; k < states_size; k++)
1131 plane_states[i][j][k] = 128;
1132 }
1133 }
1134 if (version>=2)
1135 Element_End0();
1136 }
1137
1138 if (version>=3)
1139 {
1140 Get_RU (States, ec, "ec");
1141 if (ec>1)
1142 {
1143 Param_Error("FFV1-HEADER-ec:1");
1144 Element_End0();
1145 return;
1146 }
1147 if (micro_version)
1148 {
1149 Get_RU (States, intra, "intra");
1150 if (intra>1)
1151 {
1152 Param_Error("FFV1-HEADER-intra:1");
1153 Element_End0();
1154 return;
1155 }
1156 }
1157 else
1158 intra=0;
1159 }
1160 else
1161 {
1162 ec=0;
1163 intra=0;
1164 }
1165
1166 Element_End0();
1167
1168 FILLING_BEGIN();
1169 //Marking handling of 16-bit overflow computing
1170 is_overflow_16bit=(colorspace_type==0 && bits_per_raw_sample==16 && (coder_type==1 || coder_type==2))?true:false; //TODO: check in FFmpeg the version when the stream is fixed. Note: only with YUV colorspace
1171
1172 //quant_table_index_Count
1173 quant_table_index_count=1+(alpha_plane?1:0);
1174 if (version < 4 || chroma_planes) // Warning: chroma is considered as 1 plane
1175 quant_table_index_count++;
1176
1177 //Slices
1178 if (!slices)
1179 {
1180 slices=new Slice[num_h_slices*num_v_slices];
1181 current_slice=&slices[0];
1182 }
1183 if (version<=1)
1184 {
1185 current_slice->x=0;
1186 current_slice->y=0;
1187 current_slice->w=Width;
1188 current_slice->h=Height;
1189 quant_table_index[0]=0;
1190 for (size_t i=1; i<quant_table_index_count; i++)
1191 {
1192 quant_table_index[i]=0;
1193 context_count[i]=context_count[0];
1194 }
1195 }
1196
1197 //Filling
1198 if (Frame_Count==0)
1199 {
1200 Fill(Stream_Video, 0, "coder_type", Ffv1_coder_type(coder_type));
1201 Fill(Stream_Video, 0, Video_BitDepth, bits_per_raw_sample);
1202 if (version>1)
1203 {
1204 Fill(Stream_Video, 0, "MaxSlicesCount", num_h_slices*num_v_slices);
1205 if (version>=3)
1206 {
1207 if (ec)
1208 Fill(Stream_Video, 0, "ErrorDetectionType", "Per slice");
1209 if (micro_version && intra)
1210 Fill(Stream_Video, 0, Video_Format_Settings_GOP, "N=1");
1211 }
1212 }
1213 Fill(Stream_Video, 0, Video_ColorSpace, Ffv1_colorspace_type(colorspace_type, chroma_planes, alpha_plane));
1214 if (colorspace_type==0 && chroma_planes)
1215 {
1216 string ChromaSubsampling;
1217 switch (h_chroma_subsample_log2)
1218 {
1219 case 0 :
1220 switch (v_chroma_subsample_log2)
1221 {
1222 case 0 : ChromaSubsampling="4:4:4"; break;
1223 default: ;
1224 }
1225 break;
1226 case 1 :
1227 switch (v_chroma_subsample_log2)
1228 {
1229 case 0 : ChromaSubsampling="4:2:2"; break;
1230 case 1 : ChromaSubsampling="4:2:0"; break;
1231 default: ;
1232 }
1233 break;
1234 case 2 :
1235 switch (v_chroma_subsample_log2)
1236 {
1237 case 0 : ChromaSubsampling="4:1:1"; break;
1238 case 1 : ChromaSubsampling="4:1:0"; break;
1239 case 2 : ChromaSubsampling="4:1:0 (4x4)"; break;
1240 default: ;
1241 }
1242 break;
1243 default: ;
1244 }
1245 if (!ChromaSubsampling.empty() && alpha_plane)
1246 ChromaSubsampling+=":4";
1247 Fill(Stream_Video, 0, Video_ChromaSubsampling, ChromaSubsampling);
1248 }
1249
1250 Parameters_IsValid=true;
1251 }
1252 FILLING_END();
1253 }
1254
1255 //---------------------------------------------------------------------------
SliceContent(states & States)1256 void File_Ffv1::SliceContent(states &States)
1257 {
1258 Element_Begin1("SliceContent");
1259
1260 #if MEDIAINFO_TRACE
1261 bool Trace_Activated_Save=Trace_Activated;
1262 if (Trace_Activated)
1263 Trace_Activated=false; // Trace is too huge, deactivating it during pixel decoding
1264 #endif //MEDIAINFO_TRACE
1265
1266 if (!coder_type)
1267 {
1268 if (version>=3)
1269 {
1270 int8u s = 129;
1271 RC->get_rac(&s);
1272 }
1273 Element_Offset+=RC->BytesUsed(); // Computing how many bytes where consumed by the range coder
1274 BS_Begin();
1275 }
1276
1277 if (keyframe)
1278 {
1279 int8u plane_count=1+(alpha_plane?1:0);
1280 if (version < 4 || chroma_planes) // Warning: chroma is considered as 1 plane
1281 plane_count+=1;
1282 if (!coder_type)
1283 current_slice->contexts_init(plane_count, quant_table_index, context_count);
1284 else
1285 copy_plane_states_to_slice(plane_count);
1286 }
1287 current_slice->sample_buffer_new((current_slice->w + 6) * 3 * MAX_PLANES);
1288
1289 if (colorspace_type == 0)
1290 {
1291 // YCbCr
1292 plane(0); // Y
1293 if (chroma_planes)
1294 {
1295 int32u w = current_slice->w;
1296 int32u h = current_slice->h;
1297
1298 current_slice->w = w >> h_chroma_subsample_log2;
1299 if (w & ((1 << h_chroma_subsample_log2) - 1))
1300 current_slice->w++; //Is ceil
1301 current_slice->h = h >> v_chroma_subsample_log2;
1302 if (h & ((1 << v_chroma_subsample_log2) - 1))
1303 current_slice->h++; //Is ceil
1304 plane(1); // Cb
1305 plane(1); // Cr
1306 current_slice->w = w;
1307 current_slice->h = h;
1308 }
1309 if (alpha_plane)
1310 plane(2); // Alpha
1311 }
1312 else if (colorspace_type == 1)
1313 rgb();
1314
1315 if (coder_type)
1316 {
1317 int8u s = 129;
1318 RC->get_rac(&s);
1319 }
1320
1321 if (BS->BufferUnderRun || RC->Underrun())
1322 Element_Error("FFV1-SLICE-SliceContent:1");
1323
1324 if (coder_type)
1325 Skip_XX(RC->BytesUsed(), "slice_data");
1326 else
1327 BS_End();
1328
1329 #if MEDIAINFO_DECODE
1330 //Decode(Buffer, Buffer_Size);
1331 #endif //MEDIAINFO_DECODE
1332
1333 #if MEDIAINFO_TRACE
1334 Trace_Activated=Trace_Activated_Save; // Trace is too huge, reactivating after during pixel decoding
1335 #endif //MEDIAINFO_TRACE
1336 Element_End0();
1337 }
1338
1339 //---------------------------------------------------------------------------
SliceHeader(states & States)1340 bool File_Ffv1::SliceHeader(states &States)
1341 {
1342 Element_Begin1("SliceHeader");
1343
1344 memset(States, 128, states_size);
1345
1346 int32u slice_x, slice_y, slice_width_minus1, slice_height_minus1;
1347 Get_RU (States, slice_x, "slice_x");
1348 if (slice_x >= num_h_slices)
1349 {
1350 Param_Error("FFV1-SLICE-slice_xywh:1");
1351 Element_End0();
1352 return false;
1353 }
1354
1355 Get_RU (States, slice_y, "slice_y");
1356 if (slice_y >= num_h_slices)
1357 {
1358 Param_Error("FFV1-SLICE-slice_xywh:1");
1359 Element_End0();
1360 return false;
1361 }
1362
1363 Get_RU (States, slice_width_minus1, "slice_width_minus1");
1364 int32u slice_x2 = slice_x + slice_width_minus1 + 1; //right boundary
1365 if (slice_x2 > num_h_slices)
1366 {
1367 Param_Error("FFV1-SLICE-slice_xywh:1");
1368 Element_End0();
1369 return false;
1370 }
1371
1372 Get_RU (States, slice_height_minus1, "slice_height_minus1");
1373 int32u slice_y2 = slice_y + slice_height_minus1 + 1; //bottom boundary
1374 if (slice_y2 > num_v_slices)
1375 {
1376 Param_Error("FFV1-SLICE-slice_xywh:1");
1377 Element_End0();
1378 return false;
1379 }
1380
1381 current_slice = &slices[slice_x + slice_y * num_h_slices];
1382 current_slice->slice_x = slice_x;
1383 current_slice->slice_y = slice_y;
1384 current_slice->slice_w = slice_x2;
1385 current_slice->slice_h = slice_y2;
1386
1387 //Computing boundaries, being careful about how are computed boundaries when there is not an integral number for Width / num_h_slices or Height / num_v_slices (the last slice has more pixels)
1388 current_slice->x = slice_x * Width / num_h_slices;
1389 current_slice->y = slice_y * Height / num_v_slices;
1390 current_slice->w = slice_x2 * Width / num_h_slices - current_slice->x;
1391 current_slice->h = slice_y2 * Height / num_v_slices - current_slice->y;
1392
1393
1394 for (int8u i = 0; i < quant_table_index_count; i++)
1395 {
1396 Get_RU (States, quant_table_index[i], "quant_table_index");
1397 if (quant_table_index[i]>=quant_table_count)
1398 {
1399 Param_Error("FFV1-SLICE-quant_table_index:1");
1400 Element_End0();
1401 return false;
1402 }
1403 }
1404 Get_RU (States, picture_structure, "picture_structure");
1405 if (picture_structure>3)
1406 Param_Error("FFV1-SLICE-picture_structure:1");
1407 Get_RU (States, sample_aspect_ratio_num, "sar_num");
1408 Get_RU (States, sample_aspect_ratio_den, "sar_den");
1409 if ((sample_aspect_ratio_num && !sample_aspect_ratio_den)) // || (!sample_aspect_ratio_num && sample_aspect_ratio_den)) // Second part is deactivated because FFmpeg creates such file when SAR is unknown
1410 Param_Error("FFV1-SLICE-sar_den:1");
1411 if (version > 3)
1412 {
1413 //TODO
1414 }
1415
1416 RC->AssignStateTransitions(state_transitions_table);
1417
1418 Element_End0();
1419 return true;
1420 }
1421
1422 //---------------------------------------------------------------------------
plane(int32u pos)1423 void File_Ffv1::plane(int32u pos)
1424 {
1425 #if MEDIAINFO_TRACE_FFV1CONTENT
1426 Element_Begin1("Plane");
1427 #endif //MEDIAINFO_TRACE_FFV1CONTENT
1428
1429 if (bits_per_raw_sample <= 8)
1430 bits_max = 8;
1431 else
1432 bits_max = bits_per_raw_sample;
1433 bits_mask1 = ((1 << bits_max) - 1);
1434 bits_mask2 = 1 << (bits_max - 1);
1435 bits_mask3 = bits_mask2 - 1;
1436
1437 pixel_t *sample[2];
1438 sample[0] = current_slice->sample_buffer + 3;
1439 sample[1] = sample[0] + current_slice->w + 6;
1440
1441 memset(current_slice->sample_buffer, 0, 2 * (current_slice->w + 6) * sizeof(*current_slice->sample_buffer));
1442
1443 current_slice->run_index = 0;
1444
1445 for (size_t y = 0; y < current_slice->h; y++)
1446 {
1447 #if MEDIAINFO_TRACE_FFV1CONTENT
1448 Element_Begin1("Line");
1449 Element_Info1(y);
1450 #endif //MEDIAINFO_TRACE_FFV1CONTENT
1451
1452 swap(sample[0], sample[1]);
1453
1454 sample[1][-1] = sample[0][0];
1455 sample[0][current_slice->w] = sample[0][current_slice->w - 1];
1456
1457 line(pos, sample);
1458
1459 #if MEDIAINFO_TRACE_FFV1CONTENT
1460 Element_End0();
1461 #endif //MEDIAINFO_TRACE_FFV1CONTENT
1462 }
1463
1464 #if MEDIAINFO_TRACE_FFV1CONTENT
1465 Element_End0();
1466 #endif //MEDIAINFO_TRACE_FFV1CONTENT
1467 }
1468
1469 //---------------------------------------------------------------------------
rgb()1470 void File_Ffv1::rgb()
1471 {
1472 #if MEDIAINFO_TRACE_FFV1CONTENT
1473 Element_Begin1("rgb");
1474 #endif //MEDIAINFO_TRACE_FFV1CONTENT
1475
1476 bits_max = bits_per_raw_sample + 1;
1477 bits_mask1 = (1 << bits_max) - 1;
1478 bits_mask2 = 1 << (bits_max - 1);
1479 bits_mask3 = bits_mask2-1;
1480
1481 size_t c_max = alpha_plane ? 4 : 3;
1482
1483 pixel_t *sample[4][2];
1484
1485 current_slice->run_index = 0;
1486
1487 for (size_t x = 0; x < c_max; x++) {
1488 sample[x][0] = current_slice->sample_buffer + x * 2 * (current_slice->w + 6) + 3;
1489 sample[x][1] = sample[x][0] + current_slice->w + 6;
1490 }
1491 memset(current_slice->sample_buffer, 0, 8 * (current_slice->w + 6) * sizeof(*current_slice->sample_buffer));
1492
1493 for (size_t y = 0; y < current_slice->h; y++)
1494 {
1495 #if MEDIAINFO_TRACE_FFV1CONTENT
1496 Element_Begin1("Line");
1497 Element_Info1(y);
1498 #endif //MEDIAINFO_TRACE_FFV1CONTENT
1499
1500 for (size_t c = 0; c < c_max; c++)
1501 {
1502 // Copy for next lines: 4.3 context
1503 swap(sample[c][0], sample[c][1]);
1504
1505 sample[c][1][-1]= sample[c][0][0 ];
1506 sample[c][0][current_slice->w]= sample[c][0][current_slice->w - 1];
1507
1508 line((c + 1) / 2, sample[c]);
1509 }
1510
1511 #if MEDIAINFO_TRACE_FFV1CONTENT
1512 Element_End0();
1513 #endif //MEDIAINFO_TRACE_FFV1CONTENT
1514 }
1515
1516 #if MEDIAINFO_TRACE_FFV1CONTENT
1517 Element_End0();
1518 #endif //MEDIAINFO_TRACE_FFV1CONTENT
1519 }
1520
1521 //---------------------------------------------------------------------------
get_median_number(int32s one,int32s two,int32s three)1522 static inline int32s get_median_number(int32s one, int32s two, int32s three)
1523 {
1524 if (one > two)
1525 {
1526 // one > two > three
1527 if (two > three)
1528 return two;
1529
1530 // three > one > two
1531 if (three > one)
1532 return one;
1533 // one > three > two
1534 return three;
1535 }
1536
1537 // three > two > one
1538 if (three > two)
1539 return two;
1540
1541 // two > one && two > three
1542
1543 // two > three > one
1544 if (three > one)
1545 return three;
1546 return one;
1547 }
1548
1549 //---------------------------------------------------------------------------
predict(pixel_t * current,pixel_t * current_top,bool is_overflow_16bit)1550 static inline int32s predict(pixel_t *current, pixel_t *current_top, bool is_overflow_16bit)
1551 {
1552 int32s LeftTop, Top, Left;
1553 if (is_overflow_16bit)
1554 {
1555 LeftTop = (int16s)current_top[-1];
1556 Top = (int16s)current_top[0];
1557 Left = (int16s)current[-1];
1558 }
1559 else
1560 {
1561 LeftTop = current_top[-1];
1562 Top = current_top[0];
1563 Left = current[-1];
1564 }
1565
1566 return get_median_number(Left, Left + Top - LeftTop, Top);
1567 }
1568
1569 //---------------------------------------------------------------------------
get_context_3(pixel_t quant_table[MAX_CONTEXT_INPUTS][256],pixel_t * src,pixel_t * last)1570 static inline int get_context_3(pixel_t quant_table[MAX_CONTEXT_INPUTS][256], pixel_t *src, pixel_t *last)
1571 {
1572 const int LT = last[-1];
1573 const int T = last[0];
1574 const int RT = last[1];
1575 const int L = src[-1];
1576
1577 return quant_table[0][(L - LT) & 0xFF]
1578 + quant_table[1][(LT - T) & 0xFF]
1579 + quant_table[2][(T - RT) & 0xFF];
1580 }
get_context_5(pixel_t quant_table[MAX_CONTEXT_INPUTS][256],pixel_t * src,pixel_t * last)1581 static inline int get_context_5(pixel_t quant_table[MAX_CONTEXT_INPUTS][256], pixel_t *src, pixel_t *last)
1582 {
1583 const int LT = last[-1];
1584 const int T = last[0];
1585 const int RT = last[1];
1586 const int L = src[-1];
1587 const int TT = src[0];
1588 const int LL = src[-2];
1589 return quant_table[0][(L - LT) & 0xFF]
1590 + quant_table[1][(LT - T) & 0xFF]
1591 + quant_table[2][(T - RT) & 0xFF]
1592 + quant_table[3][(LL - L) & 0xFF]
1593 + quant_table[4][(TT - T) & 0xFF];
1594 }
1595
1596 //---------------------------------------------------------------------------
pixel_RC(int32s context)1597 int32s File_Ffv1::pixel_RC(int32s context)
1598 {
1599 int32s u;
1600
1601 Get_RS(Context_RC[context], u, "symbol");
1602 return u;
1603 }
1604
1605
1606 //---------------------------------------------------------------------------
pixel_GR(int32s context)1607 int32s File_Ffv1::pixel_GR(int32s context)
1608 {
1609 #if MEDIAINFO_TRACE_FFV1CONTENT
1610 int32s u;
1611
1612 // New symbol, go to "run mode"
1613 if (context == 0 && current_slice->run_mode == RUN_MODE_STOP)
1614 current_slice->run_mode = RUN_MODE_PROCESSING;
1615
1616 // If not running, get the symbol
1617 if (current_slice->run_mode == RUN_MODE_STOP)
1618 {
1619 u = get_symbol_with_bias_correlation(&Context_GR[context]);
1620 #if MEDIAINFO_TRACE
1621 Param("symbol", u);
1622 #endif //MEDIAINFO_TRACE
1623 return u;
1624 }
1625
1626 if (current_slice->run_segment_length == 0 && current_slice->run_mode == RUN_MODE_PROCESSING) // Same symbol length
1627 {
1628 bool hits;
1629 Get_SB (hits, "hits/miss");
1630 //if (bsf.GetB()) // "hits"
1631 if (hits) // "hits"
1632 {
1633 current_slice->run_segment_length = run[current_slice->run_index];
1634 if (x + current_slice->run_segment_length <= current_slice->w) //Do not go further as the end of line
1635 ++current_slice->run_index;
1636 }
1637 else // "miss"
1638 {
1639 //current_slice->run_segment_length = bsf.Get4(log2_run[current_slice->run_index]);
1640 int32u run_segment_length;
1641 Get_S4 (log2_run[current_slice->run_index], run_segment_length, "run_segment_length");
1642 current_slice->run_segment_length=(int32s)run_segment_length;
1643 if (current_slice->run_index)
1644 --current_slice->run_index;
1645 current_slice->run_mode = RUN_MODE_INTERRUPTED;
1646 }
1647 }
1648
1649 current_slice->run_segment_length--;
1650 if (current_slice->run_segment_length < 0) // we passed the length of same symbol, time to get the new symbol
1651 {
1652 u = get_symbol_with_bias_correlation(&Context_GR[context]);
1653 #if MEDIAINFO_TRACE
1654 Param("symbol", u);
1655 #endif //MEDIAINFO_TRACE
1656 if (u >= 0) // GR(u - 1, ...)
1657 u++;
1658
1659 // Time for the new symbol length run
1660 current_slice->run_mode_init();
1661 current_slice->run_segment_length = 0;
1662 } else // same symbol as previous pixel, no difference, waiting
1663 u = 0;
1664 return u;
1665 #else //MEDIAINFO_TRACE_FFV1CONTENT
1666 if (current_slice->run_mode == RUN_MODE_STOP)
1667 {
1668 if (context)
1669 return get_symbol_with_bias_correlation(&Context_GR[context]); // If not running, get the symbol
1670
1671 current_slice->run_mode = RUN_MODE_PROCESSING; // New symbol, go to "run mode"
1672 }
1673
1674 if (current_slice->run_segment_length == 0 && current_slice->run_mode == RUN_MODE_PROCESSING) // Same symbol length
1675 {
1676 if (BS->GetB()) // "hits"
1677 {
1678 current_slice->run_segment_length = run[current_slice->run_index];
1679 if (x + current_slice->run_segment_length <= current_slice->w) //Do not go further as the end of line
1680 ++current_slice->run_index;
1681 if (--current_slice->run_segment_length >= 0)
1682 return 0;
1683 }
1684 else // "miss"
1685 {
1686 current_slice->run_mode = RUN_MODE_INTERRUPTED;
1687
1688 if (current_slice->run_index)
1689 {
1690 int8u count = log2_run[current_slice->run_index--];
1691 if (count)
1692 {
1693 current_slice->run_segment_length = ((int32s)BS->Get4(count)) - 1;
1694 if (current_slice->run_segment_length >= 0)
1695 return 0;
1696 }
1697 else
1698 current_slice->run_segment_length = -1;
1699 }
1700 else
1701 current_slice->run_segment_length = -1;
1702 }
1703 }
1704 else if (--current_slice->run_segment_length >= 0)
1705 return 0;
1706
1707 // Time for the new symbol length run
1708 current_slice->run_mode_init();
1709
1710 int32s u = get_symbol_with_bias_correlation(&Context_GR[context]);
1711 if (u >= 0) // GR(u - 1, ...)
1712 u++;
1713 return u;
1714 #endif //MEDIAINFO_TRACE_FFV1CONTENT
1715 }
1716
1717 //---------------------------------------------------------------------------
line(int pos,pixel_t * sample[2])1718 void File_Ffv1::line(int pos, pixel_t *sample[2])
1719 {
1720 // TODO: slice_coding_mode (version 4)
1721
1722 quant_table_struct& quant_table = quant_tables[quant_table_index[pos]];
1723 bool Is5 = quant_table[3][127] ? true : false;
1724 pixel_t* s0c = sample[0];
1725 pixel_t* s0e = s0c + current_slice->w;
1726 pixel_t* s1c = sample[1];
1727
1728 if (coder_type)
1729 {
1730 Context_RC = current_slice->plane_states[pos];
1731
1732 while (s0c<s0e)
1733 {
1734 int32s context = Is5 ? get_context_5(quant_table, s1c, s0c) : get_context_3(quant_table, s1c, s0c);
1735
1736 int32s Value = predict(s1c, s0c, is_overflow_16bit);
1737 #if MEDIAINFO_TRACE_FFV1CONTENT
1738 if (context >= 0)
1739 Value += pixel_RC(context);
1740 else
1741 Value -= pixel_RC(-context);
1742 #else //MEDIAINFO_TRACE_FFV1CONTENT
1743 if (context >= 0)
1744 Value += RC->get_symbol_s(Context_RC[context]);
1745 else
1746 Value -= RC->get_symbol_s(Context_RC[-context]);
1747 #endif //MEDIAINFO_TRACE_FFV1CONTENT;
1748 *s1c = Value & bits_mask1;
1749
1750 s0c++;
1751 s1c++;
1752 }
1753 }
1754 else
1755 {
1756 current_slice->run_mode_init();
1757
1758 Context_GR = current_slice->contexts[pos];
1759 x = 0;
1760
1761 while (s0c < s0e)
1762 {
1763 int32s context = Is5 ? get_context_5(quant_table, s1c, s0c) : get_context_3(quant_table, s1c, s0c);
1764
1765 *s1c = (predict(s1c, s0c, is_overflow_16bit) + (context >= 0 ? pixel_GR(context) : -pixel_GR(-context))) & bits_mask1;
1766
1767 s0c++;
1768 s1c++;
1769 x++;
1770 }
1771 }
1772 }
1773
1774 //---------------------------------------------------------------------------
QuantizationTable(size_t i)1775 bool File_Ffv1::QuantizationTable(size_t i)
1776 {
1777 Element_Begin1("QuantizationTableSet");
1778
1779 FFV1::pixel_t scale = 1;
1780
1781 for (size_t j = 0; j < 5; j++)
1782 {
1783 if (!QuantizationTablePerContext(i, j, scale))
1784 {
1785 Element_End0();
1786 return false;
1787 }
1788 }
1789 context_count[i] = (scale + 1) / 2;
1790
1791 Element_End0();
1792 return true;
1793 }
1794
1795 //---------------------------------------------------------------------------
QuantizationTablePerContext(size_t i,size_t j,FFV1::pixel_t & scale)1796 bool File_Ffv1::QuantizationTablePerContext(size_t i, size_t j, FFV1::pixel_t &scale)
1797 {
1798 Element_Begin1("QuantizationTable");
1799
1800 int8u States[states_size];
1801 memset(States, 128, sizeof(States));
1802
1803 FFV1::pixel_t v = 0;
1804 for (size_t k=0; k < 128;)
1805 {
1806 int32u len_minus1;
1807 Get_RU (States, len_minus1, "len_minus1");
1808
1809 if (k+len_minus1 >= 128)
1810 {
1811 Param_Error("FFV1-HEADER-QuantizationTable-len:1");
1812 Element_End0();
1813 return false;
1814 }
1815
1816 for (int32u a=0; a<=len_minus1; a++)
1817 {
1818 quant_tables[i][j][k] = scale * v;
1819 k++;
1820 }
1821
1822 v++;
1823 }
1824
1825 for (int k = 1; k < 128; k++)
1826 quant_tables[i][j][256 - k] = -quant_tables[i][j][k];
1827 quant_tables[i][j][128] = -quant_tables[i][j][127];
1828
1829 scale *= 2 * v - 1;
1830 if (scale > 32768U)
1831 {
1832 Element_Error("FFV1-HEADER-QuantizationTable-scale:1");
1833 Element_End0();
1834 return false;
1835 }
1836
1837 Element_End0();
1838 return true;
1839 }
1840
1841 //***************************************************************************
1842 // Helpers
1843 //***************************************************************************
1844
1845 //---------------------------------------------------------------------------
golomb_rice_decode(int k)1846 int32s File_Ffv1::golomb_rice_decode(int k)
1847 {
1848 #if MEDIAINFO_TRACE_FFV1CONTENT
1849 int32u q = 0;
1850 int32u v;
1851
1852 //while (bsf.Remain() > 0 && q < PREFIX_MAX && !bsf.GetB())
1853 while (Data_BS_Remain() > 0 && q < PREFIX_MAX)
1854 {
1855 bool Temp;
1856 Get_SB(Temp, "golomb_rice_prefix_0");
1857 if (Temp)
1858 break;
1859
1860 ++q;
1861 }
1862
1863 if (q == PREFIX_MAX) // ESC
1864 {
1865 //v = bsf.Get4(bits_max) + 11;
1866 Get_S4(bits_max, v, "escaped_value_minus_11");
1867 v+=11;
1868 }
1869 else
1870 {
1871 //int32u remain = bsf.Get8(k); // Read k bits
1872 int32u remain;
1873 Get_S4(k, remain, "golomb_rice_remain");
1874 int32u mul = q << k; // q * pow(2, k)
1875
1876 v = mul | remain;
1877 }
1878
1879 // unsigned to signed
1880 int32s code = (v >> 1) ^ -(v & 1);
1881 return code;
1882 #else //MEDIAINFO_TRACE_FFV1CONTENT
1883 int8u q = 0;
1884 while (BS->Remain() && !BS->GetB())
1885 if (++q >= PREFIX_MAX)
1886 {
1887 int32s v = 11 + BS->Get4(bits_max);
1888
1889 // unsigned to signed
1890 return (v >> 1) ^ -(v & 1);
1891 }
1892
1893 int32s v = (q << k) | BS->Get4(k);
1894
1895 // unsigned to signed
1896 return (v >> 1) ^ -(v & 1);
1897 #endif //MEDIAINFO_TRACE_FFV1CONTENT
1898 }
1899
1900 //---------------------------------------------------------------------------
get_symbol_with_bias_correlation(Slice::ContextPtr context)1901 int32s File_Ffv1::get_symbol_with_bias_correlation(Slice::ContextPtr context)
1902 {
1903 int k = 0;
1904 // Step 8: compute the Golomb parameter k
1905 for (k = 0; (context->N << k) < context->A; ++k);
1906
1907 // Step 10: Decode Golomb code (using limitation PREFIX_MAX == 12)
1908 int32s code = golomb_rice_decode(k);
1909
1910 // Step 9: Mapping
1911 int32s M = 2 * context->B + context->N;
1912 code = code ^ (M >> 31);
1913
1914 // Step 11
1915 context->B += code;
1916 context->A += code >= 0 ? code : -code;
1917
1918 code += context->C;
1919
1920 context->update_correlation_value_and_shift();
1921
1922 // Step 7 (TODO better way)
1923 bool neg = code & bits_mask2; // check if the number is negative
1924 code = code & bits_mask3; // Keep only the n bits
1925 if (neg)
1926 code = - 1 - (~code & bits_mask3); // 0xFFFFFFFF - positive value on n bits
1927
1928 return code;
1929 }
1930
1931 //---------------------------------------------------------------------------
copy_plane_states_to_slice(int8u plane_count)1932 void File_Ffv1::copy_plane_states_to_slice(int8u plane_count)
1933 {
1934 if (!coder_type)
1935 return;
1936
1937 for (size_t i = 0; i < plane_count; i++)
1938 {
1939 int32u idx = quant_table_index[i];
1940
1941 if (current_slice->plane_states[i] && current_slice->plane_states_maxsizes[i] < context_count[idx] + 1)
1942 {
1943 for (size_t j = 0; current_slice->plane_states[i][j]; ++j)
1944 delete[] current_slice->plane_states[i][j];
1945
1946 delete[] current_slice->plane_states[i];
1947 current_slice->plane_states[i] = NULL;
1948 }
1949
1950 if (!current_slice->plane_states[i])
1951 {
1952 current_slice->plane_states[i] = new int8u*[context_count[idx] + 1];
1953 current_slice->plane_states_maxsizes[i] = context_count[idx] + 1;
1954 memset(current_slice->plane_states[i], 0, (context_count[idx] + 1) * sizeof(int8u*));
1955 }
1956
1957 for (size_t j = 0; j < context_count[idx]; j++)
1958 {
1959 if (!current_slice->plane_states[i][j])
1960 current_slice->plane_states[i][j] = new int8u [states_size];
1961 for (size_t k = 0; k < states_size; k++)
1962 {
1963 current_slice->plane_states[i][j][k] = plane_states[idx][j][k];
1964 }
1965 }
1966 }
1967 }
1968
1969 //---------------------------------------------------------------------------
plane_states_clean(states_context_plane states[MAX_QUANT_TABLES])1970 void File_Ffv1::plane_states_clean(states_context_plane states[MAX_QUANT_TABLES])
1971 {
1972 if (!coder_type)
1973 return;
1974
1975 for (size_t i = 0; i < MAX_QUANT_TABLES && states[i]; ++i)
1976 {
1977 for (size_t j = 0; states[i][j]; ++j)
1978 delete[] states[i][j];
1979
1980 delete[] states[i];
1981 states[i] = NULL;
1982 }
1983 }
1984
1985 } //NameSpace
1986
1987 #endif //MEDIAINFO_FFV1_YES
1988