Re #1213 (video devices):

- fixed devices to correctly increment the frame timestamp
 - minor fix in video port to set default "active" value to 1 in the param


git-svn-id: https://svn.pjsip.org/repos/pjproject/branches/projects/2.0-dev@3459 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Benny Prijono 2011-03-17 11:25:19 +00:00
parent 0bc99a9ca3
commit 349037b25d
7 changed files with 56 additions and 14 deletions

View File

@ -56,6 +56,8 @@ typedef struct pjmedia_vid_port_param
* port by calling pjmedia_vid_port_get_passive_port(), and subsequently
* calls pjmedia_port_put_frame() or pjmedia_port_get_frame() to that
* media port.
*
* Default: PJ_TRUE
*/
pj_bool_t active;
@ -68,7 +70,8 @@ typedef struct pjmedia_vid_port pjmedia_vid_port;
/**
* Initialize the parameter with the default values. Note that this typically
* would only fill the structure to zeroes.
* would only fill the structure to zeroes unless they have different default
* values.
*
* @param prm The parameter.
*/

View File

@ -91,6 +91,8 @@ struct cbar_stream
const pjmedia_video_format_info *vfi;
pjmedia_video_apply_fmt_param vafp;
pj_uint8_t *first_line[PJMEDIA_MAX_VIDEO_PLANES];
pj_timestamp ts;
unsigned ts_inc;
};
@ -185,10 +187,10 @@ static pj_status_t cbar_factory_init(pjmedia_vid_dev_factory *f)
ddi = &cf->dev_info[0];
pj_bzero(ddi, sizeof(*ddi));
strncpy(ddi->info.name, "Colorbar generator",
sizeof(ddi->info.name));
pj_ansi_strncpy(ddi->info.name, "Colorbar generator",
sizeof(ddi->info.name));
ddi->info.driver[sizeof(ddi->info.driver)-1] = '\0';
strncpy(ddi->info.driver, "Colorbar", sizeof(ddi->info.driver));
pj_ansi_strncpy(ddi->info.driver, "Colorbar", sizeof(ddi->info.driver));
ddi->info.driver[sizeof(ddi->info.driver)-1] = '\0';
ddi->info.dir = PJMEDIA_DIR_CAPTURE;
ddi->info.has_callback = PJ_FALSE;
@ -205,8 +207,11 @@ static pj_status_t cbar_factory_init(pjmedia_vid_dev_factory *f)
DEFAULT_FPS, 1);
}
PJ_LOG(4, (THIS_FILE, "Colorbar video src initialized with %d devices:",
PJ_LOG(4, (THIS_FILE, "Colorbar video src initialized with %d device(s):",
cf->dev_count));
for (i = 0; i < cf->dev_count; i++) {
PJ_LOG(4, (THIS_FILE, "%2d: %s", i, cf->dev_info[i].info.name));
}
return PJ_SUCCESS;
}
@ -365,6 +370,7 @@ static pj_status_t cbar_factory_create_stream(
struct cbar_factory *cf = (struct cbar_factory*)f;
pj_pool_t *pool;
struct cbar_stream *strm;
const pjmedia_video_format_detail *vfd;
const pjmedia_video_format_info *vfi;
pjmedia_video_apply_fmt_param vafp;
const struct cbar_fmt_info *cbfi;
@ -377,6 +383,7 @@ static pj_status_t cbar_factory_create_stream(
pj_bzero(&vafp, sizeof(vafp));
vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);
vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);
cbfi = get_cbar_fmt_info(param->fmt.id);
if (!vfi || !cbfi)
@ -398,6 +405,7 @@ static pj_status_t cbar_factory_create_stream(
strm->vfi = vfi;
strm->cbfi = cbfi;
pj_memcpy(&strm->vafp, &vafp, sizeof(vafp));
strm->ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1);
for (i = 0; i < vfi->plane_cnt; ++i) {
strm->first_line[i] = pj_pool_alloc(pool, vafp.strides[i]);
@ -559,6 +567,8 @@ static pj_status_t cbar_stream_get_frame(pjmedia_vid_dev_stream *strm,
{
struct cbar_stream *stream = (struct cbar_stream*)strm;
frame->timestamp = stream->ts;
stream->ts.u64 += stream->ts_inc;
return spectrum_run(stream, frame->buf, frame->size);
}

View File

@ -65,6 +65,7 @@ static dshow_fmt_info dshow_fmts[] =
{PJMEDIA_FORMAT_YUY2, &MEDIASUBTYPE_YUY2} ,
{PJMEDIA_FORMAT_RGB24, &MEDIASUBTYPE_RGB24} ,
{PJMEDIA_FORMAT_RGB32, &MEDIASUBTYPE_RGB32} ,
//{PJMEDIA_FORMAT_IYUV, &MEDIASUBTYPE_IYUV} ,
};
/* dshow_ device info */
@ -112,6 +113,9 @@ struct dshow_stream
IBaseFilter *rend_filter;
AM_MEDIA_TYPE *mediatype;
} dgraph[2];
pj_timestamp cap_ts;
unsigned cap_ts_inc;
};
@ -286,10 +290,10 @@ static pj_status_t dshow_factory_init(pjmedia_vid_dev_factory *f)
ddi = &df->dev_info[df->dev_count++];
pj_bzero(ddi, sizeof(*ddi));
strncpy(ddi->info.name, "Video Mixing Renderer",
sizeof(ddi->info.name));
pj_ansi_strncpy(ddi->info.name, "Video Mixing Renderer",
sizeof(ddi->info.name));
ddi->info.name[sizeof(ddi->info.name)-1] = '\0';
strncpy(ddi->info.driver, "dshow", sizeof(ddi->info.driver));
pj_ansi_strncpy(ddi->info.driver, "dshow", sizeof(ddi->info.driver));
ddi->info.driver[sizeof(ddi->info.driver)-1] = '\0';
ddi->info.dir = PJMEDIA_DIR_RENDER;
ddi->info.has_callback = PJ_FALSE;
@ -409,7 +413,7 @@ static void input_cb(void *user_data, IMediaSample *pMediaSample)
{
struct dshow_stream *strm = (struct dshow_stream*)user_data;
unsigned char *buffer;
pjmedia_frame frame;
pjmedia_frame frame = {0};
if (strm->quit_flag) {
strm->cap_thread_exited = PJ_TRUE;
@ -434,6 +438,8 @@ static void input_cb(void *user_data, IMediaSample *pMediaSample)
IMediaSample_GetPointer(pMediaSample, (BYTE **)&frame.buf);
frame.size = IMediaSample_GetActualDataLength(pMediaSample);
frame.bit_info = 0;
frame.timestamp = strm->cap_ts;
strm->cap_ts.u64 += strm->cap_ts_inc;
if (strm->vid_cb.capture_cb)
(*strm->vid_cb.capture_cb)(&strm->base, strm->user_data, &frame);
}
@ -453,7 +459,7 @@ static pj_status_t dshow_stream_put_frame(pjmedia_vid_dev_stream *strm,
for (i = 0; i < 2; i++) {
if (stream->dgraph[i].csource_filter) {
HRESULT hr = SourceFilter_Deliver(stream->dgraph[i].csource_filter,
frame->buf, frame->size);
frame->buf, frame->size);
if (FAILED(hr)) {
return hr;
@ -726,10 +732,15 @@ static pj_status_t dshow_factory_create_stream(
/* Create capture stream here */
if (param->dir & PJMEDIA_DIR_CAPTURE) {
const pjmedia_video_format_detail *vfd;
status = create_filter_graph(PJMEDIA_DIR_CAPTURE, param->cap_id,
df, strm, &strm->dgraph[ngraph++]);
if (status != PJ_SUCCESS)
goto on_error;
vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);
strm->cap_ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1);
}
/* Create render stream here */

View File

@ -92,6 +92,9 @@ struct ios_stream
UIImageView *imgView;
void *buf;
pj_timestamp frame_ts;
unsigned ts_inc;
};
@ -355,9 +358,13 @@ static pj_status_t ios_factory_default_param(pj_pool_t *pool,
frame.buf = CVPixelBufferGetBaseAddress(imageBuffer);
frame.size = stream->frame_size;
frame.bit_info = 0;
frame.timestamp.u64 = stream->frame_ts.u64;
if (stream->vid_cb.capture_cb)
(*stream->vid_cb.capture_cb)(&stream->base, stream->user_data, &frame);
stream->frame_ts.u64 += stream->ts_inc;
/* Unlock the pixel buffer */
CVPixelBufferUnlockBaseAddress(imageBuffer,0);
}
@ -385,7 +392,7 @@ static pj_status_t ios_factory_create_stream(pjmedia_vid_dev_factory *f,
struct ios_factory *qf = (struct ios_factory*)f;
pj_pool_t *pool;
struct ios_stream *strm;
pjmedia_video_format_detail *vfd;
const pjmedia_video_format_detail *vfd;
const pjmedia_video_format_info *vfi;
pj_status_t status = PJ_SUCCESS;
ios_fmt_info *ifi = get_ios_format_info(param->fmt.id);
@ -418,6 +425,7 @@ static pj_status_t ios_factory_create_stream(pjmedia_vid_dev_factory *f,
strm->bpp = vfi->bpp;
strm->bytes_per_row = strm->size.w * strm->bpp / 8;
strm->frame_size = strm->bytes_per_row * strm->size.h;
strm->ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1);
/* Create capture stream here */
if (param->dir & PJMEDIA_DIR_CAPTURE) {

View File

@ -76,6 +76,9 @@ struct qt_stream
pjmedia_vid_param param; /**< Settings */
pj_pool_t *pool; /**< Memory pool. */
pj_timestamp cap_frame_ts; /**< Captured frame tstamp */
unsigned cap_ts_inc; /**< Increment */
pjmedia_vid_cb vid_cb; /**< Stream callback. */
void *user_data; /**< Application data. */
@ -321,9 +324,13 @@ static pj_status_t qt_factory_default_param(pj_pool_t *pool,
frame.buf = [sampleBuffer bytesForAllSamples];
frame.size = size;
frame.bit_info = 0;
frame.timestamp.u64 = stream->cap_frame_ts.u64;
if (stream->vid_cb.capture_cb)
(*stream->vid_cb.capture_cb)(&stream->base, stream->user_data,
&frame);
stream->cap_frame_ts.u64 += stream->cap_ts_inc;
}
@end
@ -379,7 +386,7 @@ static pj_status_t qt_factory_create_stream(pjmedia_vid_dev_factory *f,
/* Create capture stream here */
if (param->dir & PJMEDIA_DIR_CAPTURE) {
pjmedia_video_format_detail *vfd;
const pjmedia_video_format_detail *vfd;
qt_fmt_info *qfi = get_qt_format_info(param->fmt.id);
if (!qfi) {
@ -437,6 +444,8 @@ static pj_status_t qt_factory_create_stream(pjmedia_vid_dev_factory *f,
kCVPixelBufferHeightKey, nil]];
pj_assert(vfd->fps.num);
strm->cap_ts_inc = PJMEDIA_SPF2(&strm->param.clock_rate, &vfd->fps, 1);
[strm->video_output setMinimumVideoFrameInterval:
(1.0f * vfd->fps.denum / (double)vfd->fps.num)];

View File

@ -676,8 +676,8 @@ static pj_status_t vid4lin_stream_get_frame_mmap(vid4lin_stream *stream,
frame->type = PJMEDIA_FRAME_TYPE_VIDEO;
frame->size = buf.bytesused;
frame->timestamp.u64 = PJ_TIME_VAL_MSEC(time) * stream->param.clock_rate
/ PJ_UINT64(1000);
frame->timestamp.u64 = PJ_UINT64(1) * PJ_TIME_VAL_MSEC(time) *
stream->param.clock_rate / PJ_UINT64(1000);
pj_memcpy(frame->buf, stream->buffers[buf.index].start, buf.bytesused);
on_return:

View File

@ -100,6 +100,7 @@ static pj_status_t vid_pasv_port_get_frame(struct pjmedia_port *this_port,
PJ_DEF(void) pjmedia_vid_port_param_default(pjmedia_vid_port_param *prm)
{
pj_bzero(prm, sizeof(*prm));
prm->active = PJ_TRUE;
}
PJ_DEF(pj_status_t) pjmedia_vid_port_create( pj_pool_t *pool,