Mercurial > libavformat.hg
annotate avc.c @ 5061:5ff6a72c9686 libavformat
In mov_read_packet remember the AVStream we want to demux next instead of the
MOVStreamContext. We need the AVStream anyway and it is easier to get the
MOVStreamContext from the AVStream than the other way around.
author | reimar |
---|---|
date | Wed, 24 Jun 2009 08:23:40 +0000 |
parents | dd9383951cb9 |
children | 6ea4f08de89a |
rev | line source |
---|---|
201
85def00971c3
mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff
changeset
|
1 /* |
2922
dcd599833abc
Move isom_write_avcc() and related functions into a separate file.
aurel
parents:
2921
diff
changeset
|
2 * AVC helper functions for muxers |
dcd599833abc
Move isom_write_avcc() and related functions into a separate file.
aurel
parents:
2921
diff
changeset
|
3 * Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@smartjog.com> |
201
85def00971c3
mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff
changeset
|
4 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1292
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1292
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1292
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
201
85def00971c3
mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff
changeset
|
8 * modify it under the terms of the GNU Lesser General Public |
85def00971c3
mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff
changeset
|
9 * License as published by the Free Software Foundation; either |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1292
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
201
85def00971c3
mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff
changeset
|
11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1292
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
201
85def00971c3
mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
85def00971c3
mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
85def00971c3
mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff
changeset
|
15 * Lesser General Public License for more details. |
85def00971c3
mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff
changeset
|
16 * |
85def00971c3
mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff
changeset
|
17 * You should have received a copy of the GNU Lesser General Public |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1292
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
890
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
201
85def00971c3
mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff
changeset
|
20 */ |
4201
7d2f3f1b68d8
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
3050
diff
changeset
|
21 |
7d2f3f1b68d8
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
3050
diff
changeset
|
22 #include "libavutil/intreadwrite.h" |
201
85def00971c3
mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff
changeset
|
23 #include "avformat.h" |
85def00971c3
mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff
changeset
|
24 #include "avio.h" |
85def00971c3
mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff
changeset
|
25 |
3049 | 26 const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end) |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
27 { |
4792 | 28 const uint8_t *a = p + 4 - ((intptr_t)p & 3); |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
29 |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
30 for( end -= 3; p < a && p < end; p++ ) { |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
31 if( p[0] == 0 && p[1] == 0 && p[2] == 1 ) |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
32 return p; |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
33 } |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
34 |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
35 for( end -= 3; p < end; p += 4 ) { |
3050
be4d4abb3eed
Fix misplaced const, avoids a cast-discards-qualifiers warning
reimar
parents:
3049
diff
changeset
|
36 uint32_t x = *(const uint32_t*)p; |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
37 // if( (x - 0x01000100) & (~x) & 0x80008000 ) // little endian |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
38 // if( (x - 0x00010001) & (~x) & 0x00800080 ) // big endian |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
39 if( (x - 0x01010101) & (~x) & 0x80808080 ) { // generic |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
40 if( p[1] == 0 ) { |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
41 if( p[0] == 0 && p[2] == 1 ) |
1088 | 42 return p-1; |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
43 if( p[2] == 0 && p[3] == 1 ) |
1088 | 44 return p; |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
45 } |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
46 if( p[3] == 0 ) { |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
47 if( p[2] == 0 && p[4] == 1 ) |
1088 | 48 return p+1; |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
49 if( p[4] == 0 && p[5] == 1 ) |
1088 | 50 return p+2; |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
51 } |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
52 } |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
53 } |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
54 |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
55 for( end += 3; p < end; p++ ) { |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
56 if( p[0] == 0 && p[1] == 0 && p[2] == 1 ) |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
57 return p; |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
58 } |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
59 |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
60 return end + 3; |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
61 } |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
62 |
4224 | 63 int ff_avc_parse_nal_units(ByteIOContext *pb, const uint8_t *buf_in, int size) |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
64 { |
3049 | 65 const uint8_t *p = buf_in; |
4222
0267c4299992
Do not reallocate AVPacket's data when muxing a packet
lucabe
parents:
4201
diff
changeset
|
66 const uint8_t *end = p + size; |
3049 | 67 const uint8_t *nal_start, *nal_end; |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
68 |
4224 | 69 size = 0; |
2935
88a67636f192
Make avc_find_startcode non-static, so that it can be used from other
lucabe
parents:
2927
diff
changeset
|
70 nal_start = ff_avc_find_startcode(p, end); |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
71 while (nal_start < end) { |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
72 while(!*(nal_start++)); |
2935
88a67636f192
Make avc_find_startcode non-static, so that it can be used from other
lucabe
parents:
2927
diff
changeset
|
73 nal_end = ff_avc_find_startcode(nal_start, end); |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2669
diff
changeset
|
74 put_be32(pb, nal_end - nal_start); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2669
diff
changeset
|
75 put_buffer(pb, nal_start, nal_end - nal_start); |
4224 | 76 size += 4 + nal_end - nal_start; |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
77 nal_start = nal_end; |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
78 } |
4224 | 79 return size; |
4222
0267c4299992
Do not reallocate AVPacket's data when muxing a packet
lucabe
parents:
4201
diff
changeset
|
80 } |
0267c4299992
Do not reallocate AVPacket's data when muxing a packet
lucabe
parents:
4201
diff
changeset
|
81 |
4226 | 82 int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size) |
4222
0267c4299992
Do not reallocate AVPacket's data when muxing a packet
lucabe
parents:
4201
diff
changeset
|
83 { |
0267c4299992
Do not reallocate AVPacket's data when muxing a packet
lucabe
parents:
4201
diff
changeset
|
84 ByteIOContext *pb; |
0267c4299992
Do not reallocate AVPacket's data when muxing a packet
lucabe
parents:
4201
diff
changeset
|
85 int ret = url_open_dyn_buf(&pb); |
0267c4299992
Do not reallocate AVPacket's data when muxing a packet
lucabe
parents:
4201
diff
changeset
|
86 if(ret < 0) |
0267c4299992
Do not reallocate AVPacket's data when muxing a packet
lucabe
parents:
4201
diff
changeset
|
87 return ret; |
0267c4299992
Do not reallocate AVPacket's data when muxing a packet
lucabe
parents:
4201
diff
changeset
|
88 |
0267c4299992
Do not reallocate AVPacket's data when muxing a packet
lucabe
parents:
4201
diff
changeset
|
89 ff_avc_parse_nal_units(pb, buf_in, *size); |
0267c4299992
Do not reallocate AVPacket's data when muxing a packet
lucabe
parents:
4201
diff
changeset
|
90 |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
91 av_freep(buf); |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2669
diff
changeset
|
92 *size = url_close_dyn_buf(pb, buf); |
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2669
diff
changeset
|
93 return 0; |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
94 } |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
95 |
3049 | 96 int ff_isom_write_avcc(ByteIOContext *pb, const uint8_t *data, int len) |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
97 { |
2921 | 98 if (len > 6) { |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
99 /* check for h264 start code */ |
4229 | 100 if (AV_RB32(data) == 0x00000001 || |
101 AV_RB24(data) == 0x000001) { | |
3049 | 102 uint8_t *buf=NULL, *end, *start; |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
103 uint32_t sps_size=0, pps_size=0; |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
104 uint8_t *sps=0, *pps=0; |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
105 |
4222
0267c4299992
Do not reallocate AVPacket's data when muxing a packet
lucabe
parents:
4201
diff
changeset
|
106 int ret = ff_avc_parse_nal_units_buf(data, &buf, &len); |
2919 | 107 if (ret < 0) |
108 return ret; | |
3049 | 109 start = buf; |
2921 | 110 end = buf + len; |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
111 |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
112 /* look for sps and pps */ |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
113 while (buf < end) { |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
114 unsigned int size; |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
115 uint8_t nal_type; |
1673 | 116 size = AV_RB32(buf); |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
117 nal_type = buf[4] & 0x1f; |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
118 if (nal_type == 7) { /* SPS */ |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
119 sps = buf + 4; |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
120 sps_size = size; |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
121 } else if (nal_type == 8) { /* PPS */ |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
122 pps = buf + 4; |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
123 pps_size = size; |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
124 } |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
125 buf += size + 4; |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
126 } |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
127 assert(sps); |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
128 assert(pps); |
1056
4af4c74a4548
get avcC profile and level indication from sps (from handbrake)
bcoudurier
parents:
1055
diff
changeset
|
129 |
4af4c74a4548
get avcC profile and level indication from sps (from handbrake)
bcoudurier
parents:
1055
diff
changeset
|
130 put_byte(pb, 1); /* version */ |
4af4c74a4548
get avcC profile and level indication from sps (from handbrake)
bcoudurier
parents:
1055
diff
changeset
|
131 put_byte(pb, sps[1]); /* profile */ |
4af4c74a4548
get avcC profile and level indication from sps (from handbrake)
bcoudurier
parents:
1055
diff
changeset
|
132 put_byte(pb, sps[2]); /* profile compat */ |
4af4c74a4548
get avcC profile and level indication from sps (from handbrake)
bcoudurier
parents:
1055
diff
changeset
|
133 put_byte(pb, sps[3]); /* level */ |
4af4c74a4548
get avcC profile and level indication from sps (from handbrake)
bcoudurier
parents:
1055
diff
changeset
|
134 put_byte(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */ |
4af4c74a4548
get avcC profile and level indication from sps (from handbrake)
bcoudurier
parents:
1055
diff
changeset
|
135 put_byte(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */ |
4af4c74a4548
get avcC profile and level indication from sps (from handbrake)
bcoudurier
parents:
1055
diff
changeset
|
136 |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
137 put_be16(pb, sps_size); |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
138 put_buffer(pb, sps, sps_size); |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
139 put_byte(pb, 1); /* number of pps */ |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
140 put_be16(pb, pps_size); |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
141 put_buffer(pb, pps, pps_size); |
3049 | 142 av_free(start); |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
143 } else { |
2921 | 144 put_buffer(pb, data, len); |
1006
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
145 } |
15bfc3c063dc
do nal reformating when muxing H264, create avcc atom
bcoudurier
parents:
1000
diff
changeset
|
146 } |
2921 | 147 return 0; |
148 } |