annotate avc.c @ 3044:410abc272c3b libavformat

Read match time delta in the frame header. We do not do anything with it as lavf does not really support it yet.
author michael
date Wed, 13 Feb 2008 20:17:28 +0000
parents 88a67636f192
children df47846972da
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 */
85def00971c3 mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff changeset
21 #include "avformat.h"
85def00971c3 mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff changeset
22 #include "avio.h"
85def00971c3 mov, 3gp, mp4 muxer by (Thomas Raivio <tjraivio at cc dot hut dot fi>)
michaelni
parents:
diff changeset
23
2935
88a67636f192 Make avc_find_startcode non-static, so that it can be used from other
lucabe
parents: 2927
diff changeset
24 uint8_t *ff_avc_find_startcode(uint8_t *p, uint8_t *end)
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
25 {
2233
886efa933499 kill harmless 64-bit pointer cast warning
mru
parents: 2165
diff changeset
26 uint8_t *a = p + 4 - ((long)p & 3);
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
27
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
28 for( end -= 3; p < a && p < end; p++ ) {
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
29 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
30 return p;
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
31 }
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
32
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
33 for( end -= 3; p < end; p += 4 ) {
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
34 uint32_t x = *(uint32_t*)p;
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
35 // if( (x - 0x01000100) & (~x) & 0x80008000 ) // little endian
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
36 // if( (x - 0x00010001) & (~x) & 0x00800080 ) // big endian
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
37 if( (x - 0x01010101) & (~x) & 0x80808080 ) { // generic
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
38 if( p[1] == 0 ) {
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
39 if( p[0] == 0 && p[2] == 1 )
1088
e7fd91082489 fix avc nal parsing
bcoudurier
parents: 1085
diff changeset
40 return p-1;
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
41 if( p[2] == 0 && p[3] == 1 )
1088
e7fd91082489 fix avc nal parsing
bcoudurier
parents: 1085
diff changeset
42 return p;
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
43 }
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
44 if( p[3] == 0 ) {
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
45 if( p[2] == 0 && p[4] == 1 )
1088
e7fd91082489 fix avc nal parsing
bcoudurier
parents: 1085
diff changeset
46 return p+1;
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
47 if( p[4] == 0 && p[5] == 1 )
1088
e7fd91082489 fix avc nal parsing
bcoudurier
parents: 1085
diff changeset
48 return p+2;
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
49 }
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
50 }
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 for( end += 3; p < end; p++ ) {
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
54 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
55 return p;
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
56 }
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
57
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
58 return end + 3;
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
2927
b75a49790f31 add a ff_ prefix to newly exported functions from avc.c
aurel
parents: 2922
diff changeset
61 int ff_avc_parse_nal_units(uint8_t *buf_in, uint8_t **buf, int *size)
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
62 {
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2669
diff changeset
63 ByteIOContext *pb;
2920
5f15ed0f5fdc Add one more parameter to avc_parse_nal_units so that it allows not to
aurel
parents: 2919
diff changeset
64 uint8_t *p = buf_in;
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
65 uint8_t *end = p + *size;
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
66 uint8_t *nal_start, *nal_end;
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2669
diff changeset
67 int ret = url_open_dyn_buf(&pb);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2669
diff changeset
68 if(ret < 0)
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2669
diff changeset
69 return ret;
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
70
2935
88a67636f192 Make avc_find_startcode non-static, so that it can be used from other
lucabe
parents: 2927
diff changeset
71 nal_start = ff_avc_find_startcode(p, end);
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
72 while (nal_start < end) {
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
73 while(!*(nal_start++));
2935
88a67636f192 Make avc_find_startcode non-static, so that it can be used from other
lucabe
parents: 2927
diff changeset
74 nal_end = ff_avc_find_startcode(nal_start, end);
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2669
diff changeset
75 put_be32(pb, nal_end - nal_start);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2669
diff changeset
76 put_buffer(pb, nal_start, 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 }
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
79 av_freep(buf);
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2669
diff changeset
80 *size = url_close_dyn_buf(pb, buf);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2669
diff changeset
81 return 0;
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
82 }
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
83
2927
b75a49790f31 add a ff_ prefix to newly exported functions from avc.c
aurel
parents: 2922
diff changeset
84 int ff_isom_write_avcc(ByteIOContext *pb, uint8_t *data, int len)
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
85 {
2921
dab2aecebb97 extract isom_write_avcc into a function
aurel
parents: 2920
diff changeset
86 if (len > 6) {
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
87 /* check for h264 start code */
2921
dab2aecebb97 extract isom_write_avcc into a function
aurel
parents: 2920
diff changeset
88 if (AV_RB32(data) == 0x00000001) {
dab2aecebb97 extract isom_write_avcc into a function
aurel
parents: 2920
diff changeset
89 uint8_t *buf=NULL, *end;
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
90 uint32_t sps_size=0, pps_size=0;
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
91 uint8_t *sps=0, *pps=0;
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
92
2927
b75a49790f31 add a ff_ prefix to newly exported functions from avc.c
aurel
parents: 2922
diff changeset
93 int ret = ff_avc_parse_nal_units(data, &buf, &len);
2919
e70dc14a3f9f Check return value of avc_parse_nal_units().
aurel
parents: 2845
diff changeset
94 if (ret < 0)
e70dc14a3f9f Check return value of avc_parse_nal_units().
aurel
parents: 2845
diff changeset
95 return ret;
2921
dab2aecebb97 extract isom_write_avcc into a function
aurel
parents: 2920
diff changeset
96 data = buf;
dab2aecebb97 extract isom_write_avcc into a function
aurel
parents: 2920
diff changeset
97 end = buf + len;
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
98
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
99 /* look for sps and pps */
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
100 while (buf < end) {
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
101 unsigned int size;
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
102 uint8_t nal_type;
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1565
diff changeset
103 size = AV_RB32(buf);
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
104 nal_type = buf[4] & 0x1f;
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
105 if (nal_type == 7) { /* SPS */
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
106 sps = buf + 4;
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
107 sps_size = size;
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
108 } else if (nal_type == 8) { /* PPS */
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
109 pps = buf + 4;
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
110 pps_size = size;
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 buf += size + 4;
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
113 }
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
114 assert(sps);
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
115 assert(pps);
1056
4af4c74a4548 get avcC profile and level indication from sps (from handbrake)
bcoudurier
parents: 1055
diff changeset
116
4af4c74a4548 get avcC profile and level indication from sps (from handbrake)
bcoudurier
parents: 1055
diff changeset
117 put_byte(pb, 1); /* version */
4af4c74a4548 get avcC profile and level indication from sps (from handbrake)
bcoudurier
parents: 1055
diff changeset
118 put_byte(pb, sps[1]); /* profile */
4af4c74a4548 get avcC profile and level indication from sps (from handbrake)
bcoudurier
parents: 1055
diff changeset
119 put_byte(pb, sps[2]); /* profile compat */
4af4c74a4548 get avcC profile and level indication from sps (from handbrake)
bcoudurier
parents: 1055
diff changeset
120 put_byte(pb, sps[3]); /* level */
4af4c74a4548 get avcC profile and level indication from sps (from handbrake)
bcoudurier
parents: 1055
diff changeset
121 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
122 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
123
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
124 put_be16(pb, sps_size);
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
125 put_buffer(pb, sps, sps_size);
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
126 put_byte(pb, 1); /* number of pps */
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
127 put_be16(pb, pps_size);
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
128 put_buffer(pb, pps, pps_size);
2921
dab2aecebb97 extract isom_write_avcc into a function
aurel
parents: 2920
diff changeset
129 av_free(data);
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
130 } else {
2921
dab2aecebb97 extract isom_write_avcc into a function
aurel
parents: 2920
diff changeset
131 put_buffer(pb, data, len);
1006
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
132 }
15bfc3c063dc do nal reformating when muxing H264, create avcc atom
bcoudurier
parents: 1000
diff changeset
133 }
2921
dab2aecebb97 extract isom_write_avcc into a function
aurel
parents: 2920
diff changeset
134 return 0;
dab2aecebb97 extract isom_write_avcc into a function
aurel
parents: 2920
diff changeset
135 }