Imported Upstream version 6.1
[platform/upstream/ffmpeg.git] / libavcodec / v4l2_m2m_enc.c
index 32321f3..e08db5d 100644 (file)
 #include <linux/videodev2.h>
 #include <sys/ioctl.h>
 #include <search.h>
+#include "encode.h"
 #include "libavcodec/avcodec.h"
-#include "libavcodec/internal.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/pixfmt.h"
 #include "libavutil/opt.h"
+#include "codec_internal.h"
 #include "profiles.h"
 #include "v4l2_context.h"
 #include "v4l2_m2m.h"
@@ -102,17 +103,17 @@ static inline unsigned int v4l2_h264_profile_from_ff(int p)
         unsigned int ffmpeg_val;
         unsigned int v4l2_val;
     } profile[] = {
-        { FF_PROFILE_H264_CONSTRAINED_BASELINE, MPEG_VIDEO(H264_PROFILE_CONSTRAINED_BASELINE) },
-        { FF_PROFILE_H264_HIGH_444_PREDICTIVE, MPEG_VIDEO(H264_PROFILE_HIGH_444_PREDICTIVE) },
-        { FF_PROFILE_H264_HIGH_422_INTRA, MPEG_VIDEO(H264_PROFILE_HIGH_422_INTRA) },
-        { FF_PROFILE_H264_HIGH_444_INTRA, MPEG_VIDEO(H264_PROFILE_HIGH_444_INTRA) },
-        { FF_PROFILE_H264_HIGH_10_INTRA, MPEG_VIDEO(H264_PROFILE_HIGH_10_INTRA) },
-        { FF_PROFILE_H264_HIGH_422, MPEG_VIDEO(H264_PROFILE_HIGH_422) },
-        { FF_PROFILE_H264_BASELINE, MPEG_VIDEO(H264_PROFILE_BASELINE) },
-        { FF_PROFILE_H264_EXTENDED, MPEG_VIDEO(H264_PROFILE_EXTENDED) },
-        { FF_PROFILE_H264_HIGH_10, MPEG_VIDEO(H264_PROFILE_HIGH_10) },
-        { FF_PROFILE_H264_MAIN, MPEG_VIDEO(H264_PROFILE_MAIN) },
-        { FF_PROFILE_H264_HIGH, MPEG_VIDEO(H264_PROFILE_HIGH) },
+        { AV_PROFILE_H264_CONSTRAINED_BASELINE, MPEG_VIDEO(H264_PROFILE_CONSTRAINED_BASELINE) },
+        { AV_PROFILE_H264_HIGH_444_PREDICTIVE, MPEG_VIDEO(H264_PROFILE_HIGH_444_PREDICTIVE) },
+        { AV_PROFILE_H264_HIGH_422_INTRA, MPEG_VIDEO(H264_PROFILE_HIGH_422_INTRA) },
+        { AV_PROFILE_H264_HIGH_444_INTRA, MPEG_VIDEO(H264_PROFILE_HIGH_444_INTRA) },
+        { AV_PROFILE_H264_HIGH_10_INTRA, MPEG_VIDEO(H264_PROFILE_HIGH_10_INTRA) },
+        { AV_PROFILE_H264_HIGH_422, MPEG_VIDEO(H264_PROFILE_HIGH_422) },
+        { AV_PROFILE_H264_BASELINE, MPEG_VIDEO(H264_PROFILE_BASELINE) },
+        { AV_PROFILE_H264_EXTENDED, MPEG_VIDEO(H264_PROFILE_EXTENDED) },
+        { AV_PROFILE_H264_HIGH_10, MPEG_VIDEO(H264_PROFILE_HIGH_10) },
+        { AV_PROFILE_H264_MAIN, MPEG_VIDEO(H264_PROFILE_MAIN) },
+        { AV_PROFILE_H264_HIGH, MPEG_VIDEO(H264_PROFILE_HIGH) },
     };
     int i;
 
@@ -129,11 +130,11 @@ static inline int v4l2_mpeg4_profile_from_ff(int p)
         unsigned int ffmpeg_val;
         unsigned int v4l2_val;
     } profile[] = {
-        { FF_PROFILE_MPEG4_ADVANCED_CODING, MPEG_VIDEO(MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY) },
-        { FF_PROFILE_MPEG4_ADVANCED_SIMPLE, MPEG_VIDEO(MPEG4_PROFILE_ADVANCED_SIMPLE) },
-        { FF_PROFILE_MPEG4_SIMPLE_SCALABLE, MPEG_VIDEO(MPEG4_PROFILE_SIMPLE_SCALABLE) },
-        { FF_PROFILE_MPEG4_SIMPLE, MPEG_VIDEO(MPEG4_PROFILE_SIMPLE) },
-        { FF_PROFILE_MPEG4_CORE, MPEG_VIDEO(MPEG4_PROFILE_CORE) },
+        { AV_PROFILE_MPEG4_ADVANCED_CODING, MPEG_VIDEO(MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY) },
+        { AV_PROFILE_MPEG4_ADVANCED_SIMPLE, MPEG_VIDEO(MPEG4_PROFILE_ADVANCED_SIMPLE) },
+        { AV_PROFILE_MPEG4_SIMPLE_SCALABLE, MPEG_VIDEO(MPEG4_PROFILE_SIMPLE_SCALABLE) },
+        { AV_PROFILE_MPEG4_SIMPLE, MPEG_VIDEO(MPEG4_PROFILE_SIMPLE) },
+        { AV_PROFILE_MPEG4_CORE, MPEG_VIDEO(MPEG4_PROFILE_CORE) },
     };
     int i;
 
@@ -205,7 +206,7 @@ static int v4l2_prepare_encoder(V4L2m2mContext *s)
 
     switch (avctx->codec_id) {
     case AV_CODEC_ID_H264:
-        if (avctx->profile != FF_PROFILE_UNKNOWN) {
+        if (avctx->profile != AV_PROFILE_UNKNOWN) {
             val = v4l2_h264_profile_from_ff(avctx->profile);
             if (val < 0)
                 av_log(avctx, AV_LOG_WARNING, "h264 profile not found\n");
@@ -218,7 +219,7 @@ static int v4l2_prepare_encoder(V4L2m2mContext *s)
         qmax = 51;
         break;
     case AV_CODEC_ID_MPEG4:
-        if (avctx->profile != FF_PROFILE_UNKNOWN) {
+        if (avctx->profile != AV_PROFILE_UNKNOWN) {
             val = v4l2_mpeg4_profile_from_ff(avctx->profile);
             if (val < 0)
                 av_log(avctx, AV_LOG_WARNING, "mpeg4 profile not found\n");
@@ -288,11 +289,28 @@ static int v4l2_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
     V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context;
     V4L2Context *const capture = &s->capture;
     V4L2Context *const output = &s->output;
+    AVFrame *frame = s->frame;
     int ret;
 
     if (s->draining)
         goto dequeue;
 
+    if (!frame->buf[0]) {
+        ret = ff_encode_get_frame(avctx, frame);
+        if (ret < 0 && ret != AVERROR_EOF)
+            return ret;
+
+        if (ret == AVERROR_EOF)
+            frame = NULL;
+    }
+
+    ret = v4l2_send_frame(avctx, frame);
+    if (ret != AVERROR(EAGAIN))
+        av_frame_unref(frame);
+
+    if (ret < 0 && ret != AVERROR(EAGAIN))
+        return ret;
+
     if (!output->streamon) {
         ret = ff_v4l2_context_set_status(output, VIDIOC_STREAMON);
         if (ret) {
@@ -387,7 +405,7 @@ static const AVOption options[] = {
     { NULL },
 };
 
-static const AVCodecDefault v4l2_m2m_defaults[] = {
+static const FFCodecDefault v4l2_m2m_defaults[] = {
     { "qmin", "-1" },
     { "qmax", "-1" },
     { NULL },
@@ -403,20 +421,21 @@ static const AVCodecDefault v4l2_m2m_defaults[] = {
 
 #define M2MENC(NAME, LONGNAME, OPTIONS_NAME, CODEC) \
     M2MENC_CLASS(NAME, OPTIONS_NAME) \
-    AVCodec ff_ ## NAME ## _v4l2m2m_encoder = { \
-        .name           = #NAME "_v4l2m2m" , \
-        .long_name      = NULL_IF_CONFIG_SMALL("V4L2 mem2mem " LONGNAME " encoder wrapper"), \
-        .type           = AVMEDIA_TYPE_VIDEO, \
-        .id             = CODEC , \
+    const FFCodec ff_ ## NAME ## _v4l2m2m_encoder = { \
+        .p.name         = #NAME "_v4l2m2m" , \
+        CODEC_LONG_NAME("V4L2 mem2mem " LONGNAME " encoder wrapper"), \
+        .p.type         = AVMEDIA_TYPE_VIDEO, \
+        .p.id           = CODEC , \
         .priv_data_size = sizeof(V4L2m2mPriv), \
-        .priv_class     = &v4l2_m2m_ ## NAME ##_enc_class, \
+        .p.priv_class   = &v4l2_m2m_ ## NAME ##_enc_class, \
         .init           = v4l2_encode_init, \
-        .send_frame     = v4l2_send_frame, \
-        .receive_packet = v4l2_receive_packet, \
+        FF_CODEC_RECEIVE_PACKET_CB(v4l2_receive_packet), \
         .close          = v4l2_encode_close, \
         .defaults       = v4l2_m2m_defaults, \
-        .capabilities   = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \
-        .wrapper_name   = "v4l2m2m", \
+        .p.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \
+        .caps_internal  = FF_CODEC_CAP_NOT_INIT_THREADSAFE | \
+                          FF_CODEC_CAP_INIT_CLEANUP, \
+        .p.wrapper_name = "v4l2m2m", \
     }
 
 M2MENC(mpeg4,"MPEG4", mpeg4_options, AV_CODEC_ID_MPEG4);