Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members
CompressedVideoFrame.cpp
00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: CompressedVideoFrame.cpp * 00006 * * 00007 * * 00008 * * 00009 * ITEC institute of the University of Klagenfurt (Austria) * 00010 * http://www.itec.uni-klu.ac.at * 00011 * * 00012 * * 00013 * For more information visit the ViTooKi homepage: * 00014 * http://ViTooKi.sourceforge.net * 00015 * vitooki-user@lists.sourceforge.net * 00016 * vitooki-devel@lists.sourceforge.net * 00017 * * 00018 * This file is part of ViTooKi, a free video toolkit. * 00019 * ViTooKi is free software; you can redistribute it and/or * 00020 * modify it under the terms of the GNU General Public License * 00021 * as published by the Free Software Foundation; either version 2 * 00022 * of the License, or (at your option) any later version. * 00023 * * 00024 * This program is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU General Public License * 00030 * along with this program; if not, write to the Free Software * 00031 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * 00032 * MA 02111-1307, USA. * 00033 * * 00034 ***********************************************************************/ 00035 00036 /*********************************************************************** 00037 * * 00038 * REVISION HISTORY: * 00039 * * 00040 * * 00041 * * 00042 ***********************************************************************/ 00043 00044 #include "CompressedVideoFrame.hpp" 00045 #include <math.h> 00051 CompressedVideoFrame::CompressedVideoFrame(FrameType t, int w, int h) : VideoFrame(t,w,h) { 00052 } 00053 00054 00055 CompressedVideoFrame::~CompressedVideoFrame() { 00056 } 00057 00058 00059 Frame::FrameType CompressedVideoFrame::detectFrameType() { 00060 if (!(accessUnit && accessUnit->payload && accessUnit->size>3)) { 00061 return ERROR_VOP; 00062 } 00063 00064 00065 00066 bool typeSet = false; 00067 bool found = false; 00068 uint i = 0; 00069 00070 if(!found) { 00071 // is it THEORA??? 00072 if(memcmp(&accessUnit->payload[1],"theora",6) == 0) { 00073 //dprintf_full("CompressedVideoFrame::detectFrameType THEORA!\n"); 00074 // YES IT IS! 00075 typeSet = true; 00076 found = true; 00077 // now check, if it is a keyframe! 00078 /* 00079 * 07.03.06: [www.xiph.org/theora/doc/Theora_I_spec.pdf], page 18: 00080 * "Theora only supports intra frames (I frames in MPEG) and 00081 * inter frames (P frames in MPEG). There is no equivalent 00082 * to the bi-predictive frames (B frames) found in MPEG 00083 * codecs." 00084 * 00085 * For ViTooKi we classify inter frames as B frames in order 00086 * to profit from frame dropping strategies used in ViTooKi. 00087 */ 00088 00089 /* 00090 * from libtheora-1.0alpha5/lib/toplevel.c 00091 * 00092 * if (op->packet[0] & 0x80) return -1; // not a data packet 00093 * return (op->packet[0] & 0x40) ? 0 : 1; // inter or intra 00094 */ 00095 if(accessUnit->payload[0] & 0x80) // it is not a valid THEORA data packet, maybe HEADER frame... don't care... 00096 setType(NN_VOP); 00097 else if(accessUnit->payload[0] & 0x40) 00098 setType(B_VOP); 00099 else 00100 setType(I_VOP); 00101 00102 // all done... so return! 00103 return getType(); 00104 } 00105 } 00106 00107 00108 while((i+3) < accessUnit->size && !found) { 00109 00110 if(accessUnit->payload[i] == 0x00) 00111 if(accessUnit->payload[i+1] == 0x00) 00112 if(accessUnit->payload[i+2] == 0x01) 00113 if( (accessUnit->payload[i+3] >= 0xb0) || (accessUnit->payload[i+3] == 0x00)) { //MPEG4 or 2/1 00114 found = true; 00115 i--; 00116 } 00117 i++; 00118 } 00119 00120 //MPEG-4 video frame startcode 00121 00122 if (found && accessUnit->size > i+3) { 00123 //dprintf_full("CompressedVideoFrame::detectFrameType MPEG4!\n"); 00124 00125 // start code for MPEG-4 frame header 00126 if(accessUnit->payload[i+3] == 0xb6) { 00127 // detect MPEG-4 frame type 00128 if ( (accessUnit->size > i+4) && 00129 ( ((accessUnit->payload[i+4]) >> 6) < 4) ) { 00130 //set MPEG-4 frame type 00131 setType( (FrameType) ((accessUnit->payload[i+4]) >> 6) ); 00132 typeSet = true; 00133 } 00134 // frame type not found 00135 else { 00136 dprintf_full("CompressedVideoFrame::detectFrameType --> INVALID VOP Header %i at AU found --> MPEG-4\n", 00137 (accessUnit->payload[i+4]) >> 6); 00138 setType( ERROR_VOP ); 00139 } 00140 } else 00141 if(accessUnit->payload[i+3] >= 0xb0) { 00142 setType( HEADER_VOP ); 00143 typeSet = true; 00144 } 00145 } 00146 00147 00148 if(!typeSet && (accessUnit->size>(i+5))) { 00149 // MPEG-1/2 video frame startcode 00150 //dprintf_full("CompressedVideoFrame::detectFrameType MPEG1/2!\n"); 00151 00152 if (accessUnit->payload[i+3] == 0x00) { 00153 int type = accessUnit->payload[i+5] & 0x38; 00154 if (type == 0x08) { 00155 setType( I_VOP); 00156 typeSet = true; 00157 } 00158 if (type == 0x10){ 00159 setType( P_VOP); 00160 typeSet = true; 00161 } 00162 if (type == 0x18){ 00163 setType( B_VOP); 00164 typeSet = true; 00165 } 00166 } 00167 else { 00168 dprintf_full("CompressedVideoFrame::detectFrameType --> INVALID VOP Header at AU found --> MPEG-1/2\n"); 00169 00170 setType( ERROR_VOP ); 00171 } 00172 /* 00173 printf("Sequence: %0x %0x %0x %0x %0x %0x\n", 00174 accessUnit->payload[i], 00175 accessUnit->payload[i+1], 00176 accessUnit->payload[i+2], 00177 accessUnit->payload[i+3], 00178 accessUnit->payload[i+4], 00179 accessUnit->payload[i+5]); 00180 */ 00181 } 00182 00183 /* int ftype = getType(); 00184 if(ftype == 0) { 00185 cout << " I "; 00186 } 00187 if(ftype == 1) { 00188 cout << " P "; 00189 } 00190 if(ftype == 2) { 00191 cout << " B "; 00192 } 00193 cout << "-"; 00194 */ 00195 return getType(); 00196 }; 00197