static void *receiver_thread(void *arg) { int i, ret = 0; struct receiver_data *rd = arg; for (i = 0; i < rd->workload; i++) { if (rand() % rd->workload < rd->workload / 10) { av_log(NULL, AV_LOG_INFO, "receiver #%d: flushing the queue\n", rd->id); av_thread_message_flush(rd->queue); } else { struct message msg; AVDictionary *meta; AVDictionaryEntry *e; ret = av_thread_message_queue_recv(rd->queue, &msg, 0); if (ret < 0) break; av_assert0(msg.magic == MAGIC); meta = msg.frame->metadata; e = av_dict_get(meta, "sig", NULL, 0); av_log(NULL, AV_LOG_INFO, "got \"%s\" (%p)\n", e->value, msg.frame); av_frame_free(&msg.frame); } } av_log(NULL, AV_LOG_INFO, "consumed enough (%d), stop\n", i); av_thread_message_queue_set_err_send(rd->queue, ret < 0 ? ret : AVERROR_EOF); return NULL; }
/* Send a message to the control input and fetch from the output until we get * it back */ static int send_wait_ctl_message(struct async_context *actx, struct message *msg) { const int message_type = msg->type; const char *msg_type_str = sxpi_async_get_msg_type_string(message_type); TRACE(actx, "--> send %s", msg_type_str); int ret = av_thread_message_queue_send(actx->ctl_in_queue, msg, 0); if (ret < 0) { TRACE(actx, "couldn't send %s: %s", msg_type_str, av_err2str(ret)); return ret; } TRACE(actx, "wait %s", msg_type_str); for (;;) { ret = av_thread_message_queue_recv(actx->ctl_out_queue, msg, 0); if (ret < 0 || msg->type == message_type) break; sxpi_msg_free_data(msg); } if (ret < 0) TRACE(actx, "couldn't get %s: %s", msg_type_str, av_err2str(ret)); else TRACE(actx, "got %s", msg_type_str); return ret; }
int get_input_packet(struct lsInput *input,AVPacket *pkt) { return av_thread_message_queue_recv(input->in_thread_queue,pkt,AV_THREAD_MESSAGE_NONBLOCK); }
void sxpi_demuxing_run(struct demuxing_ctx *ctx) { int ret; int in_err, out_err; TRACE(ctx, "demuxing packets in queue %p", ctx->pkt_queue); for (;;) { AVPacket pkt; struct message msg; ret = av_thread_message_queue_recv(ctx->src_queue, &msg, AV_THREAD_MESSAGE_NONBLOCK); if (ret != AVERROR(EAGAIN)) { if (ret < 0) break; if (msg.type == MSG_SEEK) { av_assert0(!ctx->is_image); /* Make later modules stop working ASAP */ av_thread_message_flush(ctx->pkt_queue); /* do actual seek so the following packet that will be pulled in * this current thread will be at the (approximate) requested time */ const int64_t seek_to = *(int64_t *)msg.data; LOG(ctx, INFO, "Seek in media at ts=%s", PTS2TIMESTR(seek_to)); ret = avformat_seek_file(ctx->fmt_ctx, -1, INT64_MIN, seek_to, seek_to, 0); if (ret < 0) { sxpi_msg_free_data(&msg); break; } } /* Forward the message */ ret = av_thread_message_queue_send(ctx->pkt_queue, &msg, 0); if (ret < 0) { sxpi_msg_free_data(&msg); break; } } msg.type = MSG_PACKET; ret = pull_packet(ctx, &pkt); if (ret < 0) break; TRACE(ctx, "pulled a packet of size %d, sending to decoder", pkt.size); msg.data = av_memdup(&pkt, sizeof(pkt)); if (!msg.data) { av_packet_unref(&pkt); break; } ret = av_thread_message_queue_send(ctx->pkt_queue, &msg, 0); TRACE(ctx, "sent packet to decoder, ret=%s", av_err2str(ret)); if (ret < 0) { av_packet_unref(&pkt); av_freep(&msg.data); if (ret != AVERROR_EOF && ret != AVERROR_EXIT) LOG(ctx, ERROR, "Unable to send packet to decoder: %s", av_err2str(ret)); TRACE(ctx, "can't send pkt to decoder: %s", av_err2str(ret)); av_thread_message_queue_set_err_recv(ctx->pkt_queue, ret); break; } } if (ret < 0 && ret != AVERROR_EOF) { in_err = out_err = ret; } else { in_err = AVERROR_EXIT; out_err = AVERROR_EOF; } TRACE(ctx, "notify user with %s and decoder with %s", av_err2str(in_err), av_err2str(out_err)); av_thread_message_queue_set_err_send(ctx->src_queue, in_err); av_thread_message_flush(ctx->src_queue); av_thread_message_queue_set_err_recv(ctx->pkt_queue, out_err); }