Example #1
0
static pj_status_t create_file_player( pj_pool_t *pool,
				       const char *file_name,
				       pjmedia_port **p_play_port)
{
    pjmedia_avi_streams *avi_streams;
    pjmedia_avi_stream *vid_stream;
    pjmedia_port *play_port;
    pj_status_t status;

    status = pjmedia_avi_player_create_streams(pool, file_name, 0, &avi_streams);
    if (status != PJ_SUCCESS)
	return status;

    vid_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams,
                                                         0,
                                                         PJMEDIA_TYPE_VIDEO);
    if (!vid_stream)
	return PJ_ENOTFOUND;

    play_port = pjmedia_avi_stream_get_port(vid_stream);
    pj_assert(play_port);

    *p_play_port = play_port;

    return PJ_SUCCESS;
}
Example #2
0
static int aviplay(pj_pool_t *pool, const char *fname)
{
    pjmedia_vid_port *renderer=NULL;
    pjmedia_vid_port_param param;
    const pjmedia_video_format_info *vfi;
    pjmedia_video_format_detail *vfd;
    pjmedia_snd_port *snd_port = NULL;
    pj_status_t status;
    int rc = 0;
    pjmedia_avi_streams *avi_streams;
    pjmedia_avi_stream *vid_stream, *aud_stream;
    pjmedia_port *vid_port = NULL, *aud_port = NULL;
    pjmedia_vid_codec *codec=NULL;
    avi_port_t avi_port;

    pj_bzero(&avi_port, sizeof(avi_port));

    status = pjmedia_avi_player_create_streams(pool, fname, 0, &avi_streams);
    if (status != PJ_SUCCESS) {
        PJ_PERROR(2,("", status, "    Error playing %s", fname));
        rc = 210;
        goto on_return;
    }

    vid_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams,
                 0,
                 PJMEDIA_TYPE_VIDEO);
    vid_port = pjmedia_avi_stream_get_port(vid_stream);

    if (vid_port) {
        pjmedia_vid_port_param_default(&param);

        status = pjmedia_vid_dev_default_param(pool,
                                               PJMEDIA_VID_DEFAULT_RENDER_DEV,
                                               &param.vidparam);
        if (status != PJ_SUCCESS) {
            rc = 220;
            goto on_return;
        }

        /* Create renderer, set it to active  */
        param.active = PJ_TRUE;
        param.vidparam.dir = PJMEDIA_DIR_RENDER;
        vfd = pjmedia_format_get_video_format_detail(&vid_port->info.fmt,
                PJ_TRUE);
        pjmedia_format_init_video(&param.vidparam.fmt,
                                  vid_port->info.fmt.id,
                                  vfd->size.w, vfd->size.h,
                                  vfd->fps.num, vfd->fps.denum);

        vfi = pjmedia_get_video_format_info(
                  pjmedia_video_format_mgr_instance(),
                  vid_port->info.fmt.id);
        /* Check whether the frame is encoded */
        if (!vfi || vfi->bpp == 0) {
            /* Yes, prepare codec */
            pj_str_t codec_id_st;
            unsigned info_cnt = 1, i, k;
            const pjmedia_vid_codec_info *codec_info;
            pj_str_t port_name = {"codec", 5};
            pj_uint8_t *enc_buf = NULL;
            pj_size_t enc_buf_size = 0;
            pjmedia_vid_dev_info rdr_info;
            pjmedia_port codec_port;
            codec_port_data_t codec_port_data;
            pjmedia_vid_codec_param codec_param;
            struct codec_fmt *codecp = NULL;

            /* Lookup codec */
            for (i = 0; i < sizeof(codec_fmts)/sizeof(codec_fmts[0]); i++) {
                if (vid_port->info.fmt.id == codec_fmts[i].pjmedia_id) {
                    codecp = &codec_fmts[i];
                    break;
                }
            }
            if (!codecp) {
                rc = 242;
                goto on_return;
            }
            pj_cstr(&codec_id_st, codecp->codec_id);
            status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL,
                     &codec_id_st,
                     &info_cnt,
                     &codec_info,
                     NULL);
            if (status != PJ_SUCCESS) {
                rc = 245;
                goto on_return;
            }
            status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info,
                     &codec_param);
            if (status != PJ_SUCCESS) {
                rc = 246;
                goto on_return;
            }

            pjmedia_format_copy(&codec_param.enc_fmt, &param.vidparam.fmt);

            pjmedia_vid_dev_get_info(param.vidparam.rend_id, &rdr_info);
            for (i=0; i<codec_info->dec_fmt_id_cnt; ++i) {
                for (k=0; k<rdr_info.fmt_cnt; ++k) {
                    if (codec_info->dec_fmt_id[i]==(int)rdr_info.fmt[k].id)
                    {
                        param.vidparam.fmt.id = codec_info->dec_fmt_id[i];
                        i = codec_info->dec_fmt_id_cnt;
                        break;
                    }
                }
            }

            /* Open codec */
            status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info,
                     &codec);
            if (status != PJ_SUCCESS) {
                rc = 250;
                goto on_return;
            }

            status = pjmedia_vid_codec_init(codec, pool);
            if (status != PJ_SUCCESS) {
                rc = 251;
                goto on_return;
            }

            pjmedia_format_copy(&codec_param.dec_fmt, &param.vidparam.fmt);
            codec_param.dir = PJMEDIA_DIR_DECODING;
            codec_param.packing = PJMEDIA_VID_PACKING_WHOLE;
            status = pjmedia_vid_codec_open(codec, &codec_param);
            if (status != PJ_SUCCESS) {
                rc = 252;
                goto on_return;
            }

            /* Alloc encoding buffer */
            enc_buf_size =  codec_param.dec_fmt.det.vid.size.w *
                            codec_param.dec_fmt.det.vid.size.h * 4
                            + 16; /*< padding, just in case */
            enc_buf = pj_pool_alloc(pool,enc_buf_size);

            /* Init codec port */
            pj_bzero(&codec_port, sizeof(codec_port));
            status = pjmedia_port_info_init2(&codec_port.info, &port_name,
                                             0x1234,
                                             PJMEDIA_DIR_ENCODING,
                                             &codec_param.dec_fmt);
            if (status != PJ_SUCCESS) {
                rc = 260;
                goto on_return;
            }
            pj_bzero(&codec_port_data, sizeof(codec_port_data));
            codec_port_data.codec = codec;
            codec_port_data.src_port = vid_port;
            codec_port_data.enc_buf = enc_buf;
            codec_port_data.enc_buf_size = enc_buf_size;

            codec_port.get_frame = &codec_get_frame;
            codec_port.port_data.pdata = &codec_port_data;

            /* Check whether we need to convert the decoded frame */
            if (codecp->need_conversion) {
                pjmedia_conversion_param conv_param;

                pjmedia_format_copy(&conv_param.src, &param.vidparam.fmt);
                pjmedia_format_copy(&conv_param.dst, &param.vidparam.fmt);
                conv_param.dst.id = codecp->dst_fmt;
                param.vidparam.fmt.id = conv_param.dst.id;

                status = pjmedia_converter_create(NULL, pool, &conv_param,
                                                  &codec_port_data.conv);
                if (status != PJ_SUCCESS) {
                    rc = 270;
                    goto on_return;
                }
            }

            status = pjmedia_vid_port_create(pool, &param, &renderer);
            if (status != PJ_SUCCESS) {
                rc = 230;
                goto on_return;
            }

            status = pjmedia_vid_port_connect(renderer, &codec_port,
                                              PJ_FALSE);
        } else {
            status = pjmedia_vid_port_create(pool, &param, &renderer);
            if (status != PJ_SUCCESS) {
                rc = 230;
                goto on_return;
            }

            /* Connect avi port to renderer */
            status = pjmedia_vid_port_connect(renderer, vid_port,
                                              PJ_FALSE);
        }

        if (status != PJ_SUCCESS) {
            rc = 240;
            goto on_return;
        }
    }

    aud_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams,
                 0,
                 PJMEDIA_TYPE_AUDIO);
    aud_port = pjmedia_avi_stream_get_port(aud_stream);

    if (aud_port) {
        /* Create sound player port. */
        status = pjmedia_snd_port_create_player(
                     pool,				    /* pool		    */
                     -1,				    /* use default dev.	    */
                     PJMEDIA_PIA_SRATE(&aud_port->info),/* clock rate.	    */
                     PJMEDIA_PIA_CCNT(&aud_port->info), /* # of channels.	    */
                     PJMEDIA_PIA_SPF(&aud_port->info),  /* samples per frame.   */
                     PJMEDIA_PIA_BITS(&aud_port->info), /* bits per sample.	    */
                     0,				    /* options		    */
                     &snd_port			    /* returned port	    */
                 );
        if (status != PJ_SUCCESS) {
            rc = 310;
            goto on_return;
        }

        /* Connect file port to the sound player.
         * Stream playing will commence immediately.
         */
        status = pjmedia_snd_port_connect(snd_port, aud_port);
        if (status != PJ_SUCCESS) {
            rc = 330;
            goto on_return;
        }
    }

    if (vid_port) {
        pjmedia_vid_dev_cb cb;

        pj_bzero(&cb, sizeof(cb));
        avi_port.snd_port = snd_port;
        avi_port.vid_port = renderer;
        avi_port.is_running = PJ_TRUE;
        pjmedia_vid_port_set_cb(renderer, &cb, &avi_port);

        /* subscribe events */
        pjmedia_event_subscribe(NULL, &avi_event_cb, &avi_port,
                                renderer);

        if (snd_port) {
            /* Synchronize video rendering and audio playback */
            pjmedia_vid_port_set_clock_src(
                renderer,
                pjmedia_snd_port_get_clock_src(
                    snd_port, PJMEDIA_DIR_PLAYBACK));
        }


        /* Start video streaming.. */
        status = pjmedia_vid_port_start(renderer);
        if (status != PJ_SUCCESS) {
            rc = 270;
            goto on_return;
        }
    }

    while (!avi_port.is_quitting) {
        pj_thread_sleep(100);
    }

on_return:
    if (snd_port) {
        pjmedia_snd_port_disconnect(snd_port);
        /* Without this sleep, Windows/DirectSound will repeteadly
         * play the last frame during destroy.
         */
        pj_thread_sleep(100);
        pjmedia_snd_port_destroy(snd_port);
    }
    if (renderer) {
        pjmedia_event_unsubscribe(NULL, &avi_event_cb, &avi_port,
                                  renderer);
        pjmedia_vid_port_destroy(renderer);
    }
    if (aud_port)
        pjmedia_port_destroy(aud_port);
    if (vid_port)
        pjmedia_port_destroy(vid_port);
    if (codec) {
        pjmedia_vid_codec_close(codec);
        pjmedia_vid_codec_mgr_dealloc_codec(NULL, codec);
    }

    return rc;
}
Example #3
0
/* API: configure the AVI */
PJ_DEF(pj_status_t) pjmedia_avi_dev_alloc( pjmedia_vid_dev_factory *f,
                                           pjmedia_avi_dev_param *p,
                                           pjmedia_vid_dev_index *p_id)
{
    pjmedia_vid_dev_index id;
    struct avi_factory *cf = (struct avi_factory*)f;
    unsigned local_idx;
    struct avi_dev_info *adi = NULL;
    pjmedia_format avi_fmt;
    const pjmedia_video_format_info *vfi;
    pj_status_t status;

    PJ_ASSERT_RETURN(f && p && p_id, PJ_EINVAL);

    if (p_id)
	*p_id = PJMEDIA_VID_INVALID_DEV;

    /* Get a free dev */
    for (local_idx=0; local_idx<cf->dev_count; ++local_idx) {
	if (cf->dev_info[local_idx].avi == NULL) {
	    adi = &cf->dev_info[local_idx];
	    break;
	}
    }

    if (!adi)
	return PJ_ETOOMANY;

    /* Convert local ID to global id */
    status = pjmedia_vid_dev_get_global_index(&cf->base, local_idx, &id);
    if (status != PJ_SUCCESS)
	return status;

    /* Reset */
    if (adi->pool) {
	pj_pool_release(adi->pool);
    }
    pj_bzero(adi, sizeof(*adi));

    /* Reinit */
    PJ_ASSERT_RETURN(p->path.slen, PJ_EINVAL);
    adi->pool = pj_pool_create(cf->pf, "avidi%p", 512, 512, NULL);


    /* Open the AVI */
    pj_strdup_with_null(adi->pool, &adi->fpath, &p->path);
    status = pjmedia_avi_player_create_streams(adi->pool, adi->fpath.ptr, 0,
                                               &adi->avi);
    if (status != PJ_SUCCESS) {
	goto on_error;
    }

    adi->vid = pjmedia_avi_streams_get_stream_by_media(adi->avi, 0,
                                                       PJMEDIA_TYPE_VIDEO);
    if (!adi->vid) {
	status = PJMEDIA_EVID_BADFORMAT;
	PJ_LOG(4,(THIS_FILE, "Error: cannot find video in AVI %s",
		adi->fpath.ptr));
	goto on_error;
    }

    pjmedia_format_copy(&avi_fmt, &adi->vid->info.fmt);
    vfi = pjmedia_get_video_format_info(NULL, avi_fmt.id);
    /* Check whether the frame is encoded. */
    if (!vfi || vfi->bpp == 0) {
        /* Yes, prepare codec */
        const pjmedia_vid_codec_info *codec_info;
        pjmedia_vid_codec_param codec_param;
	pjmedia_video_apply_fmt_param vafp;

        /* Lookup codec */
        status = pjmedia_vid_codec_mgr_get_codec_info2(NULL,
                                                       avi_fmt.id,
                                                       &codec_info);
        if (status != PJ_SUCCESS || !codec_info)
            goto on_error;

        status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info,
                                                         &codec_param);
        if (status != PJ_SUCCESS)
            goto on_error;

        /* Open codec */
        status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info,
                                                   &adi->codec);
        if (status != PJ_SUCCESS)
            goto on_error;

        status = pjmedia_vid_codec_init(adi->codec, adi->pool);
        if (status != PJ_SUCCESS)
            goto on_error;

        codec_param.dir = PJMEDIA_DIR_DECODING;
        codec_param.packing = PJMEDIA_VID_PACKING_WHOLE;
        status = pjmedia_vid_codec_open(adi->codec, &codec_param);
        if (status != PJ_SUCCESS)
            goto on_error;

	/* Allocate buffer */
        avi_fmt.id = codec_info->dec_fmt_id[0];
        vfi = pjmedia_get_video_format_info(NULL, avi_fmt.id);
	pj_bzero(&vafp, sizeof(vafp));
	vafp.size = avi_fmt.det.vid.size;
	status = vfi->apply_fmt(vfi, &vafp);
	if (status != PJ_SUCCESS)
	    goto on_error;

	adi->enc_buf = pj_pool_alloc(adi->pool, vafp.framebytes);
	adi->enc_buf_size = vafp.framebytes;
    }

    /* Calculate title */
    if (p->title.slen) {
	pj_strdup_with_null(adi->pool, &adi->title, &p->title);
    } else {
	char *start = p->path.ptr + p->path.slen;
	pj_str_t tmp;

	while (start >= p->path.ptr) {
	    if (*start == '/' || *start == '\\')
		break;
	    --start;
	}
	tmp.ptr = start + 1;
	tmp.slen = p->path.ptr + p->path.slen - tmp.ptr;
	pj_strdup_with_null(adi->pool, &adi->title, &tmp);
    }

    /* Init device info */
    pj_ansi_strncpy(adi->info.name, adi->title.ptr, sizeof(adi->info.name)-1);
    pj_ansi_strncpy(adi->info.driver, DRIVER_NAME, sizeof(adi->info.driver)-1);
    adi->info.dir = PJMEDIA_DIR_CAPTURE;
    adi->info.has_callback = PJ_FALSE;

    adi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;
    adi->info.fmt_cnt = 1;
    pjmedia_format_copy(&adi->info.fmt[0], &avi_fmt);

    /* Set out vars */
    if (p_id)
	*p_id = id;
    p->avi_streams = adi->avi;
    if (p->title.slen == 0)
	p->title = adi->title;

    return PJ_SUCCESS;

on_error:
    if (adi->codec) {
        pjmedia_vid_codec_close(adi->codec);
        adi->codec = NULL;
    }
    if (adi->pool) {
	pj_pool_release(adi->pool);
	adi->pool = NULL;
    }
    pjmedia_avi_dev_free(id);
    return status;
}