|
|
|
@@ -24,7 +24,7 @@ |
|
|
|
#include "rm.h" |
|
|
|
|
|
|
|
struct RMStream { |
|
|
|
uint8_t *buf; ///< place to store merged video frame / reordered audio data |
|
|
|
AVPacket pkt; ///< place to store merged video frame / reordered audio data |
|
|
|
int videobufsize; ///< current assembled frame size |
|
|
|
int videobufpos; ///< position for the next slice in the video buffer |
|
|
|
int curpic_num; ///< picture number of current frame |
|
|
|
@@ -80,7 +80,7 @@ RMStream *ff_rm_alloc_rmstream (void) |
|
|
|
|
|
|
|
void ff_rm_free_rmstream (RMStream *rms) |
|
|
|
{ |
|
|
|
av_freep(&rms->buf); |
|
|
|
av_free_packet(&rms->pkt); |
|
|
|
} |
|
|
|
|
|
|
|
static int rm_read_audio_stream_info(AVFormatContext *s, ByteIOContext *pb, |
|
|
|
@@ -155,7 +155,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, ByteIOContext *pb, |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
ast->buf = av_malloc(ast->audio_framesize * sub_packet_h); |
|
|
|
av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h); |
|
|
|
} else if ((!strcmp(buf, "cook")) || (!strcmp(buf, "atrc")) || (!strcmp(buf, "sipr"))) { |
|
|
|
int codecdata_length; |
|
|
|
get_be16(pb); get_byte(pb); |
|
|
|
@@ -186,7 +186,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, ByteIOContext *pb, |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
ast->buf = av_malloc(ast->audio_framesize * sub_packet_h); |
|
|
|
av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h); |
|
|
|
} else if (!strcmp(buf, "raac") || !strcmp(buf, "racp")) { |
|
|
|
int codecdata_length; |
|
|
|
get_be16(pb); get_byte(pb); |
|
|
|
@@ -521,8 +521,8 @@ static int rm_assemble_video_frame(AVFormatContext *s, ByteIOContext *pb, |
|
|
|
if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){ |
|
|
|
vst->slices = ((hdr & 0x3F) << 1) + 1; |
|
|
|
vst->videobufsize = len2 + 8*vst->slices + 1; |
|
|
|
av_free(vst->buf); |
|
|
|
if(!(vst->buf = av_malloc(vst->videobufsize))) |
|
|
|
av_free_packet(&vst->pkt); //FIXME this should be output. |
|
|
|
if(av_new_packet(&vst->pkt, vst->videobufsize) < 0) |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
vst->videobufpos = 8*vst->slices + 1; |
|
|
|
vst->cur_slice = 0; |
|
|
|
@@ -534,22 +534,24 @@ static int rm_assemble_video_frame(AVFormatContext *s, ByteIOContext *pb, |
|
|
|
|
|
|
|
if(++vst->cur_slice > vst->slices) |
|
|
|
return 1; |
|
|
|
AV_WL32(vst->buf - 7 + 8*vst->cur_slice, 1); |
|
|
|
AV_WL32(vst->buf - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1); |
|
|
|
AV_WL32(vst->pkt.data - 7 + 8*vst->cur_slice, 1); |
|
|
|
AV_WL32(vst->pkt.data - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1); |
|
|
|
if(vst->videobufpos + len > vst->videobufsize) |
|
|
|
return 1; |
|
|
|
if (get_buffer(pb, vst->buf + vst->videobufpos, len) != len) |
|
|
|
if (get_buffer(pb, vst->pkt.data + vst->videobufpos, len) != len) |
|
|
|
return AVERROR(EIO); |
|
|
|
vst->videobufpos += len; |
|
|
|
rm->remaining_len-= len; |
|
|
|
|
|
|
|
if(type == 2 || (vst->videobufpos) == vst->videobufsize){ |
|
|
|
vst->buf[0] = vst->cur_slice-1; |
|
|
|
if(av_new_packet(pkt, vst->videobufpos - 8*(vst->slices - vst->cur_slice)) < 0) |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
memcpy(pkt->data, vst->buf, 1 + 8*vst->cur_slice); |
|
|
|
memcpy(pkt->data + 1 + 8*vst->cur_slice, vst->buf + 1 + 8*vst->slices, |
|
|
|
vst->pkt.data[0] = vst->cur_slice-1; |
|
|
|
*pkt= vst->pkt; |
|
|
|
vst->pkt.data= |
|
|
|
vst->pkt.size= 0; |
|
|
|
if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin |
|
|
|
memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices, |
|
|
|
vst->videobufpos - 1 - 8*vst->slices); |
|
|
|
pkt->size += 8*(vst->cur_slice - vst->slices); |
|
|
|
pkt->pts = AV_NOPTS_VALUE; |
|
|
|
pkt->pos = vst->pktpos; |
|
|
|
return 0; |
|
|
|
@@ -604,12 +606,12 @@ ff_rm_parse_packet (AVFormatContext *s, ByteIOContext *pb, |
|
|
|
switch(st->codec->codec_id) { |
|
|
|
case CODEC_ID_RA_288: |
|
|
|
for (x = 0; x < h/2; x++) |
|
|
|
get_buffer(pb, ast->buf+x*2*w+y*cfs, cfs); |
|
|
|
get_buffer(pb, ast->pkt.data+x*2*w+y*cfs, cfs); |
|
|
|
break; |
|
|
|
case CODEC_ID_ATRAC3: |
|
|
|
case CODEC_ID_COOK: |
|
|
|
for (x = 0; x < w/sps; x++) |
|
|
|
get_buffer(pb, ast->buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps); |
|
|
|
get_buffer(pb, ast->pkt.data+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
@@ -621,7 +623,7 @@ ff_rm_parse_packet (AVFormatContext *s, ByteIOContext *pb, |
|
|
|
rm->audio_pkt_cnt = h * w / st->codec->block_align - 1; |
|
|
|
// Release first audio packet |
|
|
|
av_new_packet(pkt, st->codec->block_align); |
|
|
|
memcpy(pkt->data, ast->buf, st->codec->block_align); |
|
|
|
memcpy(pkt->data, ast->pkt.data, st->codec->block_align); //FIXME avoid this |
|
|
|
*timestamp = ast->audiotimestamp; |
|
|
|
*flags = 2; // Mark first packet as keyframe |
|
|
|
} |
|
|
|
@@ -684,7 +686,7 @@ ff_rm_retrieve_cache (AVFormatContext *s, ByteIOContext *pb, |
|
|
|
av_get_packet(pb, pkt, ast->sub_packet_lengths[ast->sub_packet_cnt - rm->audio_pkt_cnt]); |
|
|
|
else { |
|
|
|
av_new_packet(pkt, st->codec->block_align); |
|
|
|
memcpy(pkt->data, ast->buf + st->codec->block_align * |
|
|
|
memcpy(pkt->data, ast->pkt.data + st->codec->block_align * //FIXME avoid this |
|
|
|
(ast->sub_packet_h * ast->audio_framesize / st->codec->block_align - rm->audio_pkt_cnt), |
|
|
|
st->codec->block_align); |
|
|
|
} |
|
|
|
@@ -718,13 +720,13 @@ static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) |
|
|
|
|
|
|
|
for (y = 0; y < ast->sub_packet_h; y++) |
|
|
|
for (x = 0; x < ast->sub_packet_h/2; x++) |
|
|
|
if (get_buffer(pb, ast->buf+x*2*ast->audio_framesize+y*ast->coded_framesize, ast->coded_framesize) <= 0) |
|
|
|
if (get_buffer(pb, ast->pkt.data+x*2*ast->audio_framesize+y*ast->coded_framesize, ast->coded_framesize) <= 0) |
|
|
|
return AVERROR(EIO); |
|
|
|
rm->audio_stream_num = 0; |
|
|
|
rm->audio_pkt_cnt = ast->sub_packet_h * ast->audio_framesize / st->codec->block_align - 1; |
|
|
|
// Release first audio packet |
|
|
|
av_new_packet(pkt, st->codec->block_align); |
|
|
|
memcpy(pkt->data, ast->buf, st->codec->block_align); |
|
|
|
memcpy(pkt->data, ast->pkt.data, st->codec->block_align); //FIXME avoid this |
|
|
|
pkt->flags |= PKT_FLAG_KEY; // Mark first packet as keyframe |
|
|
|
pkt->stream_index = 0; |
|
|
|
} else { |
|
|
|
|