Browse code

v4l2: add a pixel_format private option.

Anton Khirnov authored on 2011/05/24 16:02:11
Showing 1 changed files
... ...
@@ -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