yading@10
|
1 /*
|
yading@10
|
2 * Interface to the Android Stagefright library for
|
yading@10
|
3 * H/W accelerated H.264 decoding
|
yading@10
|
4 *
|
yading@10
|
5 * Copyright (C) 2011 Mohamed Naufal
|
yading@10
|
6 * Copyright (C) 2011 Martin Storsjö
|
yading@10
|
7 *
|
yading@10
|
8 * This file is part of FFmpeg.
|
yading@10
|
9 *
|
yading@10
|
10 * FFmpeg is free software; you can redistribute it and/or
|
yading@10
|
11 * modify it under the terms of the GNU Lesser General Public
|
yading@10
|
12 * License as published by the Free Software Foundation; either
|
yading@10
|
13 * version 2.1 of the License, or (at your option) any later version.
|
yading@10
|
14 *
|
yading@10
|
15 * FFmpeg is distributed in the hope that it will be useful,
|
yading@10
|
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@10
|
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@10
|
18 * Lesser General Public License for more details.
|
yading@10
|
19 *
|
yading@10
|
20 * You should have received a copy of the GNU Lesser General Public
|
yading@10
|
21 * License along with FFmpeg; if not, write to the Free Software
|
yading@10
|
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@10
|
23 */
|
yading@10
|
24
|
yading@10
|
25 #include <binder/ProcessState.h>
|
yading@10
|
26 #include <media/stagefright/MetaData.h>
|
yading@10
|
27 #include <media/stagefright/MediaBufferGroup.h>
|
yading@10
|
28 #include <media/stagefright/MediaDebug.h>
|
yading@10
|
29 #include <media/stagefright/MediaDefs.h>
|
yading@10
|
30 #include <media/stagefright/OMXClient.h>
|
yading@10
|
31 #include <media/stagefright/OMXCodec.h>
|
yading@10
|
32 #include <utils/List.h>
|
yading@10
|
33 #include <new>
|
yading@10
|
34 #include <map>
|
yading@10
|
35
|
yading@10
|
36 extern "C" {
|
yading@10
|
37 #include "avcodec.h"
|
yading@10
|
38 #include "libavutil/imgutils.h"
|
yading@10
|
39 }
|
yading@10
|
40
|
yading@10
|
41 #define OMX_QCOM_COLOR_FormatYVU420SemiPlanar 0x7FA30C00
|
yading@10
|
42
|
yading@10
|
43 using namespace android;
|
yading@10
|
44
|
yading@10
|
45 struct Frame {
|
yading@10
|
46 status_t status;
|
yading@10
|
47 size_t size;
|
yading@10
|
48 int64_t time;
|
yading@10
|
49 int key;
|
yading@10
|
50 uint8_t *buffer;
|
yading@10
|
51 AVFrame *vframe;
|
yading@10
|
52 };
|
yading@10
|
53
|
yading@10
|
54 struct TimeStamp {
|
yading@10
|
55 int64_t pts;
|
yading@10
|
56 int64_t reordered_opaque;
|
yading@10
|
57 };
|
yading@10
|
58
|
yading@10
|
59 class CustomSource;
|
yading@10
|
60
|
yading@10
|
61 struct StagefrightContext {
|
yading@10
|
62 AVCodecContext *avctx;
|
yading@10
|
63 AVBitStreamFilterContext *bsfc;
|
yading@10
|
64 uint8_t* orig_extradata;
|
yading@10
|
65 int orig_extradata_size;
|
yading@10
|
66 sp<MediaSource> *source;
|
yading@10
|
67 List<Frame*> *in_queue, *out_queue;
|
yading@10
|
68 pthread_mutex_t in_mutex, out_mutex;
|
yading@10
|
69 pthread_cond_t condition;
|
yading@10
|
70 pthread_t decode_thread_id;
|
yading@10
|
71
|
yading@10
|
72 Frame *end_frame;
|
yading@10
|
73 bool source_done;
|
yading@10
|
74 volatile sig_atomic_t thread_started, thread_exited, stop_decode;
|
yading@10
|
75
|
yading@10
|
76 AVFrame *prev_frame;
|
yading@10
|
77 std::map<int64_t, TimeStamp> *ts_map;
|
yading@10
|
78 int64_t frame_index;
|
yading@10
|
79
|
yading@10
|
80 uint8_t *dummy_buf;
|
yading@10
|
81 int dummy_bufsize;
|
yading@10
|
82
|
yading@10
|
83 OMXClient *client;
|
yading@10
|
84 sp<MediaSource> *decoder;
|
yading@10
|
85 const char *decoder_component;
|
yading@10
|
86 };
|
yading@10
|
87
|
yading@10
|
88 class CustomSource : public MediaSource {
|
yading@10
|
89 public:
|
yading@10
|
90 CustomSource(AVCodecContext *avctx, sp<MetaData> meta) {
|
yading@10
|
91 s = (StagefrightContext*)avctx->priv_data;
|
yading@10
|
92 source_meta = meta;
|
yading@10
|
93 frame_size = (avctx->width * avctx->height * 3) / 2;
|
yading@10
|
94 buf_group.add_buffer(new MediaBuffer(frame_size));
|
yading@10
|
95 }
|
yading@10
|
96
|
yading@10
|
97 virtual sp<MetaData> getFormat() {
|
yading@10
|
98 return source_meta;
|
yading@10
|
99 }
|
yading@10
|
100
|
yading@10
|
101 virtual status_t start(MetaData *params) {
|
yading@10
|
102 return OK;
|
yading@10
|
103 }
|
yading@10
|
104
|
yading@10
|
105 virtual status_t stop() {
|
yading@10
|
106 return OK;
|
yading@10
|
107 }
|
yading@10
|
108
|
yading@10
|
109 virtual status_t read(MediaBuffer **buffer,
|
yading@10
|
110 const MediaSource::ReadOptions *options) {
|
yading@10
|
111 Frame *frame;
|
yading@10
|
112 status_t ret;
|
yading@10
|
113
|
yading@10
|
114 if (s->thread_exited)
|
yading@10
|
115 return ERROR_END_OF_STREAM;
|
yading@10
|
116 pthread_mutex_lock(&s->in_mutex);
|
yading@10
|
117
|
yading@10
|
118 while (s->in_queue->empty())
|
yading@10
|
119 pthread_cond_wait(&s->condition, &s->in_mutex);
|
yading@10
|
120
|
yading@10
|
121 frame = *s->in_queue->begin();
|
yading@10
|
122 ret = frame->status;
|
yading@10
|
123
|
yading@10
|
124 if (ret == OK) {
|
yading@10
|
125 ret = buf_group.acquire_buffer(buffer);
|
yading@10
|
126 if (ret == OK) {
|
yading@10
|
127 memcpy((*buffer)->data(), frame->buffer, frame->size);
|
yading@10
|
128 (*buffer)->set_range(0, frame->size);
|
yading@10
|
129 (*buffer)->meta_data()->clear();
|
yading@10
|
130 (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame,frame->key);
|
yading@10
|
131 (*buffer)->meta_data()->setInt64(kKeyTime, frame->time);
|
yading@10
|
132 } else {
|
yading@10
|
133 av_log(s->avctx, AV_LOG_ERROR, "Failed to acquire MediaBuffer\n");
|
yading@10
|
134 }
|
yading@10
|
135 av_freep(&frame->buffer);
|
yading@10
|
136 }
|
yading@10
|
137
|
yading@10
|
138 s->in_queue->erase(s->in_queue->begin());
|
yading@10
|
139 pthread_mutex_unlock(&s->in_mutex);
|
yading@10
|
140
|
yading@10
|
141 av_freep(&frame);
|
yading@10
|
142 return ret;
|
yading@10
|
143 }
|
yading@10
|
144
|
yading@10
|
145 private:
|
yading@10
|
146 MediaBufferGroup buf_group;
|
yading@10
|
147 sp<MetaData> source_meta;
|
yading@10
|
148 StagefrightContext *s;
|
yading@10
|
149 int frame_size;
|
yading@10
|
150 };
|
yading@10
|
151
|
yading@10
|
152 void* decode_thread(void *arg)
|
yading@10
|
153 {
|
yading@10
|
154 AVCodecContext *avctx = (AVCodecContext*)arg;
|
yading@10
|
155 StagefrightContext *s = (StagefrightContext*)avctx->priv_data;
|
yading@10
|
156 const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(avctx->pix_fmt);
|
yading@10
|
157 Frame* frame;
|
yading@10
|
158 MediaBuffer *buffer;
|
yading@10
|
159 int32_t w, h;
|
yading@10
|
160 int decode_done = 0;
|
yading@10
|
161 int ret;
|
yading@10
|
162 int src_linesize[3];
|
yading@10
|
163 const uint8_t *src_data[3];
|
yading@10
|
164 int64_t out_frame_index = 0;
|
yading@10
|
165
|
yading@10
|
166 do {
|
yading@10
|
167 buffer = NULL;
|
yading@10
|
168 frame = (Frame*)av_mallocz(sizeof(Frame));
|
yading@10
|
169 if (!frame) {
|
yading@10
|
170 frame = s->end_frame;
|
yading@10
|
171 frame->status = AVERROR(ENOMEM);
|
yading@10
|
172 decode_done = 1;
|
yading@10
|
173 s->end_frame = NULL;
|
yading@10
|
174 goto push_frame;
|
yading@10
|
175 }
|
yading@10
|
176 frame->status = (*s->decoder)->read(&buffer);
|
yading@10
|
177 if (frame->status == OK) {
|
yading@10
|
178 sp<MetaData> outFormat = (*s->decoder)->getFormat();
|
yading@10
|
179 outFormat->findInt32(kKeyWidth , &w);
|
yading@10
|
180 outFormat->findInt32(kKeyHeight, &h);
|
yading@10
|
181 frame->vframe = (AVFrame*)av_mallocz(sizeof(AVFrame));
|
yading@10
|
182 if (!frame->vframe) {
|
yading@10
|
183 frame->status = AVERROR(ENOMEM);
|
yading@10
|
184 decode_done = 1;
|
yading@10
|
185 buffer->release();
|
yading@10
|
186 goto push_frame;
|
yading@10
|
187 }
|
yading@10
|
188 ret = ff_get_buffer(avctx, frame->vframe);
|
yading@10
|
189 if (ret < 0) {
|
yading@10
|
190 frame->status = ret;
|
yading@10
|
191 decode_done = 1;
|
yading@10
|
192 buffer->release();
|
yading@10
|
193 goto push_frame;
|
yading@10
|
194 }
|
yading@10
|
195
|
yading@10
|
196 // The OMX.SEC decoder doesn't signal the modified width/height
|
yading@10
|
197 if (s->decoder_component && !strncmp(s->decoder_component, "OMX.SEC", 7) &&
|
yading@10
|
198 (w & 15 || h & 15)) {
|
yading@10
|
199 if (((w + 15)&~15) * ((h + 15)&~15) * 3/2 == buffer->range_length()) {
|
yading@10
|
200 w = (w + 15)&~15;
|
yading@10
|
201 h = (h + 15)&~15;
|
yading@10
|
202 }
|
yading@10
|
203 }
|
yading@10
|
204
|
yading@10
|
205 if (!avctx->width || !avctx->height || avctx->width > w || avctx->height > h) {
|
yading@10
|
206 avctx->width = w;
|
yading@10
|
207 avctx->height = h;
|
yading@10
|
208 }
|
yading@10
|
209
|
yading@10
|
210 src_linesize[0] = av_image_get_linesize(avctx->pix_fmt, w, 0);
|
yading@10
|
211 src_linesize[1] = av_image_get_linesize(avctx->pix_fmt, w, 1);
|
yading@10
|
212 src_linesize[2] = av_image_get_linesize(avctx->pix_fmt, w, 2);
|
yading@10
|
213
|
yading@10
|
214 src_data[0] = (uint8_t*)buffer->data();
|
yading@10
|
215 src_data[1] = src_data[0] + src_linesize[0] * h;
|
yading@10
|
216 src_data[2] = src_data[1] + src_linesize[1] * -(-h>>pix_desc->log2_chroma_h);
|
yading@10
|
217 av_image_copy(frame->vframe->data, frame->vframe->linesize,
|
yading@10
|
218 src_data, src_linesize,
|
yading@10
|
219 avctx->pix_fmt, avctx->width, avctx->height);
|
yading@10
|
220
|
yading@10
|
221 buffer->meta_data()->findInt64(kKeyTime, &out_frame_index);
|
yading@10
|
222 if (out_frame_index && s->ts_map->count(out_frame_index) > 0) {
|
yading@10
|
223 frame->vframe->pts = (*s->ts_map)[out_frame_index].pts;
|
yading@10
|
224 frame->vframe->reordered_opaque = (*s->ts_map)[out_frame_index].reordered_opaque;
|
yading@10
|
225 s->ts_map->erase(out_frame_index);
|
yading@10
|
226 }
|
yading@10
|
227 buffer->release();
|
yading@10
|
228 } else if (frame->status == INFO_FORMAT_CHANGED) {
|
yading@10
|
229 if (buffer)
|
yading@10
|
230 buffer->release();
|
yading@10
|
231 av_free(frame);
|
yading@10
|
232 continue;
|
yading@10
|
233 } else {
|
yading@10
|
234 decode_done = 1;
|
yading@10
|
235 }
|
yading@10
|
236 push_frame:
|
yading@10
|
237 while (true) {
|
yading@10
|
238 pthread_mutex_lock(&s->out_mutex);
|
yading@10
|
239 if (s->out_queue->size() >= 10) {
|
yading@10
|
240 pthread_mutex_unlock(&s->out_mutex);
|
yading@10
|
241 usleep(10000);
|
yading@10
|
242 continue;
|
yading@10
|
243 }
|
yading@10
|
244 break;
|
yading@10
|
245 }
|
yading@10
|
246 s->out_queue->push_back(frame);
|
yading@10
|
247 pthread_mutex_unlock(&s->out_mutex);
|
yading@10
|
248 } while (!decode_done && !s->stop_decode);
|
yading@10
|
249
|
yading@10
|
250 s->thread_exited = true;
|
yading@10
|
251
|
yading@10
|
252 return 0;
|
yading@10
|
253 }
|
yading@10
|
254
|
yading@10
|
255 static av_cold int Stagefright_init(AVCodecContext *avctx)
|
yading@10
|
256 {
|
yading@10
|
257 StagefrightContext *s = (StagefrightContext*)avctx->priv_data;
|
yading@10
|
258 sp<MetaData> meta, outFormat;
|
yading@10
|
259 int32_t colorFormat = 0;
|
yading@10
|
260 int ret;
|
yading@10
|
261
|
yading@10
|
262 if (!avctx->extradata || !avctx->extradata_size || avctx->extradata[0] != 1)
|
yading@10
|
263 return -1;
|
yading@10
|
264
|
yading@10
|
265 s->avctx = avctx;
|
yading@10
|
266 s->bsfc = av_bitstream_filter_init("h264_mp4toannexb");
|
yading@10
|
267 if (!s->bsfc) {
|
yading@10
|
268 av_log(avctx, AV_LOG_ERROR, "Cannot open the h264_mp4toannexb BSF!\n");
|
yading@10
|
269 return -1;
|
yading@10
|
270 }
|
yading@10
|
271
|
yading@10
|
272 s->orig_extradata_size = avctx->extradata_size;
|
yading@10
|
273 s->orig_extradata = (uint8_t*) av_mallocz(avctx->extradata_size +
|
yading@10
|
274 FF_INPUT_BUFFER_PADDING_SIZE);
|
yading@10
|
275 if (!s->orig_extradata) {
|
yading@10
|
276 ret = AVERROR(ENOMEM);
|
yading@10
|
277 goto fail;
|
yading@10
|
278 }
|
yading@10
|
279 memcpy(s->orig_extradata, avctx->extradata, avctx->extradata_size);
|
yading@10
|
280
|
yading@10
|
281 meta = new MetaData;
|
yading@10
|
282 if (meta == NULL) {
|
yading@10
|
283 ret = AVERROR(ENOMEM);
|
yading@10
|
284 goto fail;
|
yading@10
|
285 }
|
yading@10
|
286 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
|
yading@10
|
287 meta->setInt32(kKeyWidth, avctx->width);
|
yading@10
|
288 meta->setInt32(kKeyHeight, avctx->height);
|
yading@10
|
289 meta->setData(kKeyAVCC, kTypeAVCC, avctx->extradata, avctx->extradata_size);
|
yading@10
|
290
|
yading@10
|
291 android::ProcessState::self()->startThreadPool();
|
yading@10
|
292
|
yading@10
|
293 s->source = new sp<MediaSource>();
|
yading@10
|
294 *s->source = new CustomSource(avctx, meta);
|
yading@10
|
295 s->in_queue = new List<Frame*>;
|
yading@10
|
296 s->out_queue = new List<Frame*>;
|
yading@10
|
297 s->ts_map = new std::map<int64_t, TimeStamp>;
|
yading@10
|
298 s->client = new OMXClient;
|
yading@10
|
299 s->end_frame = (Frame*)av_mallocz(sizeof(Frame));
|
yading@10
|
300 if (s->source == NULL || !s->in_queue || !s->out_queue || !s->client ||
|
yading@10
|
301 !s->ts_map || !s->end_frame) {
|
yading@10
|
302 ret = AVERROR(ENOMEM);
|
yading@10
|
303 goto fail;
|
yading@10
|
304 }
|
yading@10
|
305
|
yading@10
|
306 if (s->client->connect() != OK) {
|
yading@10
|
307 av_log(avctx, AV_LOG_ERROR, "Cannot connect OMX client\n");
|
yading@10
|
308 ret = -1;
|
yading@10
|
309 goto fail;
|
yading@10
|
310 }
|
yading@10
|
311
|
yading@10
|
312 s->decoder = new sp<MediaSource>();
|
yading@10
|
313 *s->decoder = OMXCodec::Create(s->client->interface(), meta,
|
yading@10
|
314 false, *s->source, NULL,
|
yading@10
|
315 OMXCodec::kClientNeedsFramebuffer);
|
yading@10
|
316 if ((*s->decoder)->start() != OK) {
|
yading@10
|
317 av_log(avctx, AV_LOG_ERROR, "Cannot start decoder\n");
|
yading@10
|
318 ret = -1;
|
yading@10
|
319 s->client->disconnect();
|
yading@10
|
320 goto fail;
|
yading@10
|
321 }
|
yading@10
|
322
|
yading@10
|
323 outFormat = (*s->decoder)->getFormat();
|
yading@10
|
324 outFormat->findInt32(kKeyColorFormat, &colorFormat);
|
yading@10
|
325 if (colorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar ||
|
yading@10
|
326 colorFormat == OMX_COLOR_FormatYUV420SemiPlanar)
|
yading@10
|
327 avctx->pix_fmt = AV_PIX_FMT_NV21;
|
yading@10
|
328 else if (colorFormat == OMX_COLOR_FormatYCbYCr)
|
yading@10
|
329 avctx->pix_fmt = AV_PIX_FMT_YUYV422;
|
yading@10
|
330 else if (colorFormat == OMX_COLOR_FormatCbYCrY)
|
yading@10
|
331 avctx->pix_fmt = AV_PIX_FMT_UYVY422;
|
yading@10
|
332 else
|
yading@10
|
333 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
|
yading@10
|
334
|
yading@10
|
335 outFormat->findCString(kKeyDecoderComponent, &s->decoder_component);
|
yading@10
|
336 if (s->decoder_component)
|
yading@10
|
337 s->decoder_component = av_strdup(s->decoder_component);
|
yading@10
|
338
|
yading@10
|
339 pthread_mutex_init(&s->in_mutex, NULL);
|
yading@10
|
340 pthread_mutex_init(&s->out_mutex, NULL);
|
yading@10
|
341 pthread_cond_init(&s->condition, NULL);
|
yading@10
|
342 return 0;
|
yading@10
|
343
|
yading@10
|
344 fail:
|
yading@10
|
345 av_bitstream_filter_close(s->bsfc);
|
yading@10
|
346 av_freep(&s->orig_extradata);
|
yading@10
|
347 av_freep(&s->end_frame);
|
yading@10
|
348 delete s->in_queue;
|
yading@10
|
349 delete s->out_queue;
|
yading@10
|
350 delete s->ts_map;
|
yading@10
|
351 delete s->client;
|
yading@10
|
352 return ret;
|
yading@10
|
353 }
|
yading@10
|
354
|
yading@10
|
355 static int Stagefright_decode_frame(AVCodecContext *avctx, void *data,
|
yading@10
|
356 int *got_frame, AVPacket *avpkt)
|
yading@10
|
357 {
|
yading@10
|
358 StagefrightContext *s = (StagefrightContext*)avctx->priv_data;
|
yading@10
|
359 Frame *frame;
|
yading@10
|
360 status_t status;
|
yading@10
|
361 int orig_size = avpkt->size;
|
yading@10
|
362 AVPacket pkt = *avpkt;
|
yading@10
|
363 AVFrame *ret_frame;
|
yading@10
|
364
|
yading@10
|
365 if (!s->thread_started) {
|
yading@10
|
366 pthread_create(&s->decode_thread_id, NULL, &decode_thread, avctx);
|
yading@10
|
367 s->thread_started = true;
|
yading@10
|
368 }
|
yading@10
|
369
|
yading@10
|
370 if (avpkt && avpkt->data) {
|
yading@10
|
371 av_bitstream_filter_filter(s->bsfc, avctx, NULL, &pkt.data, &pkt.size,
|
yading@10
|
372 avpkt->data, avpkt->size, avpkt->flags & AV_PKT_FLAG_KEY);
|
yading@10
|
373 avpkt = &pkt;
|
yading@10
|
374 }
|
yading@10
|
375
|
yading@10
|
376 if (!s->source_done) {
|
yading@10
|
377 if(!s->dummy_buf) {
|
yading@10
|
378 s->dummy_buf = (uint8_t*)av_malloc(avpkt->size);
|
yading@10
|
379 if (!s->dummy_buf)
|
yading@10
|
380 return AVERROR(ENOMEM);
|
yading@10
|
381 s->dummy_bufsize = avpkt->size;
|
yading@10
|
382 memcpy(s->dummy_buf, avpkt->data, avpkt->size);
|
yading@10
|
383 }
|
yading@10
|
384
|
yading@10
|
385 frame = (Frame*)av_mallocz(sizeof(Frame));
|
yading@10
|
386 if (avpkt->data) {
|
yading@10
|
387 frame->status = OK;
|
yading@10
|
388 frame->size = avpkt->size;
|
yading@10
|
389 frame->key = avpkt->flags & AV_PKT_FLAG_KEY ? 1 : 0;
|
yading@10
|
390 frame->buffer = (uint8_t*)av_malloc(avpkt->size);
|
yading@10
|
391 if (!frame->buffer) {
|
yading@10
|
392 av_freep(&frame);
|
yading@10
|
393 return AVERROR(ENOMEM);
|
yading@10
|
394 }
|
yading@10
|
395 uint8_t *ptr = avpkt->data;
|
yading@10
|
396 // The OMX.SEC decoder fails without this.
|
yading@10
|
397 if (avpkt->size == orig_size + avctx->extradata_size) {
|
yading@10
|
398 ptr += avctx->extradata_size;
|
yading@10
|
399 frame->size = orig_size;
|
yading@10
|
400 }
|
yading@10
|
401 memcpy(frame->buffer, ptr, orig_size);
|
yading@10
|
402 if (avpkt == &pkt)
|
yading@10
|
403 av_free(avpkt->data);
|
yading@10
|
404
|
yading@10
|
405 frame->time = ++s->frame_index;
|
yading@10
|
406 (*s->ts_map)[s->frame_index].pts = avpkt->pts;
|
yading@10
|
407 (*s->ts_map)[s->frame_index].reordered_opaque = avctx->reordered_opaque;
|
yading@10
|
408 } else {
|
yading@10
|
409 frame->status = ERROR_END_OF_STREAM;
|
yading@10
|
410 s->source_done = true;
|
yading@10
|
411 }
|
yading@10
|
412
|
yading@10
|
413 while (true) {
|
yading@10
|
414 if (s->thread_exited) {
|
yading@10
|
415 s->source_done = true;
|
yading@10
|
416 break;
|
yading@10
|
417 }
|
yading@10
|
418 pthread_mutex_lock(&s->in_mutex);
|
yading@10
|
419 if (s->in_queue->size() >= 10) {
|
yading@10
|
420 pthread_mutex_unlock(&s->in_mutex);
|
yading@10
|
421 usleep(10000);
|
yading@10
|
422 continue;
|
yading@10
|
423 }
|
yading@10
|
424 s->in_queue->push_back(frame);
|
yading@10
|
425 pthread_cond_signal(&s->condition);
|
yading@10
|
426 pthread_mutex_unlock(&s->in_mutex);
|
yading@10
|
427 break;
|
yading@10
|
428 }
|
yading@10
|
429 }
|
yading@10
|
430 while (true) {
|
yading@10
|
431 pthread_mutex_lock(&s->out_mutex);
|
yading@10
|
432 if (!s->out_queue->empty()) break;
|
yading@10
|
433 pthread_mutex_unlock(&s->out_mutex);
|
yading@10
|
434 if (s->source_done) {
|
yading@10
|
435 usleep(10000);
|
yading@10
|
436 continue;
|
yading@10
|
437 } else {
|
yading@10
|
438 return orig_size;
|
yading@10
|
439 }
|
yading@10
|
440 }
|
yading@10
|
441
|
yading@10
|
442 frame = *s->out_queue->begin();
|
yading@10
|
443 s->out_queue->erase(s->out_queue->begin());
|
yading@10
|
444 pthread_mutex_unlock(&s->out_mutex);
|
yading@10
|
445
|
yading@10
|
446 ret_frame = frame->vframe;
|
yading@10
|
447 status = frame->status;
|
yading@10
|
448 av_freep(&frame);
|
yading@10
|
449
|
yading@10
|
450 if (status == ERROR_END_OF_STREAM)
|
yading@10
|
451 return 0;
|
yading@10
|
452 if (status != OK) {
|
yading@10
|
453 if (status == AVERROR(ENOMEM))
|
yading@10
|
454 return status;
|
yading@10
|
455 av_log(avctx, AV_LOG_ERROR, "Decode failed: %x\n", status);
|
yading@10
|
456 return -1;
|
yading@10
|
457 }
|
yading@10
|
458
|
yading@10
|
459 if (s->prev_frame) {
|
yading@10
|
460 avctx->release_buffer(avctx, s->prev_frame);
|
yading@10
|
461 av_freep(&s->prev_frame);
|
yading@10
|
462 }
|
yading@10
|
463 s->prev_frame = ret_frame;
|
yading@10
|
464
|
yading@10
|
465 *got_frame = 1;
|
yading@10
|
466 *(AVFrame*)data = *ret_frame;
|
yading@10
|
467 return orig_size;
|
yading@10
|
468 }
|
yading@10
|
469
|
yading@10
|
470 static av_cold int Stagefright_close(AVCodecContext *avctx)
|
yading@10
|
471 {
|
yading@10
|
472 StagefrightContext *s = (StagefrightContext*)avctx->priv_data;
|
yading@10
|
473 Frame *frame;
|
yading@10
|
474
|
yading@10
|
475 if (s->thread_started) {
|
yading@10
|
476 if (!s->thread_exited) {
|
yading@10
|
477 s->stop_decode = 1;
|
yading@10
|
478
|
yading@10
|
479 // Make sure decode_thread() doesn't get stuck
|
yading@10
|
480 pthread_mutex_lock(&s->out_mutex);
|
yading@10
|
481 while (!s->out_queue->empty()) {
|
yading@10
|
482 frame = *s->out_queue->begin();
|
yading@10
|
483 s->out_queue->erase(s->out_queue->begin());
|
yading@10
|
484 if (frame->vframe) {
|
yading@10
|
485 avctx->release_buffer(avctx, frame->vframe);
|
yading@10
|
486 av_freep(&frame->vframe);
|
yading@10
|
487 }
|
yading@10
|
488 av_freep(&frame);
|
yading@10
|
489 }
|
yading@10
|
490 pthread_mutex_unlock(&s->out_mutex);
|
yading@10
|
491
|
yading@10
|
492 // Feed a dummy frame prior to signalling EOF.
|
yading@10
|
493 // This is required to terminate the decoder(OMX.SEC)
|
yading@10
|
494 // when only one frame is read during stream info detection.
|
yading@10
|
495 if (s->dummy_buf && (frame = (Frame*)av_mallocz(sizeof(Frame)))) {
|
yading@10
|
496 frame->status = OK;
|
yading@10
|
497 frame->size = s->dummy_bufsize;
|
yading@10
|
498 frame->key = 1;
|
yading@10
|
499 frame->buffer = s->dummy_buf;
|
yading@10
|
500 pthread_mutex_lock(&s->in_mutex);
|
yading@10
|
501 s->in_queue->push_back(frame);
|
yading@10
|
502 pthread_cond_signal(&s->condition);
|
yading@10
|
503 pthread_mutex_unlock(&s->in_mutex);
|
yading@10
|
504 s->dummy_buf = NULL;
|
yading@10
|
505 }
|
yading@10
|
506
|
yading@10
|
507 pthread_mutex_lock(&s->in_mutex);
|
yading@10
|
508 s->end_frame->status = ERROR_END_OF_STREAM;
|
yading@10
|
509 s->in_queue->push_back(s->end_frame);
|
yading@10
|
510 pthread_cond_signal(&s->condition);
|
yading@10
|
511 pthread_mutex_unlock(&s->in_mutex);
|
yading@10
|
512 s->end_frame = NULL;
|
yading@10
|
513 }
|
yading@10
|
514
|
yading@10
|
515 pthread_join(s->decode_thread_id, NULL);
|
yading@10
|
516
|
yading@10
|
517 if (s->prev_frame) {
|
yading@10
|
518 avctx->release_buffer(avctx, s->prev_frame);
|
yading@10
|
519 av_freep(&s->prev_frame);
|
yading@10
|
520 }
|
yading@10
|
521
|
yading@10
|
522 s->thread_started = false;
|
yading@10
|
523 }
|
yading@10
|
524
|
yading@10
|
525 while (!s->in_queue->empty()) {
|
yading@10
|
526 frame = *s->in_queue->begin();
|
yading@10
|
527 s->in_queue->erase(s->in_queue->begin());
|
yading@10
|
528 if (frame->size)
|
yading@10
|
529 av_freep(&frame->buffer);
|
yading@10
|
530 av_freep(&frame);
|
yading@10
|
531 }
|
yading@10
|
532
|
yading@10
|
533 while (!s->out_queue->empty()) {
|
yading@10
|
534 frame = *s->out_queue->begin();
|
yading@10
|
535 s->out_queue->erase(s->out_queue->begin());
|
yading@10
|
536 if (frame->vframe) {
|
yading@10
|
537 avctx->release_buffer(avctx, frame->vframe);
|
yading@10
|
538 av_freep(&frame->vframe);
|
yading@10
|
539 }
|
yading@10
|
540 av_freep(&frame);
|
yading@10
|
541 }
|
yading@10
|
542
|
yading@10
|
543 (*s->decoder)->stop();
|
yading@10
|
544 s->client->disconnect();
|
yading@10
|
545
|
yading@10
|
546 if (s->decoder_component)
|
yading@10
|
547 av_freep(&s->decoder_component);
|
yading@10
|
548 av_freep(&s->dummy_buf);
|
yading@10
|
549 av_freep(&s->end_frame);
|
yading@10
|
550
|
yading@10
|
551 // Reset the extradata back to the original mp4 format, so that
|
yading@10
|
552 // the next invocation (both when decoding and when called from
|
yading@10
|
553 // av_find_stream_info) get the original mp4 format extradata.
|
yading@10
|
554 av_freep(&avctx->extradata);
|
yading@10
|
555 avctx->extradata = s->orig_extradata;
|
yading@10
|
556 avctx->extradata_size = s->orig_extradata_size;
|
yading@10
|
557
|
yading@10
|
558 delete s->in_queue;
|
yading@10
|
559 delete s->out_queue;
|
yading@10
|
560 delete s->ts_map;
|
yading@10
|
561 delete s->client;
|
yading@10
|
562 delete s->decoder;
|
yading@10
|
563 delete s->source;
|
yading@10
|
564
|
yading@10
|
565 pthread_mutex_destroy(&s->in_mutex);
|
yading@10
|
566 pthread_mutex_destroy(&s->out_mutex);
|
yading@10
|
567 pthread_cond_destroy(&s->condition);
|
yading@10
|
568 av_bitstream_filter_close(s->bsfc);
|
yading@10
|
569 return 0;
|
yading@10
|
570 }
|
yading@10
|
571
|
yading@10
|
572 AVCodec ff_libstagefright_h264_decoder = {
|
yading@10
|
573 "libstagefright_h264",
|
yading@10
|
574 NULL_IF_CONFIG_SMALL("libstagefright H.264"),
|
yading@10
|
575 AVMEDIA_TYPE_VIDEO,
|
yading@10
|
576 AV_CODEC_ID_H264,
|
yading@10
|
577 CODEC_CAP_DELAY,
|
yading@10
|
578 NULL, //supported_framerates
|
yading@10
|
579 NULL, //pix_fmts
|
yading@10
|
580 NULL, //supported_samplerates
|
yading@10
|
581 NULL, //sample_fmts
|
yading@10
|
582 NULL, //channel_layouts
|
yading@10
|
583 0, //max_lowres
|
yading@10
|
584 NULL, //priv_class
|
yading@10
|
585 NULL, //profiles
|
yading@10
|
586 sizeof(StagefrightContext),
|
yading@10
|
587 NULL, //next
|
yading@10
|
588 NULL, //init_thread_copy
|
yading@10
|
589 NULL, //update_thread_context
|
yading@10
|
590 NULL, //defaults
|
yading@10
|
591 NULL, //init_static_data
|
yading@10
|
592 Stagefright_init,
|
yading@10
|
593 NULL, //encode
|
yading@10
|
594 NULL, //encode2
|
yading@10
|
595 Stagefright_decode_frame,
|
yading@10
|
596 Stagefright_close,
|
yading@10
|
597 };
|