Browse code

Move isom_write_avcc() and related functions into a separate file.

Originally committed as revision 11498 to svn://svn.ffmpeg.org/ffmpeg/trunk

Aurelien Jacobs authored on 2008/01/11 10:24:55
Showing 4 changed files
... ...
@@ -79,11 +79,11 @@ OBJS-$(CONFIG_MM_DEMUXER)                += mm.o
79 79
 OBJS-$(CONFIG_MMF_DEMUXER)               += mmf.o raw.o
80 80
 OBJS-$(CONFIG_MMF_MUXER)                 += mmf.o riff.o
81 81
 OBJS-$(CONFIG_MOV_DEMUXER)               += mov.o riff.o isom.o
82
-OBJS-$(CONFIG_MOV_MUXER)                 += movenc.o riff.o isom.o
82
+OBJS-$(CONFIG_MOV_MUXER)                 += movenc.o riff.o isom.o avc.o
83 83
 OBJS-$(CONFIG_MP2_MUXER)                 += mp3.o
84 84
 OBJS-$(CONFIG_MP3_DEMUXER)               += mp3.o
85 85
 OBJS-$(CONFIG_MP3_MUXER)                 += mp3.o
86
-OBJS-$(CONFIG_MP4_MUXER)                 += movenc.o riff.o isom.o
86
+OBJS-$(CONFIG_MP4_MUXER)                 += movenc.o riff.o isom.o avc.o
87 87
 OBJS-$(CONFIG_MPC_DEMUXER)               += mpc.o
88 88
 OBJS-$(CONFIG_MPC8_DEMUXER)              += mpc8.o
89 89
 OBJS-$(CONFIG_MPEG1SYSTEM_MUXER)         += mpegenc.o
... ...
@@ -113,7 +113,7 @@ OBJS-$(CONFIG_OGG_DEMUXER)               += oggdec.o         \
113 113
                                             oggparsevorbis.o \
114 114
                                             riff.o
115 115
 OBJS-$(CONFIG_OGG_MUXER)                 += oggenc.o
116
-OBJS-$(CONFIG_PSP_MUXER)                 += movenc.o riff.o isom.o
116
+OBJS-$(CONFIG_PSP_MUXER)                 += movenc.o riff.o isom.o avc.o
117 117
 OBJS-$(CONFIG_PVA_DEMUXER)               += pva.o
118 118
 OBJS-$(CONFIG_RAWVIDEO_DEMUXER)          += raw.o
119 119
 OBJS-$(CONFIG_RAWVIDEO_MUXER)            += raw.o
... ...
@@ -133,8 +133,8 @@ OBJS-$(CONFIG_SOL_DEMUXER)               += sol.o raw.o
133 133
 OBJS-$(CONFIG_STR_DEMUXER)               += psxstr.o
134 134
 OBJS-$(CONFIG_SWF_DEMUXER)               += swf.o
135 135
 OBJS-$(CONFIG_SWF_MUXER)                 += swf.o
136
-OBJS-$(CONFIG_TG2_MUXER)                 += movenc.o riff.o isom.o
137
-OBJS-$(CONFIG_TGP_MUXER)                 += movenc.o riff.o isom.o
136
+OBJS-$(CONFIG_TG2_MUXER)                 += movenc.o riff.o isom.o avc.o
137
+OBJS-$(CONFIG_TGP_MUXER)                 += movenc.o riff.o isom.o avc.o
138 138
 OBJS-$(CONFIG_THP_DEMUXER)               += thp.o
139 139
 OBJS-$(CONFIG_TIERTEXSEQ_DEMUXER)        += tiertexseq.o
140 140
 OBJS-$(CONFIG_TTA_DEMUXER)               += tta.o
141 141
new file mode 100644
... ...
@@ -0,0 +1,135 @@
0
+/*
1
+ * AVC helper functions for muxers
2
+ * Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@smartjog.com>
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+#include "avformat.h"
21
+#include "avio.h"
22
+
23
+static uint8_t *avc_find_startcode( uint8_t *p, uint8_t *end )
24
+{
25
+    uint8_t *a = p + 4 - ((long)p & 3);
26
+
27
+    for( end -= 3; p < a && p < end; p++ ) {
28
+        if( p[0] == 0 && p[1] == 0 && p[2] == 1 )
29
+            return p;
30
+    }
31
+
32
+    for( end -= 3; p < end; p += 4 ) {
33
+        uint32_t x = *(uint32_t*)p;
34
+//      if( (x - 0x01000100) & (~x) & 0x80008000 ) // little endian
35
+//      if( (x - 0x00010001) & (~x) & 0x00800080 ) // big endian
36
+        if( (x - 0x01010101) & (~x) & 0x80808080 ) { // generic
37
+            if( p[1] == 0 ) {
38
+                if( p[0] == 0 && p[2] == 1 )
39
+                    return p-1;
40
+                if( p[2] == 0 && p[3] == 1 )
41
+                    return p;
42
+            }
43
+            if( p[3] == 0 ) {
44
+                if( p[2] == 0 && p[4] == 1 )
45
+                    return p+1;
46
+                if( p[4] == 0 && p[5] == 1 )
47
+                    return p+2;
48
+            }
49
+        }
50
+    }
51
+
52
+    for( end += 3; p < end; p++ ) {
53
+        if( p[0] == 0 && p[1] == 0 && p[2] == 1 )
54
+            return p;
55
+    }
56
+
57
+    return end + 3;
58
+}
59
+
60
+int avc_parse_nal_units(uint8_t *buf_in, uint8_t **buf, int *size)
61
+{
62
+    ByteIOContext *pb;
63
+    uint8_t *p = buf_in;
64
+    uint8_t *end = p + *size;
65
+    uint8_t *nal_start, *nal_end;
66
+    int ret = url_open_dyn_buf(&pb);
67
+    if(ret < 0)
68
+        return ret;
69
+
70
+    nal_start = avc_find_startcode(p, end);
71
+    while (nal_start < end) {
72
+        while(!*(nal_start++));
73
+        nal_end = avc_find_startcode(nal_start, end);
74
+        put_be32(pb, nal_end - nal_start);
75
+        put_buffer(pb, nal_start, nal_end - nal_start);
76
+        nal_start = nal_end;
77
+    }
78
+    av_freep(buf);
79
+    *size = url_close_dyn_buf(pb, buf);
80
+    return 0;
81
+}
82
+
83
+int isom_write_avcc(ByteIOContext *pb, uint8_t *data, int len)
84
+{
85
+    if (len > 6) {
86
+        /* check for h264 start code */
87
+        if (AV_RB32(data) == 0x00000001) {
88
+            uint8_t *buf=NULL, *end;
89
+            uint32_t sps_size=0, pps_size=0;
90
+            uint8_t *sps=0, *pps=0;
91
+
92
+            int ret = avc_parse_nal_units(data, &buf, &len);
93
+            if (ret < 0)
94
+                return ret;
95
+            data = buf;
96
+            end = buf + len;
97
+
98
+            /* look for sps and pps */
99
+            while (buf < end) {
100
+                unsigned int size;
101
+                uint8_t nal_type;
102
+                size = AV_RB32(buf);
103
+                nal_type = buf[4] & 0x1f;
104
+                if (nal_type == 7) { /* SPS */
105
+                    sps = buf + 4;
106
+                    sps_size = size;
107
+                } else if (nal_type == 8) { /* PPS */
108
+                    pps = buf + 4;
109
+                    pps_size = size;
110
+                }
111
+                buf += size + 4;
112
+            }
113
+            assert(sps);
114
+            assert(pps);
115
+
116
+            put_byte(pb, 1); /* version */
117
+            put_byte(pb, sps[1]); /* profile */
118
+            put_byte(pb, sps[2]); /* profile compat */
119
+            put_byte(pb, sps[3]); /* level */
120
+            put_byte(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */
121
+            put_byte(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */
122
+
123
+            put_be16(pb, sps_size);
124
+            put_buffer(pb, sps, sps_size);
125
+            put_byte(pb, 1); /* number of pps */
126
+            put_be16(pb, pps_size);
127
+            put_buffer(pb, pps, pps_size);
128
+            av_free(data);
129
+        } else {
130
+            put_buffer(pb, data, len);
131
+        }
132
+    }
133
+    return 0;
134
+}
0 135
new file mode 100644
... ...
@@ -0,0 +1,31 @@
0
+/*
1
+ * AVC helper functions for muxers
2
+ * Copyright (c) 2008 Aurelien Jacobs <aurel@gnuage.org>
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+#ifndef AVC_H
22
+#define AVC_H
23
+
24
+#include <stdint.h>
25
+#include "avio.h"
26
+
27
+int avc_parse_nal_units(uint8_t *buf_in, uint8_t **buf, int *size);
28
+int isom_write_avcc(ByteIOContext *pb, uint8_t *data, int len);
29
+
30
+#endif /* AVC_H */
... ...
@@ -23,6 +23,7 @@
23 23
 #include "riff.h"
24 24
 #include "avio.h"
25 25
 #include "isom.h"
26
+#include "avc.h"
26 27
 
27 28
 #undef NDEBUG
28 29
 #include <assert.h>
... ...
@@ -415,119 +416,6 @@ static int mov_write_svq3_tag(ByteIOContext *pb)
415 415
     return 0x15;
416 416
 }
417 417
 
418
-static uint8_t *avc_find_startcode( uint8_t *p, uint8_t *end )
419
-{
420
-    uint8_t *a = p + 4 - ((long)p & 3);
421
-
422
-    for( end -= 3; p < a && p < end; p++ ) {
423
-        if( p[0] == 0 && p[1] == 0 && p[2] == 1 )
424
-            return p;
425
-    }
426
-
427
-    for( end -= 3; p < end; p += 4 ) {
428
-        uint32_t x = *(uint32_t*)p;
429
-//      if( (x - 0x01000100) & (~x) & 0x80008000 ) // little endian
430
-//      if( (x - 0x00010001) & (~x) & 0x00800080 ) // big endian
431
-        if( (x - 0x01010101) & (~x) & 0x80808080 ) { // generic
432
-            if( p[1] == 0 ) {
433
-                if( p[0] == 0 && p[2] == 1 )
434
-                    return p-1;
435
-                if( p[2] == 0 && p[3] == 1 )
436
-                    return p;
437
-            }
438
-            if( p[3] == 0 ) {
439
-                if( p[2] == 0 && p[4] == 1 )
440
-                    return p+1;
441
-                if( p[4] == 0 && p[5] == 1 )
442
-                    return p+2;
443
-            }
444
-        }
445
-    }
446
-
447
-    for( end += 3; p < end; p++ ) {
448
-        if( p[0] == 0 && p[1] == 0 && p[2] == 1 )
449
-            return p;
450
-    }
451
-
452
-    return end + 3;
453
-}
454
-
455
-static int avc_parse_nal_units(uint8_t *buf_in, uint8_t **buf, int *size)
456
-{
457
-    ByteIOContext *pb;
458
-    uint8_t *p = buf_in;
459
-    uint8_t *end = p + *size;
460
-    uint8_t *nal_start, *nal_end;
461
-    int ret = url_open_dyn_buf(&pb);
462
-    if(ret < 0)
463
-        return ret;
464
-
465
-    nal_start = avc_find_startcode(p, end);
466
-    while (nal_start < end) {
467
-        while(!*(nal_start++));
468
-        nal_end = avc_find_startcode(nal_start, end);
469
-        put_be32(pb, nal_end - nal_start);
470
-        put_buffer(pb, nal_start, nal_end - nal_start);
471
-        nal_start = nal_end;
472
-    }
473
-    av_freep(buf);
474
-    *size = url_close_dyn_buf(pb, buf);
475
-    return 0;
476
-}
477
-
478
-static int isom_write_avcc(ByteIOContext *pb, uint8_t *data, int len)
479
-{
480
-    if (len > 6) {
481
-        /* check for h264 start code */
482
-        if (AV_RB32(data) == 0x00000001) {
483
-            uint8_t *buf=NULL, *end;
484
-            uint32_t sps_size=0, pps_size=0;
485
-            uint8_t *sps=0, *pps=0;
486
-
487
-            int ret = avc_parse_nal_units(data, &buf, &len);
488
-            if (ret < 0)
489
-                return ret;
490
-            data = buf;
491
-            end = buf + len;
492
-
493
-            /* look for sps and pps */
494
-            while (buf < end) {
495
-                unsigned int size;
496
-                uint8_t nal_type;
497
-                size = AV_RB32(buf);
498
-                nal_type = buf[4] & 0x1f;
499
-                if (nal_type == 7) { /* SPS */
500
-                    sps = buf + 4;
501
-                    sps_size = size;
502
-                } else if (nal_type == 8) { /* PPS */
503
-                    pps = buf + 4;
504
-                    pps_size = size;
505
-                }
506
-                buf += size + 4;
507
-            }
508
-            assert(sps);
509
-            assert(pps);
510
-
511
-            put_byte(pb, 1); /* version */
512
-            put_byte(pb, sps[1]); /* profile */
513
-            put_byte(pb, sps[2]); /* profile compat */
514
-            put_byte(pb, sps[3]); /* level */
515
-            put_byte(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */
516
-            put_byte(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */
517
-
518
-            put_be16(pb, sps_size);
519
-            put_buffer(pb, sps, sps_size);
520
-            put_byte(pb, 1); /* number of pps */
521
-            put_be16(pb, pps_size);
522
-            put_buffer(pb, pps, pps_size);
523
-            av_free(data);
524
-        } else {
525
-            put_buffer(pb, data, len);
526
-        }
527
-    }
528
-    return 0;
529
-}
530
-
531 418
 static int mov_write_avcc_tag(ByteIOContext *pb, MOVTrack *track)
532 419
 {
533 420
     offset_t pos = url_ftell(pb);