...
|
...
|
@@ -47,6 +47,7 @@
|
47
|
47
|
#include "libavutil/log.h"
|
48
|
48
|
#include "libavutil/opt.h"
|
49
|
49
|
#include "libavutil/parseutils.h"
|
|
50
|
+#include "libavutil/pixdesc.h"
|
50
|
51
|
|
51
|
52
|
static const int desired_video_buffers = 256;
|
52
|
53
|
|
...
|
...
|
@@ -71,6 +72,7 @@ struct video_data {
|
71
|
71
|
char *standard;
|
72
|
72
|
int channel;
|
73
|
73
|
char *video_size; /**< String describing video size, set by a private option. */
|
|
74
|
+ char *pixel_format; /**< Set by a private option. */
|
74
|
75
|
};
|
75
|
76
|
|
76
|
77
|
struct buff_data {
|
...
|
...
|
@@ -544,12 +546,12 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
|
544
|
544
|
}
|
545
|
545
|
|
546
|
546
|
static uint32_t device_try_init(AVFormatContext *s1,
|
547
|
|
- const AVFormatParameters *ap,
|
|
547
|
+ enum PixelFormat pix_fmt,
|
548
|
548
|
int *width,
|
549
|
549
|
int *height,
|
550
|
550
|
enum CodecID *codec_id)
|
551
|
551
|
{
|
552
|
|
- uint32_t desired_format = fmt_ff2v4l(ap->pix_fmt, s1->video_codec_id);
|
|
552
|
+ uint32_t desired_format = fmt_ff2v4l(pix_fmt, s1->video_codec_id);
|
553
|
553
|
|
554
|
554
|
if (desired_format == 0 ||
|
555
|
555
|
device_init(s1, width, height, desired_format) < 0) {
|
...
|
...
|
@@ -582,6 +584,7 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
|
582
|
582
|
int res = 0;
|
583
|
583
|
uint32_t desired_format, capabilities;
|
584
|
584
|
enum CodecID codec_id;
|
|
585
|
+ enum PixelFormat pix_fmt = PIX_FMT_NONE;
|
585
|
586
|
|
586
|
587
|
st = av_new_stream(s1, 0);
|
587
|
588
|
if (!st) {
|
...
|
...
|
@@ -594,11 +597,18 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
|
594
|
594
|
av_log(s1, AV_LOG_ERROR, "Couldn't parse video size.\n");
|
595
|
595
|
goto out;
|
596
|
596
|
}
|
|
597
|
+ if (s->pixel_format && (pix_fmt = av_get_pix_fmt(s->pixel_format)) == PIX_FMT_NONE) {
|
|
598
|
+ av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n", s->pixel_format);
|
|
599
|
+ res = AVERROR(EINVAL);
|
|
600
|
+ goto out;
|
|
601
|
+ }
|
597
|
602
|
#if FF_API_FORMAT_PARAMETERS
|
598
|
603
|
if (ap->width > 0)
|
599
|
604
|
s->width = ap->width;
|
600
|
605
|
if (ap->height > 0)
|
601
|
606
|
s->height = ap->height;
|
|
607
|
+ if (ap->pix_fmt)
|
|
608
|
+ pix_fmt = ap->pix_fmt;
|
602
|
609
|
#endif
|
603
|
610
|
|
604
|
611
|
capabilities = 0;
|
...
|
...
|
@@ -624,7 +634,7 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
|
624
|
624
|
av_log(s1, AV_LOG_VERBOSE, "Setting frame size to %dx%d\n", s->width, s->height);
|
625
|
625
|
}
|
626
|
626
|
|
627
|
|
- desired_format = device_try_init(s1, ap, &s->width, &s->height, &codec_id);
|
|
627
|
+ desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height, &codec_id);
|
628
|
628
|
if (desired_format == 0) {
|
629
|
629
|
av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "
|
630
|
630
|
"codec_id %d, pix_fmt %d.\n", s1->video_codec_id, ap->pix_fmt);
|
...
|
...
|
@@ -670,6 +680,7 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
|
670
|
670
|
|
671
|
671
|
out:
|
672
|
672
|
av_freep(&s->video_size);
|
|
673
|
+ av_freep(&s->pixel_format);
|
673
|
674
|
return res;
|
674
|
675
|
}
|
675
|
676
|
|
...
|
...
|
@@ -719,6 +730,7 @@ static const AVOption options[] = {
|
719
|
719
|
{ "standard", "", offsetof(struct video_data, standard), FF_OPT_TYPE_STRING, {.str = "NTSC" }, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
|
720
|
720
|
{ "channel", "", offsetof(struct video_data, channel), FF_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
|
721
|
721
|
{ "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
|
|
722
|
+ { "pixel_format", "", OFFSET(pixel_format), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
|
722
|
723
|
{ NULL },
|
723
|
724
|
};
|
724
|
725
|
|