FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mediacodecdec_h264.c
Go to the documentation of this file.
1 /*
2  * Android MediaCodec H.264 decoder
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/fifo.h"
29 #include "libavutil/opt.h"
30 #include "libavutil/intreadwrite.h"
31 #include "libavutil/pixfmt.h"
32 #include "libavutil/atomic.h"
33 
34 #include "avcodec.h"
35 #include "h264.h"
36 #include "internal.h"
37 #include "mediacodecdec.h"
38 #include "mediacodec_wrapper.h"
39 
40 #define CODEC_MIME "video/avc"
41 
42 typedef struct MediaCodecH264DecContext {
43 
45 
47 
49 
51 
53 
55 {
57 
58  ff_mediacodec_dec_close(avctx, &s->ctx);
59 
60  av_fifo_free(s->fifo);
61 
62  av_bsf_free(&s->bsf);
64 
65  return 0;
66 }
67 
69 {
70  int i;
71  int ret;
72 
73  H264ParamSets ps;
74  const PPS *pps = NULL;
75  const SPS *sps = NULL;
76  int is_avc = 0;
77  int nal_length_size = 0;
78 
81 
82  memset(&ps, 0, sizeof(ps));
83 
84  format = ff_AMediaFormat_new();
85  if (!format) {
86  av_log(avctx, AV_LOG_ERROR, "Failed to create media format\n");
87  ret = AVERROR_EXTERNAL;
88  goto done;
89  }
90 
91  ff_AMediaFormat_setString(format, "mime", CODEC_MIME);
92  ff_AMediaFormat_setInt32(format, "width", avctx->width);
93  ff_AMediaFormat_setInt32(format, "height", avctx->height);
94 
96  &ps, &is_avc, &nal_length_size, 0, avctx);
97  if (ret < 0) {
98  goto done;
99  }
100 
101  for (i = 0; i < MAX_PPS_COUNT; i++) {
102  if (ps.pps_list[i]) {
103  pps = (const PPS*)ps.pps_list[i]->data;
104  break;
105  }
106  }
107 
108  if (pps) {
109  if (ps.sps_list[pps->sps_id]) {
110  sps = (const SPS*)ps.sps_list[pps->sps_id]->data;
111  }
112  }
113 
114  if (pps && sps) {
115  ff_AMediaFormat_setBuffer(format, "csd-0", (void*)sps->data, sps->data_size);
116  ff_AMediaFormat_setBuffer(format, "csd-1", (void*)pps->data, pps->data_size);
117  } else {
118  av_log(avctx, AV_LOG_ERROR, "Could not extract PPS/SPS from extradata");
119  ret = AVERROR_INVALIDDATA;
120  goto done;
121  }
122 
123  if ((ret = ff_mediacodec_dec_init(avctx, &s->ctx, CODEC_MIME, format)) < 0) {
124  goto done;
125  }
126 
127  av_log(avctx, AV_LOG_INFO, "MediaCodec started successfully, ret = %d\n", ret);
128 
129  s->fifo = av_fifo_alloc(sizeof(AVPacket));
130  if (!s->fifo) {
131  ret = AVERROR(ENOMEM);
132  goto done;
133  }
134 
135  const AVBitStreamFilter *bsf = av_bsf_get_by_name("h264_mp4toannexb");
136  if(!bsf) {
137  ret = AVERROR_BSF_NOT_FOUND;
138  goto done;
139  }
140 
141  if ((ret = av_bsf_alloc(bsf, &s->bsf))) {
142  goto done;
143  }
144 
145  if (((ret = avcodec_parameters_from_context(s->bsf->par_in, avctx)) < 0) ||
146  ((ret = av_bsf_init(s->bsf)) < 0)) {
147  goto done;
148  }
149 
151 
152 done:
153  if (format) {
154  ff_AMediaFormat_delete(format);
155  }
156 
157  if (ret < 0) {
159  }
160 
161  ff_h264_ps_uninit(&ps);
162 
163  return ret;
164 }
165 
166 
168  int *got_frame, AVPacket *pkt)
169 {
171 
172  return ff_mediacodec_dec_decode(avctx, &s->ctx, frame, got_frame, pkt);
173 }
174 
175 static int mediacodec_decode_frame(AVCodecContext *avctx, void *data,
176  int *got_frame, AVPacket *avpkt)
177 {
179  AVFrame *frame = data;
180  int ret;
181 
182  /* buffer the input packet */
183  if (avpkt->size) {
184  AVPacket input_pkt = { 0 };
185 
186  if (av_fifo_space(s->fifo) < sizeof(input_pkt)) {
187  ret = av_fifo_realloc2(s->fifo,
188  av_fifo_size(s->fifo) + sizeof(input_pkt));
189  if (ret < 0)
190  return ret;
191  }
192 
193  ret = av_packet_ref(&input_pkt, avpkt);
194  if (ret < 0)
195  return ret;
196  av_fifo_generic_write(s->fifo, &input_pkt, sizeof(input_pkt), NULL);
197  }
198 
199  /* process buffered data */
200  while (!*got_frame) {
201  /* prepare the input data -- convert to Annex B if needed */
202  if (s->filtered_pkt.size <= 0) {
203  AVPacket input_pkt = { 0 };
204 
206 
207  /* no more data */
208  if (av_fifo_size(s->fifo) < sizeof(AVPacket)) {
209  return avpkt->size ? avpkt->size :
210  ff_mediacodec_dec_decode(avctx, &s->ctx, frame, got_frame, avpkt);
211  }
212 
213  av_fifo_generic_read(s->fifo, &input_pkt, sizeof(input_pkt), NULL);
214 
215  ret = av_bsf_send_packet(s->bsf, &input_pkt);
216  if (ret < 0) {
217  return ret;
218  }
219 
220  ret = av_bsf_receive_packet(s->bsf, &s->filtered_pkt);
221  if (ret == AVERROR(EAGAIN)) {
222  goto done;
223  }
224 
225  /* h264_mp4toannexb is used here and does not requires flushing */
226  av_assert0(ret != AVERROR_EOF);
227 
228  if (ret < 0) {
229  return ret;
230  }
231  }
232 
233  ret = mediacodec_process_data(avctx, frame, got_frame, &s->filtered_pkt);
234  if (ret < 0)
235  return ret;
236 
237  s->filtered_pkt.size -= ret;
238  s->filtered_pkt.data += ret;
239  }
240 done:
241  return avpkt->size;
242 }
243 
245 {
247 
248  while (av_fifo_size(s->fifo)) {
249  AVPacket pkt;
250  av_fifo_generic_read(s->fifo, &pkt, sizeof(pkt), NULL);
251  av_packet_unref(&pkt);
252  }
253  av_fifo_reset(s->fifo);
254 
256 
257  ff_mediacodec_dec_flush(avctx, &s->ctx);
258 }
259 
261  .name = "h264_mediacodec",
262  .long_name = NULL_IF_CONFIG_SMALL("H.264 Android MediaCodec decoder"),
263  .type = AVMEDIA_TYPE_VIDEO,
264  .id = AV_CODEC_ID_H264,
265  .priv_data_size = sizeof(MediaCodecH264DecContext),
269  .close = mediacodec_decode_close,
270  .capabilities = CODEC_CAP_DELAY,
271  .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS,
272 };
void av_bsf_free(AVBSFContext **ctx)
Free a bitstream filter context and everything associated with it; write NULL into the supplied point...
Definition: bsf.c:33
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:631
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
This structure describes decoded (raw) audio or video data.
Definition: frame.h:184
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
static void flush(AVCodecContext *avctx)
AVBufferRef * sps_list[MAX_SPS_COUNT]
Definition: h264.h:230
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
#define MAX_PPS_COUNT
Definition: h264.h:54
Sequence parameter set.
Definition: h264.h:136
The bitstream filter state.
Definition: avcodec.h:5677
int size
Definition: avcodec.h:1581
void ff_AMediaFormat_setBuffer(FFAMediaFormat *format, const char *name, void *data, size_t size)
const AVBitStreamFilter * av_bsf_get_by_name(const char *name)
Picture parameter set.
Definition: h264.h:200
#define CODEC_MIME
static AVPacket pkt
AVCodec.
Definition: avcodec.h:3542
int av_bsf_init(AVBSFContext *ctx)
Prepare the filter for use, after all the parameters and options have been set.
Definition: bsf.c:132
int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int(*func)(void *, void *, int))
Feed data from a user-supplied callback to an AVFifoBuffer.
Definition: fifo.c:122
int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **ctx)
Allocate a context for a given bitstream filter.
Definition: bsf.c:79
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
Retrieve a filtered packet.
Definition: bsf.c:194
#define av_cold
Definition: attributes.h:82
AVOptions.
FFAMediaFormat * ff_AMediaFormat_new(void)
int av_fifo_space(const AVFifoBuffer *f)
Return the amount of space in bytes in the AVFifoBuffer, that is the amount of data you can write int...
Definition: fifo.c:82
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1764
static AVFrame * frame
static int mediacodec_process_data(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
int ff_h264_decode_extradata(const uint8_t *data, int size, H264ParamSets *ps, int *is_avc, int *nal_length_size, int err_recognition, void *logctx)
Definition: h264_parse.c:412
uint8_t * data
Definition: avcodec.h:1580
#define AVERROR_EOF
End of file.
Definition: error.h:55
void av_fifo_free(AVFifoBuffer *f)
Free an AVFifoBuffer.
Definition: fifo.c:55
MediaCodecDecContext ctx
#define av_log(a,...)
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: avpacket.c:572
AVCodec ff_h264_mediacodec_decoder
H.264 / AVC / MPEG-4 part10 codec.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static int mediacodec_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
#define CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: avcodec.h:1163
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:176
int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void(*func)(void *, void *, int))
Feed data from an AVFifoBuffer to a user-supplied callback.
Definition: fifo.c:213
simple assert() macros that are a bit more flexible than ISO C assert().
const char * name
Name of the codec implementation.
Definition: avcodec.h:3549
int ff_mediacodec_dec_decode(AVCodecContext *avctx, MediaCodecDecContext *s, AVFrame *frame, int *got_frame, AVPacket *pkt)
size_t data_size
Definition: h264.h:194
uint8_t data[4096]
Definition: h264.h:220
void ff_AMediaFormat_setInt32(FFAMediaFormat *format, const char *name, int32_t value)
int width
picture width / height.
Definition: avcodec.h:1836
int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
Submit a packet for filtering.
Definition: bsf.c:173
#define AVERROR_BSF_NOT_FOUND
Bitstream filter not found.
Definition: error.h:49
int ff_mediacodec_dec_close(AVCodecContext *avctx, MediaCodecDecContext *s)
void ff_AMediaFormat_setString(FFAMediaFormat *format, const char *name, const char *value)
static av_cold int mediacodec_decode_close(AVCodecContext *avctx)
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
Libavcodec external API header.
AVBufferRef * pps_list[MAX_PPS_COUNT]
Definition: h264.h:231
int av_fifo_size(const AVFifoBuffer *f)
Return the amount of data in bytes in the AVFifoBuffer, that is the amount of data you can read from ...
Definition: fifo.c:77
int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
Resize an AVFifoBuffer.
Definition: fifo.c:87
main external API structure.
Definition: avcodec.h:1649
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:563
uint8_t * data
The data buffer.
Definition: buffer.h:89
a very simple circular buffer FIFO implementation
int extradata_size
Definition: avcodec.h:1765
static const char * format
Definition: movenc.c:47
int avcodec_parameters_from_context(AVCodecParameters *par, const AVCodecContext *codec)
Fill the parameters struct based on the values from the supplied codec context.
Definition: utils.c:4077
unsigned int sps_id
Definition: h264.h:201
int ff_AMediaFormat_delete(FFAMediaFormat *format)
#define FF_CODEC_CAP_SETS_PKT_DTS
Decoders marked with FF_CODEC_CAP_SETS_PKT_DTS want to set AVFrame.pkt_dts manually.
Definition: internal.h:55
static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avpkt)
Definition: ccaption_dec.c:722
common internal api header.
common internal and external API header
uint8_t data[4096]
Definition: h264.h:193
size_t data_size
Definition: h264.h:221
void av_init_packet(AVPacket *pkt)
Initialize optional fields of a packet with default values.
Definition: avpacket.c:33
void * priv_data
Definition: avcodec.h:1691
pixel format definitions
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
Definition: fifo.c:43
int ff_mediacodec_dec_flush(AVCodecContext *avctx, MediaCodecDecContext *s)
static void mediacodec_decode_flush(AVCodecContext *avctx)
static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
void ff_h264_ps_uninit(H264ParamSets *ps)
Uninit H264 param sets structure.
Definition: h264_ps.c:301
int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, const char *mime, FFAMediaFormat *format)
void av_fifo_reset(AVFifoBuffer *f)
Reset the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied...
Definition: fifo.c:71
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
This structure stores compressed data.
Definition: avcodec.h:1557
AVCodecParameters * par_in
Parameters of the input stream.
Definition: avcodec.h:5703