]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/mmaldec.c
Move check_marker() from get_bits to mpeg4videodec
[ffmpeg] / libavcodec / mmaldec.c
index 331a01791083d60e74f742042da09bac8336c57c..193df7e07df1d6d95be720240343628618d03dd9 100644 (file)
@@ -67,6 +67,7 @@ typedef struct FFBufferRef {
 typedef struct MMALDecodeContext {
     AVClass *av_class;
     int extra_buffers;
+    int extra_decoder_buffers;
 
     MMAL_COMPONENT_T *decoder;
     MMAL_QUEUE_T *queue_decoded_frames;
@@ -161,6 +162,9 @@ static void ffmmal_stop_decoder(AVCodecContext *avctx)
 
         ctx->waiting_buffers = buffer->next;
 
+        if (buffer->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
+            avpriv_atomic_int_add_and_fetch(&ctx->packets_buffered, -1);
+
         av_buffer_unref(&buffer->ref);
         av_free(buffer);
     }
@@ -330,6 +334,7 @@ static av_cold int ffmmal_init_decoder(AVCodecContext *avctx)
     MMAL_STATUS_T status;
     MMAL_ES_FORMAT_T *format_in;
     MMAL_COMPONENT_T *decoder;
+    char tmp[32];
     int ret = 0;
 
     bcm_host_init();
@@ -354,12 +359,13 @@ static av_cold int ffmmal_init_decoder(AVCodecContext *avctx)
     switch (avctx->codec_id) {
     case AV_CODEC_ID_MPEG2VIDEO:
         format_in->encoding = MMAL_ENCODING_MP2V;
-        av_log(avctx, AV_LOG_DEBUG, "Use MMAL MP2V encoding\n");
+        break;
+    case AV_CODEC_ID_VC1:
+        format_in->encoding = MMAL_ENCODING_WVC1;
         break;
     case AV_CODEC_ID_H264:
     default:
         format_in->encoding = MMAL_ENCODING_H264;
-        av_log(avctx, AV_LOG_DEBUG, "Use MMAL H264 encoding\n");
         break;
     }
     format_in->es->video.width = FFALIGN(avctx->width, 32);
@@ -372,6 +378,16 @@ static av_cold int ffmmal_init_decoder(AVCodecContext *avctx)
     format_in->es->video.par.den = avctx->sample_aspect_ratio.den;
     format_in->flags = MMAL_ES_FORMAT_FLAG_FRAMED;
 
+    av_get_codec_tag_string(tmp, sizeof(tmp), format_in->encoding);
+    av_log(avctx, AV_LOG_DEBUG, "Using MMAL %s encoding.\n", tmp);
+
+#if HAVE_MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS
+    if (mmal_port_parameter_set_uint32(decoder->input[0], MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS,
+                                       -1 - ctx->extra_decoder_buffers)) {
+        av_log(avctx, AV_LOG_WARNING, "Could not set input buffering limit.\n");
+    }
+#endif
+
     if ((status = mmal_port_format_commit(decoder->input[0])))
         goto fail;
 
@@ -470,6 +486,8 @@ static int ffmmal_add_packet(AVCodecContext *avctx, AVPacket *avpkt,
         if (!is_extradata)
             ctx->packets_sent++;
     } else {
+        if (ctx->eos_sent)
+            goto done;
         if (!ctx->packets_sent) {
             // Short-cut the flush logic to avoid upsetting MMAL.
             ctx->eos_sent = 1;
@@ -639,7 +657,7 @@ static int ffmmal_read_frame(AVCodecContext *avctx, AVFrame *frame, int *got_fra
         // being busy from decoder waiting for input. So just poll at the start and
         // keep feeding new data to the buffer.
         // We are pretty sure the decoder will produce output if we sent more input
-        // frames than what a h264 decoder could logically delay. This avoids too
+        // frames than what a H.264 decoder could logically delay. This avoids too
         // excessive buffering.
         // We also wait if we sent eos, but didn't receive it yet (think of decoding
         // stream with a very low number of frames).
@@ -777,8 +795,16 @@ AVHWAccel ff_mpeg2_mmal_hwaccel = {
     .pix_fmt    = AV_PIX_FMT_MMAL,
 };
 
+AVHWAccel ff_vc1_mmal_hwaccel = {
+    .name       = "vc1_mmal",
+    .type       = AVMEDIA_TYPE_VIDEO,
+    .id         = AV_CODEC_ID_VC1,
+    .pix_fmt    = AV_PIX_FMT_MMAL,
+};
+
 static const AVOption options[]={
     {"extra_buffers", "extra buffers", offsetof(MMALDecodeContext, extra_buffers), AV_OPT_TYPE_INT, {.i64 = 10}, 0, 256, 0},
+    {"extra_decoder_buffers", "extra MMAL internal buffered frames", offsetof(MMALDecodeContext, extra_decoder_buffers), AV_OPT_TYPE_INT, {.i64 = 10}, 0, 256, 0},
     {NULL}
 };
 
@@ -811,3 +837,4 @@ static const AVOption options[]={
 
 FFMMAL_DEC(h264, AV_CODEC_ID_H264)
 FFMMAL_DEC(mpeg2, AV_CODEC_ID_MPEG2VIDEO)
+FFMMAL_DEC(vc1, AV_CODEC_ID_VC1)