OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2012 Intel Corporation. All Rights Reserved. |
| 3 * |
| 4 * Permission is hereby granted, free of charge, to any person obtaining a |
| 5 * copy of this software and associated documentation files (the |
| 6 * "Software"), to deal in the Software without restriction, including |
| 7 * without limitation the rights to use, copy, modify, merge, publish, |
| 8 * distribute, sub license, and/or sell copies of the Software, and to |
| 9 * permit persons to whom the Software is furnished to do so, subject to |
| 10 * the following conditions: |
| 11 * |
| 12 * The above copyright notice and this permission notice (including the |
| 13 * next paragraph) shall be included in all copies or substantial portions |
| 14 * of the Software. |
| 15 * |
| 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
| 18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| 19 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
| 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
| 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
| 22 * USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 23 */ |
| 24 |
| 25 /* |
| 26 * Example based on Simple AVC encoder. |
| 27 * http://cgit.freedesktop.org/libva/tree/test/encode/avcenc.c |
| 28 * |
| 29 */ |
| 30 |
| 31 #include <cstdio> |
| 32 #include <cstring> |
| 33 #include <cstdarg> |
| 34 #include <cassert> |
| 35 #include <va/va_x11.h> |
| 36 #include <X11/Xlib.h> |
| 37 #include <X11/Xutil.h> |
| 38 |
| 39 #include <iostream> |
| 40 #include <cstdlib> |
| 41 |
| 42 #include "TCPSocketClient.h" |
| 43 |
| 44 #define MY_Y 0x22 |
| 45 #define MY_U 0xff |
| 46 #define MY_V 0x55 |
| 47 |
| 48 |
| 49 extern TCPSocketClient *sock_ptr; |
| 50 extern int g_Debug; |
| 51 extern char *device_settings; |
| 52 Window win2; |
| 53 int win2_width = 640; |
| 54 int win2_height = 480; |
| 55 int g_PX = -1; |
| 56 int g_PY = -1; |
| 57 |
| 58 |
| 59 bool g_LiveView = true; |
| 60 bool g_Force_P_Only = false; |
| 61 bool g_ShowNumber = true; |
| 62 |
| 63 |
| 64 |
| 65 |
| 66 #define SLICE_TYPE_P 0 |
| 67 #define SLICE_TYPE_B 1 |
| 68 #define SLICE_TYPE_I 2 |
| 69 |
| 70 #define ENTROPY_MODE_CAVLC 0 |
| 71 #define ENTROPY_MODE_CABAC 1 |
| 72 |
| 73 #define PROFILE_IDC_BASELINE 66 |
| 74 #define PROFILE_IDC_MAIN 77 |
| 75 #define PROFILE_IDC_HIGH 100 |
| 76 |
| 77 #define CHECK_VASTATUS(va_status,func) \ |
| 78 if (va_status != VA_STATUS_SUCCESS) { \ |
| 79 std::cerr << __func__ << ':' << func << '(' << __LINE__ << ") failed, ex
it\n"; \ |
| 80 exit(1); \ |
| 81 } |
| 82 |
| 83 static Display *x11_display; |
| 84 static VADisplay va_dpy; |
| 85 static VAContextID context_id; |
| 86 static VAConfigID config_id; |
| 87 |
| 88 static int picture_width, picture_width_in_mbs; |
| 89 static int picture_height, picture_height_in_mbs; |
| 90 static int frame_size; |
| 91 static int codedbuf_size; |
| 92 |
| 93 static int qp_value = 26; |
| 94 |
| 95 static int log2_max_frame_num_minus4 = 0; |
| 96 static int pic_order_cnt_type = 0; |
| 97 static int log2_max_pic_order_cnt_lsb_minus4 = 0; |
| 98 static int entropy_coding_mode_flag = ENTROPY_MODE_CABAC; |
| 99 static int deblocking_filter_control_present_flag = 1; |
| 100 static int frame_mbs_only_flag = 1; |
| 101 |
| 102 static void create_encode_pipe() |
| 103 { |
| 104 VAEntrypoint entrypoints[5]; |
| 105 int num_entrypoints,slice_entrypoint; |
| 106 VAConfigAttrib attrib[2]; |
| 107 int major_ver, minor_ver; |
| 108 VAStatus va_status; |
| 109 |
| 110 x11_display = XOpenDisplay(":0.0"); |
| 111 assert(x11_display); |
| 112 |
| 113 va_dpy = vaGetDisplay(x11_display); |
| 114 va_status = vaInitialize(va_dpy, &major_ver, &minor_ver); |
| 115 CHECK_VASTATUS(va_status, "vaInitialize"); |
| 116 vaQueryConfigEntrypoints(va_dpy, VAProfileH264Baseline, entrypoints, &num_en
trypoints); |
| 117 |
| 118 for (slice_entrypoint = 0; slice_entrypoint < num_entrypoints; slice_entrypo
int++) { |
| 119 if (entrypoints[slice_entrypoint] == VAEntrypointEncSlice) |
| 120 break; |
| 121 } |
| 122 |
| 123 if (slice_entrypoint == num_entrypoints) { |
| 124 /* not find Slice entry point */ |
| 125 assert(0); |
| 126 } |
| 127 |
| 128 /* find out the format for the render target, and rate control mode */ |
| 129 attrib[0].type = VAConfigAttribRTFormat; |
| 130 attrib[1].type = VAConfigAttribRateControl; |
| 131 vaGetConfigAttributes(va_dpy, VAProfileH264Baseline, VAEntrypointEncSlice, &
attrib[0], 2); |
| 132 |
| 133 if ((attrib[0].value & VA_RT_FORMAT_YUV420) == 0) { |
| 134 /* not find desired YUV420 RT format */ |
| 135 assert(0); |
| 136 } |
| 137 |
| 138 if ((attrib[1].value & VA_RC_VBR) == 0) { |
| 139 /* Can't find matched RC mode */ |
| 140 std::cerr << "VBR mode not found, exit\n"; |
| 141 assert(0); |
| 142 } |
| 143 |
| 144 attrib[0].value = VA_RT_FORMAT_YUV420; /* set to desired RT format */ |
| 145 attrib[1].value = VA_RC_VBR; /* set to desired RC mode */ |
| 146 |
| 147 va_status = vaCreateConfig(va_dpy, VAProfileH264Baseline, VAEntrypointEncSli
ce, &attrib[0], 2,&config_id); |
| 148 CHECK_VASTATUS(va_status, "vaCreateConfig"); |
| 149 |
| 150 /* Create a context for this decode pipe */ |
| 151 va_status = vaCreateContext(va_dpy, config_id, picture_width, picture_height
, VA_PROGRESSIVE, 0, 0, &context_id); |
| 152 CHECK_VASTATUS(va_status, "vaCreateContext"); |
| 153 } |
| 154 |
| 155 static void destory_encode_pipe() |
| 156 { |
| 157 vaDestroyContext(va_dpy,context_id); |
| 158 vaDestroyConfig(va_dpy,config_id); |
| 159 vaTerminate(va_dpy); |
| 160 XCloseDisplay(x11_display); |
| 161 } |
| 162 |
| 163 /*************************************************** |
| 164 * |
| 165 * The encode pipe resource define |
| 166 * |
| 167 ***************************************************/ |
| 168 static VABufferID seq_parameter = VA_INVALID_ID; /*Sequence level
parameter*/ |
| 169 static VABufferID pic_parameter = VA_INVALID_ID; /*Picture level
parameter*/ |
| 170 static VABufferID slice_parameter = VA_INVALID_ID; /*Slice level pa
rameter, multil slices*/ |
| 171 static VABufferID coded_buf = VA_INVALID_ID; /*Output buffer,
compressed data*/ |
| 172 |
| 173 #define SID_NUMBER 3 |
| 174 #define SID_INPUT_PICTURE 0 |
| 175 #define SID_REFERENCE_PICTURE 1 |
| 176 #define SID_RECON_PICTURE 2 |
| 177 static VASurfaceID surface_ids[SID_NUMBER]; |
| 178 |
| 179 /***************************************************/ |
| 180 |
| 181 static void alloc_encode_resource() |
| 182 { |
| 183 VAStatus va_status; |
| 184 seq_parameter = VA_INVALID_ID; |
| 185 pic_parameter = VA_INVALID_ID; |
| 186 slice_parameter = VA_INVALID_ID; |
| 187 |
| 188 //1. Create sequence parameter set |
| 189 { |
| 190 VAEncSequenceParameterBufferH264 seq_h264 = {0}; |
| 191 seq_h264.level_idc = 30; |
| 192 seq_h264.picture_width_in_mbs = picture_width_in_mbs; |
| 193 seq_h264.picture_height_in_mbs = picture_height_in_mbs; |
| 194 seq_h264.bits_per_second = 384*1000; |
| 195 seq_h264.initial_qp = qp_value; |
| 196 seq_h264.min_qp = 3; |
| 197 va_status = vaCreateBuffer(va_dpy, context_id, VAEncSequenceParameterBuf
ferType, |
| 198 sizeof(seq_h264),1,&seq_h264,&seq_parameter); |
| 199 CHECK_VASTATUS(va_status,"vaCreateBuffer");; |
| 200 } |
| 201 //2. Create surface |
| 202 va_status = vaCreateSurfaces(va_dpy, picture_width, picture_height, VA_RT_FO
RMAT_YUV420, SID_NUMBER, &surface_ids[0]); |
| 203 CHECK_VASTATUS(va_status, "vaCreateSurfaces"); |
| 204 //3. Create coded buffer |
| 205 { |
| 206 va_status = vaCreateBuffer(va_dpy,context_id,VAEncCodedBufferType, coded
buf_size, 1, NULL, &coded_buf); |
| 207 CHECK_VASTATUS(va_status,"vaBeginPicture"); |
| 208 } |
| 209 } |
| 210 |
| 211 static void release_encode_resource() |
| 212 { |
| 213 //-3 Relese coded buffer |
| 214 if (coded_buf != VA_INVALID_ID) |
| 215 vaDestroyBuffer(va_dpy, coded_buf); |
| 216 //-2 Release all the surfaces resource |
| 217 vaDestroySurfaces(va_dpy, &surface_ids[0], SID_NUMBER); |
| 218 //-1 Destory the sequence level parameter |
| 219 if (seq_parameter != VA_INVALID_ID) |
| 220 vaDestroyBuffer(va_dpy, seq_parameter); |
| 221 } |
| 222 |
| 223 |
| 224 static int get_coded_bitsteam_length(unsigned char *buffer, int buffer_length) |
| 225 { |
| 226 int i; |
| 227 for (i = buffer_length - 1; i >= 0; i--) { |
| 228 if (buffer[i]) |
| 229 break; |
| 230 } |
| 231 return i + 1; |
| 232 } |
| 233 |
| 234 |
| 235 |
| 236 void SetWindowTitle(const char* title, ...) |
| 237 { |
| 238 va_list args; |
| 239 va_start(args, title); |
| 240 char buf[256]; |
| 241 vsprintf(buf, title, args); |
| 242 va_end(args); |
| 243 XSetStandardProperties(x11_display,win2, buf, buf, None, NULL, 0, NULL); |
| 244 } |
| 245 |
| 246 |
| 247 |
| 248 int encoder_init(int width, int height) |
| 249 { |
| 250 picture_width = width; |
| 251 picture_height = height; |
| 252 picture_width_in_mbs = (picture_width + 15) / 16; |
| 253 picture_height_in_mbs = (picture_height + 15) / 16; |
| 254 qp_value = 26; |
| 255 frame_size = picture_width * picture_height + ((picture_width * picture_hei
ght) >> 1) ; |
| 256 codedbuf_size = picture_width * picture_height * 1.5; |
| 257 create_encode_pipe(); |
| 258 alloc_encode_resource(); |
| 259 sock_ptr->send(picture_width); |
| 260 sock_ptr->send(picture_height); |
| 261 sock_ptr->send(picture_width_in_mbs-1); |
| 262 sock_ptr->send(picture_height_in_mbs-1); |
| 263 if (g_LiveView) { |
| 264 win2 = XCreateSimpleWindow(x11_display, RootWindow(x11_display, 0), 0, 0
, win2_width, win2_height, 0, 0, WhitePixel(x11_display, 0)); |
| 265 XMapWindow(x11_display, win2); |
| 266 if ((g_PX !=-1) && (g_PY !=-1)) { |
| 267 XMoveWindow(x11_display, win2, g_PX, g_PY); |
| 268 } |
| 269 SetWindowTitle("Input: %dx%d [TCP] %s",picture_width,picture_height, dev
ice_settings); |
| 270 XSync(x11_display, False); |
| 271 } |
| 272 return 0; |
| 273 } |
| 274 |
| 275 void encoder_close() |
| 276 { |
| 277 release_encode_resource(); |
| 278 destory_encode_pipe(); |
| 279 } |
| 280 |
| 281 |
| 282 /* 8x8 font 0-9 only - asm type format */ |
| 283 unsigned char mydigits[80] { |
| 284 // 0 |
| 285 0x0E,0x11,0x13,0x15,0x19,0x11,0x0E,0x00, |
| 286 // 1 |
| 287 0x04,0x0C,0x04,0x04,0x04,0x04,0x0E,0x00, |
| 288 // 2 |
| 289 0x0E,0x11,0x01,0x02,0x04,0x08,0x1F,0x00, |
| 290 // 3 |
| 291 0x1F,0x02,0x04,0x02,0x01,0x11,0x0E,0x00, |
| 292 // 4 |
| 293 0x02,0x06,0x0A,0x12,0x1F,0x02,0x02,0x00, |
| 294 // 5 |
| 295 0x1F,0x10,0x1E,0x01,0x01,0x11,0x0E,0x00, |
| 296 // 6 |
| 297 0x06,0x08,0x10,0x1E,0x11,0x11,0x0E,0x00, |
| 298 // 7 |
| 299 0x1F,0x01,0x02,0x04,0x04,0x04,0x04,0x00, |
| 300 // 8 |
| 301 0x1E,0x11,0x11,0x0E,0x11,0x11,0x0E,0x00, |
| 302 //9 |
| 303 0x0E,0x11,0x11,0x0F,0x01,0x02,0x0C,0x00 |
| 304 }; |
| 305 |
| 306 #define INTERSIZE 16 |
| 307 |
| 308 static void ShowNumber(int num, unsigned char *buffer, VAImage *image) |
| 309 { |
| 310 int j; |
| 311 char buf[20]; |
| 312 unsigned char *dst_y; |
| 313 unsigned char *dst_uv_line; |
| 314 unsigned char *digits_ptr; |
| 315 assert(image); |
| 316 int maxlen = sprintf(buf, "%d", num); |
| 317 assert(maxlen<20); |
| 318 for (int a=0; a<maxlen;a++) { |
| 319 digits_ptr = &mydigits[(buf[a]-'0')*8]; |
| 320 for (int i=0; i<8; i++) { |
| 321 unsigned char current = digits_ptr[i]; |
| 322 dst_y = (buffer+ image->offsets[0]) + ((i*2)*image->pitches[0])+(a*I
NTERSIZE); |
| 323 dst_uv_line = (buffer + image->offsets[1]) + (i*image->pitches[1])+(
a*INTERSIZE); |
| 324 for (j=7; j>=0;j--) { |
| 325 if ((current >>j) & 1) { |
| 326 *dst_y ++ = MY_Y; |
| 327 *dst_y ++ = MY_Y; |
| 328 *dst_uv_line++ = MY_U; |
| 329 *dst_uv_line++ = MY_V; |
| 330 } else { |
| 331 dst_y += 2; |
| 332 dst_uv_line +=2; |
| 333 } |
| 334 } |
| 335 dst_y = (buffer+ image->offsets[0]) + (((i*2)+1)*image->pitches[0])+
(a*INTERSIZE); |
| 336 for (j=7; j>=0;j--) { |
| 337 if ((current >>j) & 1) { |
| 338 *dst_y ++ = MY_Y; |
| 339 *dst_y ++ = MY_Y; |
| 340 } else { |
| 341 dst_y += 2; |
| 342 } |
| 343 } |
| 344 } |
| 345 } |
| 346 } |
| 347 |
| 348 |
| 349 |
| 350 static void upload_yuv_to_surface(unsigned char *inbuf, VASurfaceID surface_id,
unsigned int frame) |
| 351 { |
| 352 VAImage image; |
| 353 VAStatus va_status; |
| 354 void *pbuffer=NULL; |
| 355 unsigned char *psrc = inbuf; |
| 356 unsigned char *pdst = NULL; |
| 357 unsigned char *dst_y, *dst_uv; |
| 358 unsigned char *src_u, *src_v; |
| 359 unsigned char *dst_uv_line = NULL; |
| 360 int i,j; |
| 361 va_status = vaDeriveImage(va_dpy, surface_id, &image); |
| 362 va_status = vaMapBuffer(va_dpy, image.buf, &pbuffer); |
| 363 pdst = (unsigned char *)pbuffer; |
| 364 dst_uv_line = pdst + image.offsets[1]; |
| 365 dst_uv = dst_uv_line; |
| 366 for (i=0; i<picture_height; i+=2) { |
| 367 dst_y = (pdst + image.offsets[0]) + i*image.pitches[0]; |
| 368 for (j=0; j<(picture_width/2); ++j) { |
| 369 *(dst_y++) = psrc[0];//y1; |
| 370 *(dst_uv++) = psrc[1];//u; |
| 371 *(dst_y++) = psrc[2];//y1; |
| 372 *(dst_uv++) = psrc[3];//v; |
| 373 psrc+=4; |
| 374 } |
| 375 dst_y = (pdst + image.offsets[0]) + (i+1)*image.pitches[0]; |
| 376 for (j=0; j<picture_width/2; ++j) { |
| 377 *(dst_y++) = psrc[0];//y1; |
| 378 *(dst_y++) = psrc[2];//y2; |
| 379 psrc+=4; |
| 380 } |
| 381 dst_uv_line += image.pitches[1]; |
| 382 dst_uv = dst_uv_line; |
| 383 } |
| 384 if (g_ShowNumber) { |
| 385 ShowNumber(frame, (unsigned char *)pbuffer, &image); |
| 386 } |
| 387 va_status = vaUnmapBuffer(va_dpy, image.buf); |
| 388 CHECK_VASTATUS(va_status,"vaUnmapBuffer"); |
| 389 va_status = vaDestroyImage(va_dpy, image.image_id); |
| 390 CHECK_VASTATUS(va_status,"vaDestroyImage"); |
| 391 if (g_LiveView) { |
| 392 va_status = vaPutSurface(va_dpy, surface_id, win2, 0, 0, picture_width,p
icture_height, 0, 0, win2_width, win2_height, NULL, 0, VA_FRAME_PICTURE); |
| 393 CHECK_VASTATUS(va_status,"vaPutSurface"); |
| 394 } |
| 395 } |
| 396 |
| 397 |
| 398 static void prepare_input(unsigned char *buffer, int intra_slice, unsigned int f
rame) |
| 399 { |
| 400 static VAEncPictureParameterBufferH264 pic_h264; |
| 401 static VAEncSliceParameterBuffer slice_h264; |
| 402 VAStatus va_status; |
| 403 VABufferID tempID; |
| 404 VACodedBufferSegment *coded_buffer_segment = NULL; |
| 405 unsigned char *coded_mem; |
| 406 // Sequence level |
| 407 va_status = vaRenderPicture(va_dpy, context_id, &seq_parameter, 1); |
| 408 CHECK_VASTATUS(va_status,"vaRenderPicture");; |
| 409 // Copy Image to target surface according input YUV data. |
| 410 upload_yuv_to_surface(buffer, surface_ids[SID_INPUT_PICTURE], frame); |
| 411 // Picture level |
| 412 pic_h264.reference_picture = surface_ids[SID_REFERENCE_PICTURE]; |
| 413 pic_h264.reconstructed_picture = surface_ids[SID_RECON_PICTURE]; |
| 414 pic_h264.coded_buf = coded_buf; |
| 415 pic_h264.picture_width = picture_width; |
| 416 pic_h264.picture_height = picture_height; |
| 417 pic_h264.last_picture = 0; |
| 418 if (pic_parameter != VA_INVALID_ID) { |
| 419 vaDestroyBuffer(va_dpy, pic_parameter); |
| 420 } |
| 421 va_status = vaCreateBuffer(va_dpy, context_id,VAEncPictureParameterBufferTyp
e, |
| 422 sizeof(pic_h264),1,&pic_h264,&pic_parameter); |
| 423 CHECK_VASTATUS(va_status,"vaCreateBuffer"); |
| 424 va_status = vaRenderPicture(va_dpy,context_id, &pic_parameter, 1); |
| 425 CHECK_VASTATUS(va_status,"vaRenderPicture"); |
| 426 // clean old memory |
| 427 va_status = vaMapBuffer(va_dpy,coded_buf,(void **)(&coded_buffer_segment)); |
| 428 CHECK_VASTATUS(va_status,"vaMapBuffer"); |
| 429 coded_mem = (unsigned char*)coded_buffer_segment->buf; |
| 430 memset(coded_mem, 0, coded_buffer_segment->size); |
| 431 vaUnmapBuffer(va_dpy, coded_buf); |
| 432 // Slice level |
| 433 slice_h264.start_row_number = 0; |
| 434 slice_h264.slice_height = picture_height/16; /* Measured by MB */ |
| 435 slice_h264.slice_flags.bits.is_intra = intra_slice; |
| 436 slice_h264.slice_flags.bits.disable_deblocking_filter_idc = 0; |
| 437 if ( slice_parameter != VA_INVALID_ID) { |
| 438 vaDestroyBuffer(va_dpy, slice_parameter); |
| 439 } |
| 440 va_status = vaCreateBuffer(va_dpy,context_id,VAEncSliceParameterBufferType, |
| 441 sizeof(slice_h264),1,&slice_h264,&slice_parameter); |
| 442 CHECK_VASTATUS(va_status,"vaCreateBuffer");; |
| 443 va_status = vaRenderPicture(va_dpy,context_id, &slice_parameter, 1); |
| 444 CHECK_VASTATUS(va_status,"vaRenderPicture"); |
| 445 |
| 446 // Prepare for next picture |
| 447 tempID = surface_ids[SID_RECON_PICTURE]; |
| 448 surface_ids[SID_RECON_PICTURE] = surface_ids[SID_REFERENCE_PICTURE]; |
| 449 surface_ids[SID_REFERENCE_PICTURE] = tempID; |
| 450 } |
| 451 |
| 452 static void send_slice_data(unsigned int frcount, int slice_type) |
| 453 { |
| 454 VACodedBufferSegment *coded_buffer_segment; |
| 455 unsigned char *coded_mem; |
| 456 int i, slice_data_length; |
| 457 int mm; |
| 458 VAStatus va_status; |
| 459 VASurfaceStatus surface_status; |
| 460 int is_cabac = (entropy_coding_mode_flag == ENTROPY_MODE_CABAC); |
| 461 va_status = vaSyncSurface(va_dpy, surface_ids[SID_INPUT_PICTURE]); |
| 462 CHECK_VASTATUS(va_status,"vaSyncSurface"); |
| 463 surface_status = (VASurfaceStatus)0; |
| 464 va_status = vaQuerySurfaceStatus(va_dpy, surface_ids[SID_INPUT_PICTURE], &su
rface_status); |
| 465 CHECK_VASTATUS(va_status,"vaQuerySurfaceStatus"); |
| 466 va_status = vaMapBuffer(va_dpy, coded_buf, (void **)(&coded_buffer_segment))
; |
| 467 CHECK_VASTATUS(va_status,"vaMapBuffer"); |
| 468 coded_mem = (unsigned char*)coded_buffer_segment->buf; |
| 469 sock_ptr->send(frcount); |
| 470 sock_ptr->send(slice_type); |
| 471 |
| 472 if (is_cabac) { |
| 473 if (!coded_buffer_segment->next) { |
| 474 slice_data_length = get_coded_bitsteam_length(coded_mem, codedbuf_si
ze); |
| 475 } else { |
| 476 /* Fixme me - to do: loop to each block and calculate the real data_
lenght */ |
| 477 assert(0); |
| 478 } |
| 479 if (g_Debug) { |
| 480 printf("T=%d BS=%8d SZ=%8d C=%d\n", slice_type, codedbuf_size, slice
_data_length, frcount); |
| 481 }sock_ptr->send(slice_data_length); |
| 482 sock_ptr->send((unsigned char*)coded_mem, slice_data_length); |
| 483 } else { |
| 484 /* FIXME */ |
| 485 assert(0); |
| 486 } |
| 487 vaUnmapBuffer(va_dpy, coded_buf); |
| 488 } |
| 489 |
| 490 |
| 491 int encode_frame(unsigned char *inbuf) |
| 492 { |
| 493 static unsigned int framecount = 0; |
| 494 int is_intra = (framecount % 30 == 0); |
| 495 if (g_Force_P_Only) { |
| 496 is_intra = 1; |
| 497 } |
| 498 VAStatus va_status; |
| 499 va_status = vaBeginPicture(va_dpy, context_id, surface_ids[SID_INPUT_PICTURE
]); |
| 500 CHECK_VASTATUS(va_status,"vaBeginPicture"); |
| 501 prepare_input(inbuf, is_intra, framecount); |
| 502 va_status = vaEndPicture(va_dpy,context_id); |
| 503 CHECK_VASTATUS(va_status,"vaRenderPicture"); |
| 504 send_slice_data(framecount, is_intra ? SLICE_TYPE_I : SLICE_TYPE_P); |
| 505 framecount++; |
| 506 return 1; |
| 507 } |
| 508 |
OLD | NEW |