add support for real audio in matroska
Originally committed as revision 9217 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		
							parent
							
								
									407a3d94f5
								
							
						
					
					
						commit
						eabb8ba445
					
				@ -53,6 +53,11 @@ CodecTags ff_mkv_codec_tags[]={
 | 
				
			|||||||
    {"A_FLAC"           , CODEC_ID_FLAC},
 | 
					    {"A_FLAC"           , CODEC_ID_FLAC},
 | 
				
			||||||
    {"A_WAVPACK4"       , CODEC_ID_WAVPACK},
 | 
					    {"A_WAVPACK4"       , CODEC_ID_WAVPACK},
 | 
				
			||||||
    {"A_TTA1"           , CODEC_ID_TTA},
 | 
					    {"A_TTA1"           , CODEC_ID_TTA},
 | 
				
			||||||
 | 
					    {"A_REAL/14_4"      , CODEC_ID_RA_144},
 | 
				
			||||||
 | 
					    {"A_REAL/28_8"      , CODEC_ID_RA_288},
 | 
				
			||||||
 | 
					    {"A_REAL/ATRC"      , CODEC_ID_ATRAC3},
 | 
				
			||||||
 | 
					    {"A_REAL/COOK"      , CODEC_ID_COOK},
 | 
				
			||||||
 | 
					//    {"A_REAL/SIPR"      , CODEC_ID_SIPRO},
 | 
				
			||||||
    {NULL               , CODEC_ID_NONE}
 | 
					    {NULL               , CODEC_ID_NONE}
 | 
				
			||||||
/* TODO: AC3-9/10 (?), Real, Musepack, Quicktime */
 | 
					/* TODO: AC3-9/10 (?), Real, Musepack, Quicktime */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -79,6 +79,16 @@ typedef struct MatroskaAudioTrack {
 | 
				
			|||||||
        bitdepth,
 | 
					        bitdepth,
 | 
				
			||||||
        internal_samplerate,
 | 
					        internal_samplerate,
 | 
				
			||||||
        samplerate;
 | 
					        samplerate;
 | 
				
			||||||
 | 
					    int block_align;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* real audio header */
 | 
				
			||||||
 | 
					    int coded_framesize;
 | 
				
			||||||
 | 
					    int sub_packet_h;
 | 
				
			||||||
 | 
					    int frame_size;
 | 
				
			||||||
 | 
					    int sub_packet_size;
 | 
				
			||||||
 | 
					    int sub_packet_cnt;
 | 
				
			||||||
 | 
					    int pkt_cnt;
 | 
				
			||||||
 | 
					    uint8_t *buf;
 | 
				
			||||||
    //..
 | 
					    //..
 | 
				
			||||||
} MatroskaAudioTrack;
 | 
					} MatroskaAudioTrack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2103,6 +2113,37 @@ matroska_read_header (AVFormatContext    *s,
 | 
				
			|||||||
                track->flags |= MATROSKA_TRACK_REAL_V;
 | 
					                track->flags |= MATROSKA_TRACK_REAL_V;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            else if (codec_id == CODEC_ID_RA_144) {
 | 
				
			||||||
 | 
					                MatroskaAudioTrack *audiotrack = (MatroskaAudioTrack *)track;
 | 
				
			||||||
 | 
					                audiotrack->samplerate = 8000;
 | 
				
			||||||
 | 
					                audiotrack->channels = 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            else if (codec_id == CODEC_ID_RA_288 ||
 | 
				
			||||||
 | 
					                     codec_id == CODEC_ID_COOK ||
 | 
				
			||||||
 | 
					                     codec_id == CODEC_ID_ATRAC3) {
 | 
				
			||||||
 | 
					                MatroskaAudioTrack *audiotrack = (MatroskaAudioTrack *)track;
 | 
				
			||||||
 | 
					                ByteIOContext b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                init_put_byte(&b, track->codec_priv, track->codec_priv_size, 0,
 | 
				
			||||||
 | 
					                              NULL, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					                url_fskip(&b, 24);
 | 
				
			||||||
 | 
					                audiotrack->coded_framesize = get_be32(&b);
 | 
				
			||||||
 | 
					                url_fskip(&b, 12);
 | 
				
			||||||
 | 
					                audiotrack->sub_packet_h    = get_be16(&b);
 | 
				
			||||||
 | 
					                audiotrack->frame_size      = get_be16(&b);
 | 
				
			||||||
 | 
					                audiotrack->sub_packet_size = get_be16(&b);
 | 
				
			||||||
 | 
					                audiotrack->buf = av_malloc(audiotrack->frame_size * audiotrack->sub_packet_h);
 | 
				
			||||||
 | 
					                if (codec_id == CODEC_ID_RA_288) {
 | 
				
			||||||
 | 
					                    audiotrack->block_align = audiotrack->coded_framesize;
 | 
				
			||||||
 | 
					                    track->codec_priv_size = 0;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    audiotrack->block_align = audiotrack->sub_packet_size;
 | 
				
			||||||
 | 
					                    extradata_offset = 78;
 | 
				
			||||||
 | 
					                    track->codec_priv_size -= extradata_offset;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (codec_id == CODEC_ID_NONE) {
 | 
					            if (codec_id == CODEC_ID_NONE) {
 | 
				
			||||||
                av_log(matroska->ctx, AV_LOG_INFO,
 | 
					                av_log(matroska->ctx, AV_LOG_INFO,
 | 
				
			||||||
                       "Unknown/unsupported CodecID %s.\n",
 | 
					                       "Unknown/unsupported CodecID %s.\n",
 | 
				
			||||||
@ -2159,6 +2200,7 @@ matroska_read_header (AVFormatContext    *s,
 | 
				
			|||||||
                st->codec->codec_type = CODEC_TYPE_AUDIO;
 | 
					                st->codec->codec_type = CODEC_TYPE_AUDIO;
 | 
				
			||||||
                st->codec->sample_rate = audiotrack->samplerate;
 | 
					                st->codec->sample_rate = audiotrack->samplerate;
 | 
				
			||||||
                st->codec->channels = audiotrack->channels;
 | 
					                st->codec->channels = audiotrack->channels;
 | 
				
			||||||
 | 
					                st->codec->block_align = audiotrack->block_align;
 | 
				
			||||||
            } else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) {
 | 
					            } else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) {
 | 
				
			||||||
                st->codec->codec_type = CODEC_TYPE_SUBTITLE;
 | 
					                st->codec->codec_type = CODEC_TYPE_SUBTITLE;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -2347,6 +2389,43 @@ matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, int size,
 | 
				
			|||||||
                    slice_size = lace_size[n] - slice_offset;
 | 
					                    slice_size = lace_size[n] - slice_offset;
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                    slice_size = rv_offset(data, slice+1, slices) - slice_offset;
 | 
					                    slice_size = rv_offset(data, slice+1, slices) - slice_offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (st->codec->codec_id == CODEC_ID_RA_288 ||
 | 
				
			||||||
 | 
					                    st->codec->codec_id == CODEC_ID_COOK ||
 | 
				
			||||||
 | 
					                    st->codec->codec_id == CODEC_ID_ATRAC3) {
 | 
				
			||||||
 | 
					                    MatroskaAudioTrack *audiotrack = (MatroskaAudioTrack *)matroska->tracks[track];
 | 
				
			||||||
 | 
					                    int a = st->codec->block_align;
 | 
				
			||||||
 | 
					                    int sps = audiotrack->sub_packet_size;
 | 
				
			||||||
 | 
					                    int cfs = audiotrack->coded_framesize;
 | 
				
			||||||
 | 
					                    int h = audiotrack->sub_packet_h;
 | 
				
			||||||
 | 
					                    int y = audiotrack->sub_packet_cnt;
 | 
				
			||||||
 | 
					                    int w = audiotrack->frame_size;
 | 
				
			||||||
 | 
					                    int x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (!audiotrack->pkt_cnt) {
 | 
				
			||||||
 | 
					                        if (st->codec->codec_id == CODEC_ID_RA_288)
 | 
				
			||||||
 | 
					                            for (x=0; x<h/2; x++)
 | 
				
			||||||
 | 
					                                memcpy(audiotrack->buf+x*2*w+y*cfs,
 | 
				
			||||||
 | 
					                                       data+x*cfs, cfs);
 | 
				
			||||||
 | 
					                        else
 | 
				
			||||||
 | 
					                            for (x=0; x<w/sps; x++)
 | 
				
			||||||
 | 
					                                memcpy(audiotrack->buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (++audiotrack->sub_packet_cnt >= h) {
 | 
				
			||||||
 | 
					                            audiotrack->sub_packet_cnt = 0;
 | 
				
			||||||
 | 
					                            audiotrack->pkt_cnt = h*w / a;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    while (audiotrack->pkt_cnt) {
 | 
				
			||||||
 | 
					                        pkt = av_mallocz(sizeof(AVPacket));
 | 
				
			||||||
 | 
					                        av_new_packet(pkt, a);
 | 
				
			||||||
 | 
					                        memcpy(pkt->data, audiotrack->buf
 | 
				
			||||||
 | 
					                               + a * (h*w / a - audiotrack->pkt_cnt--), a);
 | 
				
			||||||
 | 
					                        pkt->pos = pos;
 | 
				
			||||||
 | 
					                        pkt->stream_index = matroska->tracks[track]->stream_index;
 | 
				
			||||||
 | 
					                        matroska_queue_packet(matroska, pkt);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
                pkt = av_mallocz(sizeof(AVPacket));
 | 
					                pkt = av_mallocz(sizeof(AVPacket));
 | 
				
			||||||
                /* XXX: prevent data copy... */
 | 
					                /* XXX: prevent data copy... */
 | 
				
			||||||
                if (av_new_packet(pkt, slice_size) < 0) {
 | 
					                if (av_new_packet(pkt, slice_size) < 0) {
 | 
				
			||||||
@ -2365,6 +2444,7 @@ matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, int size,
 | 
				
			|||||||
                pkt->duration = duration;
 | 
					                pkt->duration = duration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                matroska_queue_packet(matroska, pkt);
 | 
					                matroska_queue_packet(matroska, pkt);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (timecode != AV_NOPTS_VALUE)
 | 
					                if (timecode != AV_NOPTS_VALUE)
 | 
				
			||||||
                    timecode = duration ? timecode + duration : AV_NOPTS_VALUE;
 | 
					                    timecode = duration ? timecode + duration : AV_NOPTS_VALUE;
 | 
				
			||||||
@ -2625,6 +2705,11 @@ matroska_read_close (AVFormatContext *s)
 | 
				
			|||||||
        av_free(track->name);
 | 
					        av_free(track->name);
 | 
				
			||||||
        av_free(track->language);
 | 
					        av_free(track->language);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
 | 
				
			||||||
 | 
					            MatroskaAudioTrack *audiotrack = (MatroskaAudioTrack *)track;
 | 
				
			||||||
 | 
					            av_free(audiotrack->buf);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        av_free(track);
 | 
					        av_free(track);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user