Open nonocast opened 2 years ago
FLV: Flash Video.
FLV Layout:
main ()
int main(int argc, char *argv[]) { RTMP_LogSetLevel(RTMP_LOGINFO); char *prog = argv[0]; int c; while ((c = getopt(argc, argv, "vV")) != -1) { switch (c) { case 'v': RTMP_LogSetLevel(RTMP_LOGDEBUG); break; case 'V': RTMP_LogSetLevel(RTMP_LOGDEBUG2); break; default: usage(prog); break; } } RTMP_Log(RTMP_LOGDEBUG, "input: %s", argv[1]); infile = fopen(argv[optind], "r"); if (!infile) { usage(argv[0]); } flv_read_header(); flv_tag_t *tag; while ((tag = flv_read_tag()) != NULL) { push_tag(tag); print_tag(tag); if (feof(infile)) break; } printf("flv tag count: %lu\n", get_tag_count()); // video tags int i = 0; flv_tag_t *current = flv_tag_list_head; if (current != NULL) { do { if (TAGTYPE_VIDEODATA == current->tag_type) { ++i; RTMP_Log(RTMP_LOGINFO, "%s, t: %d, data size: %d", flv_tag_types[current->tag_type], current->timestamp, current->data_size); } } while ((current = (flv_tag_t *) current->next) != NULL && i < 10); } RTMP_Log(RTMP_LOGDEBUG, "the end."); release(); return 0; }
说明
size_t fread(void *buffer, size_t size, size_t count, FILE *stream);
#pragma pack(1)
__attribute__((__packed__)) __
void generate_h264_file() { // open outfile FILE *outfile = fopen("out.h264", "wb"); static const byte startcode[] = {0x00, 0x00, 0x00, 0x01}; // write pps/sps flv_tag_t *current = flv_tag_list_head; assert(current); do { if (TAGTYPE_VIDEODATA == current->tag_type) { video_tag_t *video_tag = (video_tag_t *) current->data; avc_video_packet_t *packet = (avc_video_packet_t *) video_tag->data; if (AVC_SEQUENCE_HEADER == packet->avc_packet_type) { avc_decoder_configuration_record_t *record = (avc_decoder_configuration_record_t *) packet->data; RTMP_LogHex(RTMP_LOGINFO, record->sps, record->sequenceParameterSetLength); fwrite(&startcode, sizeof(startcode), 1, outfile); fwrite(record->sps, record->sequenceParameterSetLength, 1, outfile); RTMP_LogHex(RTMP_LOGINFO, record->pps, record->pictureParameterSetLength); fwrite(&startcode, sizeof(startcode), 1, outfile); fwrite(record->pps, record->pictureParameterSetLength, 1, outfile); } else if (AVC_NALU == packet->avc_packet_type) { avc_nalus_t *nalus = (avc_nalus_t *) packet->data; // AVCC to AnnexB uint32_t offset = 0; uint32_t nalu_len = 0; while (offset < (nalus->size - 4)) { memcpy(&nalu_len, nalus->data + offset, 4); nalu_len = ntohl(nalu_len); printf("."); fwrite(&startcode, sizeof(startcode), 1, outfile); fwrite(nalus->data + offset + 4, nalu_len, 1, outfile); offset += nalu_len + 4; } } } } while ((current = (flv_tag_t *) current->next) != NULL); printf("\n"); fclose(outfile); }
最后
FLV Layout:
main ()
说明
size_t fread(void *buffer, size_t size, size_t count, FILE *stream);
,size是每个读取单元的大小,而count是读的批次数#pragma pack(1)
, gcc则更多用__attribute__((__packed__)) __
AVCC and AnnexB
最后
参考文档