OSDN Git Service

add TODO
[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 "config.h"
27
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <inttypes.h>
31 #include <math.h>
32 #include <limits.h> /* INT_MAX */
33
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 #include <cutils/properties.h>
63
64 // log
65 static int flags;
66
67 // dummy
68 const char program_name[] = "dummy";
69 const int program_birth_year = 2012;
70
71 // init ffmpeg
72 static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
73 static int ref_count = 0;
74
75 namespace android {
76
77 //////////////////////////////////////////////////////////////////////////////////
78 // dummy
79 //////////////////////////////////////////////////////////////////////////////////
80 #ifdef __cplusplus
81 extern "C" {
82 #endif
83
84 void av_noreturn exit_program(int ret)
85 {
86     // do nothing
87 }
88
89 void show_help_default(const char *opt, const char *arg)
90 {
91     // do nothing
92 }
93
94 #ifdef __cplusplus
95 }
96 #endif
97
98 //////////////////////////////////////////////////////////////////////////////////
99 // log
100 //////////////////////////////////////////////////////////////////////////////////
101 static void sanitize(uint8_t *line){
102     while(*line){
103         if(*line < 0x08 || (*line > 0x0D && *line < 0x20))
104             *line='?';
105         line++;
106     }
107 }
108
109 // TODO, remove static variables to support multi-instances
110 void nam_av_log_callback(void* ptr, int level, const char* fmt, va_list vl)
111 {
112     static int print_prefix = 1;
113     static int count;
114     static char prev[1024];
115     char line[1024];
116     static int is_atty;
117
118     if (level > av_log_get_level())
119         return;
120     av_log_format_line(ptr, level, fmt, vl, line, sizeof(line), &print_prefix);
121
122     if (print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strcmp(line, prev)){
123         count++;
124         return;
125     }
126     if (count > 0) {
127         LOGI("Last message repeated %d times\n", count);
128         count = 0;
129     }
130     strcpy(prev, line);
131     sanitize((uint8_t *)line);
132
133 #if 0
134     LOGI("%s", line);
135 #else
136 #define LOG_BUF_SIZE 1024
137     static char g_msg[LOG_BUF_SIZE];
138     static int g_msg_len = 0;
139
140     int saw_lf, check_len;
141
142     do {
143         check_len = g_msg_len + strlen(line) + 1;
144         if (check_len <= LOG_BUF_SIZE) {
145             /* lf: Line feed ('\n') */
146             saw_lf = (strchr(line, '\n') != NULL) ? 1 : 0;
147             strncpy(g_msg + g_msg_len, line, strlen(line));
148             g_msg_len += strlen(line);
149             if (!saw_lf) {
150                /* skip */
151                return;
152             } else {
153                /* attach the line feed */
154                g_msg_len += 1;
155                g_msg[g_msg_len] = '\n';
156             }
157         } else {
158             /* trace is fragmented */
159             g_msg_len += 1;
160             g_msg[g_msg_len] = '\n';
161         }
162         LOGI("%s", g_msg);
163         /* reset g_msg and g_msg_len */
164         memset(g_msg, 0, LOG_BUF_SIZE);
165         g_msg_len = 0;
166      } while (check_len > LOG_BUF_SIZE);
167 #endif
168 }
169
170 void nam_av_log_set_flags(int arg)
171 {
172     flags = arg;
173 }
174
175 #if 0
176 const struct { const char *name; int level; } log_levels[] = {
177     { "quiet"  , AV_LOG_QUIET   },
178     { "panic"  , AV_LOG_PANIC   },
179     { "fatal"  , AV_LOG_FATAL   },
180     { "error"  , AV_LOG_ERROR   },
181     { "warning", AV_LOG_WARNING },
182     { "info"   , AV_LOG_INFO    },
183     { "verbose", AV_LOG_VERBOSE },
184     { "debug"  , AV_LOG_DEBUG   },
185 };
186
187 #define AV_LOG_QUIET    -8
188 #define AV_LOG_PANIC     0
189 #define AV_LOG_FATAL     8
190 #define AV_LOG_ERROR    16
191 #define AV_LOG_WARNING  24
192 #define AV_LOG_INFO     32
193 #define AV_LOG_VERBOSE  40
194 #define AV_LOG_DEBUG    48
195 #endif
196
197 //////////////////////////////////////////////////////////////////////////////////
198 // constructor and destructor
199 //////////////////////////////////////////////////////////////////////////////////
200 /* Mutex manager callback. */
201 static int lockmgr(void **mtx, enum AVLockOp op)
202 {
203     switch (op) {
204     case AV_LOCK_CREATE:
205         *mtx = (void *)av_malloc(sizeof(pthread_mutex_t));
206         if (!*mtx)
207             return 1;
208         return !!pthread_mutex_init((pthread_mutex_t *)(*mtx), NULL);
209     case AV_LOCK_OBTAIN:
210         return !!pthread_mutex_lock((pthread_mutex_t *)(*mtx));
211     case AV_LOCK_RELEASE:
212         return !!pthread_mutex_unlock((pthread_mutex_t *)(*mtx));
213     case AV_LOCK_DESTROY:
214         pthread_mutex_destroy((pthread_mutex_t *)(*mtx));
215         av_freep(mtx);
216         return 0;
217     }
218     return 1;
219 }
220
221 /**
222  * To debug ffmpeg", type this command on the console before starting playback:
223  *     setprop debug.nam.ffmpeg 1
224  * To disable the debug, type:
225  *     setprop debug.nam.ffmpge 0
226 */
227 status_t initFFmpeg() 
228 {
229     status_t ret = OK;
230     bool debug_enabled = false;
231     char value[PROPERTY_VALUE_MAX];
232
233     pthread_mutex_lock(&init_mutex);
234
235     if (property_get("debug.nam.ffmpeg", value, NULL)
236         && (!strcmp(value, "1") || !av_strcasecmp(value, "true"))) {
237         LOGI("set ffmpeg debug level to AV_LOG_DEBUG");
238         debug_enabled = true;
239     }
240     if (debug_enabled)
241         av_log_set_level(AV_LOG_DEBUG);
242     else
243         av_log_set_level(AV_LOG_INFO);
244
245     if(ref_count == 0) {
246         nam_av_log_set_flags(AV_LOG_SKIP_REPEATED);
247         av_log_set_callback(nam_av_log_callback);
248
249         /* register all codecs, demux and protocols */
250         avcodec_register_all();
251 #if CONFIG_AVDEVICE
252         avdevice_register_all();
253 #endif
254         av_register_all();
255         avformat_network_init();
256
257         init_opts();
258
259         if (av_lockmgr_register(lockmgr)) {
260             LOGE("could not initialize lock manager!");
261             ret = NO_INIT;
262         }
263     }
264
265     // update counter
266     ref_count++;
267
268     pthread_mutex_unlock(&init_mutex);
269
270     return ret;
271 }
272
273 void deInitFFmpeg()
274 {
275     pthread_mutex_lock(&init_mutex);
276
277     // update counter
278     ref_count--;
279
280     if(ref_count == 0) {
281         av_lockmgr_register(NULL);
282         uninit_opts();
283         avformat_network_deinit();
284     }
285
286     pthread_mutex_unlock(&init_mutex);
287 }
288
289 //////////////////////////////////////////////////////////////////////////////////
290 // parser
291 //////////////////////////////////////////////////////////////////////////////////
292 /* H.264 bitstream with start codes, NOT AVC1! ref: libavcodec/h264_parser.c */
293 static int h264_split(AVCodecContext *avctx,
294                       const uint8_t *buf, int buf_size, int check_compatible_only)
295 {
296     int i;
297     uint32_t state = -1;
298     int has_sps= 0;
299     int has_pps= 0;
300
301     //av_hex_dump(stderr, buf, 100);
302
303     for(i=0; i<=buf_size; i++){
304         if((state&0xFFFFFF1F) == 0x107) {
305             LOGI("found NAL_SPS");
306             has_sps=1;
307         }
308         if((state&0xFFFFFF1F) == 0x108) {
309             LOGI("found NAL_PPS");
310             has_pps=1;
311             if (check_compatible_only)
312                 return (has_sps & has_pps);
313         }
314         if((state&0xFFFFFF00) == 0x100 && ((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105)){
315             if(has_pps){
316                 while(i>4 && buf[i-5]==0) i--;
317                 return i-4;
318             }
319         }
320         if (i<buf_size)
321             state= (state<<8) | buf[i];
322     }
323     return 0;
324 }
325
326 /* ref: libavcodec/mpegvideo_parser.c */
327 static int mpegvideo_split(AVCodecContext *avctx,
328                            const uint8_t *buf, int buf_size, int check_compatible_only)
329 {
330     int i;
331     uint32_t state= -1;
332     int found=0;
333
334     for(i=0; i<buf_size; i++){
335         state= (state<<8) | buf[i];
336         if(state == 0x1B3){
337             found=1;
338         }else if(found && state != 0x1B5 && state < 0x200 && state >= 0x100)
339             return i-3;
340     }
341     return 0;
342 }
343
344 /* split extradata from buf for Android OMXCodec */
345 int parser_split(AVCodecContext *avctx,
346                       const uint8_t *buf, int buf_size)
347 {
348     if (!avctx || !buf || buf_size <= 0) {
349         LOGE("parser split, valid params");
350         return 0;
351     }
352
353     if (avctx->codec_id == CODEC_ID_H264) {
354         return h264_split(avctx, buf, buf_size, 0);
355     } else if (avctx->codec_id == CODEC_ID_MPEG2VIDEO ||
356             avctx->codec_id == CODEC_ID_MPEG4) {
357         return mpegvideo_split(avctx, buf, buf_size, 0);
358     } else {
359         LOGE("parser split, unsupport the codec, id: 0x%0x", avctx->codec_id);
360     }
361
362     return 0;
363 }
364
365 int is_extradata_compatible_with_android(AVCodecContext *avctx)
366 {
367     if (avctx->extradata_size <= 0) {
368         LOGI("extradata_size <= 0, extradata is not compatible with android decoder, the codec id: 0x%0x", avctx->codec_id);
369         return 0;
370     }
371
372     if (avctx->codec_id == CODEC_ID_H264 && avctx->extradata[0] != 1 /* configurationVersion */) {
373         // SPS + PPS
374         return !!(h264_split(avctx, avctx->extradata, avctx->extradata_size, 1) > 0);
375     } else {
376         // default, FIXME
377         return !!(avctx->extradata_size > 0);
378     }
379 }
380
381 }  // namespace android
382