summaryrefslogtreecommitdiff
path: root/pjmedia
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2016-07-27 07:49:14 +0000
committerNanang Izzuddin <nanang@teluu.com>2016-07-27 07:49:14 +0000
commit53e80fb632fee4b377cd652aafdebe996279090e (patch)
treea91a5c3001924b7106818d13c620c6a094096084 /pjmedia
parent93dd0499e90a87efec235e1dbdc354cb45e9d88a (diff)
Misc (re #1945): Updated ffmpeg video device to query supported format from the device/ffmpeg instead of hardcoded to RGB24.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5399 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia')
-rw-r--r--pjmedia/src/pjmedia-videodev/ffmpeg_dev.c106
1 files changed, 73 insertions, 33 deletions
diff --git a/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c b/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c
index 19aec9c6..e506b2c5 100644
--- a/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c
+++ b/pjmedia/src/pjmedia-videodev/ffmpeg_dev.c
@@ -58,6 +58,11 @@
#define MAX_DEV_CNT 8
+#ifndef PJMEDIA_USE_OLD_FFMPEG
+# define av_close_input_stream(ctx) avformat_close_input(&ctx)
+#endif
+
+
typedef struct ffmpeg_dev_info
{
pjmedia_vid_dev_info base;
@@ -169,16 +174,24 @@ static pj_status_t ffmpeg_capture_open(AVFormatContext **ctx,
#if LIBAVFORMAT_VER_AT_LEAST(53,2)
AVDictionary *format_opts = NULL;
char buf[128];
+ enum AVPixelFormat av_fmt;
#else
AVFormatParameters fp;
#endif
pjmedia_video_format_detail *vfd;
+ pj_status_t status;
int err;
PJ_ASSERT_RETURN(ctx && ifmt && dev_name && param, PJ_EINVAL);
PJ_ASSERT_RETURN(param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO,
PJ_EINVAL);
+ status = pjmedia_format_id_to_PixelFormat(param->fmt.id, &av_fmt);
+ if (status != PJ_SUCCESS) {
+ avformat_free_context(*ctx);
+ return status;
+ }
+
vfd = pjmedia_format_get_video_format_detail(&param->fmt, PJ_TRUE);
/* Init ffmpeg format context */
@@ -190,7 +203,7 @@ static pj_status_t ffmpeg_capture_open(AVFormatContext **ctx,
av_dict_set(&format_opts, "framerate", buf, 0);
snprintf(buf, sizeof(buf), "%dx%d", vfd->size.w, vfd->size.h);
av_dict_set(&format_opts, "video_size", buf, 0);
- av_dict_set(&format_opts, "pixel_format", av_get_pix_fmt_name(PIX_FMT_BGR24), 0);
+ av_dict_set(&format_opts, "pixel_format", av_get_pix_fmt_name(av_fmt), 0);
/* Open capture stream */
err = avformat_open_input(ctx, dev_name, ifmt, &format_opts);
@@ -200,7 +213,7 @@ static pj_status_t ffmpeg_capture_open(AVFormatContext **ctx,
fp.prealloced_context = 1;
fp.width = vfd->size.w;
fp.height = vfd->size.h;
- fp.pix_fmt = PIX_FMT_BGR24;
+ fp.pix_fmt = av_fmt;
fp.time_base.num = vfd->fps.denum;
fp.time_base.den = vfd->fps.num;
@@ -219,11 +232,7 @@ static pj_status_t ffmpeg_capture_open(AVFormatContext **ctx,
static void ffmpeg_capture_close(AVFormatContext *ctx)
{
if (ctx)
-#if LIBAVFORMAT_VER_AT_LEAST(53,2)
- avformat_close_input(&ctx);
-#else
av_close_input_stream(ctx);
-#endif
}
@@ -294,39 +303,70 @@ static pj_status_t ffmpeg_factory_refresh(pjmedia_vid_dev_factory *f)
p = av_iformat_next(NULL);
while (p) {
- if (p->flags & AVFMT_NOFILE) {
- unsigned i;
-
- info = &ff->dev_info[ff->dev_count++];
- pj_bzero(info, sizeof(*info));
- pj_ansi_strncpy(info->base.name, "default",
- sizeof(info->base.name));
- pj_ansi_snprintf(info->base.driver, sizeof(info->base.driver),
- "%s (ffmpeg)", p->name);
- info->base.dir = PJMEDIA_DIR_CAPTURE;
- info->base.has_callback = PJ_FALSE;
-
- info->host_api = p;
+ AVFormatContext *ctx;
+ AVCodecContext *codec = NULL;
+ pjmedia_format_id fmt_id;
+ pj_status_t status;
+ unsigned i;
+
+ if ((p->flags & AVFMT_NOFILE)==0 || p->read_probe) {
+ goto next_format;
+ }
+
+ info = &ff->dev_info[ff->dev_count];
+ pj_bzero(info, sizeof(*info));
+ pj_ansi_strncpy(info->base.name, "default",
+ sizeof(info->base.name));
+ pj_ansi_snprintf(info->base.driver, sizeof(info->base.driver),
+ "%s (ffmpeg)", p->name);
+ info->base.dir = PJMEDIA_DIR_CAPTURE;
+ info->base.has_callback = PJ_FALSE;
+
+ info->host_api = p;
#if (defined(PJ_WIN32) && PJ_WIN32!=0) || \
(defined(PJ_WIN64) && PJ_WIN64!=0)
- info->def_devname = "0";
+ info->def_devname = "0";
#elif defined(PJ_LINUX) && PJ_LINUX!=0
- info->def_devname = "/dev/video0";
+ info->def_devname = "/dev/video0";
#endif
- /* Set supported formats, currently hardcoded to RGB24 only */
- info->base.caps = PJMEDIA_VID_DEV_CAP_FORMAT;
- info->base.fmt_cnt = 1;
- for (i = 0; i < info->base.fmt_cnt; ++i) {
- pjmedia_format *fmt = &info->base.fmt[i];
-
- fmt->id = PJMEDIA_FORMAT_RGB24;
- fmt->type = PJMEDIA_TYPE_VIDEO;
- fmt->detail_type = PJMEDIA_FORMAT_DETAIL_NONE;
- }
- }
- p = av_iformat_next(p);
+ ctx = avformat_alloc_context();
+ if (!ctx || avformat_open_input(&ctx, info->def_devname, p, NULL)!=0)
+ goto next_format;
+
+ for(i = 0; i < ctx->nb_streams; i++) {
+ if (ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ codec = ctx->streams[i]->codec;
+ break;
+ }
+ }
+ if (!codec) {
+ av_close_input_stream(ctx);
+ goto next_format;
+ }
+
+ status = PixelFormat_to_pjmedia_format_id(codec->pix_fmt, &fmt_id);
+ if (status != PJ_SUCCESS) {
+ av_close_input_stream(ctx);
+ goto next_format;
+ }
+
+ /* Set supported formats */
+ info->base.caps = PJMEDIA_VID_DEV_CAP_FORMAT;
+ info->base.fmt_cnt = 1;
+ for (i = 0; i < info->base.fmt_cnt; ++i) {
+ pjmedia_format *fmt = &info->base.fmt[i];
+ pjmedia_format_init_video(fmt, fmt_id,
+ codec->width, codec->height, 15, 1);
+ }
+
+ av_close_input_stream(ctx);
+
+ ff->dev_count++;
+
+next_format:
+ p = av_iformat_next(p);
}
return PJ_SUCCESS;