extern int output_flv(struct mp4_context_t const* mp4_context, unsigned int* trak_sample_start, unsigned int* trak_sample_end, struct bucket_t** buckets, struct mp4_split_options_t* options) { struct moov_t* moov = mp4_context->moov; unsigned int track = 0; for(track = 0; track != moov->tracks_; ++track) { struct trak_t* trak = moov->traks_[track]; struct stsd_t const* stsd = trak->mdia_->minf_->stbl_->stsd_; struct sample_entry_t const* sample_entry = &stsd->sample_entries_[0]; unsigned int start_sample = trak_sample_start[track]; unsigned int end_sample = trak_sample_end[track]; unsigned int s; if(trak->mdia_->hdlr_->handler_type_ != FOURCC('v', 'i', 'd', 'e')) continue; if(trak->mdia_->hdlr_->handler_type_ == FOURCC('v', 'i', 'd', 'e')) { unsigned char* buffer = (unsigned char*)malloc(1 + 1 + 3 + sample_entry->codec_private_data_length_); unsigned char* p = buffer; p = write_8(p, 0x17); p = write_8(p, RTMP_AVC_SEQUENCE_HEADER); p = write_24(p, 0); memcpy(p, sample_entry->codec_private_data_, sample_entry->codec_private_data_length_); p += sample_entry->codec_private_data_length_; bucket_insert_tail(buckets, bucket_init_memory(buffer, p - buffer)); free(buffer); } else if(trak->mdia_->hdlr_->handler_type_ == FOURCC('s', 'o', 'u', 'n')) { unsigned char* buffer = (unsigned char*)malloc(1 + 1 + sample_entry->codec_private_data_length_); unsigned char* p = buffer; p = write_8(p, 0xaf); p = write_8(p, RTMP_AAC_SEQUENCE_HEADER); memcpy(p, sample_entry->codec_private_data_, sample_entry->codec_private_data_length_); p += sample_entry->codec_private_data_length_; bucket_insert_tail(buckets, bucket_init_memory(buffer, p - buffer)); free(buffer); } else { continue; } for(s = start_sample; s != end_sample; ++s) { uint64_t sample_pos = trak->samples_[s].pos_; unsigned int sample_size = trak->samples_[s].size_; int cto = trak->samples_[s].cto_; // FLV uses a fixed 1000 timescale unsigned int composition_time = (unsigned int) (trak_time_to_moov_time(cto, 1000, trak->mdia_->mdhd_->timescale_)); MP4_INFO( "frame=%u pts=%u offset=%llu size=%u\n", s, composition_time, sample_pos, sample_size); if(trak->mdia_->hdlr_->handler_type_ == FOURCC('v', 'i', 'd', 'e')) { // if(is_avc) { // VIDEODATA unsigned char header[5]; unsigned int is_keyframe = trak->samples_[s].is_ss_; unsigned int codec_id = 7; // AVC write_8(header, ((is_keyframe ? 1 : 2) << 4) + codec_id); write_8(header + 1, RTMP_AVC_NALU); write_24(header + 2, composition_time); bucket_insert_tail(buckets, bucket_init_memory(header, 5)); bucket_insert_tail(buckets, bucket_init_file(sample_pos, sample_size)); } } else { // AUDIODATA unsigned char header[2]; write_8(header, 0xaf); write_8(header + 1, RTMP_AAC_RAW); // AACAUDIODATA bucket_insert_tail(buckets, bucket_init_memory(header, 2)); bucket_insert_tail(buckets, bucket_init_file(sample_pos, sample_size)); } } } return 1; }
static void do_set(int fd, int argc, const char *argv[]) { int x, y, w, h; int bpp; if (argc != 6) usage(); screen = mmap(NULL, mem_size, PROT_WRITE, MAP_SHARED, fd, 0); if (screen == MAP_FAILED) { printf("Can't mmap %s\n", argv[1]); perror("mmap"); usage(); } do_ioctl(fd, IOCTRL_GET_LCD_BPP, &bpp); if (bpp == 8) bytes_per_pixel = 1; else if (bpp == 16) bytes_per_pixel = 2; else if (bpp == 24) bytes_per_pixel = 3; else if (bpp == 32) bytes_per_pixel = 4; do_ioctl(fd, IOCTRL_GET_LCD_WIDTH, &screen_w); do_ioctl(fd, IOCTRL_GET_LCD_HEIGHT, &screen_h); printf("Screen is %lux%lu, %u bits per pixel\n", screen_w, screen_h, bpp); do_ioctl(fd, IOCTRL_DISPLAY_ENABLE, NULL); do_ioctl(fd, IOCTRL_CLEAR_LCD, NULL); x = strtoul(argv[1], NULL, 0); y = strtoul(argv[2], NULL, 0); w = strtoul(argv[3], NULL, 0); h = strtoul(argv[4], NULL, 0); val = strtoul(argv[5], NULL, 0); if ( y * screen_w + x * bytes_per_pixel > mem_size ) { printf("Would write outside of memory\n"); usage(); } switch (bytes_per_pixel) { case 1: write_8(w, h, x, y); break; case 2: write_16(w, h, x, y); break; case 3: write_24(w, h, x, y); break; case 4: write_32(w, h, x, y); break; default: printf("Illegal byte-per-pixel, bpp %d\n", bpp); usage(); break; } do_ioctl(fd, IOCTRL_UPDATE_NOW, NULL); msync(screen, mem_size, MS_SYNC); munmap(screen, mem_size); }