mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
Merge commit 'b6c61fb83e876d404ac3b0b3657ebfcafdcd1926'
* commit 'b6c61fb83e876d404ac3b0b3657ebfcafdcd1926': movenc: enable Annex B to MP4 conversion for HEVC tracks. Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
a379813cee
@ -1014,6 +1014,107 @@ static int hvcc_write(AVIOContext *pb, HEVCDecoderConfigurationRecord *hvcc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_hevc_annexb2mp4(AVIOContext *pb, const uint8_t *buf_in,
|
||||
int size, int filter_ps, int *ps_count)
|
||||
{
|
||||
int num_ps = 0, ret = 0;
|
||||
uint8_t *buf, *end, *start = NULL;
|
||||
|
||||
if (!filter_ps) {
|
||||
ret = ff_avc_parse_nal_units(pb, buf_in, size);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = ff_avc_parse_nal_units_buf(buf_in, &start, &size);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
ret = 0;
|
||||
buf = start;
|
||||
end = start + size;
|
||||
|
||||
while (end - buf > 4) {
|
||||
uint32_t len = FFMIN(AV_RB32(buf), end - buf - 4);
|
||||
uint8_t type = (buf[4] >> 1) & 0x3f;
|
||||
|
||||
buf += 4;
|
||||
|
||||
switch (type) {
|
||||
case NAL_VPS:
|
||||
case NAL_SPS:
|
||||
case NAL_PPS:
|
||||
num_ps++;
|
||||
break;
|
||||
default:
|
||||
ret += 4 + len;
|
||||
avio_wb32(pb, len);
|
||||
avio_write(pb, buf, len);
|
||||
break;
|
||||
}
|
||||
|
||||
buf += len;
|
||||
}
|
||||
|
||||
end:
|
||||
free(start);
|
||||
if (ps_count)
|
||||
*ps_count = num_ps;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ff_hevc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out,
|
||||
int *size, int filter_ps, int *ps_count)
|
||||
{
|
||||
AVIOContext *pb;
|
||||
int num_ps = 0, ret = 0;
|
||||
uint8_t *buf, *end, *start = NULL;
|
||||
|
||||
if (!filter_ps) {
|
||||
ret = ff_avc_parse_nal_units_buf(buf_in, buf_out, size);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avio_open_dyn_buf(&pb);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
ret = ff_avc_parse_nal_units_buf(buf_in, &start, size);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
buf = start;
|
||||
end = start + *size;
|
||||
|
||||
while (end - buf > 4) {
|
||||
uint32_t len = FFMIN(AV_RB32(buf), end - buf - 4);
|
||||
uint8_t type = (buf[4] >> 1) & 0x3f;
|
||||
|
||||
buf += 4;
|
||||
|
||||
switch (type) {
|
||||
case NAL_VPS:
|
||||
case NAL_SPS:
|
||||
case NAL_PPS:
|
||||
num_ps++;
|
||||
break;
|
||||
default:
|
||||
avio_wb32(pb, len);
|
||||
avio_write(pb, buf, len);
|
||||
break;
|
||||
}
|
||||
|
||||
buf += len;
|
||||
}
|
||||
|
||||
*size = avio_close_dyn_buf(pb, buf_out);
|
||||
|
||||
end:
|
||||
free(start);
|
||||
if (ps_count)
|
||||
*ps_count = num_ps;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data,
|
||||
int size, int ps_array_completeness)
|
||||
{
|
||||
|
@ -29,6 +29,54 @@
|
||||
#include <stdint.h>
|
||||
#include "avio.h"
|
||||
|
||||
/**
|
||||
* Writes Annex B formatted HEVC NAL units to the provided AVIOContext.
|
||||
*
|
||||
* The NAL units are converted to an MP4-compatible format (start code prefixes
|
||||
* are replaced by 4-byte size fields, as per ISO/IEC 14496-15).
|
||||
*
|
||||
* If filter_ps is non-zero, any HEVC parameter sets found in the input will be
|
||||
* discarded, and *ps_count will be set to the number of discarded PS NAL units.
|
||||
*
|
||||
* @param pb address of the AVIOContext where the data shall be written
|
||||
* @param buf_in address of the buffer holding the input data
|
||||
* @param size size (in bytes) of the input buffer
|
||||
* @param filter_ps whether to write parameter set NAL units to the output (0)
|
||||
* or to discard them (non-zero)
|
||||
* @param ps_count address of the variable where the number of discarded
|
||||
* parameter set NAL units shall be written, may be NULL
|
||||
* @return the amount (in bytes) of data written in case of success, a negative
|
||||
* value corresponding to an AVERROR code in case of failure
|
||||
*/
|
||||
int ff_hevc_annexb2mp4(AVIOContext *pb, const uint8_t *buf_in,
|
||||
int size, int filter_ps, int *ps_count);
|
||||
|
||||
/**
|
||||
* Writes Annex B formatted HEVC NAL units to a data buffer.
|
||||
*
|
||||
* The NAL units are converted to an MP4-compatible format (start code prefixes
|
||||
* are replaced by 4-byte size fields, as per ISO/IEC 14496-15).
|
||||
*
|
||||
* If filter_ps is non-zero, any HEVC parameter sets found in the input will be
|
||||
* discarded, and *ps_count will be set to the number of discarded PS NAL units.
|
||||
*
|
||||
* On output, *size holds the size (in bytes) of the output data buffer.
|
||||
*
|
||||
* @param buf_in address of the buffer holding the input data
|
||||
* @param size address of the variable holding the size (in bytes) of the input
|
||||
* buffer (on input) and of the output buffer (on output)
|
||||
* @param buf_out address of the variable holding the address of the output
|
||||
* buffer
|
||||
* @param filter_ps whether to write parameter set NAL units to the output (0)
|
||||
* or to discard them (non-zero)
|
||||
* @param ps_count address of the variable where the number of discarded
|
||||
* parameter set NAL units shall be written, may be NULL
|
||||
* @return 0 in case of success, a negative value corresponding to an AVERROR
|
||||
* code in case of failure
|
||||
*/
|
||||
int ff_hevc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out,
|
||||
int *size, int filter_ps, int *ps_count);
|
||||
|
||||
/**
|
||||
* Writes HEVC extradata (parameter sets, declarative SEI NAL units) to the
|
||||
* provided AVIOContext.
|
||||
|
@ -3351,6 +3351,15 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
} else {
|
||||
size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size);
|
||||
}
|
||||
} else if (enc->codec_id == AV_CODEC_ID_HEVC && trk->vos_len > 6 &&
|
||||
(AV_RB24(trk->vos_data) == 1 || AV_RB32(trk->vos_data) == 1)) {
|
||||
/* extradata is Annex B, assume the bitstream is too and convert it */
|
||||
if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
|
||||
ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data, &size, 0, NULL);
|
||||
avio_write(pb, reformatted_data, size);
|
||||
} else {
|
||||
size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
|
||||
}
|
||||
} else {
|
||||
avio_write(pb, pkt->data, size);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user