示例#1
0
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);
}
示例#2
0
static void *sender_thread(void *arg)
{
    int i, ret = 0;
    struct sender_data *wd = arg;

    av_log(NULL, AV_LOG_INFO, "sender #%d: workload=%d\n", wd->id, wd->workload);
    for (i = 0; i < wd->workload; i++) {
        if (rand() % wd->workload < wd->workload / 10) {
            av_log(NULL, AV_LOG_INFO, "sender #%d: flushing the queue\n", wd->id);
            av_thread_message_flush(wd->queue);
        } else {
            char *val;
            AVDictionary *meta = NULL;
            struct message msg = {
                .magic = MAGIC,
                .frame = av_frame_alloc(),
            };

            if (!msg.frame) {
                ret = AVERROR(ENOMEM);
                break;
            }

            /* we add some metadata to identify the frames */
            val = av_asprintf("frame %d/%d from sender %d",
                              i + 1, wd->workload, wd->id);
            if (!val) {
                av_frame_free(&msg.frame);
                ret = AVERROR(ENOMEM);
                break;
            }
            ret = av_dict_set(&meta, "sig", val, AV_DICT_DONT_STRDUP_VAL);
            if (ret < 0) {
                av_frame_free(&msg.frame);
                break;
            }
            msg.frame->metadata = meta;

            /* allocate a real frame in order to simulate "real" work */
            msg.frame->format = AV_PIX_FMT_RGBA;
            msg.frame->width  = 320;
            msg.frame->height = 240;
            ret = av_frame_get_buffer(msg.frame, 32);
            if (ret < 0) {
                av_frame_free(&msg.frame);
                break;
            }

            /* push the frame in the common queue */
            av_log(NULL, AV_LOG_INFO, "sender #%d: sending my work (%d/%d frame:%p)\n",
                   wd->id, i + 1, wd->workload, msg.frame);
            ret = av_thread_message_queue_send(wd->queue, &msg, 0);
            if (ret < 0) {
                av_frame_free(&msg.frame);
                break;
            }
        }
    }
    av_log(NULL, AV_LOG_INFO, "sender #%d: my work is done here (%s)\n",
           wd->id, av_err2str(ret));
    av_thread_message_queue_set_err_recv(wd->queue, ret < 0 ? ret : AVERROR_EOF);
    return NULL;
}