C_RESULT video_decode_picture( video_controller_t* controller, vp_api_picture_t* picture, video_stream_t* ex_stream, bool_t* got_image ) { vp_api_picture_t blockline = { 0 }; controller->mode = VIDEO_DECODE; // mandatory because of video_cache_stream blockline = *picture; blockline.height = MB_HEIGHT_Y; blockline.complete = 1; blockline.vision_complete = 0; while( SUCCEED(video_cache_stream( controller, ex_stream )) ) { video_decode_blockline( controller, &blockline, got_image ); } return C_OK; }
int p264_process_blockline(p264_state_t* s, char* buf, size_t buf_size) { bool_t got_image; if(s == NULL) return 0; //printf("Got buffer at 0x%p size %lu. First byte: %i\n", buf, buf_size, (int)(buf[0])); got_image = FALSE; #if 1 //printf("Stream buffer: 0x%p\n", video_controller_get_stream_ptr(s->controller)); //memcpy(video_controller_get_stream_ptr(s->controller), buf, buf_size); s->controller->in_stream.bytes = (uint32_t*)(buf); s->controller->in_stream.used = buf_size; s->controller->in_stream.size = buf_size; s->controller->in_stream.index = 0; s->controller->in_stream.length = 32; s->controller->in_stream.code = 0; //memset(s->picture->y_buf, 0, WIDTH*HEIGHT*2); //memcpy(s->picture->y_buf, buf, buf_size); //got_image = TRUE; video_decode_blockline(s->controller, s->picture, &got_image); #else stream.index = 0; stream.used = buf_size; memcpy(&stream.bytes[0], (uint32_t*)buf, buf_size); video_decode_picture(s->controller, s->picture, &stream, &got_image ); #endif //printf("Picture width %u\n", s->picture->width); //printf("Got image: %i\n", got_image); //printf("Nframes: %i\n", s->controller->num_frames); //memset((char*)(s->picture->y_buf) + (WIDTH*HEIGHT), 0xff, WIDTH*HEIGHT); return got_image; }
C_RESULT video_decode_picture( video_controller_t* controller, vp_api_picture_t* picture, video_stream_t* ex_stream, bool_t* got_image ) { vp_api_picture_t blockline = { 0 }; controller->mode = VIDEO_DECODE; // mandatory because of video_cache_stream blockline = *picture; blockline.height = MB_HEIGHT_Y; blockline.complete = 1; blockline.vision_complete = 0; while( VP_SUCCEEDED(video_cache_stream( controller, ex_stream )) ) { // TODO: choix dynamique de codec video_codec_type_select(controller,ex_stream); // to be verified video_decode_blockline( controller, &blockline, got_image ); } return C_OK; }
void* stream_loop(void *arg) { C_RESULT status; int sockfd, addr_in_size; struct sockaddr_in *my_addr, *from; INFO("VIDEO stream thread starting (thread=%d)...\n", (long int)pthread_self()); int32_t one = 1; video_write ((int8_t*)&one, sizeof( one )); addr_in_size = sizeof(struct sockaddr_in); from = (struct sockaddr_in *)malloc(addr_in_size); my_addr = (struct sockaddr_in *)malloc(addr_in_size); assert(from); assert(my_addr); memset((char *)my_addr,(char)0,addr_in_size); my_addr->sin_family = AF_INET; my_addr->sin_addr.s_addr = htonl(INADDR_ANY); my_addr->sin_port = htons( VIDEO_PORT ); if((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) { INFO ("socket: %s\n", strerror(errno)); goto fail; }; if (bind(sockfd, (struct sockaddr *)my_addr, addr_in_size) < 0) { INFO ("bind: %s\n", strerror(errno)); goto fail; }; { struct timeval tv; // 1 second timeout tv.tv_sec = 0; tv.tv_usec = 100000; setsockopt( sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); int numi= 1; setsockopt( sockfd, SOL_SOCKET, SO_DEBUG, &numi, sizeof(int)); numi= 256*256*256*16; socklen_t numi1= sizeof(int);; fprintf(stdout,"Setting buffer size %i\n",setsockopt( sockfd, SOL_SOCKET, SO_RCVBUF, &numi,numi1)); getsockopt( sockfd, SOL_SOCKET, SO_RCVBUF, &numi,&numi1); fprintf(stdout,"Socket buffer size is %i \n",numi); } while( stream_thread_alive ) { int size; size = recvfrom (sockfd, video_controller_get_stream_ptr(&controller), DATA_RECEIVED_MAX_SIZE, 0, (struct sockaddr *)from, (socklen_t*)&addr_in_size); // INFO ("Stream %i ",size); // if (size == -1) INFO ("error %i",errno); // INFO ("\n"); picture_size=size; if (size == 0) { INFO ("Lost connection \n"); int32_t one = 1; video_write ((int8_t*)&one, sizeof(one)); } else if (size > 0) { int decodeOK = FALSE; controller.in_stream.used = size; controller.in_stream.size = size; controller.in_stream.index = 0; controller.in_stream.length = 32; controller.in_stream.code = 0; //INFO("decode=%d\n", size); status = video_decode_blockline(&controller, &picture, &decodeOK); if (status) { INFO("failed\n"); } else if (decodeOK) { picture_width = controller.width; picture_height = controller.height; // this is ugly: update counter and notify video renderer num_picture_decoded = controller.num_frames; //INFO("num_picture_decoded = %d\n", num_picture_decoded); } } } fail: free(from); free(my_addr); if (sockfd >= 0) { close(sockfd); sockfd = -1; } INFO("VIDEO stream thread stopping\n"); return NULL; }
C_RESULT vlib_stage_decoding_transform(vlib_stage_decoding_config_t *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out) { bool_t got_image; vp_os_mutex_lock( &out->lock ); if(out->status == VP_API_STATUS_INIT) { out->numBuffers = 1; out->buffers = (int8_t**)(int8_t*)cfg->picture; out->indexBuffer = 0; out->lineSize = 0; out->status = VP_API_STATUS_PROCESSING; } if( in->status == VP_API_STATUS_ENDED ) { out->status = in->status; } if(out->status == VP_API_STATUS_PROCESSING ) { // If out->size == 1 it means picture is ready out->size = 0; cfg->picture->vision_complete = 0; cfg->picture->complete = 0; cfg->picture->blockline = 0; got_image = FALSE; if(cfg->block_mode_enable) { cfg->controller.in_stream.bytes = (uint32_t*)in->buffers[0]; cfg->controller.in_stream.used = in->size; cfg->controller.in_stream.size = in->size; cfg->controller.in_stream.index = 0; cfg->controller.in_stream.length = 32; cfg->controller.in_stream.code = 0; video_decode_blockline( &cfg->controller, cfg->picture, &got_image ); } else { stream.index = 0; stream.used = in->size; vp_os_memcpy(&stream.bytes[0], (uint32_t*)in->buffers[0], in->size); video_decode_picture( &cfg->controller, cfg->picture, &stream, &got_image ); } if( got_image ) { // we got one picture out->size = 1; cfg->picture->complete = 1; cfg->num_picture_decoded++; if( cfg->luma_only ) { int32_t i; for(i = 0; i < (int32_t)cfg->picture->width * (int32_t)cfg->picture->height / 4; i++ ) { cfg->picture->cr_buf[i] = 0x80; cfg->picture->cb_buf[i] = 0x80; } } } } vp_os_mutex_unlock( &out->lock ); return C_OK; }