static s32 vdecoder_request_write(cedarv_decoder_t*p, u32 require_size, u8** buf0, u32* size0, u8** buf1, u32* size1) { u8* start; u32 free_size; u8* vbv_end; video_decoder_t* decoder; if(p == NULL) return CEDARV_RESULT_ERR_INVALID_PARAM; decoder = (video_decoder_t*)p; if(p == NULL || buf0 == NULL || buf1 == NULL || size0 == NULL || size1 == NULL) return CEDARV_RESULT_ERR_INVALID_PARAM; *buf0 = NULL; *size0 = 0; *buf1 = NULL; *size1 = 0; if(decoder->vbv == NULL) { return CEDARV_RESULT_ERR_FAIL; } //* do not receive bitstream when decoding not started. if(decoder->status == CEDARV_STATUS_STOP) { return CEDARV_RESULT_ERR_FAIL; } //* do not receive bitstream when swithing play mode. // if(decoder->mode_switched != 0) //{ // return CEDARV_RESULT_ERR_FAIL; // } //* only receive one frame of bitstream when not in normal play mode. if(decoder->status == CEDARV_STATUS_FORWARD || decoder->status == CEDARV_STATUS_BACKWARD) { if(vbv_get_stream_num(decoder->vbv) > 1) { return CEDARV_RESULT_ERR_FAIL; } } if(require_size == 0) { return CEDARV_RESULT_ERR_FAIL; } if(vbv_request_buffer(&start, &free_size, require_size + decoder->cur_stream_part.length, decoder->vbv) != 0) { return CEDARV_RESULT_ERR_FAIL; } if(free_size <= decoder->cur_stream_part.length) { return CEDARV_RESULT_ERR_FAIL; } vbv_end = vbv_get_base_addr(decoder->vbv) + vbv_get_buffer_size(decoder->vbv); start = start + decoder->cur_stream_part.length; if(start >= vbv_end) { start -= vbv_get_buffer_size(decoder->vbv); } free_size -= decoder->cur_stream_part.length; #if 1 //* give ring buffer. if((start + free_size) > vbv_end) { *buf0 = start; *size0 = vbv_end - start; *buf1 = vbv_get_base_addr(decoder->vbv); *size1 = free_size - *size0; } else { *buf0 = start; *size0 = free_size; } #else //* do not give ring buffer. if((start + free_size) > vbv_end) { free_size = vbv_end - start; } *buf0 = start; *size0 = free_size; #endif return 0; }
static s32 vdecoder_update_data(cedarv_decoder_t* p, cedarv_stream_data_info_t* data_info) { Handle vbv = NULL; vstream_data_t* stream= NULL; video_decoder_t* decoder = NULL; if(p == NULL) return CEDARV_RESULT_ERR_INVALID_PARAM; decoder = (video_decoder_t*)p; if(data_info == NULL) return CEDARV_RESULT_ERR_INVALID_PARAM; vbv = decoder->vbv; stream = &decoder->cur_stream_part; if(data_info->flags & CEDARV_FLAG_FIRST_PART) { if(stream->length != 0) { stream->valid = 0; vbv_add_stream(stream, vbv); } stream->data = vbv_get_current_write_addr(vbv); stream->length = data_info->lengh; if(data_info->flags & CEDARV_FLAG_PTS_VALID) { stream->pts = data_info->pts; } else { stream->pts = (u64)(-1); } } else { stream->length += data_info->lengh; } if(data_info->flags & CEDARV_FLAG_LAST_PART) { if(data_info->flags & CEDARV_FLAG_DATA_INVALID) { stream->valid = 0; } else { stream->valid = 1; } vbv_add_stream(stream, vbv); #ifdef SAVE_DATA if(fpStream) { u8* vbv_end; u32 tmp_length; printf("writing data.........., stream length %x\n", stream->length); vbv_end = vbv_get_base_addr(decoder->vbv) + vbv_get_buffer_size(decoder->vbv); if(stream->data + stream->length > vbv_end) { tmp_length = vbv_end - stream->data; fwrite(stream->data, 1, tmp_length, fpStream); fwrite(vbv_get_base_addr(decoder->vbv), 1, stream->length - tmp_length, fpStream); } else { fwrite(stream->data, 1, stream->length, fpStream); } } #endif stream->data = NULL; stream->length = 0; stream->pts = 0; stream->valid = 0; } return 0; }