00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <mxcpcMxPEGRawFrameDumper.h>
00021 #include <mxcpcByteStreamReceiver.h>
00022
00023 #include <memory>
00024
00025
00026
00027 mxcpcMxPEGRawFrameDumper
00028 ::mxcpcMxPEGRawFrameDumper(mxcpcByteStreamReceiver *frame_receiver,
00029 bool convert_to_YUV) {
00030
00031 FrameReceiver = frame_receiver;
00032 ConvertToYUV = convert_to_YUV;
00033
00034 YUVBuffer = 0;
00035
00036 ExplicitDumpMode = false;
00037 }
00038
00039
00040 mxcpcMxPEGRawFrameDumper::~mxcpcMxPEGRawFrameDumper() {
00041
00042 delete FrameReceiver;
00043
00044 delete[] YUVBuffer;
00045 }
00046
00047
00048
00049 void mxcpcMxPEGRawFrameDumper::setExplicitDumpModeEnabled(bool enabled) {
00050
00051 ExplicitDumpMode = enabled;
00052 }
00053
00054
00055 void mxcpcMxPEGRawFrameDumper::dumpFrame(void) {
00056
00057 int row_size;
00058 int x, y;
00059 mxcpc::u32 *line_start_ptr;
00060 mxcpc::u8 *ptr;
00061 int yuv_bytenum, yuv_uv_bytenum;
00062 int yuv_Cr_offset, yuv_Cb_offset;
00063 mxcpc::u8 col_y, col_Cb, col_Cr;
00064 int i;
00065 mxcpc::u8 *yuv_Cr_ptr, *yuv_Cb_ptr;
00066
00067 if(!PixelBuffer) return;
00068 if(ConvertToYUV && !YUVBuffer) return;
00069
00070 row_size = TileNumX*16*3/4;
00071
00072 line_start_ptr = PixelBuffer
00073 + PixelBufferOffset
00074 + (Height - 1) * row_size;
00075
00076 if(!ConvertToYUV) {
00077
00078 for(y = 0; y < Height; y++) {
00079
00080 ptr = (mxcpc::u8 *)line_start_ptr;
00081
00082 FrameReceiver->receiveStreamBytes(ptr, Width * 3);
00083
00084 line_start_ptr -= row_size;
00085 }
00086 }
00087
00088 else {
00089
00090 yuv_bytenum = Width*Height + 2 * Width*Height/4;
00091 yuv_uv_bytenum = 2 * Width*Height/4;
00092 yuv_Cr_offset = Width*Height;
00093 yuv_Cb_offset = yuv_Cr_offset + Width*Height/4;
00094 yuv_Cr_ptr = YUVBuffer + yuv_Cr_offset;
00095 yuv_Cb_ptr = YUVBuffer + yuv_Cb_offset;
00096
00097 for(i = 0; i < yuv_uv_bytenum; i++) YUVBuffer[yuv_Cr_offset + i] = 0;
00098
00099 for(y = 0; y < Height; y++) {
00100
00101 ptr = (mxcpc::u8 *)line_start_ptr;
00102 for(x = 0; x < Width; x++) {
00103
00104 mxcpc::convert_RGB_to_YCbCr(ptr[0], ptr[1], ptr[2],
00105 &col_y, &col_Cb, &col_Cr);
00106 ptr += 3;
00107
00108 YUVBuffer[y*Width + x] = col_y;
00109 *yuv_Cb_ptr += (col_Cb>>2);
00110 *yuv_Cr_ptr += (col_Cr>>2);
00111
00112 if(x & 1) {
00113 yuv_Cb_ptr++;
00114 yuv_Cr_ptr++;
00115 }
00116 }
00117
00118 line_start_ptr -= row_size;
00119 if(!(y & 1)) {
00120 yuv_Cb_ptr -= Width>>1;
00121 yuv_Cr_ptr -= Width>>1;
00122 }
00123 }
00124
00125 FrameReceiver->receiveStreamBytes(YUVBuffer, yuv_bytenum);
00126 }
00127 }
00128
00129
00130 void mxcpcMxPEGRawFrameDumper::videoResolutionChanged(int width, int height) {
00131
00132 char txt[100];
00133
00134 mxcpcBufferedMxPEGDecoderBackEnd::videoResolutionChanged(width, height);
00135
00136 delete[] YUVBuffer;
00137 YUVBuffer = 0;
00138
00139 if(PixelBuffer) {
00140
00141 if(width%2 || height%2) {
00142 mxcpc::sendStatusMsg("MxPEGRawFrameDumper : cannot allocate YUV buffer "
00143 "for odd image dimensions!!!");
00144 errorEncountered();
00145 }
00146
00147 try {
00148
00149 YUVBuffer = new mxcpc::u8[width*height + 2 * width*height/4];
00150
00151 std::sprintf(txt, "MxPEGRawFrameDumper : resized YUV buffer to %dx%d",
00152 width, height);
00153 mxcpc::sendStatusMsg(txt);
00154
00155 } catch(std::bad_alloc) {
00156
00157 std::sprintf(txt, "MxPEGRawFrameDumper : failed to resize YUV buffer "
00158 "to %dx%d !!!",
00159 width, height);
00160 mxcpc::sendStatusMsg(txt);
00161
00162 errorEncountered();
00163
00164
00165 }
00166 }
00167 }
00168
00169
00170 void mxcpcMxPEGRawFrameDumper::errorEncountered(void) {
00171
00172 }
00173
00174
00175 void mxcpcMxPEGRawFrameDumper::frameComplete(void) {
00176
00177 if(!ExplicitDumpMode) dumpFrame();
00178 }
00179
00180
00181 void mxcpcMxPEGRawFrameDumper::videoTileReceived(void) {
00182
00183 }
00184