Project

General

Profile

Bug #555 » mkv_h264_fix_v2.patch

tvheadend H264 fix - patrick boissonade, 2011-10-20 14:44

View differences:

andoma-tvheadend-c88a646_modif/Makefile 2011-10-14 15:05:59.461127001 +0200
26 26

  
27 27
CFLAGS  = -Wall -Werror -Wwrite-strings -Wno-deprecated-declarations 
28 28
CFLAGS += -Wmissing-prototypes
29
LDFLAGS += -lrt -ldl
29
LDFLAGS += -lrt -ldl -lavformat -lavutil
30 30

  
31 31
#
32 32
# Core
......
78 78
	src/dvr/dvr_autorec.c \
79 79
	src/dvr/ebml.c \
80 80
	src/dvr/mkmux.c \
81
	src/avc.c \
81 82

  
82 83
SRCS-${CONFIG_LINUXDVB} += \
83 84
	src/dvb/dvb.c \
andoma-tvheadend-c88a646_modif/src/avc.c 2011-10-14 14:59:29.456127002 +0200
23 23

  
24 24
const uint8_t *avc_find_startcode(const uint8_t *p, const uint8_t *end)
25 25
{
26
    const uint8_t *a = p + 4 - ((long)p & 3);
27

  
28
    for( end -= 3; p < a && p < end; p++ ) {
29
        if( p[0] == 0 && p[1] == 0 && p[2] == 1 )
30
            return p;
31
    }
32

  
33
    for( end -= 3; p < end; p += 4 ) {
34
        uint32_t x = *(const uint32_t*)p;
35
//      if( (x - 0x01000100) & (~x) & 0x80008000 ) // little endian
36
//      if( (x - 0x00010001) & (~x) & 0x00800080 ) // big endian
37
        if( (x - 0x01010101) & (~x) & 0x80808080 ) { // generic
38
            if( p[1] == 0 ) {
39
                if( p[0] == 0 && p[2] == 1 )
40
                    return p-1;
41
                if( p[2] == 0 && p[3] == 1 )
42
                    return p;
43
            }
44
            if( p[3] == 0 ) {
45
                if( p[2] == 0 && p[4] == 1 )
46
                    return p+1;
47
                if( p[4] == 0 && p[5] == 1 )
48
                    return p+2;
49
            }
50
        }
51
    }
52

  
53
    for( end += 3; p < end; p++ ) {
54
        if( p[0] == 0 && p[1] == 0 && p[2] == 1 )
55
            return p;
56
    }
57

  
58
    return end + 3;
26
	int i;
27
	
28
	uint32_t sc=0xFFFFFFFF;
29
	size_t len = (end -p)+1;
30
	for (i=0;i<len;i++)
31
	{
32
		sc = (sc <<8) | p[i];
33
		if((sc & 0xffffff00) == 0x00000100) {
34
			return p+i-3;
35
		}
36
		
37
	}
38
	return end;
59 39
}
60

  
61 40
int avc_parse_nal_units(ByteIOContext *pb, const uint8_t *buf_in, int size)
62 41
{
63 42
    const uint8_t *p = buf_in;
64 43
    const uint8_t *end = p + size;
65
    const uint8_t *nal_start, *nal_end, *b;
44
    const uint8_t *nal_start, *nal_end; 
66 45

  
67
    printf("CONVERT SIZE %d\n", size);
46
    //printf("CONVERT SIZE %d\n", size);
68 47

  
69 48
    size = 0;
70 49
    nal_start = avc_find_startcode(p, end);
71 50
    while (nal_start < end) {
72 51
        while(!*(nal_start++));
73 52
        nal_end = avc_find_startcode(nal_start, end);
74
	printf("%4d bytes  %5d : %d\n", nal_end - nal_start,
53
	/*printf("%4d bytes  %5d : %d\n", nal_end - nal_start,
75 54
	       nal_start - buf_in,
76
	       nal_end   - buf_in);
55
	       nal_end   - buf_in);*/
77 56

  
78 57
	int l = nal_end - nal_start;
79 58

  
80
	b = nal_start;
81
	while(l > 3 && !(b[l-3] | b[l-2] | b[l-1]))
82
	  l--;
83
        put_be32(pb, l);
84
        put_buffer(pb, nal_start, l);
85
        size += 4 + l;
59
	if (l) {
60
          put_be32(pb, l);
61
          put_buffer(pb, nal_start, l);
62
          size += 4 + l;
63
        }
86 64
        nal_start = nal_end;
87 65
    }
88 66
    printf("size=%d\n", size);
......
125 103
        if (RB32(data) == 0x00000001 ||
126 104
            RB24(data) == 0x000001) {
127 105
            uint8_t *buf=NULL, *end, *start;
128
            uint32_t sps_size=0, pps_size=0;
129
            uint8_t *sps=0, *pps=0;
106
            uint32_t *sps_size_array=0, *pps_size_array=0;
107
            uint32_t pps_count=0,sps_count=0;
108
            uint8_t **sps_array=0, **pps_array=0;
109
            int i;
130 110

  
131 111
            int ret = avc_parse_nal_units_buf(data, &buf, &len);
132 112
            if (ret < 0)
......
141 121
                size = RB32(buf);
142 122
                nal_type = buf[4] & 0x1f;
143 123
                if (nal_type == 7) { /* SPS */
144
                    sps = buf + 4;
145
                    sps_size = size;
124
                    sps_array = realloc(sps_array,sizeof(uint8_t*)*(sps_count+1));
125
                    sps_size_array = realloc(sps_size_array,sizeof(uint32_t)*(sps_count+1));
126
                    sps_array[sps_count] = buf + 4;
127
                    sps_size_array[sps_count] = size;
128
                    sps_count++;
146 129
                } else if (nal_type == 8) { /* PPS */
147
                    pps = buf + 4;
148
                    pps_size = size;
130
                    pps_size_array = realloc(pps_size_array,sizeof(uint32_t)*(pps_count+1));
131
                    pps_array = realloc(pps_array,sizeof (uint8_t*)*(pps_count+1));
132
                    pps_array[pps_count] = buf + 4;
133
                    pps_size_array[pps_count] = size;
134
                    pps_count++;
149 135
                }
150 136
                buf += size + 4;
151 137
            }
152
	    if(!sps || !pps) {
138
	    if(!sps_count || !pps_count) {
153 139
	      av_free(start);
140
              if (sps_count)
141
                free(sps_array);
142
              if (pps_count)
143
                free(pps_array);
154 144
	      return -1;
155 145
	    }
156 146

  
157 147
            put_byte(pb, 1); /* version */
158
            put_byte(pb, sps[1]); /* profile */
159
            put_byte(pb, sps[2]); /* profile compat */
160
            put_byte(pb, sps[3]); /* level */
148
            put_byte(pb, sps_array[0][1]); /* profile */
149
            put_byte(pb, sps_array[0][2]); /* profile compat */
150
            put_byte(pb, sps_array[0][3]); /* level */
161 151
            put_byte(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */
162
            put_byte(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */
152
            put_byte(pb, 0xe0+sps_count); /* 3 bits reserved (111) + 5 bits number of sps (00001) */
153
            for (i=0;i<sps_count;i++) {
154
              put_be16(pb, sps_size_array[i]);
155
              put_buffer(pb, sps_array[i], sps_size_array[i]);
156
            }
163 157

  
164
            put_be16(pb, sps_size);
165
            put_buffer(pb, sps, sps_size);
166
            put_byte(pb, 1); /* number of pps */
167
            put_be16(pb, pps_size);
168
            put_buffer(pb, pps, pps_size);
158
            put_byte(pb, pps_count); /* number of pps */
159
            for (i=0;i<pps_count;i++) {
160
              put_be16(pb, pps_size_array[i]);
161
              put_buffer(pb, pps_array[i], pps_size_array[i]);
162
            }
169 163
            av_free(start);
164

  
165
            if (sps_count)
166
              free(sps_array);
167
            if (pps_count)
168
              free(pps_array);
170 169
        } else {
171 170
            put_buffer(pb, data, len);
172 171
        }
......
180 179
th_pkt_t *
181 180
avc_convert_pkt(th_pkt_t *src)
182 181
{
182
  uint8_t *new_payload=0;
183
  int32_t new_payload_len=0;
183 184
  ByteIOContext *payload, *headers;
184 185

  
185 186
  th_pkt_t *pkt = malloc(sizeof(th_pkt_t));
186 187
  *pkt = *src;
187 188
  pkt->pkt_refcount = 1;
189
  pkt->pkt_header = NULL;
190
  pkt->pkt_payload = NULL;
191

  
192
  pkt->pkt_payload = malloc(sizeof(pktbuf_t));
193
  pkt->pkt_payload->pb_refcount=1;
194
  if (src->pkt_header) {
195
	uint8_t *privateData;
196
	int32_t privateDataLen;
197
	url_open_dyn_buf(&headers);
198
	isom_write_avcc(headers, pktbuf_ptr(src->pkt_header), pktbuf_len(src->pkt_header));
199
	privateDataLen = url_close_dyn_buf(headers, &privateData);
200
	hexdump("   AVC before : ", pktbuf_ptr(src->pkt_header), pktbuf_len(src->pkt_header));
201
	hexdump("   AVC after  : ", privateData, privateDataLen);
202
	
203
	pkt->pkt_header = pktbuf_make(privateData, privateDataLen);
204
  }
188 205

  
189 206
  url_open_dyn_buf(&payload);
190
  avc_parse_nal_units(payload, pkt->pkt_payload, pkt->pkt_payloadlen);
207
  if (src->pkt_header)
208
	avc_parse_nal_units(payload, pktbuf_ptr(src->pkt_header), pktbuf_len(src->pkt_header));
209
  avc_parse_nal_units(payload, pktbuf_ptr(src->pkt_payload), pktbuf_len(src->pkt_payload));
191 210
  
192
  pkt->pkt_payloadlen = url_close_dyn_buf(payload, &pkt->pkt_payload);
211
  new_payload_len = url_close_dyn_buf(payload, &new_payload);
193 212

  
194
  if(pkt->pkt_globaldata) {
195
    url_open_dyn_buf(&headers);
196

  
197
    isom_write_avcc(headers, pkt->pkt_globaldata, pkt->pkt_globaldata_len);
198
    pkt->pkt_globaldata_len = url_close_dyn_buf(headers, &pkt->pkt_globaldata);
199

  
200
    hexdump("annexB: ", src->pkt_globaldata, src->pkt_globaldata_len);
201
    hexdump("   AVC: ", pkt->pkt_globaldata, pkt->pkt_globaldata_len);
202

  
203

  
204
  }
213
  pkt->pkt_payload = pktbuf_make(new_payload,new_payload_len);
205 214
  pkt_ref_dec(src);
206 215
  return pkt;
207 216
}
andoma-tvheadend-c88a646_modif/src/avc.h 2011-10-11 13:43:12.600127001 +0200
25 25
#include <stdint.h>
26 26
#include <libavformat/avformat.h>
27 27
#include <libavformat/avio.h>
28
#include "tvhead.h"
28
#include "tvheadend.h"
29 29
#include "packet.h"
30 30

  
31 31
const uint8_t *avc_find_startcode(const uint8_t *p, const uint8_t *end);
andoma-tvheadend-c88a646_modif/src/plumbing/globalheaders.c 2011-10-11 13:42:51.312127001 +0200
20 20
#include "tvheadend.h"
21 21
#include "streaming.h"
22 22
#include "globalheaders.h"
23
#include "avc.h"
23 24

  
24 25
typedef struct globalheaders {
25 26
  streaming_target_t gh_input;
......
164 165
{
165 166
  switch(ssc->ssc_type) {
166 167
  case SCT_H264:
167
    //    return avc_convert_pkt(pkt);
168
       return avc_convert_pkt(pkt);
168 169

  
169 170
  default:
170 171
    return pkt;
(2-2/6)