comparison movenc.c @ 659:6d7c0e6d929e libavformat

Sony PSP variation of MP4 patch by <tjcannell AT blueyonder DOT co DOT uk>
author mmu_man
date Thu, 27 Jan 2005 14:48:15 +0000
parents 5b9575f5b6e8
children ff3b403d0498
comparison
equal deleted inserted replaced
658:0624def73c76 659:6d7c0e6d929e
28 #define globalTimescale 1000 28 #define globalTimescale 1000
29 29
30 #define MODE_MP4 0 30 #define MODE_MP4 0
31 #define MODE_MOV 1 31 #define MODE_MOV 1
32 #define MODE_3GP 2 32 #define MODE_3GP 2
33 #define MODE_PSP 3 // example working PSP command line:
34 // ffmpeg -i testinput.avi -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4
33 35
34 typedef struct MOVIentry { 36 typedef struct MOVIentry {
35 unsigned int flags, pos, size; 37 unsigned int flags, pos, size;
36 unsigned int samplesInChunk; 38 unsigned int samplesInChunk;
37 char key_frame; 39 char key_frame;
55 int vosLen; 57 int vosLen;
56 uint8_t *vosData; 58 uint8_t *vosData;
57 MOVIentry** cluster; 59 MOVIentry** cluster;
58 } MOVTrack; 60 } MOVTrack;
59 61
60 typedef struct { 62 typedef struct MOVContext {
61 int mode; 63 int mode;
62 long time; 64 long time;
63 int nb_streams; 65 int nb_streams;
64 int mdat_written; 66 int mdat_written;
65 offset_t mdat_pos; 67 offset_t mdat_pos;
393 395
394 static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track) // Basic 396 static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track) // Basic
395 { 397 {
396 int decoderSpecificInfoLen = track->vosLen ? descrLength(track->vosLen):0; 398 int decoderSpecificInfoLen = track->vosLen ? descrLength(track->vosLen):0;
397 int pos = url_ftell(pb); 399 int pos = url_ftell(pb);
400 void *vosDataBackup=track->vosData;
401 int vosLenBackup=track->vosLen;
402
403 // we should be able to have these passed in, via vosData, then we wouldn't need to attack this routine at all
404 static const char PSPAACData[]={0x13,0x10};
405 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 };
406
407
408 if (track->mode == MODE_PSP) // fails on psp if this is not here
409 {
410 if (track->enc->codec_id == CODEC_ID_AAC)
411 {
412 track->vosLen = 2;
413 track->vosData = PSPAACData;
414 }
415
416 if (track->enc->codec_id == CODEC_ID_MPEG4)
417 {
418 track->vosLen = 28;
419 track->vosData = PSPMP4Data;
420 }
421 }
398 422
399 put_be32(pb, 0); // size 423 put_be32(pb, 0); // size
400 put_tag(pb, "esds"); 424 put_tag(pb, "esds");
401 put_be32(pb, 0); // Version 425 put_be32(pb, 0); // Version
402 426
421 445
422 put_byte(pb, 0x0); // Buffersize DB (24 bits) 446 put_byte(pb, 0x0); // Buffersize DB (24 bits)
423 put_be16(pb, 0x0dd2); // Buffersize DB 447 put_be16(pb, 0x0dd2); // Buffersize DB
424 448
425 // TODO: find real values for these 449 // TODO: find real values for these
426 put_be32(pb, 0x0002e918); // maxbitrate 450 put_be32(pb, track->enc->bit_rate); // maxbitrate
427 put_be32(pb, 0x00017e6b); // avg bitrate 451 put_be32(pb, track->enc->bit_rate); // avg bitrate
428 452
429 if (track->vosLen) 453 if (track->vosLen)
430 { 454 {
431 // DecoderSpecific info descriptor 455 // DecoderSpecific info descriptor
432 putDescr(pb, 0x05, track->vosLen); 456 putDescr(pb, 0x05, track->vosLen);
433 put_buffer(pb, track->vosData, track->vosLen); 457 put_buffer(pb, track->vosData, track->vosLen);
434 } 458 }
459
460 track->vosData = vosDataBackup;
461 track->vosLen = vosLenBackup;
435 462
436 // SL descriptor 463 // SL descriptor
437 putDescr(pb, 0x06, 1); 464 putDescr(pb, 0x06, 1);
438 put_byte(pb, 0x02); 465 put_byte(pb, 0x02);
439 return updateSize (pb, pos); 466 return updateSize (pb, pos);
709 put_be32(pb, 0); 736 put_be32(pb, 0);
710 } 737 }
711 return 0x5c; 738 return 0x5c;
712 } 739 }
713 740
741 // This box seems important for the psp playback ... without it the movie seems to hang
742 static int mov_write_edts_tag(ByteIOContext *pb, MOVTrack *track)
743 {
744 int64_t maxTrackLenTemp;
745 put_be32(pb, 0x24); /* size */
746 put_tag(pb, "edts");
747 put_be32(pb, 0x1c); /* size */
748 put_tag(pb, "elst");
749 put_be32(pb, 0x0);
750 put_be32(pb, 0x1);
751
752 maxTrackLenTemp = ((int64_t)globalTimescale*(int64_t)track->trackDuration)/(int64_t)track->timescale;
753 put_be32(pb, (long)maxTrackLenTemp); /* duration ... doesn't seem to effect psp */
754
755 put_be32(pb, 0x0);
756 put_be32(pb, 0x00010000);
757 return 0x24;
758 }
759
760 // goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it)
761 static int mov_write_uuid_tag_psp(ByteIOContext *pb, MOVTrack *mov)
762 {
763 put_be32(pb, 0x34); /* size ... reports as 28 in mp4box! */
764 put_tag(pb, "uuid");
765 put_tag(pb, "USMT");
766 put_be32(pb, 0x21d24fce);
767 put_be32(pb, 0xbb88695c);
768 put_be32(pb, 0xfac9c740);
769 put_be32(pb, 0x1c); // another size here!
770 put_tag(pb, "MTDT");
771 put_be32(pb, 0x00010012);
772 put_be32(pb, 0x0a);
773 put_be32(pb, 0x55c40000);
774 put_be32(pb, 0x1);
775 put_be32(pb, 0x0);
776 return 0x34;
777 }
778
714 static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack* track) 779 static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack* track)
715 { 780 {
716 int pos = url_ftell(pb); 781 int pos = url_ftell(pb);
717 put_be32(pb, 0); /* size */ 782 put_be32(pb, 0); /* size */
718 put_tag(pb, "trak"); 783 put_tag(pb, "trak");
719 mov_write_tkhd_tag(pb, track); 784 mov_write_tkhd_tag(pb, track);
785 if (track->mode == MODE_PSP)
786 mov_write_edts_tag(pb, track); // PSP Movies require edts box
720 mov_write_mdia_tag(pb, track); 787 mov_write_mdia_tag(pb, track);
788 if (track->mode == MODE_PSP)
789 mov_write_uuid_tag_psp(pb,track); // PSP Movies require this uuid box
721 return updateSize(pb, pos); 790 return updateSize(pb, pos);
722 } 791 }
723 792
724 /* TODO: Not sorted out, but not necessary either */ 793 /* TODO: Not sorted out, but not necessary either */
725 static int mov_write_iods_tag(ByteIOContext *pb, MOVContext *mov) 794 static int mov_write_iods_tag(ByteIOContext *pb, MOVContext *mov)
1137 put_be32(pb, 0x14 ); /* size */ 1206 put_be32(pb, 0x14 ); /* size */
1138 put_tag(pb, "ftyp"); 1207 put_tag(pb, "ftyp");
1139 1208
1140 if ( mov->mode == MODE_3GP ) 1209 if ( mov->mode == MODE_3GP )
1141 put_tag(pb, "3gp4"); 1210 put_tag(pb, "3gp4");
1211 else if ( mov->mode == MODE_PSP )
1212 put_tag(pb, "MSNV");
1142 else 1213 else
1143 put_tag(pb, "isom"); 1214 put_tag(pb, "isom");
1144 1215
1145 put_be32(pb, 0x200 ); 1216 put_be32(pb, 0x200 );
1146 1217
1147 if ( mov->mode == MODE_3GP ) 1218 if ( mov->mode == MODE_3GP )
1148 put_tag(pb, "3gp4"); 1219 put_tag(pb, "3gp4");
1220 else if ( mov->mode == MODE_PSP )
1221 put_tag(pb, "MSNV");
1149 else 1222 else
1150 put_tag(pb, "mp41"); 1223 put_tag(pb, "mp41");
1151 1224
1152 return 0x14; 1225 return 0x14;
1226 }
1227
1228 int mov_write_uuidprof_tag(ByteIOContext *pb, AVFormatContext *s)
1229 {
1230 MOVContext *mov = s->priv_data;
1231 int AudioRate = s->streams[1]->codec.sample_rate;
1232 int FrameRate = ((s->streams[0]->codec.frame_rate) * (0x10000))/ (s->streams[0]->codec.frame_rate_base);
1233
1234 //printf("audiorate = %d\n",AudioRate);
1235 //printf("framerate = %d / %d = 0x%x\n",s->streams[0]->codec.frame_rate,s->streams[0]->codec.frame_rate_base,FrameRate);
1236
1237 put_be32(pb, 0x94 ); /* size */
1238 put_tag(pb, "uuid");
1239 put_tag(pb, "PROF");
1240
1241 put_be32(pb, 0x21d24fce ); /* 96 bit UUID */
1242 put_be32(pb, 0xbb88695c );
1243 put_be32(pb, 0xfac9c740 );
1244
1245 put_be32(pb, 0x0 ); /* ? */
1246 put_be32(pb, 0x3 ); /* 3 sections ? */
1247
1248 put_be32(pb, 0x14 ); /* size */
1249 put_tag(pb, "FPRF");
1250 put_be32(pb, 0x0 ); /* ? */
1251 put_be32(pb, 0x0 ); /* ? */
1252 put_be32(pb, 0x0 ); /* ? */
1253
1254 put_be32(pb, 0x2c ); /* size */
1255 put_tag(pb, "APRF"); /* audio */
1256 put_be32(pb, 0x0 );
1257 put_be32(pb, 0x2 );
1258 put_tag(pb, "mp4a");
1259 put_be32(pb, 0x20f );
1260 put_be32(pb, 0x0 );
1261 put_be32(pb, 0x40 );
1262 put_be32(pb, 0x40 );
1263 put_be32(pb, AudioRate ); //24000 ... audio rate?
1264 put_be32(pb, 0x2 );
1265
1266 put_be32(pb, 0x34 ); /* size */
1267 put_tag(pb, "VPRF"); /* video */
1268 put_be32(pb, 0x0 );
1269 put_be32(pb, 0x1 );
1270 put_tag(pb, "mp4v");
1271 put_be32(pb, 0x103 );
1272 put_be32(pb, 0x0 );
1273 put_be32(pb, 0xc0 );
1274 put_be32(pb, 0xc0 );
1275 put_be32(pb, FrameRate); // was 0xefc29
1276 put_be32(pb, FrameRate ); // was 0xefc29
1277 put_be16(pb, s->streams[0]->codec.width);
1278 put_be16(pb, s->streams[0]->codec.height);
1279 put_be32(pb, 0x010001 );
1280
1281 return 0x94;
1153 } 1282 }
1154 1283
1155 static int mov_write_header(AVFormatContext *s) 1284 static int mov_write_header(AVFormatContext *s)
1156 { 1285 {
1157 ByteIOContext *pb = &s->pb; 1286 ByteIOContext *pb = &s->pb;
1182 mov->mode = MODE_MP4; 1311 mov->mode = MODE_MP4;
1183 1312
1184 if (s->oformat != NULL) { 1313 if (s->oformat != NULL) {
1185 if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP; 1314 if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
1186 else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV; 1315 else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
1187 1316 else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
1188 if ( mov->mode == MODE_3GP || mov->mode == MODE_MP4 ) 1317
1318 if ( mov->mode == MODE_3GP || mov->mode == MODE_MP4 || mov->mode == MODE_PSP )
1189 mov_write_ftyp_tag(pb,s); 1319 mov_write_ftyp_tag(pb,s);
1320 if ( mov->mode == MODE_PSP )
1321 mov_write_uuidprof_tag(pb,s);
1190 } 1322 }
1191 1323
1192 for (i=0; i<MAX_STREAMS; i++) { 1324 for (i=0; i<MAX_STREAMS; i++) {
1193 mov->tracks[i].mode = mov->mode; 1325 mov->tracks[i].mode = mov->mode;
1194 } 1326 }
1358 mov_write_header, 1490 mov_write_header,
1359 mov_write_packet, 1491 mov_write_packet,
1360 mov_write_trailer, 1492 mov_write_trailer,
1361 }; 1493 };
1362 1494
1495 static AVOutputFormat psp_oformat = {
1496 "psp",
1497 "psp mp4 format",
1498 NULL,
1499 "mp4,psp",
1500 sizeof(MOVContext),
1501 CODEC_ID_AAC,
1502 CODEC_ID_MPEG4,
1503 mov_write_header,
1504 mov_write_packet,
1505 mov_write_trailer,
1506 };
1507
1363 int movenc_init(void) 1508 int movenc_init(void)
1364 { 1509 {
1365 av_register_output_format(&mov_oformat); 1510 av_register_output_format(&mov_oformat);
1366 av_register_output_format(&_3gp_oformat); 1511 av_register_output_format(&_3gp_oformat);
1367 av_register_output_format(&mp4_oformat); 1512 av_register_output_format(&mp4_oformat);
1513 av_register_output_format(&psp_oformat);
1368 return 0; 1514 return 0;
1369 } 1515 }