本文整理汇总了C++中SDL_UnlockMutex函数的典型用法代码示例。如果您正苦于以下问题:C++ SDL_UnlockMutex函数的具体用法?C++ SDL_UnlockMutex怎么用?C++ SDL_UnlockMutex使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了SDL_UnlockMutex函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: queue_picture
int queue_picture(VideoState *is, AVFrame *pFrame, double pts) {
VideoPicture *vp;
AVPicture pict;
/* wait until we have space for a new pic */
SDL_LockMutex(is->pictq_mutex);
while(is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
!is->quit) {
SDL_CondWait(is->pictq_cond, is->pictq_mutex);
}
SDL_UnlockMutex(is->pictq_mutex);
if(is->quit)
return -1;
// windex is set to 0 initially
vp = &is->pictq[is->pictq_windex];
/* allocate or resize the buffer! */
// if(!vp->bmp ||
if(!vp->m_pFrame ||
vp->width != is->video_st->codec->width ||
vp->height != is->video_st->codec->height) {
SDL_Event event;
vp->allocated = 0;
/* we have to do it in the main thread */
event.type = FF_ALLOC_EVENT;
event.user.data1 = is;
SDL_PushEvent(&event);
/* wait until we have a picture allocated */
SDL_LockMutex(is->pictq_mutex);
while(!vp->allocated && !is->quit) {
SDL_CondWait(is->pictq_cond, is->pictq_mutex);
}
SDL_UnlockMutex(is->pictq_mutex);
if(is->quit) {
return -1;
}
}
/* We have a place to put our picture on the queue */
/* If we are skipping a frame, do we set this to null
but still return vp->allocated = 1? */
// if(vp->bmp) {
if(vp->m_pFrame){
// SDL_LockYUVOverlay(vp->bmp);
/* point pict at the queue */
// pict.data[0] = vp->bmp->pixels[0];
// pict.data[1] = vp->bmp->pixels[2];
// pict.data[2] = vp->bmp->pixels[1];
//
// pict.linesize[0] = vp->bmp->pitches[0];
// pict.linesize[1] = vp->bmp->pitches[2];
// pict.linesize[2] = vp->bmp->pitches[1];
// Convert the image into YUV format that SDL uses
// sws_scale
// (
// is->sws_ctx,
// (uint8_t const * const *)pFrame->data,
// pFrame->linesize,
// 0,
// is->video_st->codec->height,
// pict.data,
// pict.linesize
// );
// SDL_UnlockYUVOverlay(vp->bmp);
sws_scale(is->sws_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, is->video_st->codec->height,
m_pFrameYUV->data, m_pFrameYUV->linesize);
SDL_Rect rect;
rect.x = 0;
rect.y = 0;
rect.w = is->video_st->codec->width;
rect.h = is->video_st->codec->height;
SDL_UpdateYUVTexture(m_pSdlTexture, &rect,
m_pFrameYUV->data[0], m_pFrameYUV->linesize[0],
m_pFrameYUV->data[1], m_pFrameYUV->linesize[1],
m_pFrameYUV->data[2], m_pFrameYUV->linesize[2]);
vp->pts = pts;
/* now we inform our display thread that we have a pic ready */
if(++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE) {
is->pictq_windex = 0;
}
SDL_LockMutex(is->pictq_mutex);
is->pictq_size++;
SDL_UnlockMutex(is->pictq_mutex);
}
return 0;
}
示例2: get_x
void ClientConnection::send_entity(Uint32 eid, const Entity *ent)
{
DataEntity dent = {
eid, ent->world->difference(ent->get_x(), get_x()) * 64 + ent->get_offset_x(),
ent->world->difference(ent->get_y(), get_y()) * 64 + ent->get_offset_y(),
ent->get_z() + ent->get_offset_z(),
ent->get_w(),
ent->get_h(),
ent->get_tex(),
false
};
// Check if the entity exists allready
typeof(client_entities.begin()) it = client_entities.find(eid);
if (it != client_entities.end())
{
DataEntity &itde = it->second;
// Check bounds
if ((dent.x + dent.w < -1024 || dent.x > 1024 || dent.y + dent.h < -1024
|| dent.y > 1024)
&& (itde.x + itde.w < -1024 || itde.x > 1024
|| itde.y + itde.h < -1024 || itde.y > 1024))
return;
// FIXME: If the entity moves across a corner, it will never be sent
// If it exists send only modifications
bool move = itde.x != dent.x || itde.y != dent.y || itde.z != dent.z;
bool resize = itde.w != dent.w || itde.h != dent.h;
bool change_tex = itde.tex != dent.tex;
itde = dent;
if (!move && !resize && !change_tex)
return; // Nothing has changed, send nothing
if (move && !resize && !change_tex)
{
// Only move the entity
static const int len = 9;
DataPacket packet =
{ len, new char[len] };
packet.data[0] = 'M';
SDLNet_Write16(dent.id, packet.data + 1);
SDLNet_Write16(dent.x, packet.data + 3);
SDLNet_Write16(dent.y, packet.data + 5);
SDLNet_Write16(dent.z, packet.data + 7);
SDL_LockMutex(send_mutex);
data_to_send.push_back(packet);
SDL_UnlockMutex(send_mutex);
return;
}
if (!move && (resize || change_tex))
{
// Only send width height and texture
static const int len = 9;
DataPacket packet =
{ len, new char[len] };
packet.data[0] = 'i';
SDLNet_Write16(dent.id, packet.data + 1);
SDLNet_Write16(dent.w, packet.data + 3);
SDLNet_Write16(dent.h, packet.data + 5);
SDLNet_Write16(dent.tex, packet.data + 7);
SDL_LockMutex(send_mutex);
data_to_send.push_back(packet);
SDL_UnlockMutex(send_mutex);
return;
}
{
// Otherwise send everything
static const int len = 15;
DataPacket packet =
{ len, new char[len] };
packet.data[0] = 'a';
SDLNet_Write16(dent.id, packet.data + 1);
SDLNet_Write16(dent.x, packet.data + 3);
SDLNet_Write16(dent.y, packet.data + 5);
SDLNet_Write16(dent.z, packet.data + 7);
SDLNet_Write16(dent.w, packet.data + 9);
SDLNet_Write16(dent.h, packet.data + 11);
SDLNet_Write16(dent.tex, packet.data + 13);
SDL_LockMutex(send_mutex);
data_to_send.push_back(packet);
SDL_UnlockMutex(send_mutex);
}
}
else
{
// If it's new, send it as a new entity
// Check bounds
if (dent.x + dent.w < -1024 || dent.x > 1024 || dent.y + dent.h < -1024 || dent.y > 1024)
//.........这里部分代码省略.........
示例3: SDL_UnlockMutex
~ScopedMutex() {
SDL_UnlockMutex(mutex_);
}
示例4: rtp_message
uint64_t CRtpByteStreamBase::rtp_ts_to_msec (uint32_t rtp_ts,
uint64_t uts,
uint64_t &wrap_offset)
{
uint64_t timetick;
uint64_t adjusted_rtp_ts;
uint64_t adjusted_wc_rtp_ts;
bool have_wrap = false;
uint32_t this_mask, last_mask;
last_mask = m_last_rtp_ts & (1U << 31);
this_mask = rtp_ts & (1U << 31);
if (last_mask != this_mask) {
if (this_mask == 0) {
wrap_offset += (TO_U64(1) << 32);
have_wrap = true;
rtp_message(LOG_DEBUG, "%s - have wrap %x new %x", m_name,
m_last_rtp_ts, rtp_ts);
} else {
// need to do something here
}
}
if (m_stream_ondemand) {
adjusted_rtp_ts = wrap_offset;
adjusted_rtp_ts += rtp_ts;
adjusted_wc_rtp_ts = m_base_rtp_ts;
if (adjusted_wc_rtp_ts > adjusted_rtp_ts) {
timetick = adjusted_wc_rtp_ts - adjusted_rtp_ts;
timetick *= TO_U64(1000);
timetick /= m_timescale;
if (timetick > m_play_start_time) {
timetick = 0;
} else {
timetick = m_play_start_time - timetick;
}
} else {
timetick = adjusted_rtp_ts - adjusted_wc_rtp_ts;
timetick *= TO_U64(1000);
timetick /= m_timescale;
timetick += m_play_start_time;
}
} else {
// We've got a broadcast scenario here...
if (m_have_first_pak_ts == false) {
// We haven't processed the first packet yet - we record
// the data here.
m_first_pak_rtp_ts = rtp_ts;
m_first_pak_ts = uts;
m_have_first_pak_ts = true;
rtp_message(LOG_DEBUG, "%s first pak ts %u "U64,
m_name, m_first_pak_rtp_ts, m_first_pak_ts);
// if we have received RTCP, set the wallclock offset, which
// triggers the synchronization effort.
if (m_rtcp_received) {
// calculate other stuff
//rtp_message(LOG_DEBUG, "%s rtp_ts_to_msec calling wallclock", m_name);
set_wallclock_offset(m_rtcp_ts, m_rtcp_rtp_ts);
}
}
SDL_LockMutex(m_rtp_packet_mutex);
// fairly simple calculation to calculate the timestamp
// based on this rtp timestamp, the first pak rtp timestamp and
// the first packet timestamp.
int32_t adder;
int64_t ts_adder;
if (have_wrap) {
adder = rtp_ts - m_first_pak_rtp_ts;
// adjust once an hour, to keep errors low
// we'll adjust the timestamp and rtp timestamp
ts_adder = (int64_t)adder;
ts_adder *= TO_D64(1000);
ts_adder /= (int64_t)m_timescale;
m_first_pak_ts += ts_adder;
m_first_pak_rtp_ts = rtp_ts;
#ifdef DEBUG_RTP_BCAST
rtp_message(LOG_DEBUG, "%s adjust for wrap - first pak ts is now "U64" rtp %u",
m_name, m_first_pak_ts, m_first_pak_rtp_ts);
#endif
}
// adder could be negative here, based on the RTCP we receive
adder = rtp_ts - m_first_pak_rtp_ts;
ts_adder = (int64_t)adder;
ts_adder *= TO_D64(1000);
ts_adder /= (int64_t)m_timescale;
timetick = m_first_pak_ts;
timetick += ts_adder;
SDL_UnlockMutex(m_rtp_packet_mutex);
#ifdef DEBUG_RTP_BCAST
rtp_message(LOG_DEBUG, "%s ts %x base %x "U64" tp "U64" adder %d "D64,
m_name, rtp_ts, m_first_pak_rtp_ts, m_first_pak_ts,
timetick, adder, ts_adder);
#endif
}
#ifdef DEBUG_RTP_TS
rtp_message(LOG_DEBUG,"%s time "U64" %u", m_name, timetick, rtp_ts);
//.........这里部分代码省略.........
示例5: Sys_Mutex_Unlock
/*
* Sys_Mutex_Unlock
*/
void Sys_Mutex_Unlock( qmutex_t *mutex )
{
SDL_UnlockMutex(mutex->m);
}
示例6: SDL_LockMutex
void Graph::startTick()
{
SDL_LockMutex(mutex);
data.push_back(std::vector<ParamState>(dim));
SDL_UnlockMutex(mutex);
}
示例7: SDL_UnlockMutex
void Graphics::Update()
{
SDL_UnlockMutex(Graphics::ThreadData.graphMutex);
}
示例8: fe_mt_mutex_unlock
void fe_mt_mutex_unlock(fe_mt_mutex *mutex) {
SDL_UnlockMutex(*mutex);
}
示例9: SDL_LockMutex
// called by the runner when a job completes
void AsyncJobQueue::Finish(Job *job, const uint8_t threadIdx)
{
SDL_LockMutex(m_finishedLock[threadIdx]);
m_finished[threadIdx].push_back(job);
SDL_UnlockMutex(m_finishedLock[threadIdx]);
}
示例10: reader_thread_loop
static int reader_thread_loop(void *dummy)
{
static uint8_t *readbuf = NULL;
static int readbuf_size = 256;
int readbuf_len = 0;
int header_len = 0;
int cmd_len = -1;
if (!readbuf) {
readbuf = emalloc(readbuf_size);
}
while (!abort_thread) {
int toread;
/* First, try to read a command length sequence */
if (readbuf_len < 2) {
/* Three-byte length? */
if (readbuf_len > 0 && (readbuf[0] & 0x80)) {
toread = 3 - readbuf_len;
} else {
toread = 2 - readbuf_len;
}
} else if (readbuf_len == 2 && (readbuf[0] & 0x80)) {
toread = 1;
} else {
/* If we have a finished header, get the packet size from it. */
if (readbuf_len <= 3) {
uint8_t *p = readbuf;
header_len = (*p & 0x80) ? 3 : 2;
cmd_len = 0;
if (header_len == 3) {
cmd_len += ((int) (*p++) & 0x7f) << 16;
}
cmd_len += ((int) (*p++)) << 8;
cmd_len += ((int) (*p++));
}
toread = cmd_len + header_len - readbuf_len;
if (readbuf_len + toread > readbuf_size) {
uint8_t *tmp = readbuf;
readbuf_size = readbuf_len + toread;
readbuf = emalloc(readbuf_size);
memcpy(readbuf, tmp, readbuf_len);
efree(tmp);
}
}
size_t amt;
bool success = socket_read(csocket.sc, (void *) (readbuf + readbuf_len),
toread, &amt);
if (!success) {
break;
}
readbuf_len += amt;
network_graph_update(NETWORK_GRAPH_TYPE_GAME, NETWORK_GRAPH_TRAFFIC_RX,
amt);
/* Finished with a command? */
if (readbuf_len == cmd_len + header_len && !abort_thread) {
command_buffer *buf = command_buffer_new(readbuf_len - header_len,
readbuf + header_len);
SDL_LockMutex(input_buffer_mutex);
command_buffer_enqueue(buf, &input_queue_start, &input_queue_end);
SDL_CondSignal(input_buffer_cond);
SDL_UnlockMutex(input_buffer_mutex);
cmd_len = -1;
header_len = 0;
readbuf_len = 0;
}
}
client_socket_close(&csocket);
if (readbuf != NULL) {
efree(readbuf);
readbuf = NULL;
}
return -1;
}
示例11: Sys_LeaveCriticalSection
/*
==================
Sys_LeaveCriticalSection
==================
*/
void Sys_LeaveCriticalSection(int index) {
assert(index >= 0 && index < MAX_CRITICAL_SECTIONS);
if (SDL_UnlockMutex(mutex[index]) != 0)
common->Error("ERROR: SDL_UnlockMutex failed\n");
}
示例12: init_sample
/*
* The bulk of the Sound_NewSample() work is done here...
* Ask the specified decoder to handle the data in (rw), and if
* so, construct the Sound_Sample. Otherwise, try to wind (rw)'s stream
* back to where it was, and return false.
*/
static int init_sample(const Sound_DecoderFunctions *funcs,
Sound_Sample *sample, const char *ext,
Sound_AudioInfo *_desired)
{
Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
Sound_AudioInfo desired;
int pos = SDL_RWtell(internal->rw);
/* fill in the funcs for this decoder... */
sample->decoder = &funcs->info;
internal->funcs = funcs;
if (!funcs->open(sample, ext))
{
SDL_RWseek(internal->rw, pos, SEEK_SET); /* set for next try... */
return(0);
} /* if */
/* success; we've got a decoder! */
/* Now we need to set up the conversion buffer... */
memcpy(&desired, (_desired != NULL) ? _desired : &sample->actual,
sizeof (Sound_AudioInfo));
if (desired.format == 0)
desired.format = sample->actual.format;
if (desired.channels == 0)
desired.channels = sample->actual.channels;
if (desired.rate == 0)
desired.rate = sample->actual.rate;
if (Sound_BuildAudioCVT(&internal->sdlcvt,
sample->actual.format,
sample->actual.channels,
sample->actual.rate,
desired.format,
desired.channels,
desired.rate,
sample->buffer_size) == -1)
{
__Sound_SetError(SDL_GetError());
funcs->close(sample);
SDL_RWseek(internal->rw, pos, SEEK_SET); /* set for next try... */
return(0);
} /* if */
if (internal->sdlcvt.len_mult > 1)
{
void *rc = realloc(sample->buffer,
sample->buffer_size * internal->sdlcvt.len_mult);
if (rc == NULL)
{
funcs->close(sample);
SDL_RWseek(internal->rw, pos, SEEK_SET); /* set for next try... */
return(0);
} /* if */
sample->buffer = rc;
} /* if */
/* these pointers are all one and the same. */
memcpy(&sample->desired, &desired, sizeof (Sound_AudioInfo));
internal->sdlcvt.buf = internal->buffer = sample->buffer;
internal->buffer_size = sample->buffer_size / internal->sdlcvt.len_mult;
internal->sdlcvt.len = internal->buffer_size;
/* Prepend our new Sound_Sample to the sample_list... */
SDL_LockMutex(samplelist_mutex);
internal->next = sample_list;
if (sample_list != NULL)
((Sound_SampleInternal *) sample_list->opaque)->prev = sample;
sample_list = sample;
SDL_UnlockMutex(samplelist_mutex);
SNDDBG(("New sample DESIRED format: %s format, %d rate, %d channels.\n",
fmt_to_str(sample->desired.format),
sample->desired.rate,
sample->desired.channels));
SNDDBG(("New sample ACTUAL format: %s format, %d rate, %d channels.\n",
fmt_to_str(sample->actual.format),
sample->actual.rate,
sample->actual.channels));
SNDDBG(("On-the-fly conversion: %s.\n",
internal->sdlcvt.needed ? "ENABLED" : "DISABLED"));
return(1);
} /* init_sample */
示例13: rt_data
//.........这里部分代码省略.........
// we started rendering it. The check is implemented via equality
// comparisons because current_frame_id will eventually wrap.)
missed_frame_history[history_index] =
(current_frame_id != last_frame_id + 1) &&
(current_frame_id != last_frame_id);
if (missed_frame_history[history_index]) {
total_dropped_frames++;
}
history_index = (history_index + 1) % kHistorySize;
last_frame_id = current_frame_id;
// -------------------------------------------
// Steps 1, 2.
// Wait for start of frame. (triggered at vsync start on android.)
// For performance, we only wait if we're not dropping frames. Otherwise,
// we just keep rendering as fast as we can and stuff the render queue.
if (total_dropped_frames <= kMaxDroppedFrames) {
SDL_CondWait(sync_.start_render_cv_, sync_.renderthread_mutex_);
}
// Grab the lock to make sure the game isn't still updating.
SDL_LockMutex(sync_.gameupdate_mutex_);
SystraceBegin("RenderFrame");
// Input update must happen from the render thread.
// From the SDL documentation on SDL_PollEvent(),
// https://wiki.libsdl.org/SDL_PollEvent):
// "As this function implicitly calls SDL_PumpEvents(), you can only call
// this function in the thread that set the video mode."
SystraceBegin("Input::AdvanceFrame()");
input_.AdvanceFrame(&renderer_.window_size());
game_exiting_ |= input_.exit_requested();
SystraceEnd();
// Milliseconds elapsed since last update.
rt_data.frame_start = CurrentWorldTimeSubFrame(input_);
// -------------------------------------------
// Step 3.
// Render everything.
// -------------------------------------------
SystraceBegin("StateMachine::Render()");
fplbase::RenderTarget::ScreenRenderTarget(renderer_).SetAsRenderTarget();
renderer_.ClearDepthBuffer();
renderer_.SetCulling(fplbase::Renderer::kCullBack);
state_machine_.Render(&renderer_);
SystraceEnd();
SDL_UnlockMutex(sync_.gameupdate_mutex_);
SystraceBegin("StateMachine::HandleUI()");
state_machine_.HandleUI(&renderer_);
SystraceEnd();
// -------------------------------------------
// Step 4.
// Signal the update thread that it is safe to start messing with
// data, now that we've already handed it all off to openGL.
// -------------------------------------------
SDL_CondBroadcast(sync_.start_update_cv_);
// -------------------------------------------
// Step 5a.
// Start openGL actually rendering. AdvanceFrame will (among other things)
// trigger a gl_flush. This thread will block until it is completed,
// but that's ok because the update thread is humming in the background
// preparing the worlds tate for next frame.
// -------------------------------------------
SystraceBegin("AdvanceFrame");
renderer_.AdvanceFrame(input_.minimized(), input_.Time());
SystraceEnd(); // AdvanceFrame
SystraceEnd(); // RenderFrame
gpg_manager_.Update();
// Process input device messages since the last game loop.
// Update render window size.
if (input_.GetButton(fplbase::FPLK_BACKQUOTE).went_down()) {
ToggleRelativeMouseMode();
}
int new_time = CurrentWorldTimeSubFrame(input_);
int frame_time = new_time - rt_data.frame_start;
#if DISPLAY_FRAMERATE_HISTOGRAM
UpdateProfiling(frame_time);
#endif // DISPLAY_FRAMERATE_HISTOGRAM
SystraceCounter("FrameTime", frame_time);
}
SDL_UnlockMutex(sync_.renderthread_mutex_);
// Clean up asynchronous callbacks to prevent crashing on garbage data.
#ifdef __ANDROID__
fplbase::RegisterVsyncCallback(nullptr);
#endif // __ANDROID__
input_.AddAppEventCallback(nullptr);
}
示例14: drain_output_buffer_l
static int drain_output_buffer_l(JNIEnv *env, IJKFF_Pipenode *node, int64_t timeUs, int *dequeue_count)
{
IJKFF_Pipenode_Opaque *opaque = node->opaque;
int ret = 0;
SDL_AMediaCodecBufferInfo bufferInfo;
ssize_t output_buffer_index = 0;
if (dequeue_count)
*dequeue_count = 0;
if (JNI_OK != SDL_JNI_SetupThreadEnv(&env)) {
ALOGE("%s:create: SetupThreadEnv failed\n", __func__);
return -1;
}
output_buffer_index = SDL_AMediaCodec_dequeueOutputBuffer(opaque->acodec, &bufferInfo, timeUs);
if (output_buffer_index == AMEDIACODEC__INFO_OUTPUT_BUFFERS_CHANGED) {
ALOGI("AMEDIACODEC__INFO_OUTPUT_BUFFERS_CHANGED\n");
// continue;
} else if (output_buffer_index == AMEDIACODEC__INFO_OUTPUT_FORMAT_CHANGED) {
ALOGI("AMEDIACODEC__INFO_OUTPUT_FORMAT_CHANGED\n");
SDL_AMediaFormat_deleteP(&opaque->output_aformat);
opaque->output_aformat = SDL_AMediaCodec_getOutputFormat(opaque->acodec);
if (opaque->output_aformat) {
int width = 0;
int height = 0;
int color_format = 0;
int stride = 0;
int slice_height = 0;
int crop_left = 0;
int crop_top = 0;
int crop_right = 0;
int crop_bottom = 0;
SDL_AMediaFormat_getInt32(opaque->output_aformat, "width", &width);
SDL_AMediaFormat_getInt32(opaque->output_aformat, "height", &height);
SDL_AMediaFormat_getInt32(opaque->output_aformat, "color-format", &color_format);
SDL_AMediaFormat_getInt32(opaque->output_aformat, "stride", &stride);
SDL_AMediaFormat_getInt32(opaque->output_aformat, "slice-height", &slice_height);
SDL_AMediaFormat_getInt32(opaque->output_aformat, "crop-left", &crop_left);
SDL_AMediaFormat_getInt32(opaque->output_aformat, "crop-top", &crop_top);
SDL_AMediaFormat_getInt32(opaque->output_aformat, "crop-right", &crop_right);
SDL_AMediaFormat_getInt32(opaque->output_aformat, "crop-bottom", &crop_bottom);
// TI decoder could crash after reconfigure
// ffp_notify_msg3(ffp, FFP_MSG_VIDEO_SIZE_CHANGED, width, height);
// opaque->frame_width = width;
// opaque->frame_height = height;
ALOGI(
"AMEDIACODEC__INFO_OUTPUT_FORMAT_CHANGED\n"
" width-height: (%d x %d)\n"
" color-format: (%s: 0x%x)\n"
" stride: (%d)\n"
" slice-height: (%d)\n"
" crop: (%d, %d, %d, %d)\n"
,
width, height,
SDL_AMediaCodec_getColorFormatName(color_format), color_format,
stride,
slice_height,
crop_left, crop_top, crop_right, crop_bottom);
}
// continue;
} else if (output_buffer_index == AMEDIACODEC__INFO_TRY_AGAIN_LATER) {
AMCTRACE("AMEDIACODEC__INFO_TRY_AGAIN_LATER\n");
// continue;
} else if (output_buffer_index < 0) {
// enqueue packet as a fake picture
PacketQueue *fake_q = &opaque->fake_pictq;
SDL_LockMutex(fake_q->mutex);
if (!fake_q->abort_request && fake_q->nb_packets <= 0) {
SDL_CondWaitTimeout(fake_q->cond, fake_q->mutex, 1000);
}
SDL_UnlockMutex(fake_q->mutex);
if (fake_q->abort_request) {
ret = -1;
goto fail;
} else {
AVPacket pkt;
if (ffp_packet_queue_get(&opaque->fake_pictq, &pkt, 1, &opaque->fake_pictq_serial) < 0) {
ret = -1;
goto fail;
} else {
if (!ffp_is_flush_packet(&pkt)) {
if (dequeue_count)
++*dequeue_count;
ret = amc_queue_picture_fake(node, &pkt);
av_free_packet(&pkt);
}
ret = 0;
goto fail;
}
}
} else if (output_buffer_index >= 0) {
if (dequeue_count)
++*dequeue_count;
//.........这里部分代码省略.........
示例15: aout_thread_n
static int aout_thread_n(JNIEnv *env, SDL_Aout *aout)
{
SDL_Aout_Opaque *opaque = aout->opaque;
SDL_Android_AudioTrack *atrack = opaque->atrack;
SDL_AudioCallback audio_cblk = opaque->spec.callback;
void *userdata = opaque->spec.userdata;
uint8_t *buffer = opaque->buffer;
int copy_size = 256;
assert(atrack);
assert(buffer);
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
if (!opaque->abort_request && !opaque->pause_on)
SDL_Android_AudioTrack_play(env, atrack);
while (!opaque->abort_request) {
SDL_LockMutex(opaque->wakeup_mutex);
if (!opaque->abort_request && opaque->pause_on) {
SDL_Android_AudioTrack_pause(env, atrack);
while (!opaque->abort_request && opaque->pause_on) {
SDL_CondWaitTimeout(opaque->wakeup_cond, opaque->wakeup_mutex, 1000);
}
if (!opaque->abort_request && !opaque->pause_on)
SDL_Android_AudioTrack_play(env, atrack);
}
if (opaque->need_flush) {
opaque->need_flush = 0;
SDL_Android_AudioTrack_flush(env, atrack);
}
if (opaque->need_set_volume) {
opaque->need_set_volume = 0;
SDL_Android_AudioTrack_set_volume(env, atrack, opaque->left_volume, opaque->right_volume);
}
if (opaque->speed_changed) {
opaque->speed_changed = 0;
if (AirStash_GetSystemAndroidApiLevel(env) >= 23) {
SDL_Android_AudioTrack_setSpeed(env, atrack, opaque->speed);
}
}
SDL_UnlockMutex(opaque->wakeup_mutex);
audio_cblk(userdata, buffer, copy_size);
if (opaque->need_flush) {
SDL_Android_AudioTrack_flush(env, atrack);
opaque->need_flush = false;
}
if (opaque->need_flush) {
opaque->need_flush = 0;
SDL_Android_AudioTrack_flush(env, atrack);
} else {
int written = SDL_Android_AudioTrack_write(env, atrack, buffer, copy_size);
if (written != copy_size) {
ALOGW("AudioTrack: not all data copied %d/%d", (int)written, (int)copy_size);
}
}
// TODO: 1 if callback return -1 or 0
}
SDL_Android_AudioTrack_free(env, atrack);
return 0;
}