• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Android MediaCodec MPEG-2 / H.264 / H.265 / MPEG-4 / VP8 / VP9 decoders
3  *
4  * Copyright (c) 2015-2016 Matthieu Bouron <matthieu.bouron stupeflix.com>
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include <stdint.h>
24 #include <string.h>
25 
26 #include "libavutil/avassert.h"
27 #include "libavutil/common.h"
28 #include "libavutil/opt.h"
29 #include "libavutil/intreadwrite.h"
30 #include "libavutil/pixfmt.h"
31 #include "libavutil/internal.h"
32 
33 #include "avcodec.h"
34 #include "decode.h"
35 #include "h264_parse.h"
36 #include "hevc_parse.h"
37 #include "hwconfig.h"
38 #include "internal.h"
39 #include "mediacodec_wrapper.h"
40 #include "mediacodecdec_common.h"
41 
42 typedef struct MediaCodecH264DecContext {
43 
44     AVClass *avclass;
45 
46     MediaCodecDecContext *ctx;
47 
48     AVPacket buffered_pkt;
49 
50     int delay_flush;
51     int amlogic_mpeg2_api23_workaround;
52 
53 } MediaCodecH264DecContext;
54 
mediacodec_decode_close(AVCodecContext * avctx)55 static av_cold int mediacodec_decode_close(AVCodecContext *avctx)
56 {
57     MediaCodecH264DecContext *s = avctx->priv_data;
58 
59     ff_mediacodec_dec_close(avctx, s->ctx);
60     s->ctx = NULL;
61 
62     av_packet_unref(&s->buffered_pkt);
63 
64     return 0;
65 }
66 
67 #if CONFIG_H264_MEDIACODEC_DECODER || CONFIG_HEVC_MEDIACODEC_DECODER
h2645_ps_to_nalu(const uint8_t * src,int src_size,uint8_t ** out,int * out_size)68 static int h2645_ps_to_nalu(const uint8_t *src, int src_size, uint8_t **out, int *out_size)
69 {
70     int i;
71     int ret = 0;
72     uint8_t *p = NULL;
73     static const uint8_t nalu_header[] = { 0x00, 0x00, 0x00, 0x01 };
74 
75     if (!out || !out_size) {
76         return AVERROR(EINVAL);
77     }
78 
79     p = av_malloc(sizeof(nalu_header) + src_size);
80     if (!p) {
81         return AVERROR(ENOMEM);
82     }
83 
84     *out = p;
85     *out_size = sizeof(nalu_header) + src_size;
86 
87     memcpy(p, nalu_header, sizeof(nalu_header));
88     memcpy(p + sizeof(nalu_header), src, src_size);
89 
90     /* Escape 0x00, 0x00, 0x0{0-3} pattern */
91     for (i = 4; i < *out_size; i++) {
92         if (i < *out_size - 3 &&
93             p[i + 0] == 0 &&
94             p[i + 1] == 0 &&
95             p[i + 2] <= 3) {
96             uint8_t *new;
97 
98             *out_size += 1;
99             new = av_realloc(*out, *out_size);
100             if (!new) {
101                 ret = AVERROR(ENOMEM);
102                 goto done;
103             }
104             *out = p = new;
105 
106             i = i + 2;
107             memmove(p + i + 1, p + i, *out_size - (i + 1));
108             p[i] = 0x03;
109         }
110     }
111 done:
112     if (ret < 0) {
113         av_freep(out);
114         *out_size = 0;
115     }
116 
117     return ret;
118 }
119 #endif
120 
121 #if CONFIG_H264_MEDIACODEC_DECODER
h264_set_extradata(AVCodecContext * avctx,FFAMediaFormat * format)122 static int h264_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
123 {
124     int i;
125     int ret;
126 
127     H264ParamSets ps;
128     const PPS *pps = NULL;
129     const SPS *sps = NULL;
130     int is_avc = 0;
131     int nal_length_size = 0;
132 
133     memset(&ps, 0, sizeof(ps));
134 
135     ret = ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size,
136                                    &ps, &is_avc, &nal_length_size, 0, avctx);
137     if (ret < 0) {
138         goto done;
139     }
140 
141     for (i = 0; i < MAX_PPS_COUNT; i++) {
142         if (ps.pps_list[i]) {
143             pps = (const PPS*)ps.pps_list[i]->data;
144             break;
145         }
146     }
147 
148     if (pps) {
149         if (ps.sps_list[pps->sps_id]) {
150             sps = (const SPS*)ps.sps_list[pps->sps_id]->data;
151         }
152     }
153 
154     if (pps && sps) {
155         uint8_t *data = NULL;
156         int data_size = 0;
157 
158         if ((ret = h2645_ps_to_nalu(sps->data, sps->data_size, &data, &data_size)) < 0) {
159             goto done;
160         }
161         ff_AMediaFormat_setBuffer(format, "csd-0", (void*)data, data_size);
162         av_freep(&data);
163 
164         if ((ret = h2645_ps_to_nalu(pps->data, pps->data_size, &data, &data_size)) < 0) {
165             goto done;
166         }
167         ff_AMediaFormat_setBuffer(format, "csd-1", (void*)data, data_size);
168         av_freep(&data);
169     } else {
170         const int warn = is_avc && (avctx->codec_tag == MKTAG('a','v','c','1') ||
171                                     avctx->codec_tag == MKTAG('a','v','c','2'));
172         av_log(avctx, warn ? AV_LOG_WARNING : AV_LOG_DEBUG,
173                "Could not extract PPS/SPS from extradata\n");
174         ret = 0;
175     }
176 
177 done:
178     ff_h264_ps_uninit(&ps);
179 
180     return ret;
181 }
182 #endif
183 
184 #if CONFIG_HEVC_MEDIACODEC_DECODER
hevc_set_extradata(AVCodecContext * avctx,FFAMediaFormat * format)185 static int hevc_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
186 {
187     int i;
188     int ret;
189 
190     HEVCParamSets ps;
191     HEVCSEI sei;
192 
193     const HEVCVPS *vps = NULL;
194     const HEVCPPS *pps = NULL;
195     const HEVCSPS *sps = NULL;
196     int is_nalff = 0;
197     int nal_length_size = 0;
198 
199     uint8_t *vps_data = NULL;
200     uint8_t *sps_data = NULL;
201     uint8_t *pps_data = NULL;
202     int vps_data_size = 0;
203     int sps_data_size = 0;
204     int pps_data_size = 0;
205 
206     memset(&ps, 0, sizeof(ps));
207     memset(&sei, 0, sizeof(sei));
208 
209     ret = ff_hevc_decode_extradata(avctx->extradata, avctx->extradata_size,
210                                    &ps, &sei, &is_nalff, &nal_length_size, 0, 1, avctx);
211     if (ret < 0) {
212         goto done;
213     }
214 
215     for (i = 0; i < HEVC_MAX_VPS_COUNT; i++) {
216         if (ps.vps_list[i]) {
217             vps = (const HEVCVPS*)ps.vps_list[i]->data;
218             break;
219         }
220     }
221 
222     for (i = 0; i < HEVC_MAX_PPS_COUNT; i++) {
223         if (ps.pps_list[i]) {
224             pps = (const HEVCPPS*)ps.pps_list[i]->data;
225             break;
226         }
227     }
228 
229     if (pps) {
230         if (ps.sps_list[pps->sps_id]) {
231             sps = (const HEVCSPS*)ps.sps_list[pps->sps_id]->data;
232         }
233     }
234 
235     if (vps && pps && sps) {
236         uint8_t *data;
237         int data_size;
238 
239         if ((ret = h2645_ps_to_nalu(vps->data, vps->data_size, &vps_data, &vps_data_size)) < 0 ||
240             (ret = h2645_ps_to_nalu(sps->data, sps->data_size, &sps_data, &sps_data_size)) < 0 ||
241             (ret = h2645_ps_to_nalu(pps->data, pps->data_size, &pps_data, &pps_data_size)) < 0) {
242             goto done;
243         }
244 
245         data_size = vps_data_size + sps_data_size + pps_data_size;
246         data = av_mallocz(data_size);
247         if (!data) {
248             ret = AVERROR(ENOMEM);
249             goto done;
250         }
251 
252         memcpy(data                                , vps_data, vps_data_size);
253         memcpy(data + vps_data_size                , sps_data, sps_data_size);
254         memcpy(data + vps_data_size + sps_data_size, pps_data, pps_data_size);
255 
256         ff_AMediaFormat_setBuffer(format, "csd-0", data, data_size);
257 
258         av_freep(&data);
259     } else {
260         const int warn = is_nalff && avctx->codec_tag == MKTAG('h','v','c','1');
261         av_log(avctx, warn ? AV_LOG_WARNING : AV_LOG_DEBUG,
262                "Could not extract VPS/PPS/SPS from extradata\n");
263         ret = 0;
264     }
265 
266 done:
267     ff_hevc_ps_uninit(&ps);
268 
269     av_freep(&vps_data);
270     av_freep(&sps_data);
271     av_freep(&pps_data);
272 
273     return ret;
274 }
275 #endif
276 
277 #if CONFIG_MPEG2_MEDIACODEC_DECODER || \
278     CONFIG_MPEG4_MEDIACODEC_DECODER || \
279     CONFIG_VP8_MEDIACODEC_DECODER   || \
280     CONFIG_VP9_MEDIACODEC_DECODER
common_set_extradata(AVCodecContext * avctx,FFAMediaFormat * format)281 static int common_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
282 {
283     int ret = 0;
284 
285     if (avctx->extradata) {
286         ff_AMediaFormat_setBuffer(format, "csd-0", avctx->extradata, avctx->extradata_size);
287     }
288 
289     return ret;
290 }
291 #endif
292 
mediacodec_decode_init(AVCodecContext * avctx)293 static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
294 {
295     int ret;
296     int sdk_int;
297 
298     const char *codec_mime = NULL;
299 
300     FFAMediaFormat *format = NULL;
301     MediaCodecH264DecContext *s = avctx->priv_data;
302 
303     format = ff_AMediaFormat_new();
304     if (!format) {
305         av_log(avctx, AV_LOG_ERROR, "Failed to create media format\n");
306         ret = AVERROR_EXTERNAL;
307         goto done;
308     }
309 
310     switch (avctx->codec_id) {
311 #if CONFIG_H264_MEDIACODEC_DECODER
312     case AV_CODEC_ID_H264:
313         codec_mime = "video/avc";
314 
315         ret = h264_set_extradata(avctx, format);
316         if (ret < 0)
317             goto done;
318         break;
319 #endif
320 #if CONFIG_HEVC_MEDIACODEC_DECODER
321     case AV_CODEC_ID_HEVC:
322         codec_mime = "video/hevc";
323 
324         ret = hevc_set_extradata(avctx, format);
325         if (ret < 0)
326             goto done;
327         break;
328 #endif
329 #if CONFIG_MPEG2_MEDIACODEC_DECODER
330     case AV_CODEC_ID_MPEG2VIDEO:
331         codec_mime = "video/mpeg2";
332 
333         ret = common_set_extradata(avctx, format);
334         if (ret < 0)
335             goto done;
336         break;
337 #endif
338 #if CONFIG_MPEG4_MEDIACODEC_DECODER
339     case AV_CODEC_ID_MPEG4:
340         codec_mime = "video/mp4v-es",
341 
342         ret = common_set_extradata(avctx, format);
343         if (ret < 0)
344             goto done;
345         break;
346 #endif
347 #if CONFIG_VP8_MEDIACODEC_DECODER
348     case AV_CODEC_ID_VP8:
349         codec_mime = "video/x-vnd.on2.vp8";
350 
351         ret = common_set_extradata(avctx, format);
352         if (ret < 0)
353             goto done;
354         break;
355 #endif
356 #if CONFIG_VP9_MEDIACODEC_DECODER
357     case AV_CODEC_ID_VP9:
358         codec_mime = "video/x-vnd.on2.vp9";
359 
360         ret = common_set_extradata(avctx, format);
361         if (ret < 0)
362             goto done;
363         break;
364 #endif
365     default:
366         av_assert0(0);
367     }
368 
369     ff_AMediaFormat_setString(format, "mime", codec_mime);
370     ff_AMediaFormat_setInt32(format, "width", avctx->width);
371     ff_AMediaFormat_setInt32(format, "height", avctx->height);
372 
373     s->ctx = av_mallocz(sizeof(*s->ctx));
374     if (!s->ctx) {
375         av_log(avctx, AV_LOG_ERROR, "Failed to allocate MediaCodecDecContext\n");
376         ret = AVERROR(ENOMEM);
377         goto done;
378     }
379 
380     s->ctx->delay_flush = s->delay_flush;
381 
382     if ((ret = ff_mediacodec_dec_init(avctx, s->ctx, codec_mime, format)) < 0) {
383         s->ctx = NULL;
384         goto done;
385     }
386 
387     av_log(avctx, AV_LOG_INFO,
388            "MediaCodec started successfully: codec = %s, ret = %d\n",
389            s->ctx->codec_name, ret);
390 
391     sdk_int = ff_Build_SDK_INT(avctx);
392     if (sdk_int <= 23 &&
393         strcmp(s->ctx->codec_name, "OMX.amlogic.mpeg2.decoder.awesome") == 0) {
394         av_log(avctx, AV_LOG_INFO, "Enabling workaround for %s on API=%d\n",
395                s->ctx->codec_name, sdk_int);
396         s->amlogic_mpeg2_api23_workaround = 1;
397     }
398 
399 done:
400     if (format) {
401         ff_AMediaFormat_delete(format);
402     }
403 
404     if (ret < 0) {
405         mediacodec_decode_close(avctx);
406     }
407 
408     return ret;
409 }
410 
mediacodec_receive_frame(AVCodecContext * avctx,AVFrame * frame)411 static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
412 {
413     MediaCodecH264DecContext *s = avctx->priv_data;
414     int ret;
415     ssize_t index;
416 
417     /* In delay_flush mode, wait until the user has released or rendered
418        all retained frames. */
419     if (s->delay_flush && ff_mediacodec_dec_is_flushing(avctx, s->ctx)) {
420         if (!ff_mediacodec_dec_flush(avctx, s->ctx)) {
421             return AVERROR(EAGAIN);
422         }
423     }
424 
425     /* poll for new frame */
426     ret = ff_mediacodec_dec_receive(avctx, s->ctx, frame, false);
427     if (ret != AVERROR(EAGAIN))
428         return ret;
429 
430     /* feed decoder */
431     while (1) {
432         if (s->ctx->current_input_buffer < 0) {
433             /* poll for input space */
434             index = ff_AMediaCodec_dequeueInputBuffer(s->ctx->codec, 0);
435             if (index < 0) {
436                 /* no space, block for an output frame to appear */
437                 return ff_mediacodec_dec_receive(avctx, s->ctx, frame, true);
438             }
439             s->ctx->current_input_buffer = index;
440         }
441 
442         /* try to flush any buffered packet data */
443         if (s->buffered_pkt.size > 0) {
444             ret = ff_mediacodec_dec_send(avctx, s->ctx, &s->buffered_pkt, false);
445             if (ret >= 0) {
446                 s->buffered_pkt.size -= ret;
447                 s->buffered_pkt.data += ret;
448                 if (s->buffered_pkt.size <= 0) {
449                     av_packet_unref(&s->buffered_pkt);
450                 } else {
451                     av_log(avctx, AV_LOG_WARNING,
452                            "could not send entire packet in single input buffer (%d < %d)\n",
453                            ret, s->buffered_pkt.size+ret);
454                 }
455             } else if (ret < 0 && ret != AVERROR(EAGAIN)) {
456                 return ret;
457             }
458 
459             if (s->amlogic_mpeg2_api23_workaround && s->buffered_pkt.size <= 0) {
460                 /* fallthrough to fetch next packet regardless of input buffer space */
461             } else {
462                 /* poll for space again */
463                 continue;
464             }
465         }
466 
467         /* fetch new packet or eof */
468         ret = ff_decode_get_packet(avctx, &s->buffered_pkt);
469         if (ret == AVERROR_EOF) {
470             AVPacket null_pkt = { 0 };
471             ret = ff_mediacodec_dec_send(avctx, s->ctx, &null_pkt, true);
472             if (ret < 0)
473                 return ret;
474             return ff_mediacodec_dec_receive(avctx, s->ctx, frame, true);
475         } else if (ret == AVERROR(EAGAIN) && s->ctx->current_input_buffer < 0) {
476             return ff_mediacodec_dec_receive(avctx, s->ctx, frame, true);
477         } else if (ret < 0) {
478             return ret;
479         }
480     }
481 
482     return AVERROR(EAGAIN);
483 }
484 
mediacodec_decode_flush(AVCodecContext * avctx)485 static void mediacodec_decode_flush(AVCodecContext *avctx)
486 {
487     MediaCodecH264DecContext *s = avctx->priv_data;
488 
489     av_packet_unref(&s->buffered_pkt);
490 
491     ff_mediacodec_dec_flush(avctx, s->ctx);
492 }
493 
494 static const AVCodecHWConfigInternal *const mediacodec_hw_configs[] = {
495     &(const AVCodecHWConfigInternal) {
496         .public          = {
497             .pix_fmt     = AV_PIX_FMT_MEDIACODEC,
498             .methods     = AV_CODEC_HW_CONFIG_METHOD_AD_HOC |
499                            AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX,
500             .device_type = AV_HWDEVICE_TYPE_MEDIACODEC,
501         },
502         .hwaccel         = NULL,
503     },
504     NULL
505 };
506 
507 #define OFFSET(x) offsetof(MediaCodecH264DecContext, x)
508 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
509 static const AVOption ff_mediacodec_vdec_options[] = {
510     { "delay_flush", "Delay flush until hw output buffers are returned to the decoder",
511                      OFFSET(delay_flush), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VD },
512     { NULL }
513 };
514 
515 #define DECLARE_MEDIACODEC_VCLASS(short_name)                   \
516 static const AVClass ff_##short_name##_mediacodec_dec_class = { \
517     .class_name = #short_name "_mediacodec",                    \
518     .item_name  = av_default_item_name,                         \
519     .option     = ff_mediacodec_vdec_options,                   \
520     .version    = LIBAVUTIL_VERSION_INT,                        \
521 };
522 
523 #define DECLARE_MEDIACODEC_VDEC(short_name, full_name, codec_id, bsf)                          \
524 DECLARE_MEDIACODEC_VCLASS(short_name)                                                          \
525 AVCodec ff_##short_name##_mediacodec_decoder = {                                               \
526     .name           = #short_name "_mediacodec",                                               \
527     .long_name      = NULL_IF_CONFIG_SMALL(full_name " Android MediaCodec decoder"),           \
528     .type           = AVMEDIA_TYPE_VIDEO,                                                      \
529     .id             = codec_id,                                                                \
530     .priv_class     = &ff_##short_name##_mediacodec_dec_class,                                 \
531     .priv_data_size = sizeof(MediaCodecH264DecContext),                                        \
532     .init           = mediacodec_decode_init,                                                  \
533     .receive_frame  = mediacodec_receive_frame,                                                \
534     .flush          = mediacodec_decode_flush,                                                 \
535     .close          = mediacodec_decode_close,                                                 \
536     .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
537     .caps_internal  = FF_CODEC_CAP_SETS_PKT_DTS,                                               \
538     .bsfs           = bsf,                                                                     \
539     .hw_configs     = mediacodec_hw_configs,                                                   \
540     .wrapper_name   = "mediacodec",                                                            \
541 };                                                                                             \
542 
543 #if CONFIG_H264_MEDIACODEC_DECODER
544 DECLARE_MEDIACODEC_VDEC(h264, "H.264", AV_CODEC_ID_H264, "h264_mp4toannexb")
545 #endif
546 
547 #if CONFIG_HEVC_MEDIACODEC_DECODER
548 DECLARE_MEDIACODEC_VDEC(hevc, "H.265", AV_CODEC_ID_HEVC, "hevc_mp4toannexb")
549 #endif
550 
551 #if CONFIG_MPEG2_MEDIACODEC_DECODER
552 DECLARE_MEDIACODEC_VDEC(mpeg2, "MPEG-2", AV_CODEC_ID_MPEG2VIDEO, NULL)
553 #endif
554 
555 #if CONFIG_MPEG4_MEDIACODEC_DECODER
556 DECLARE_MEDIACODEC_VDEC(mpeg4, "MPEG-4", AV_CODEC_ID_MPEG4, NULL)
557 #endif
558 
559 #if CONFIG_VP8_MEDIACODEC_DECODER
560 DECLARE_MEDIACODEC_VDEC(vp8, "VP8", AV_CODEC_ID_VP8, NULL)
561 #endif
562 
563 #if CONFIG_VP9_MEDIACODEC_DECODER
564 DECLARE_MEDIACODEC_VDEC(vp9, "VP9", AV_CODEC_ID_VP9, NULL)
565 #endif
566