133 lines
3.1 KiB
C++
133 lines
3.1 KiB
C++
|
|
#include "flv-demuxer.h"
|
||
|
|
#include "flv-reader.h"
|
||
|
|
#include "flv-proto.h"
|
||
|
|
#include "aom-av1.h"
|
||
|
|
#include <assert.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
static unsigned char packet[8 * 1024 * 1024];
|
||
|
|
static FILE* aac;
|
||
|
|
static FILE* h264;
|
||
|
|
|
||
|
|
inline const char* ftimestamp(uint32_t t, char* buf)
|
||
|
|
{
|
||
|
|
sprintf(buf, "%02u:%02u:%02u.%03u", t / 3600000, (t / 60000) % 60, (t / 1000) % 60, t % 1000);
|
||
|
|
return buf;
|
||
|
|
}
|
||
|
|
|
||
|
|
inline size_t get_adts_length(const uint8_t* data, size_t bytes)
|
||
|
|
{
|
||
|
|
assert(bytes >= 6);
|
||
|
|
return ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] >> 5) & 0x07);
|
||
|
|
}
|
||
|
|
|
||
|
|
inline char flv_type(int type)
|
||
|
|
{
|
||
|
|
switch (type)
|
||
|
|
{
|
||
|
|
case FLV_AUDIO_ASC:
|
||
|
|
case FLV_AUDIO_OPUS_HEAD:
|
||
|
|
return 'a';
|
||
|
|
case FLV_AUDIO_AAC:
|
||
|
|
case FLV_AUDIO_MP3:
|
||
|
|
case FLV_AUDIO_OPUS:
|
||
|
|
return 'A';
|
||
|
|
case FLV_VIDEO_AVCC:
|
||
|
|
case FLV_VIDEO_HVCC:
|
||
|
|
case FLV_VIDEO_VVCC:
|
||
|
|
case FLV_VIDEO_AV1C:
|
||
|
|
return 'v';
|
||
|
|
case FLV_VIDEO_H264:
|
||
|
|
case FLV_VIDEO_H265:
|
||
|
|
case FLV_VIDEO_H266:
|
||
|
|
case FLV_VIDEO_AV1:
|
||
|
|
return 'V';
|
||
|
|
default: return '*';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static int onFLV(void* /*param*/, int codec, const void* data, size_t bytes, uint32_t pts, uint32_t dts, int flags)
|
||
|
|
{
|
||
|
|
static char s_pts[64], s_dts[64];
|
||
|
|
static uint32_t v_pts = 0, v_dts = 0;
|
||
|
|
static uint32_t a_pts = 0, a_dts = 0;
|
||
|
|
|
||
|
|
printf("[%c] pts: %s, dts: %s, %u, cts: %d, bytes: %d ", flv_type(codec), ftimestamp(pts, s_pts), ftimestamp(dts, s_dts), dts, (int)(pts - dts), (int)bytes);
|
||
|
|
|
||
|
|
if (FLV_AUDIO_AAC == codec)
|
||
|
|
{
|
||
|
|
printf("diff: %03d/%03d", (int)(pts - a_pts), (int)(dts - a_dts));
|
||
|
|
a_pts = pts;
|
||
|
|
a_dts = dts;
|
||
|
|
|
||
|
|
assert(bytes == get_adts_length((const uint8_t*)data, bytes));
|
||
|
|
fwrite(data, bytes, 1, aac);
|
||
|
|
}
|
||
|
|
else if (FLV_VIDEO_AV1 == codec)
|
||
|
|
{
|
||
|
|
struct aom_av1_t av1;
|
||
|
|
memset(&av1, 0, sizeof(av1));
|
||
|
|
aom_av1_codec_configuration_record_init(&av1, data, bytes);
|
||
|
|
uint8_t extra[32] = { 0 };
|
||
|
|
aom_av1_codec_configuration_record_save(&av1, extra, sizeof(extra));
|
||
|
|
}
|
||
|
|
else if (FLV_VIDEO_H264 == codec || FLV_VIDEO_H265 == codec || FLV_VIDEO_H266 == codec || FLV_VIDEO_AV1 == codec)
|
||
|
|
{
|
||
|
|
printf("diff: %03d/%03d %s", (int)(pts - v_pts), (int)(dts - v_dts), flags ? "[I]" : "");
|
||
|
|
v_pts = pts;
|
||
|
|
v_dts = dts;
|
||
|
|
|
||
|
|
fwrite(data, bytes, 1, h264);
|
||
|
|
}
|
||
|
|
else if (FLV_AUDIO_MP3 == codec || FLV_AUDIO_OPUS == codec)
|
||
|
|
{
|
||
|
|
fwrite(data, bytes, 1, aac);
|
||
|
|
}
|
||
|
|
else if (FLV_AUDIO_ASC == codec || FLV_AUDIO_OPUS_HEAD == codec || FLV_VIDEO_AVCC == codec || FLV_VIDEO_HVCC == codec || FLV_VIDEO_VVCC == codec || FLV_VIDEO_AV1C == codec)
|
||
|
|
{
|
||
|
|
// nothing to do
|
||
|
|
}
|
||
|
|
else if ((3 << 4) == codec)
|
||
|
|
{
|
||
|
|
fwrite(data, bytes, 1, aac);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
// nothing to do
|
||
|
|
assert(FLV_SCRIPT_METADATA == codec);
|
||
|
|
}
|
||
|
|
|
||
|
|
printf("\n");
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
// flv_reader_test("53340.flv");
|
||
|
|
void flv_reader_test(const char* file)
|
||
|
|
{
|
||
|
|
aac = fopen("audio.aac", "wb");
|
||
|
|
h264 = fopen("video.h264", "wb");
|
||
|
|
|
||
|
|
void* reader = flv_reader_create(file);
|
||
|
|
flv_demuxer_t* flv = flv_demuxer_create(onFLV, NULL);
|
||
|
|
|
||
|
|
int type, r;
|
||
|
|
size_t taglen;
|
||
|
|
uint32_t timestamp;
|
||
|
|
while (1 == flv_reader_read(reader, &type, ×tamp, &taglen, packet, sizeof(packet)))
|
||
|
|
{
|
||
|
|
r = flv_demuxer_input(flv, type, packet, taglen, timestamp);
|
||
|
|
if (r < 0)
|
||
|
|
{
|
||
|
|
assert(0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
flv_demuxer_destroy(flv);
|
||
|
|
flv_reader_destroy(reader);
|
||
|
|
|
||
|
|
fclose(aac);
|
||
|
|
fclose(h264);
|
||
|
|
}
|