Originally committed as revision 16616 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -60,15 +60,11 @@ const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end) | |||||
| return end + 3; | return end + 3; | ||||
| } | } | ||||
| int ff_avc_parse_nal_units(const uint8_t *buf_in, uint8_t **buf, int *size) | |||||
| void ff_avc_parse_nal_units(ByteIOContext *pb, const uint8_t *buf_in, int size) | |||||
| { | { | ||||
| ByteIOContext *pb; | |||||
| const uint8_t *p = buf_in; | const uint8_t *p = buf_in; | ||||
| const uint8_t *end = p + *size; | |||||
| const uint8_t *end = p + size; | |||||
| const uint8_t *nal_start, *nal_end; | const uint8_t *nal_start, *nal_end; | ||||
| int ret = url_open_dyn_buf(&pb); | |||||
| if(ret < 0) | |||||
| return ret; | |||||
| nal_start = ff_avc_find_startcode(p, end); | nal_start = ff_avc_find_startcode(p, end); | ||||
| while (nal_start < end) { | while (nal_start < end) { | ||||
| @@ -78,6 +74,17 @@ int ff_avc_parse_nal_units(const uint8_t *buf_in, uint8_t **buf, int *size) | |||||
| put_buffer(pb, nal_start, nal_end - nal_start); | put_buffer(pb, nal_start, nal_end - nal_start); | ||||
| nal_start = nal_end; | nal_start = nal_end; | ||||
| } | } | ||||
| } | |||||
| static int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size) | |||||
| { | |||||
| ByteIOContext *pb; | |||||
| int ret = url_open_dyn_buf(&pb); | |||||
| if(ret < 0) | |||||
| return ret; | |||||
| ff_avc_parse_nal_units(pb, buf_in, *size); | |||||
| av_freep(buf); | av_freep(buf); | ||||
| *size = url_close_dyn_buf(pb, buf); | *size = url_close_dyn_buf(pb, buf); | ||||
| return 0; | return 0; | ||||
| @@ -92,7 +99,7 @@ int ff_isom_write_avcc(ByteIOContext *pb, const uint8_t *data, int len) | |||||
| uint32_t sps_size=0, pps_size=0; | uint32_t sps_size=0, pps_size=0; | ||||
| uint8_t *sps=0, *pps=0; | uint8_t *sps=0, *pps=0; | ||||
| int ret = ff_avc_parse_nal_units(data, &buf, &len); | |||||
| int ret = ff_avc_parse_nal_units_buf(data, &buf, &len); | |||||
| if (ret < 0) | if (ret < 0) | ||||
| return ret; | return ret; | ||||
| start = buf; | start = buf; | ||||
| @@ -25,7 +25,7 @@ | |||||
| #include <stdint.h> | #include <stdint.h> | ||||
| #include "avio.h" | #include "avio.h" | ||||
| int ff_avc_parse_nal_units(const uint8_t *buf_in, uint8_t **buf, int *size); | |||||
| void ff_avc_parse_nal_units(ByteIOContext *s, const uint8_t *buf, int size); | |||||
| int ff_isom_write_avcc(ByteIOContext *pb, const uint8_t *data, int len); | int ff_isom_write_avcc(ByteIOContext *pb, const uint8_t *data, int len); | ||||
| const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end); | const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end); | ||||
| @@ -341,13 +341,6 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) | |||||
| } | } | ||||
| if (enc->codec_id == CODEC_ID_H264) { | if (enc->codec_id == CODEC_ID_H264) { | ||||
| /* check if extradata looks like mp4 formated */ | |||||
| if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1) { | |||||
| if (ff_avc_parse_nal_units(pkt->data, &pkt->data, &pkt->size) < 0) | |||||
| return -1; | |||||
| assert(pkt->size); | |||||
| size = pkt->size; | |||||
| } | |||||
| if (!flv->delay && pkt->dts < 0) | if (!flv->delay && pkt->dts < 0) | ||||
| flv->delay = -pkt->dts; | flv->delay = -pkt->dts; | ||||
| } | } | ||||
| @@ -368,7 +361,13 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) | |||||
| put_byte(pb,1); // AVC NALU | put_byte(pb,1); // AVC NALU | ||||
| put_be24(pb,pkt->pts - pkt->dts); | put_be24(pb,pkt->pts - pkt->dts); | ||||
| } | } | ||||
| if (enc->codec_id == CODEC_ID_H264 && | |||||
| /* check if extradata looks like mp4 formated */ | |||||
| enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1) { | |||||
| ff_avc_parse_nal_units(pb, pkt->data, pkt->size); | |||||
| } else { | |||||
| put_buffer(pb, pkt->data, size); | put_buffer(pb, pkt->data, size); | ||||
| } | |||||
| put_be32(pb,size+flags_size+11); // previous tag size | put_be32(pb,size+flags_size+11); // previous tag size | ||||
| flv->duration = FFMAX(flv->duration, pkt->pts + flv->delay + pkt->duration); | flv->duration = FFMAX(flv->duration, pkt->pts + flv->delay + pkt->duration); | ||||
| @@ -785,6 +785,7 @@ static void mkv_write_block(AVFormatContext *s, unsigned int blockid, AVPacket * | |||||
| { | { | ||||
| MatroskaMuxContext *mkv = s->priv_data; | MatroskaMuxContext *mkv = s->priv_data; | ||||
| ByteIOContext *pb = s->pb; | ByteIOContext *pb = s->pb; | ||||
| AVCodecContext *codec = s->streams[pkt->stream_index]->codec; | |||||
| av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, " | av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, " | ||||
| "pts %" PRId64 ", dts %" PRId64 ", duration %d, flags %d\n", | "pts %" PRId64 ", dts %" PRId64 ", duration %d, flags %d\n", | ||||
| @@ -794,7 +795,14 @@ static void mkv_write_block(AVFormatContext *s, unsigned int blockid, AVPacket * | |||||
| put_byte(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126 | put_byte(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126 | ||||
| put_be16(pb, pkt->pts - mkv->cluster_pts); | put_be16(pb, pkt->pts - mkv->cluster_pts); | ||||
| put_byte(pb, flags); | put_byte(pb, flags); | ||||
| if (codec->codec_id == CODEC_ID_H264 && | |||||
| codec->extradata_size > 0 && AV_RB32(codec->extradata) == 0x00000001) { | |||||
| /* from x264 or from bytestream h264 */ | |||||
| /* nal reformating needed */ | |||||
| ff_avc_parse_nal_units(pb, pkt->data, pkt->size); | |||||
| } else { | |||||
| put_buffer(pb, pkt->data, pkt->size); | put_buffer(pb, pkt->data, pkt->size); | ||||
| } | |||||
| } | } | ||||
| static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) | static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) | ||||
| @@ -822,16 +830,6 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) | |||||
| av_md5_update(mkv->md5_ctx, pkt->data, FFMIN(200, pkt->size)); | av_md5_update(mkv->md5_ctx, pkt->data, FFMIN(200, pkt->size)); | ||||
| } | } | ||||
| if (codec->codec_id == CODEC_ID_H264 && | |||||
| codec->extradata_size > 0 && AV_RB32(codec->extradata) == 0x00000001) { | |||||
| /* from x264 or from bytestream h264 */ | |||||
| /* nal reformating needed */ | |||||
| int ret = ff_avc_parse_nal_units(pkt->data, &pkt->data, &pkt->size); | |||||
| if (ret < 0) | |||||
| return ret; | |||||
| assert(pkt->size); | |||||
| } | |||||
| if (codec->codec_type != CODEC_TYPE_SUBTITLE) { | if (codec->codec_type != CODEC_TYPE_SUBTITLE) { | ||||
| mkv_write_block(s, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe << 7); | mkv_write_block(s, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe << 7); | ||||
| } else if (codec->codec_id == CODEC_ID_SSA) { | } else if (codec->codec_id == CODEC_ID_SSA) { | ||||
| @@ -1732,15 +1732,7 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt) | |||||
| memcpy(trk->vosData, enc->extradata, trk->vosLen); | memcpy(trk->vosData, enc->extradata, trk->vosLen); | ||||
| } | } | ||||
| if (enc->codec_id == CODEC_ID_H264 && trk->vosLen > 0 && *(uint8_t *)trk->vosData != 1) { | |||||
| /* from x264 or from bytestream h264 */ | |||||
| /* nal reformating needed */ | |||||
| int ret = ff_avc_parse_nal_units(pkt->data, &pkt->data, &pkt->size); | |||||
| if (ret < 0) | |||||
| return ret; | |||||
| assert(pkt->size); | |||||
| size = pkt->size; | |||||
| } else if ((enc->codec_id == CODEC_ID_DNXHD || | |||||
| if ((enc->codec_id == CODEC_ID_DNXHD || | |||||
| enc->codec_id == CODEC_ID_AC3) && !trk->vosLen) { | enc->codec_id == CODEC_ID_AC3) && !trk->vosLen) { | ||||
| /* copy frame to create needed atoms */ | /* copy frame to create needed atoms */ | ||||
| trk->vosLen = size; | trk->vosLen = size; | ||||
| @@ -1777,7 +1769,13 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt) | |||||
| trk->sampleCount += samplesInChunk; | trk->sampleCount += samplesInChunk; | ||||
| mov->mdat_size += size; | mov->mdat_size += size; | ||||
| if (enc->codec_id == CODEC_ID_H264 && trk->vosLen > 0 && *(uint8_t *)trk->vosData != 1) { | |||||
| /* from x264 or from bytestream h264 */ | |||||
| /* nal reformating needed */ | |||||
| ff_avc_parse_nal_units(pb, pkt->data, pkt->size); | |||||
| } else { | |||||
| put_buffer(pb, pkt->data, size); | put_buffer(pb, pkt->data, size); | ||||
| } | |||||
| put_flush_packet(pb); | put_flush_packet(pb); | ||||
| return 0; | return 0; | ||||