OSDN Git Service

remove SDL
[android-x86/external-stagefright-plugins.git] / utils / ffmpeg_utils.cpp
1 /*
2  * Copyright 2012 Michael Chen <omxcodec@gmail.com>
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #define LOG_NDEBUG 0
17 #define LOG_TAG "FFMPEG"
18 #include <utils/Log.h>
19
20 #include <utils/Errors.h>
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <inttypes.h>
29 #include <math.h>
30 #include <signal.h>
31 #include <limits.h> /* INT_MAX */
32
33 #include "config.h"
34 #include "libavutil/avstring.h"
35 #include "libavutil/colorspace.h"
36 #include "libavutil/mathematics.h"
37 #include "libavutil/pixdesc.h"
38 #include "libavutil/imgutils.h"
39 #include "libavutil/dict.h"
40 #include "libavutil/parseutils.h"
41 #include "libavutil/samplefmt.h"
42 #include "libavutil/avassert.h"
43 #include "libavutil/intreadwrite.h"
44 #include "libavformat/avformat.h"
45 #include "libavdevice/avdevice.h"
46 #include "libswscale/swscale.h"
47 #include "libavcodec/audioconvert.h"
48 #include "libavutil/opt.h"
49 #include "libavutil/internal.h"
50 #include "libavcodec/avfft.h"
51 #include "libswresample/swresample.h"
52
53 #include "cmdutils.h"
54
55 #undef strncpy
56 #include <string.h>
57
58 #ifdef __cplusplus
59 }
60 #endif
61
62 // log
63 static int flags;
64
65 // dummy
66 const char program_name[] = "dummy";
67 const int program_birth_year = 2012;
68
69 // init ffmpeg
70 static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
71 static int ref_count = 0;
72
73 namespace android {
74
75 //////////////////////////////////////////////////////////////////////////////////
76 // dummy
77 //////////////////////////////////////////////////////////////////////////////////
78 #ifdef __cplusplus
79 extern "C" {
80 #endif
81
82 void av_noreturn exit_program(int ret)
83 {
84     // do nothing
85 }
86
87 void show_help_default(const char *opt, const char *arg)
88 {
89     // do nothing
90 }
91
92 #ifdef __cplusplus
93 }
94 #endif
95
96 //////////////////////////////////////////////////////////////////////////////////
97 // log
98 //////////////////////////////////////////////////////////////////////////////////
99 static void sanitize(uint8_t *line){
100     while(*line){
101         if(*line < 0x08 || (*line > 0x0D && *line < 0x20))
102             *line='?';
103         line++;
104     }
105 }
106
107 void nam_av_log_callback(void* ptr, int level, const char* fmt, va_list vl)
108 {
109     static int print_prefix = 1;
110     static int count;
111     static char prev[1024];
112     char line[1024];
113     static int is_atty;
114
115     if (level > av_log_get_level())
116         return;
117     av_log_format_line(ptr, level, fmt, vl, line, sizeof(line), &print_prefix);
118
119     if (print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strcmp(line, prev)){
120         count++;
121         return;
122     }
123     if (count > 0) {
124         LOGI("Last message repeated %d times\n", count);
125         count = 0;
126     }
127     strcpy(prev, line);
128     sanitize((uint8_t *)line);
129
130 #if 0
131     LOGI("%s", line);
132 #else
133 #define LOG_BUF_SIZE 1024
134     static char g_msg[LOG_BUF_SIZE];
135     static int g_msg_len = 0;
136
137     int saw_lf, check_len;
138
139     do {
140         check_len = g_msg_len + strlen(line) + 1;
141         if (check_len <= LOG_BUF_SIZE) {
142             /* lf: Line feed ('\n') */
143             saw_lf = (strchr(line, '\n') != NULL) ? 1 : 0;
144             strncpy(g_msg + g_msg_len, line, strlen(line));
145             g_msg_len += strlen(line);
146             if (!saw_lf) {
147                /* skip */
148                return;
149             } else {
150                /* attach the line feed */
151                g_msg_len += 1;
152                g_msg[g_msg_len] = '\n';
153             }
154         } else {
155             /* trace is fragmented */
156             g_msg_len += 1;
157             g_msg[g_msg_len] = '\n';
158         }
159         LOGI("%s", g_msg);
160         /* reset g_msg and g_msg_len */
161         memset(g_msg, 0, LOG_BUF_SIZE);
162         g_msg_len = 0;
163      } while (check_len > LOG_BUF_SIZE);
164 #endif
165 }
166
167 void nam_av_log_set_flags(int arg)
168 {
169     flags = arg;
170 }
171
172 #if 0
173 const struct { const char *name; int level; } log_levels[] = {
174     { "quiet"  , AV_LOG_QUIET   },
175     { "panic"  , AV_LOG_PANIC   },
176     { "fatal"  , AV_LOG_FATAL   },
177     { "error"  , AV_LOG_ERROR   },
178     { "warning", AV_LOG_WARNING },
179     { "info"   , AV_LOG_INFO    },
180     { "verbose", AV_LOG_VERBOSE },
181     { "debug"  , AV_LOG_DEBUG   },
182 };
183
184 #define AV_LOG_QUIET    -8
185 #define AV_LOG_PANIC     0
186 #define AV_LOG_FATAL     8
187 #define AV_LOG_ERROR    16
188 #define AV_LOG_WARNING  24
189 #define AV_LOG_INFO     32
190 #define AV_LOG_VERBOSE  40
191 #define AV_LOG_DEBUG    48
192 #endif
193
194 //////////////////////////////////////////////////////////////////////////////////
195 // constructor and destructor
196 //////////////////////////////////////////////////////////////////////////////////
197 /* Mutex manager callback. */
198 static int lockmgr(void **mtx, enum AVLockOp op)
199 {
200     switch (op) {
201     case AV_LOCK_CREATE:
202         *mtx = (void *)av_malloc(sizeof(pthread_mutex_t));
203         if (!*mtx)
204             return 1;
205         return !!pthread_mutex_init((pthread_mutex_t *)(*mtx), NULL);
206     case AV_LOCK_OBTAIN:
207         return !!pthread_mutex_lock((pthread_mutex_t *)(*mtx));
208     case AV_LOCK_RELEASE:
209         return !!pthread_mutex_unlock((pthread_mutex_t *)(*mtx));
210     case AV_LOCK_DESTROY:
211         pthread_mutex_destroy((pthread_mutex_t *)(*mtx));
212         av_freep(mtx);
213         return 0;
214     }
215     return 1;
216 }
217
218 status_t initFFmpeg() 
219 {
220     status_t ret = OK;
221
222     pthread_mutex_lock(&init_mutex);
223
224     if(ref_count == 0) {
225         nam_av_log_set_flags(AV_LOG_SKIP_REPEATED);
226         av_log_set_level(AV_LOG_DEBUG);
227         av_log_set_callback(nam_av_log_callback);
228
229         /* register all codecs, demux and protocols */
230         avcodec_register_all();
231 #if CONFIG_AVDEVICE
232         avdevice_register_all();
233 #endif
234         av_register_all();
235         avformat_network_init();
236
237         init_opts();
238
239         if (av_lockmgr_register(lockmgr)) {
240             LOGE("could not initialize lock manager!");
241             ret = NO_INIT;
242         }
243     }
244
245     // update counter
246     ref_count++;
247
248     pthread_mutex_unlock(&init_mutex);
249
250     return ret;
251 }
252
253 void deInitFFmpeg()
254 {
255     pthread_mutex_lock(&init_mutex);
256
257     // update counter
258     ref_count--;
259
260     if(ref_count == 0) {
261         av_lockmgr_register(NULL);
262         uninit_opts();
263         avformat_network_deinit();
264     }
265
266     pthread_mutex_unlock(&init_mutex);
267 }
268
269 //////////////////////////////////////////////////////////////////////////////////
270 // parser
271 //////////////////////////////////////////////////////////////////////////////////
272 /* H.264 bitstream with start codes, NOT AVC1! ref: libavcodec/h264_parser.c */
273 static int h264_split(AVCodecContext *avctx,
274                       const uint8_t *buf, int buf_size, int check_compatible_only)
275 {
276     int i;
277     uint32_t state = -1;
278     int has_sps= 0;
279     int has_pps= 0;
280
281     //av_hex_dump(stderr, buf, 100);
282
283     for(i=0; i<=buf_size; i++){
284         if((state&0xFFFFFF1F) == 0x107) {
285             LOGI("found NAL_SPS");
286             has_sps=1;
287         }
288         if((state&0xFFFFFF1F) == 0x108) {
289             LOGI("found NAL_PPS");
290             has_pps=1;
291             if (check_compatible_only)
292                 return (has_sps & has_pps);
293         }
294         if((state&0xFFFFFF00) == 0x100 && ((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105)){
295             if(has_pps){
296                 while(i>4 && buf[i-5]==0) i--;
297                 return i-4;
298             }
299         }
300         if (i<buf_size)
301             state= (state<<8) | buf[i];
302     }
303     return 0;
304 }
305
306 /* ref: libavcodec/mpegvideo_parser.c */
307 static int mpegvideo_split(AVCodecContext *avctx,
308                            const uint8_t *buf, int buf_size, int check_compatible_only)
309 {
310     int i;
311     uint32_t state= -1;
312     int found=0;
313
314     for(i=0; i<buf_size; i++){
315         state= (state<<8) | buf[i];
316         if(state == 0x1B3){
317             found=1;
318         }else if(found && state != 0x1B5 && state < 0x200 && state >= 0x100)
319             return i-3;
320     }
321     return 0;
322 }
323
324 /* split extradata from buf for Android OMXCodec */
325 int parser_split(AVCodecContext *avctx,
326                       const uint8_t *buf, int buf_size)
327 {
328     if (!avctx || !buf || buf_size <= 0) {
329         LOGE("parser split, valid params");
330         return 0;
331     }
332
333     if (avctx->codec_id == CODEC_ID_H264) {
334         return h264_split(avctx, buf, buf_size, 0);
335     } else if (avctx->codec_id == CODEC_ID_MPEG2VIDEO ||
336             avctx->codec_id == CODEC_ID_MPEG4) {
337         return mpegvideo_split(avctx, buf, buf_size, 0);
338     } else {
339         LOGE("parser split, unsupport the codec, id: 0x%0x", avctx->codec_id);
340     }
341
342     return 0;
343 }
344
345 int is_extradata_compatible_with_android(AVCodecContext *avctx)
346 {
347     if (avctx->extradata_size <= 0) {
348         LOGI("extradata_size <= 0, extradata is not compatible with android decoder, the codec id: 0x%0x", avctx->codec_id);
349         return 0;
350     }
351
352     if (avctx->codec_id == CODEC_ID_H264 && avctx->extradata[0] != 1 /* configurationVersion */) {
353         // SPS + PPS
354         return !!(h264_split(avctx, avctx->extradata, avctx->extradata_size, 1) > 0);
355     } else {
356         // default, FIXME
357         return !!(avctx->extradata_size > 0);
358     }
359 }
360
361 }  // namespace android
362