OSDN Git Service

disable verbose log
[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
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 #undef strncpy
35 #include <string.h>
36
37 #ifdef __cplusplus
38 }
39 #endif
40
41 #include <cutils/properties.h>
42
43 #include "ffmpeg_utils.h"
44 #include "ffmpeg_source.h"
45
46 // log
47 static int flags;
48
49 // dummy
50 const char program_name[] = "dummy";
51 const int program_birth_year = 2012;
52
53 // init ffmpeg
54 static pthread_mutex_t s_init_mutex = PTHREAD_MUTEX_INITIALIZER;
55 static int s_ref_count = 0;
56
57 namespace android {
58
59 //////////////////////////////////////////////////////////////////////////////////
60 // dummy
61 //////////////////////////////////////////////////////////////////////////////////
62 #ifdef __cplusplus
63 extern "C" {
64 #endif
65
66 void exit_program(int ret)
67 {
68     // do nothing
69 }
70
71 void show_help_default(const char *opt, const char *arg)
72 {
73     // do nothing
74 }
75
76 #ifdef __cplusplus
77 }
78 #endif
79
80 //////////////////////////////////////////////////////////////////////////////////
81 // log
82 //////////////////////////////////////////////////////////////////////////////////
83 static void sanitize(uint8_t *line){
84     while(*line){
85         if(*line < 0x08 || (*line > 0x0D && *line < 0x20))
86             *line='?';
87         line++;
88     }
89 }
90
91 // TODO, remove static variables to support multi-instances
92 void nam_av_log_callback(void* ptr, int level, const char* fmt, va_list vl)
93 {
94     static int print_prefix = 1;
95     static int count;
96     static char prev[1024];
97     char line[1024];
98     static int is_atty;
99
100     if (level > av_log_get_level())
101         return;
102     av_log_format_line(ptr, level, fmt, vl, line, sizeof(line), &print_prefix);
103
104     if (print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strcmp(line, prev)){
105         count++;
106         return;
107     }
108     if (count > 0) {
109         ALOGI("Last message repeated %d times\n", count);
110         count = 0;
111     }
112     strcpy(prev, line);
113     sanitize((uint8_t *)line);
114
115 #if 0
116     ALOGI("%s", line);
117 #else
118 #define LOG_BUF_SIZE 1024
119     static char g_msg[LOG_BUF_SIZE];
120     static int g_msg_len = 0;
121
122     int saw_lf, check_len;
123
124     do {
125         check_len = g_msg_len + strlen(line) + 1;
126         if (check_len <= LOG_BUF_SIZE) {
127             /* lf: Line feed ('\n') */
128             saw_lf = (strchr(line, '\n') != NULL) ? 1 : 0;
129             strncpy(g_msg + g_msg_len, line, strlen(line));
130             g_msg_len += strlen(line);
131             if (!saw_lf) {
132                /* skip */
133                return;
134             } else {
135                /* attach the line feed */
136                g_msg_len += 1;
137                g_msg[g_msg_len] = '\n';
138             }
139         } else {
140             /* trace is fragmented */
141             g_msg_len += 1;
142             g_msg[g_msg_len] = '\n';
143         }
144         ALOGI("%s", g_msg);
145         /* reset g_msg and g_msg_len */
146         memset(g_msg, 0, LOG_BUF_SIZE);
147         g_msg_len = 0;
148      } while (check_len > LOG_BUF_SIZE);
149 #endif
150 }
151
152 void nam_av_log_set_flags(int arg)
153 {
154     flags = arg;
155 }
156
157 #if 0
158 const struct { const char *name; int level; } log_levels[] = {
159     { "quiet"  , AV_LOG_QUIET   },
160     { "panic"  , AV_LOG_PANIC   },
161     { "fatal"  , AV_LOG_FATAL   },
162     { "error"  , AV_LOG_ERROR   },
163     { "warning", AV_LOG_WARNING },
164     { "info"   , AV_LOG_INFO    },
165     { "verbose", AV_LOG_VERBOSE },
166     { "debug"  , AV_LOG_DEBUG   },
167 };
168
169 #define AV_LOG_QUIET    -8
170 #define AV_LOG_PANIC     0
171 #define AV_LOG_FATAL     8
172 #define AV_LOG_ERROR    16
173 #define AV_LOG_WARNING  24
174 #define AV_LOG_INFO     32
175 #define AV_LOG_VERBOSE  40
176 #define AV_LOG_DEBUG    48
177 #endif
178
179 //////////////////////////////////////////////////////////////////////////////////
180 // constructor and destructor
181 //////////////////////////////////////////////////////////////////////////////////
182 /* Mutex manager callback. */
183 static int lockmgr(void **mtx, enum AVLockOp op)
184 {
185     switch (op) {
186     case AV_LOCK_CREATE:
187         *mtx = (void *)av_malloc(sizeof(pthread_mutex_t));
188         if (!*mtx)
189             return 1;
190         return !!pthread_mutex_init((pthread_mutex_t *)(*mtx), NULL);
191     case AV_LOCK_OBTAIN:
192         return !!pthread_mutex_lock((pthread_mutex_t *)(*mtx));
193     case AV_LOCK_RELEASE:
194         return !!pthread_mutex_unlock((pthread_mutex_t *)(*mtx));
195     case AV_LOCK_DESTROY:
196         pthread_mutex_destroy((pthread_mutex_t *)(*mtx));
197         av_freep(mtx);
198         return 0;
199     }
200     return 1;
201 }
202
203 /**
204  * To debug ffmpeg", type this command on the console before starting playback:
205  *     setprop debug.nam.ffmpeg 1
206  * To disable the debug, type:
207  *     setprop debug.nam.ffmpge 0
208 */
209 status_t initFFmpeg() 
210 {
211     status_t ret = OK;
212     bool debug_enabled = false;
213     char value[PROPERTY_VALUE_MAX];
214
215     pthread_mutex_lock(&s_init_mutex);
216
217     if (property_get("debug.nam.ffmpeg", value, NULL)
218         && (!strcmp(value, "1") || !av_strcasecmp(value, "true"))) {
219         ALOGI("set ffmpeg debug level to AV_LOG_DEBUG");
220         debug_enabled = true;
221     }
222     if (debug_enabled)
223         av_log_set_level(AV_LOG_DEBUG);
224     else
225         av_log_set_level(AV_LOG_INFO);
226
227     if(s_ref_count == 0) {
228         nam_av_log_set_flags(AV_LOG_SKIP_REPEATED);
229         av_log_set_callback(nam_av_log_callback);
230
231         /* register all codecs, demux and protocols */
232         avcodec_register_all();
233 #if CONFIG_AVDEVICE
234         avdevice_register_all();
235 #endif
236         av_register_all();
237         avformat_network_init();
238
239         /* register android source */
240         ffmpeg_register_android_source();
241
242         if (av_lockmgr_register(lockmgr)) {
243             ALOGE("could not initialize lock manager!");
244             ret = NO_INIT;
245         }
246     }
247
248     // update counter
249     s_ref_count++;
250
251     pthread_mutex_unlock(&s_init_mutex);
252
253     return ret;
254 }
255
256 void deInitFFmpeg()
257 {
258     pthread_mutex_lock(&s_init_mutex);
259
260     // update counter
261     s_ref_count--;
262
263     if(s_ref_count == 0) {
264         av_lockmgr_register(NULL);
265         avformat_network_deinit();
266     }
267
268     pthread_mutex_unlock(&s_init_mutex);
269 }
270
271 //////////////////////////////////////////////////////////////////////////////////
272 // parser
273 //////////////////////////////////////////////////////////////////////////////////
274 /* H.264 bitstream with start codes, NOT AVC1! */
275 static int h264_split(AVCodecContext *avctx,
276                 const uint8_t *buf, int buf_size, int check_compatible_only)
277 {
278     int i;
279     uint32_t state = -1;
280     int has_sps= 0;
281     int has_pps= 0;
282
283     //av_hex_dump(stderr, buf, 100);
284
285     for(i=0; i<=buf_size; i++){
286         if((state&0xFFFFFF1F) == 0x107) {
287             ALOGI("found NAL_SPS");
288             has_sps=1;
289         }
290         if((state&0xFFFFFF1F) == 0x108) {
291             ALOGI("found NAL_PPS");
292             has_pps=1;
293             if (check_compatible_only)
294                 return (has_sps & has_pps);
295         }
296         if((state&0xFFFFFF00) == 0x100
297                                 && ((state&0xFFFFFF1F) == 0x101
298                                         || (state&0xFFFFFF1F) == 0x102
299                                         || (state&0xFFFFFF1F) == 0x105)){
300             if(has_pps){
301                 while(i>4 && buf[i-5]==0) i--;
302                 return i-4;
303             }
304         }
305         if (i<buf_size)
306             state= (state<<8) | buf[i];
307     }
308     return 0;
309 }
310
311 static int mpegvideo_split(AVCodecContext *avctx,
312                 const uint8_t *buf, int buf_size, int check_compatible_only)
313 {
314     int i;
315     uint32_t state= -1;
316     int found=0;
317
318     for(i=0; i<buf_size; i++){
319         state= (state<<8) | buf[i];
320         if(state == 0x1B3){
321             found=1;
322         }else if(found && state != 0x1B5 && state < 0x200 && state >= 0x100)
323             return i-3;
324     }
325     return 0;
326 }
327
328 /* split extradata from buf for Android OMXCodec */
329 int parser_split(AVCodecContext *avctx,
330                 const uint8_t *buf, int buf_size)
331 {
332     if (!avctx || !buf || buf_size <= 0) {
333         ALOGE("parser split, valid params");
334         return 0;
335     }
336
337     if (avctx->codec_id == AV_CODEC_ID_H264) {
338         return h264_split(avctx, buf, buf_size, 0);
339     } else if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
340             avctx->codec_id == AV_CODEC_ID_MPEG4) {
341         return mpegvideo_split(avctx, buf, buf_size, 0);
342     } else {
343         ALOGE("parser split, unsupport the codec, id: 0x%0x", avctx->codec_id);
344     }
345
346     return 0;
347 }
348
349 int is_extradata_compatible_with_android(AVCodecContext *avctx)
350 {
351     if (avctx->extradata_size <= 0) {
352         ALOGI("extradata_size <= 0, extradata is not compatible with "
353                                 "android decoder, the codec id: 0x%0x", avctx->codec_id);
354         return 0;
355     }
356
357     if (avctx->codec_id == AV_CODEC_ID_H264
358                         && avctx->extradata[0] != 1 /* configurationVersion */) {
359         // SPS + PPS
360         return !!(h264_split(avctx, avctx->extradata,
361                                         avctx->extradata_size, 1) > 0);
362     } else {
363         // default, FIXME
364         return !!(avctx->extradata_size > 0);
365     }
366 }
367
368 //////////////////////////////////////////////////////////////////////////////////
369 // packet queue
370 //////////////////////////////////////////////////////////////////////////////////
371 void packet_queue_init(PacketQueue *q)
372 {
373     memset(q, 0, sizeof(PacketQueue));
374     pthread_mutex_init(&q->mutex, NULL);
375     pthread_cond_init(&q->cond, NULL);
376
377     av_init_packet(&q->flush_pkt);
378     q->flush_pkt.data = (uint8_t *)&q->flush_pkt;
379     q->flush_pkt.size = 0;
380
381     packet_queue_put(q, &q->flush_pkt);
382 }
383
384 void packet_queue_destroy(PacketQueue *q)
385 {
386     packet_queue_flush(q);
387     pthread_mutex_destroy(&q->mutex);
388     pthread_cond_destroy(&q->cond);
389 }
390
391 void packet_queue_flush(PacketQueue *q)
392 {
393     AVPacketList *pkt, *pkt1;
394
395     pthread_mutex_lock(&q->mutex);
396     for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
397         pkt1 = pkt->next;
398         av_free_packet(&pkt->pkt);
399         av_freep(&pkt);
400     }
401     q->last_pkt = NULL;
402     q->first_pkt = NULL;
403     q->nb_packets = 0;
404     q->size = 0;
405     pthread_mutex_unlock(&q->mutex);
406 }
407
408 void packet_queue_end(PacketQueue *q)
409 {
410     packet_queue_flush(q);
411 }
412
413 void packet_queue_abort(PacketQueue *q)
414 {
415     pthread_mutex_lock(&q->mutex);
416
417     q->abort_request = 1;
418
419     pthread_cond_signal(&q->cond);
420
421     pthread_mutex_unlock(&q->mutex);
422 }
423
424 int packet_queue_put(PacketQueue *q, AVPacket *pkt)
425 {
426     AVPacketList *pkt1;
427
428     /* duplicate the packet */
429     if (pkt != &q->flush_pkt && av_dup_packet(pkt) < 0)
430         return -1;
431
432     pkt1 = (AVPacketList *)av_malloc(sizeof(AVPacketList));
433     if (!pkt1)
434         return -1;
435     pkt1->pkt = *pkt;
436     pkt1->next = NULL;
437
438     pthread_mutex_lock(&q->mutex);
439
440     if (!q->last_pkt)
441
442         q->first_pkt = pkt1;
443     else
444         q->last_pkt->next = pkt1;
445     q->last_pkt = pkt1;
446     q->nb_packets++;
447     //q->size += pkt1->pkt.size + sizeof(*pkt1);
448     q->size += pkt1->pkt.size;
449     pthread_cond_signal(&q->cond);
450
451     pthread_mutex_unlock(&q->mutex);
452     return 0;
453 }
454
455 int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
456 {
457     AVPacket pkt1, *pkt = &pkt1;
458     av_init_packet(pkt);
459     pkt->data = NULL;
460     pkt->size = 0;
461     pkt->stream_index = stream_index;
462     return packet_queue_put(q, pkt);
463 }
464
465 /* packet queue handling */
466 /* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
467 int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
468 {
469     AVPacketList *pkt1;
470     int ret;
471
472     pthread_mutex_lock(&q->mutex);
473
474     for (;;) {
475         if (q->abort_request) {
476             ret = -1;
477             break;
478         }
479
480         pkt1 = q->first_pkt;
481         if (pkt1) {
482             q->first_pkt = pkt1->next;
483             if (!q->first_pkt)
484                 q->last_pkt = NULL;
485             q->nb_packets--;
486             //q->size -= pkt1->pkt.size + sizeof(*pkt1);
487             q->size -= pkt1->pkt.size;
488             *pkt = pkt1->pkt;
489             av_free(pkt1);
490             ret = 1;
491             break;
492         } else if (!block) {
493             ret = 0;
494             break;
495         } else {
496             pthread_cond_wait(&q->cond, &q->mutex);
497         }
498     }
499     pthread_mutex_unlock(&q->mutex);
500     return ret;
501 }
502
503 //////////////////////////////////////////////////////////////////////////////////
504 // misc
505 //////////////////////////////////////////////////////////////////////////////////
506 bool setup_vorbis_extradata(uint8_t **extradata, int *extradata_size,
507         const uint8_t *header_start[3], const int header_len[3])
508 {
509         uint8_t *p = NULL;
510     int len = 0;
511     int i = 0;
512
513     len = header_len[0] + header_len[1] + header_len[2];
514     p = *extradata = (uint8_t *)av_mallocz(64 + len + len/255);
515     if (!p) {
516         ALOGE("oom for vorbis extradata");
517         return false;
518         }
519
520     *p++ = 2;
521     p += av_xiphlacing(p, header_len[0]);
522     p += av_xiphlacing(p, header_len[1]);
523     for (i = 0; i < 3; i++) {
524         if (header_len[i] > 0) {
525             memcpy(p, header_start[i], header_len[i]);
526             p += header_len[i];
527         }
528     }
529     *extradata_size = p - *extradata;
530
531     return true;
532 }
533
534 }  // namespace android
535