comparison movenc.c @ 911:343ddd5b793c libavformat

Fix for title field in PSP compatible mp4 files. Patch by Olivier, oandrieu <at> gmail.com.
author banan
date Tue, 24 Jan 2006 08:03:42 +0000
parents d92e6d673ef5
children 4e7a66723f1d
comparison
equal deleted inserted replaced
910:d92e6d673ef5 911:343ddd5b793c
431 431
432 static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track) // Basic 432 static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track) // Basic
433 { 433 {
434 int decoderSpecificInfoLen; 434 int decoderSpecificInfoLen;
435 offset_t pos = url_ftell(pb); 435 offset_t pos = url_ftell(pb);
436 void *vosDataBackup=track->vosData;
437 int vosLenBackup=track->vosLen;
438
439 // we should be able to have these passed in, via vosData, then we wouldn't need to attack this routine at all
440 static const char PSPAACData[]={0x13,0x10};
441 static const char PSPMP4Data[]={0x00,0x00,0x01,0xB0,0x03,0x00,0x00,0x01,0xB5,0x09,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x20,0x00,0x84,0x5D,0x4C,0x28,0x50,0x20,0xF0,0xA3,0x1F };
442
443
444 if (track->mode == MODE_PSP) // fails on psp if this is not here
445 {
446 if (track->enc->codec_id == CODEC_ID_AAC)
447 {
448 track->vosLen = 2;
449 track->vosData = (uint8_t *) PSPAACData;
450 }
451
452 if (track->enc->codec_id == CODEC_ID_MPEG4)
453 {
454 track->vosLen = 28;
455 track->vosData = (uint8_t *) PSPMP4Data;
456 }
457 }
458 436
459 decoderSpecificInfoLen = track->vosLen ? descrLength(track->vosLen):0; 437 decoderSpecificInfoLen = track->vosLen ? descrLength(track->vosLen):0;
460 438
461 put_be32(pb, 0); // size 439 put_be32(pb, 0); // size
462 put_tag(pb, "esds"); 440 put_tag(pb, "esds");
495 // DecoderSpecific info descriptor 473 // DecoderSpecific info descriptor
496 putDescr(pb, 0x05, track->vosLen); 474 putDescr(pb, 0x05, track->vosLen);
497 put_buffer(pb, track->vosData, track->vosLen); 475 put_buffer(pb, track->vosData, track->vosLen);
498 } 476 }
499 477
500 track->vosData = vosDataBackup;
501 track->vosLen = vosLenBackup;
502 478
503 // SL descriptor 479 // SL descriptor
504 putDescr(pb, 0x06, 1); 480 putDescr(pb, 0x06, 1);
505 put_byte(pb, 0x02); 481 put_byte(pb, 0x02);
506 return updateSize (pb, pos); 482 return updateSize (pb, pos);
1180 } 1156 }
1181 1157
1182 return updateSize(pb, pos); 1158 return updateSize(pb, pos);
1183 } 1159 }
1184 1160
1161
1162 static size_t ascii_to_wc (ByteIOContext *pb, char *b, size_t n)
1163 {
1164 size_t i;
1165 unsigned char c;
1166 for (i = 0; i < n - 1; i++) {
1167 c = b[i];
1168 if (! (0x20 <= c && c <= 0x7f ))
1169 c = 0x3f; /* '?' */
1170 put_be16(pb, c);
1171 }
1172 put_be16(pb, 0x00);
1173 return 2*n;
1174 }
1175
1176 static uint16_t language_code (char *str)
1177 {
1178 return ((((str[0]-'a') & 0x1F)<<10) + (((str[1]-'a') & 0x1F)<<5) + ((str[2]-'a') & 0x1F));
1179 }
1180
1181 static int mov_write_uuidusmt_tag (ByteIOContext *pb, AVFormatContext *s)
1182 {
1183 size_t len, size;
1184 offset_t pos, curpos;
1185
1186 size = 0;
1187 if (s->title[0]) {
1188 pos = url_ftell(pb);
1189 put_be32(pb, 0); /* size placeholder*/
1190 put_tag(pb, "uuid");
1191 put_tag(pb, "USMT");
1192 put_be32(pb, 0x21d24fce ); /* 96 bit UUID */
1193 put_be32(pb, 0xbb88695c );
1194 put_be32(pb, 0xfac9c740 );
1195 size += 24;
1196
1197 put_be32(pb, 0); /* size placeholder*/
1198 put_tag(pb, "MTDT");
1199 put_be16(pb, 1);
1200 size += 10;
1201
1202 // Title
1203 len = strlen(s->title)+1;
1204 put_be16(pb, len*2+10); /* size */
1205 put_be32(pb, 0x01); /* type */
1206 put_be16(pb, language_code("und")); /* language */
1207 put_be16(pb, 0x01); /* ? */
1208 ascii_to_wc (pb, s->title, len);
1209 size += len*2+10;
1210
1211 // size
1212 curpos = url_ftell(pb);
1213 url_fseek(pb, pos, SEEK_SET);
1214 put_be32(pb, size);
1215 url_fseek(pb, pos+24, SEEK_SET);
1216 put_be32(pb, size-24);
1217 url_fseek(pb, curpos, SEEK_SET);
1218 }
1219
1220 return size;
1221 }
1222
1185 static int mov_write_moov_tag(ByteIOContext *pb, MOVContext *mov, 1223 static int mov_write_moov_tag(ByteIOContext *pb, MOVContext *mov,
1186 AVFormatContext *s) 1224 AVFormatContext *s)
1187 { 1225 {
1188 int i; 1226 int i;
1189 offset_t pos = url_ftell(pb); 1227 offset_t pos = url_ftell(pb);
1222 if(mov->tracks[i].entry > 0) { 1260 if(mov->tracks[i].entry > 0) {
1223 mov_write_trak_tag(pb, &(mov->tracks[i])); 1261 mov_write_trak_tag(pb, &(mov->tracks[i]));
1224 } 1262 }
1225 } 1263 }
1226 1264
1265 if (mov->mode == MODE_PSP)
1266 mov_write_uuidusmt_tag(pb, s);
1267 else
1227 mov_write_udta_tag(pb, mov, s); 1268 mov_write_udta_tag(pb, mov, s);
1228 1269
1229 return updateSize(pb, pos); 1270 return updateSize(pb, pos);
1230 } 1271 }
1231 1272
1239 put_tag(pb, "mdat"); 1280 put_tag(pb, "mdat");
1240 return 0; 1281 return 0;
1241 } 1282 }
1242 1283
1243 /* TODO: This needs to be more general */ 1284 /* TODO: This needs to be more general */
1244 int mov_write_ftyp_tag(ByteIOContext *pb, AVFormatContext *s) 1285 static void mov_write_ftyp_tag (ByteIOContext *pb, AVFormatContext *s)
1245 { 1286 {
1246 MOVContext *mov = s->priv_data; 1287 MOVContext *mov = s->priv_data;
1247 1288
1248 put_be32(pb, 0x14 ); /* size */ 1289 put_be32(pb, 0x14 ); /* size */
1249 put_tag(pb, "ftyp"); 1290 put_tag(pb, "ftyp");
1265 put_tag(pb, "3g2a"); 1306 put_tag(pb, "3g2a");
1266 else if ( mov->mode == MODE_PSP ) 1307 else if ( mov->mode == MODE_PSP )
1267 put_tag(pb, "MSNV"); 1308 put_tag(pb, "MSNV");
1268 else 1309 else
1269 put_tag(pb, "mp41"); 1310 put_tag(pb, "mp41");
1270
1271 return 0x14;
1272 } 1311 }
1273 1312
1274 static void mov_write_uuidprof_tag(ByteIOContext *pb, AVFormatContext *s) 1313 static void mov_write_uuidprof_tag(ByteIOContext *pb, AVFormatContext *s)
1275 { 1314 {
1276 int AudioRate = s->streams[1]->codec->sample_rate; 1315 AVCodecContext *VideoCodec = s->streams[0]->codec;
1277 int FrameRate = ((s->streams[0]->codec->time_base.den) * (0x10000))/ (s->streams[0]->codec->time_base.num); 1316 AVCodecContext *AudioCodec = s->streams[1]->codec;
1278 1317 int AudioRate = AudioCodec->sample_rate;
1279 //printf("audiorate = %d\n",AudioRate); 1318 int FrameRate = ((VideoCodec->time_base.den) * (0x10000))/ (VideoCodec->time_base.num);
1280 //printf("framerate = %d / %d = 0x%x\n",s->streams[0]->codec->time_base.den,s->streams[0]->codec->time_base.num,FrameRate);
1281 1319
1282 put_be32(pb, 0x94 ); /* size */ 1320 put_be32(pb, 0x94 ); /* size */
1283 put_tag(pb, "uuid"); 1321 put_tag(pb, "uuid");
1284 put_tag(pb, "PROF"); 1322 put_tag(pb, "PROF");
1285 1323
1297 put_be32(pb, 0x0 ); /* ? */ 1335 put_be32(pb, 0x0 ); /* ? */
1298 1336
1299 put_be32(pb, 0x2c ); /* size */ 1337 put_be32(pb, 0x2c ); /* size */
1300 put_tag(pb, "APRF"); /* audio */ 1338 put_tag(pb, "APRF"); /* audio */
1301 put_be32(pb, 0x0 ); 1339 put_be32(pb, 0x0 );
1302 put_be32(pb, 0x2 ); 1340 put_be32(pb, 0x2 ); /* TrackID */
1303 put_tag(pb, "mp4a"); 1341 put_tag(pb, "mp4a");
1304 put_be32(pb, 0x20f ); 1342 put_be32(pb, 0x20f );
1305 put_be32(pb, 0x0 ); 1343 put_be32(pb, 0x0 );
1306 put_be32(pb, 0x40 ); 1344 put_be32(pb, AudioCodec->bit_rate / 1000);
1307 put_be32(pb, 0x40 ); 1345 put_be32(pb, AudioCodec->bit_rate / 1000);
1308 put_be32(pb, AudioRate ); //24000 ... audio rate? 1346 put_be32(pb, AudioRate );
1309 put_be32(pb, 0x2 ); 1347 put_be32(pb, AudioCodec->channels );
1310 1348
1311 put_be32(pb, 0x34 ); /* size */ 1349 put_be32(pb, 0x34 ); /* size */
1312 put_tag(pb, "VPRF"); /* video */ 1350 put_tag(pb, "VPRF"); /* video */
1313 put_be32(pb, 0x0 ); 1351 put_be32(pb, 0x0 );
1314 put_be32(pb, 0x1 ); 1352 put_be32(pb, 0x1 ); /* TrackID */
1315 put_tag(pb, "mp4v"); 1353 put_tag(pb, "mp4v");
1316 put_be32(pb, 0x103 ); 1354 put_be32(pb, 0x103 );
1317 put_be32(pb, 0x0 ); 1355 put_be32(pb, 0x0 );
1318 put_be32(pb, 0xc0 ); 1356 put_be32(pb, VideoCodec->bit_rate / 1000);
1319 put_be32(pb, 0xc0 ); 1357 put_be32(pb, VideoCodec->bit_rate / 1000);
1320 put_be32(pb, FrameRate); // was 0xefc29 1358 put_be32(pb, FrameRate);
1321 put_be32(pb, FrameRate ); // was 0xefc29 1359 put_be32(pb, FrameRate);
1322 put_be16(pb, s->streams[0]->codec->width); 1360 put_be16(pb, VideoCodec->width);
1323 put_be16(pb, s->streams[0]->codec->height); 1361 put_be16(pb, VideoCodec->height);
1324 put_be32(pb, 0x010001 ); 1362 put_be32(pb, 0x010001); /* ? */
1325 } 1363 }
1326 1364
1327 static int mov_write_header(AVFormatContext *s) 1365 static int mov_write_header(AVFormatContext *s)
1328 { 1366 {
1329 ByteIOContext *pb = &s->pb; 1367 ByteIOContext *pb = &s->pb;
1565 CODEC_ID_AAC, 1603 CODEC_ID_AAC,
1566 CODEC_ID_MPEG4, 1604 CODEC_ID_MPEG4,
1567 mov_write_header, 1605 mov_write_header,
1568 mov_write_packet, 1606 mov_write_packet,
1569 mov_write_trailer, 1607 mov_write_trailer,
1570 // .flags = AVFMT_GLOBALHEADER, 1608 .flags = AVFMT_GLOBALHEADER,
1571 }; 1609 };
1572 1610
1573 static AVOutputFormat _3g2_oformat = { 1611 static AVOutputFormat _3g2_oformat = {
1574 "3g2", 1612 "3g2",
1575 "3gp2 format", 1613 "3gp2 format",