configure: fix build
[ffmpeg.git] / libavdevice / fbdev_enc.c
index be93093..4191596 100644 (file)
@@ -28,6 +28,8 @@
 #include "libavutil/mem.h"
 #include "libavutil/opt.h"
 #include "libavformat/avformat.h"
+#include "fbdev_common.h"
+#include "avdevice.h"
 
 typedef struct {
     AVClass *class;                   ///< class for private options
@@ -36,71 +38,31 @@ typedef struct {
     struct fb_var_screeninfo varinfo; ///< framebuffer variable info
     struct fb_fix_screeninfo fixinfo; ///< framebuffer fixed info
     int fd;                           ///< framebuffer device file descriptor
-    int index;                        ///< index of a video stream
     uint8_t *data;                    ///< framebuffer data
 } FBDevContext;
 
-struct rgb_pixfmt_map_entry {
-    int bits_per_pixel;
-    int red_offset, green_offset, blue_offset, alpha_offset;
-    enum AVPixelFormat pixfmt;
-};
-
-static const struct rgb_pixfmt_map_entry rgb_pixfmt_map[] = {
-    // bpp, red_offset,  green_offset, blue_offset, alpha_offset, pixfmt
-    {  32,       0,           8,          16,           24,   AV_PIX_FMT_RGBA  },
-    {  32,      16,           8,           0,           24,   AV_PIX_FMT_BGRA  },
-    {  32,       8,          16,          24,            0,   AV_PIX_FMT_ARGB  },
-    {  32,       3,           2,           8,            0,   AV_PIX_FMT_ABGR  },
-    {  24,       0,           8,          16,            0,   AV_PIX_FMT_RGB24 },
-    {  24,      16,           8,           0,            0,   AV_PIX_FMT_BGR24 },
-    {  16,      11,           5,           0,           16,   AV_PIX_FMT_RGB565 },
-};
-
-static enum AVPixelFormat get_pixfmt_from_fb_varinfo(struct fb_var_screeninfo *varinfo)
-{
-    int i;
-
-    for (i = 0; i < FF_ARRAY_ELEMS(rgb_pixfmt_map); i++) {
-        const struct rgb_pixfmt_map_entry *entry = &rgb_pixfmt_map[i];
-        if (entry->bits_per_pixel == varinfo->bits_per_pixel &&
-            entry->red_offset     == varinfo->red.offset     &&
-            entry->green_offset   == varinfo->green.offset   &&
-            entry->blue_offset    == varinfo->blue.offset)
-            return entry->pixfmt;
-    }
-
-    return AV_PIX_FMT_NONE;
-}
-
 static av_cold int fbdev_write_header(AVFormatContext *h)
 {
     FBDevContext *fbdev = h->priv_data;
     enum AVPixelFormat pix_fmt;
-    AVStream *st = NULL;
     int ret, flags = O_RDWR;
+    const char* device;
 
-    for (int i = 0; i < h->nb_streams; i++) {
-        if (h->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
-            if (!st) {
-                fbdev->index = i;
-                st = h->streams[i];
-            } else {
-                av_log(h, AV_LOG_WARNING, "More than one video stream found. First one is used.\n");
-                break;
-            }
-        }
-    }
-    if (!st) {
-        av_log(h, AV_LOG_ERROR, "No video stream found.\n");
+    if (h->nb_streams != 1 || h->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) {
+        av_log(fbdev, AV_LOG_ERROR, "Only a single video stream is supported.\n");
         return AVERROR(EINVAL);
     }
 
-    if ((fbdev->fd = avpriv_open(h->filename, flags)) == -1) {
+    if (h->url[0])
+        device = h->url;
+    else
+        device = ff_fbdev_default_device();
+
+    if ((fbdev->fd = avpriv_open(device, flags)) == -1) {
         ret = AVERROR(errno);
         av_log(h, AV_LOG_ERROR,
                "Could not open framebuffer device '%s': %s\n",
-               h->filename, av_err2str(ret));
+               device, av_err2str(ret));
         return ret;
     }
 
@@ -116,7 +78,7 @@ static av_cold int fbdev_write_header(AVFormatContext *h)
         goto fail;
     }
 
-    pix_fmt = get_pixfmt_from_fb_varinfo(&fbdev->varinfo);
+    pix_fmt = ff_get_pixfmt_from_fb_varinfo(&fbdev->varinfo);
     if (pix_fmt == AV_PIX_FMT_NONE) {
         ret = AVERROR(EINVAL);
         av_log(h, AV_LOG_ERROR, "Framebuffer pixel format not supported.\n");
@@ -143,21 +105,19 @@ static int fbdev_write_packet(AVFormatContext *h, AVPacket *pkt)
     enum AVPixelFormat fb_pix_fmt;
     int disp_height;
     int bytes_to_copy;
-    AVCodecContext *codec_ctx = h->streams[fbdev->index]->codec;
-    enum AVPixelFormat video_pix_fmt = codec_ctx->pix_fmt;
-    int video_width = codec_ctx->width;
-    int video_height = codec_ctx->height;
-    int bytes_per_pixel = ((codec_ctx->bits_per_coded_sample + 7) >> 3);
+    AVCodecParameters *par = h->streams[0]->codecpar;
+    enum AVPixelFormat video_pix_fmt = par->format;
+    int video_width = par->width;
+    int video_height = par->height;
+    int bytes_per_pixel = ((par->bits_per_coded_sample + 7) >> 3);
     int src_line_size = video_width * bytes_per_pixel;
-
-    if (fbdev->index != pkt->stream_index)
-        return 0;
+    int i;
 
     if (ioctl(fbdev->fd, FBIOGET_VSCREENINFO, &fbdev->varinfo) < 0)
         av_log(h, AV_LOG_WARNING,
                "Error refreshing variable info: %s\n", av_err2str(AVERROR(errno)));
 
-    fb_pix_fmt = get_pixfmt_from_fb_varinfo(&fbdev->varinfo);
+    fb_pix_fmt = ff_get_pixfmt_from_fb_varinfo(&fbdev->varinfo);
 
     if (fb_pix_fmt != video_pix_fmt) {
         av_log(h, AV_LOG_ERROR, "Pixel format %s is not supported, use %s\n",
@@ -207,7 +167,7 @@ static int fbdev_write_packet(AVFormatContext *h, AVPacket *pkt)
         }
     }
 
-    for (int i = 0; i < disp_height; i++) {
+    for (i = 0; i < disp_height; i++) {
         memcpy(pout, pin, bytes_to_copy);
         pout += fbdev->fixinfo.line_length;
         pin  += src_line_size;
@@ -224,6 +184,11 @@ static av_cold int fbdev_write_trailer(AVFormatContext *h)
     return 0;
 }
 
+static int fbdev_get_device_list(AVFormatContext *s, AVDeviceInfoList *device_list)
+{
+    return ff_fbdev_get_device_list(device_list);
+}
+
 #define OFFSET(x) offsetof(FBDevContext, x)
 #define ENC AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
@@ -237,6 +202,7 @@ static const AVClass fbdev_class = {
     .item_name  = av_default_item_name,
     .option     = options,
     .version    = LIBAVUTIL_VERSION_INT,
+    .category   = AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT,
 };
 
 AVOutputFormat ff_fbdev_muxer = {
@@ -248,6 +214,7 @@ AVOutputFormat ff_fbdev_muxer = {
     .write_header   = fbdev_write_header,
     .write_packet   = fbdev_write_packet,
     .write_trailer  = fbdev_write_trailer,
+    .get_device_list = fbdev_get_device_list,
     .flags          = AVFMT_NOFILE | AVFMT_VARIABLE_FPS | AVFMT_NOTIMESTAMPS,
     .priv_class     = &fbdev_class,
 };